@backstage/frontend-plugin-api 0.13.2 → 0.14.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/dist/alpha.d.ts +71 -0
- package/dist/alpha.esm.js +3 -0
- package/dist/alpha.esm.js.map +1 -0
- package/dist/apis/definitions/PluginWrapperApi.esm.js +8 -0
- package/dist/apis/definitions/PluginWrapperApi.esm.js.map +1 -0
- package/dist/apis/system/ApiRef.esm.js.map +1 -1
- package/dist/blueprints/PluginWrapperBlueprint.esm.js +24 -0
- package/dist/blueprints/PluginWrapperBlueprint.esm.js.map +1 -0
- package/dist/components/ExtensionBoundary.esm.js +18 -2
- package/dist/components/ExtensionBoundary.esm.js.map +1 -1
- package/dist/index.d.ts +81 -234
- package/dist/index.esm.js +0 -8
- package/dist/index.esm.js.map +1 -1
- package/dist/wiring/createExtension.esm.js.map +1 -1
- package/dist/wiring/createExtensionInput.esm.js +2 -1
- package/dist/wiring/createExtensionInput.esm.js.map +1 -1
- package/dist/wiring/createFrontendPlugin.esm.js +1 -0
- package/dist/wiring/createFrontendPlugin.esm.js.map +1 -1
- package/dist/wiring/resolveInputOverrides.esm.js.map +1 -1
- package/package.json +19 -11
- package/dist/blueprints/AppRootWrapperBlueprint.esm.js +0 -21
- package/dist/blueprints/AppRootWrapperBlueprint.esm.js.map +0 -1
- package/dist/blueprints/IconBundleBlueprint.esm.js +0 -21
- package/dist/blueprints/IconBundleBlueprint.esm.js.map +0 -1
- package/dist/blueprints/NavContentBlueprint.esm.js +0 -23
- package/dist/blueprints/NavContentBlueprint.esm.js.map +0 -1
- package/dist/blueprints/RouterBlueprint.esm.js +0 -21
- package/dist/blueprints/RouterBlueprint.esm.js.map +0 -1
- package/dist/blueprints/SignInPageBlueprint.esm.js +0 -52
- package/dist/blueprints/SignInPageBlueprint.esm.js.map +0 -1
- package/dist/blueprints/SwappableComponentBlueprint.esm.js +0 -27
- package/dist/blueprints/SwappableComponentBlueprint.esm.js.map +0 -1
- package/dist/blueprints/ThemeBlueprint.esm.js +0 -21
- package/dist/blueprints/ThemeBlueprint.esm.js.map +0 -1
- package/dist/blueprints/TranslationBlueprint.esm.js +0 -21
- package/dist/blueprints/TranslationBlueprint.esm.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, JSX as JSX$1, ComponentType, PropsWithChildren } from 'react';
|
|
4
4
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
5
|
-
import { IconComponent as IconComponent$1, RouteRef as RouteRef$1 } from '@backstage/frontend-plugin-api';
|
|
6
5
|
import { Expand, JsonObject, Observable, JsonValue, ExpandRecursive } from '@backstage/types';
|
|
7
6
|
import { z } from 'zod';
|
|
8
7
|
import { Config } from '@backstage/config';
|
|
@@ -132,9 +131,11 @@ interface ExtensionInput<UExtensionData extends ExtensionDataRef<unknown, string
|
|
|
132
131
|
}> = ExtensionDataRef, TConfig extends {
|
|
133
132
|
singleton: boolean;
|
|
134
133
|
optional: boolean;
|
|
134
|
+
internal?: boolean;
|
|
135
135
|
} = {
|
|
136
136
|
singleton: boolean;
|
|
137
137
|
optional: boolean;
|
|
138
|
+
internal?: boolean;
|
|
138
139
|
}> {
|
|
139
140
|
readonly $$type: '@backstage/ExtensionInput';
|
|
140
141
|
readonly extensionData: Array<UExtensionData>;
|
|
@@ -144,12 +145,59 @@ interface ExtensionInput<UExtensionData extends ExtensionDataRef<unknown, string
|
|
|
144
145
|
input: string;
|
|
145
146
|
}>;
|
|
146
147
|
}
|
|
147
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Creates a new extension input to be passed to the input map of an extension.
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
*
|
|
153
|
+
* Extension inputs created with this function can be passed to any `inputs` map
|
|
154
|
+
* as part of creating or overriding an extension.
|
|
155
|
+
*
|
|
156
|
+
* The array of extension data references defines the data this input expects.
|
|
157
|
+
* If the required data is not provided by the attached extension, the
|
|
158
|
+
* attachment will fail.
|
|
159
|
+
*
|
|
160
|
+
* The `config` object can be used to restrict the behavior and shape of the
|
|
161
|
+
* input. By default an input will accept zero or more extensions from any
|
|
162
|
+
* plugin. The following options are available:
|
|
163
|
+
*
|
|
164
|
+
* - `singleton`: If set to `true`, only one extension can be attached to the
|
|
165
|
+
* input at a time. Additional extensions will trigger an app error and be
|
|
166
|
+
* ignored.
|
|
167
|
+
* - `optional`: If set to `true`, the input is optional and can be omitted,
|
|
168
|
+
* this only has an effect if the `singleton` is set to `true`.
|
|
169
|
+
* - `internal`: If set to `true`, only extensions from the same plugin will be
|
|
170
|
+
* allowed to attach to this input. Other extensions will trigger an app error
|
|
171
|
+
* and be ignored.
|
|
172
|
+
*
|
|
173
|
+
* @param extensionData - The array of extension data references that this input
|
|
174
|
+
* expects.
|
|
175
|
+
* @param config - The configuration object for the input.
|
|
176
|
+
* @returns An extension input declaration.
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* const extension = createExtension({
|
|
180
|
+
* attachTo: { id: 'example-parent', input: 'example-input' },
|
|
181
|
+
* inputs: {
|
|
182
|
+
* content: createExtensionInput([coreExtensionData.reactElement], {
|
|
183
|
+
* singleton: true,
|
|
184
|
+
* }),
|
|
185
|
+
* },
|
|
186
|
+
* output: [coreExtensionData.reactElement],
|
|
187
|
+
* *factory({ inputs }) {
|
|
188
|
+
* const content = inputs.content?.get(coreExtensionData.reactElement);
|
|
189
|
+
* yield coreExtensionData.reactElement(<ContentWrapper>{content}</ContentWrapper>);
|
|
190
|
+
* },
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
* @public
|
|
194
|
+
*/
|
|
148
195
|
declare function createExtensionInput<UExtensionData extends ExtensionDataRef<unknown, string, {
|
|
149
196
|
optional?: true;
|
|
150
197
|
}>, TConfig extends {
|
|
151
198
|
singleton?: boolean;
|
|
152
199
|
optional?: boolean;
|
|
200
|
+
internal?: boolean;
|
|
153
201
|
}>(extensionData: Array<UExtensionData>, config?: TConfig & {
|
|
154
202
|
replaces?: Array<{
|
|
155
203
|
id: string;
|
|
@@ -158,6 +206,7 @@ declare function createExtensionInput<UExtensionData extends ExtensionDataRef<un
|
|
|
158
206
|
}): ExtensionInput<UExtensionData, {
|
|
159
207
|
singleton: TConfig['singleton'] extends true ? true : false;
|
|
160
208
|
optional: TConfig['optional'] extends true ? true : false;
|
|
209
|
+
internal: TConfig['internal'] extends true ? true : false;
|
|
161
210
|
}>;
|
|
162
211
|
|
|
163
212
|
/** @ignore */
|
|
@@ -169,17 +218,21 @@ type ResolvedInputValueOverrides<TInputs extends {
|
|
|
169
218
|
[KName in keyof TInputs as TInputs[KName] extends ExtensionInput<any, {
|
|
170
219
|
optional: infer IOptional extends boolean;
|
|
171
220
|
singleton: boolean;
|
|
221
|
+
internal?: boolean;
|
|
172
222
|
}> ? IOptional extends true ? never : KName : never]: TInputs[KName] extends ExtensionInput<infer IDataRefs, {
|
|
173
223
|
optional: boolean;
|
|
174
224
|
singleton: infer ISingleton extends boolean;
|
|
225
|
+
internal?: boolean;
|
|
175
226
|
}> ? ISingleton extends true ? Iterable<ExtensionDataRefToValue<IDataRefs>> : Array<Iterable<ExtensionDataRefToValue<IDataRefs>>> : never;
|
|
176
227
|
} & {
|
|
177
228
|
[KName in keyof TInputs as TInputs[KName] extends ExtensionInput<any, {
|
|
178
229
|
optional: infer IOptional extends boolean;
|
|
179
230
|
singleton: boolean;
|
|
231
|
+
internal?: boolean;
|
|
180
232
|
}> ? IOptional extends true ? KName : never : never]?: TInputs[KName] extends ExtensionInput<infer IDataRefs, {
|
|
181
233
|
optional: boolean;
|
|
182
234
|
singleton: infer ISingleton extends boolean;
|
|
235
|
+
internal?: boolean;
|
|
183
236
|
}> ? ISingleton extends true ? Iterable<ExtensionDataRefToValue<IDataRefs>> : Array<Iterable<ExtensionDataRefToValue<IDataRefs>>> : never;
|
|
184
237
|
}>;
|
|
185
238
|
|
|
@@ -529,6 +582,15 @@ interface FrontendPlugin<TRoutes extends {
|
|
|
529
582
|
[name in string]: ExternalRouteRef;
|
|
530
583
|
}> {
|
|
531
584
|
readonly $$type: '@backstage/FrontendPlugin';
|
|
585
|
+
/**
|
|
586
|
+
* The plugin ID.
|
|
587
|
+
*/
|
|
588
|
+
readonly pluginId: string;
|
|
589
|
+
/**
|
|
590
|
+
* Deprecated alias for `pluginId`.
|
|
591
|
+
*
|
|
592
|
+
* @deprecated Use `pluginId` instead.
|
|
593
|
+
*/
|
|
532
594
|
readonly id: string;
|
|
533
595
|
readonly routes: TRoutes;
|
|
534
596
|
readonly externalRoutes: TExternalRoutes;
|
|
@@ -930,7 +992,7 @@ type VerifyExtensionAttachTo<UOutput extends ExtensionDataRef, UParentInput exte
|
|
|
930
992
|
* const page = ParentBlueprint.make({ ... });
|
|
931
993
|
* const child = ChildBlueprint.make({ attachTo: page.inputs.children });
|
|
932
994
|
*
|
|
933
|
-
* // Attach to multiple parents at once
|
|
995
|
+
* // Attach to multiple parents at once (deprecated - use Utility APIs instead)
|
|
934
996
|
* [
|
|
935
997
|
* { id: 'page/home', input: 'widgets' },
|
|
936
998
|
* { relative: { kind: 'page' }, input: 'widgets' },
|
|
@@ -950,7 +1012,11 @@ type ExtensionDefinitionAttachTo<UParentInputs extends ExtensionDataRef = Extens
|
|
|
950
1012
|
};
|
|
951
1013
|
input: string;
|
|
952
1014
|
id?: never;
|
|
953
|
-
} | ExtensionInput<UParentInputs>
|
|
1015
|
+
} | ExtensionInput<UParentInputs>
|
|
1016
|
+
/**
|
|
1017
|
+
* @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.
|
|
1018
|
+
*/
|
|
1019
|
+
| Array<{
|
|
954
1020
|
id: string;
|
|
955
1021
|
input: string;
|
|
956
1022
|
relative?: never;
|
|
@@ -1323,7 +1389,15 @@ type ApiRefConfig = {
|
|
|
1323
1389
|
id: string;
|
|
1324
1390
|
};
|
|
1325
1391
|
/**
|
|
1326
|
-
* Creates a reference to an API.
|
|
1392
|
+
* Creates a reference to an API. The provided `id` is a stable identifier for
|
|
1393
|
+
* the API implementation.
|
|
1394
|
+
*
|
|
1395
|
+
* @remarks
|
|
1396
|
+
*
|
|
1397
|
+
* The frontend system infers the owning plugin for an API from the `id`. The
|
|
1398
|
+
* recommended pattern is `plugin.<plugin-id>.*` (for example,
|
|
1399
|
+
* `plugin.catalog.entity-presentation`). This ensures that other plugins can't
|
|
1400
|
+
* mistakenly override your API implementation.
|
|
1327
1401
|
*
|
|
1328
1402
|
* @param config - The descriptor of the API to reference.
|
|
1329
1403
|
* @returns An API reference.
|
|
@@ -3182,101 +3256,6 @@ declare const AppRootElementBlueprint: _backstage_frontend_plugin_api.ExtensionB
|
|
|
3182
3256
|
dataRefs: never;
|
|
3183
3257
|
}>;
|
|
3184
3258
|
|
|
3185
|
-
/**
|
|
3186
|
-
* Creates a extensions that render a React wrapper at the app root, enclosing
|
|
3187
|
-
* the app layout. This is useful for example for adding global React contexts
|
|
3188
|
-
* and similar.
|
|
3189
|
-
*
|
|
3190
|
-
* @public
|
|
3191
|
-
*/
|
|
3192
|
-
declare const AppRootWrapperBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3193
|
-
kind: "app-root-wrapper";
|
|
3194
|
-
params: {
|
|
3195
|
-
/** @deprecated use the `component` parameter instead */
|
|
3196
|
-
Component?: [error: "Use the `component` parameter instead"];
|
|
3197
|
-
component: (props: {
|
|
3198
|
-
children: ReactNode;
|
|
3199
|
-
}) => JSX.Element | null;
|
|
3200
|
-
};
|
|
3201
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<(props: {
|
|
3202
|
-
children: ReactNode;
|
|
3203
|
-
}) => JSX.Element | null, "app.root.wrapper", {}>;
|
|
3204
|
-
inputs: {};
|
|
3205
|
-
config: {};
|
|
3206
|
-
configInput: {};
|
|
3207
|
-
dataRefs: {
|
|
3208
|
-
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: {
|
|
3209
|
-
children: ReactNode;
|
|
3210
|
-
}) => JSX.Element | null, "app.root.wrapper", {}>;
|
|
3211
|
-
};
|
|
3212
|
-
}>;
|
|
3213
|
-
|
|
3214
|
-
/** @public */
|
|
3215
|
-
declare const IconBundleBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3216
|
-
kind: "icon-bundle";
|
|
3217
|
-
params: {
|
|
3218
|
-
icons: { [key in string]: IconComponent; };
|
|
3219
|
-
};
|
|
3220
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
3221
|
-
[x: string]: IconComponent;
|
|
3222
|
-
}, "core.icons", {}>;
|
|
3223
|
-
inputs: {};
|
|
3224
|
-
config: {};
|
|
3225
|
-
configInput: {};
|
|
3226
|
-
dataRefs: {
|
|
3227
|
-
icons: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
|
|
3228
|
-
[x: string]: IconComponent;
|
|
3229
|
-
}, "core.icons", {}>;
|
|
3230
|
-
};
|
|
3231
|
-
}>;
|
|
3232
|
-
|
|
3233
|
-
/**
|
|
3234
|
-
* The props for the {@link NavContentComponent}.
|
|
3235
|
-
*
|
|
3236
|
-
* @public
|
|
3237
|
-
*/
|
|
3238
|
-
interface NavContentComponentProps {
|
|
3239
|
-
/**
|
|
3240
|
-
* The nav items available to the component. These are all the items created
|
|
3241
|
-
* with the {@link NavItemBlueprint} in the app.
|
|
3242
|
-
*
|
|
3243
|
-
* In addition to the original properties from the nav items, these also
|
|
3244
|
-
* include a resolved route path as `to`, and duplicated `title` as `text` to
|
|
3245
|
-
* simplify rendering.
|
|
3246
|
-
*/
|
|
3247
|
-
items: Array<{
|
|
3248
|
-
icon: IconComponent$1;
|
|
3249
|
-
title: string;
|
|
3250
|
-
routeRef: RouteRef$1<undefined>;
|
|
3251
|
-
to: string;
|
|
3252
|
-
text: string;
|
|
3253
|
-
}>;
|
|
3254
|
-
}
|
|
3255
|
-
/**
|
|
3256
|
-
* A component that renders the nav bar content, to be passed to the {@link NavContentBlueprint}.
|
|
3257
|
-
*
|
|
3258
|
-
* @public
|
|
3259
|
-
*/
|
|
3260
|
-
type NavContentComponent = (props: NavContentComponentProps) => JSX.Element | null;
|
|
3261
|
-
/**
|
|
3262
|
-
* Creates an extension that replaces the entire nav bar with your own component.
|
|
3263
|
-
*
|
|
3264
|
-
* @public
|
|
3265
|
-
*/
|
|
3266
|
-
declare const NavContentBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3267
|
-
kind: "nav-content";
|
|
3268
|
-
params: {
|
|
3269
|
-
component: NavContentComponent;
|
|
3270
|
-
};
|
|
3271
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<NavContentComponent, "core.nav-content.component", {}>;
|
|
3272
|
-
inputs: {};
|
|
3273
|
-
config: {};
|
|
3274
|
-
configInput: {};
|
|
3275
|
-
dataRefs: {
|
|
3276
|
-
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<NavContentComponent, "core.nav-content.component", {}>;
|
|
3277
|
-
};
|
|
3278
|
-
}>;
|
|
3279
|
-
|
|
3280
3259
|
/**
|
|
3281
3260
|
* Creates extensions that make up the items of the nav bar.
|
|
3282
3261
|
*
|
|
@@ -3335,137 +3314,5 @@ declare const PageBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
|
3335
3314
|
dataRefs: never;
|
|
3336
3315
|
}>;
|
|
3337
3316
|
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
kind: "app-router-component";
|
|
3341
|
-
params: {
|
|
3342
|
-
/** @deprecated use the `component` parameter instead */
|
|
3343
|
-
Component?: [error: "Use the `component` parameter instead"];
|
|
3344
|
-
component: (props: {
|
|
3345
|
-
children: ReactNode;
|
|
3346
|
-
}) => JSX.Element | null;
|
|
3347
|
-
};
|
|
3348
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<(props: {
|
|
3349
|
-
children: ReactNode;
|
|
3350
|
-
}) => JSX.Element | null, "app.router.wrapper", {}>;
|
|
3351
|
-
inputs: {};
|
|
3352
|
-
config: {};
|
|
3353
|
-
configInput: {};
|
|
3354
|
-
dataRefs: {
|
|
3355
|
-
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: {
|
|
3356
|
-
children: ReactNode;
|
|
3357
|
-
}) => JSX.Element | null, "app.router.wrapper", {}>;
|
|
3358
|
-
};
|
|
3359
|
-
}>;
|
|
3360
|
-
|
|
3361
|
-
/**
|
|
3362
|
-
* Props for the `SignInPage` component.
|
|
3363
|
-
*
|
|
3364
|
-
* @public
|
|
3365
|
-
*/
|
|
3366
|
-
type SignInPageProps = {
|
|
3367
|
-
/**
|
|
3368
|
-
* Set the IdentityApi on successful sign-in. This should only be called once.
|
|
3369
|
-
*/
|
|
3370
|
-
onSignInSuccess(identityApi: IdentityApi): void;
|
|
3371
|
-
/**
|
|
3372
|
-
* The children to render.
|
|
3373
|
-
*/
|
|
3374
|
-
children?: ReactNode;
|
|
3375
|
-
};
|
|
3376
|
-
/**
|
|
3377
|
-
* Creates an extension that replaces the sign in page.
|
|
3378
|
-
*
|
|
3379
|
-
* @public
|
|
3380
|
-
*/
|
|
3381
|
-
declare const SignInPageBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3382
|
-
kind: "sign-in-page";
|
|
3383
|
-
params: {
|
|
3384
|
-
loader: () => Promise<ComponentType<SignInPageProps>>;
|
|
3385
|
-
};
|
|
3386
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<ComponentType<SignInPageProps>, "core.sign-in-page.component", {}>;
|
|
3387
|
-
inputs: {};
|
|
3388
|
-
config: {};
|
|
3389
|
-
configInput: {};
|
|
3390
|
-
dataRefs: {
|
|
3391
|
-
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<ComponentType<SignInPageProps>, "core.sign-in-page.component", {}>;
|
|
3392
|
-
};
|
|
3393
|
-
}>;
|
|
3394
|
-
|
|
3395
|
-
/**
|
|
3396
|
-
* Creates an extension that adds/replaces an app theme.
|
|
3397
|
-
*
|
|
3398
|
-
* @public
|
|
3399
|
-
*/
|
|
3400
|
-
declare const ThemeBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3401
|
-
kind: "theme";
|
|
3402
|
-
params: {
|
|
3403
|
-
theme: AppTheme;
|
|
3404
|
-
};
|
|
3405
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<AppTheme, "core.theme.theme", {}>;
|
|
3406
|
-
inputs: {};
|
|
3407
|
-
config: {};
|
|
3408
|
-
configInput: {};
|
|
3409
|
-
dataRefs: {
|
|
3410
|
-
theme: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<AppTheme, "core.theme.theme", {}>;
|
|
3411
|
-
};
|
|
3412
|
-
}>;
|
|
3413
|
-
|
|
3414
|
-
/**
|
|
3415
|
-
* Creates an extension that adds translations to your app.
|
|
3416
|
-
*
|
|
3417
|
-
* @public
|
|
3418
|
-
*/
|
|
3419
|
-
declare const TranslationBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3420
|
-
kind: "translation";
|
|
3421
|
-
params: {
|
|
3422
|
-
resource: TranslationResource | TranslationMessages;
|
|
3423
|
-
};
|
|
3424
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<TranslationResource<string> | TranslationMessages<string, {
|
|
3425
|
-
[x: string]: string;
|
|
3426
|
-
}, boolean>, "core.translation.translation", {}>;
|
|
3427
|
-
inputs: {};
|
|
3428
|
-
config: {};
|
|
3429
|
-
configInput: {};
|
|
3430
|
-
dataRefs: {
|
|
3431
|
-
translation: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<TranslationResource<string> | TranslationMessages<string, {
|
|
3432
|
-
[x: string]: string;
|
|
3433
|
-
}, boolean>, "core.translation.translation", {}>;
|
|
3434
|
-
};
|
|
3435
|
-
}>;
|
|
3436
|
-
|
|
3437
|
-
/**
|
|
3438
|
-
* Blueprint for creating swappable components from a SwappableComponentRef and a loader
|
|
3439
|
-
*
|
|
3440
|
-
* @public
|
|
3441
|
-
*/
|
|
3442
|
-
declare const SwappableComponentBlueprint: _backstage_frontend_plugin_api.ExtensionBlueprint<{
|
|
3443
|
-
kind: "component";
|
|
3444
|
-
params: <Ref extends SwappableComponentRef<any>>(params: {
|
|
3445
|
-
component: Ref extends SwappableComponentRef<any, infer IExternalComponentProps> ? {
|
|
3446
|
-
ref: Ref;
|
|
3447
|
-
} & ((props: IExternalComponentProps) => JSX.Element | null) : never;
|
|
3448
|
-
loader: Ref extends SwappableComponentRef<infer IInnerComponentProps, any> ? (() => (props: IInnerComponentProps) => JSX.Element | null) | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) : never;
|
|
3449
|
-
}) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<{
|
|
3450
|
-
component: Ref extends SwappableComponentRef<any, infer IExternalComponentProps> ? {
|
|
3451
|
-
ref: Ref;
|
|
3452
|
-
} & ((props: IExternalComponentProps) => JSX.Element | null) : never;
|
|
3453
|
-
loader: Ref extends SwappableComponentRef<infer IInnerComponentProps, any> ? (() => (props: IInnerComponentProps) => JSX.Element | null) | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) : never;
|
|
3454
|
-
}>;
|
|
3455
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
3456
|
-
ref: SwappableComponentRef;
|
|
3457
|
-
loader: (() => (props: {}) => JSX.Element | null) | (() => Promise<(props: {}) => JSX.Element | null>);
|
|
3458
|
-
}, "core.swappableComponent", {}>;
|
|
3459
|
-
inputs: {};
|
|
3460
|
-
config: {};
|
|
3461
|
-
configInput: {};
|
|
3462
|
-
dataRefs: {
|
|
3463
|
-
component: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
|
|
3464
|
-
ref: SwappableComponentRef;
|
|
3465
|
-
loader: (() => (props: {}) => JSX.Element | null) | (() => Promise<(props: {}) => JSX.Element | null>);
|
|
3466
|
-
}, "core.swappableComponent", {}>;
|
|
3467
|
-
};
|
|
3468
|
-
}>;
|
|
3469
|
-
|
|
3470
|
-
export { AnalyticsContext, AnalyticsImplementationBlueprint, ApiBlueprint, AppRootElementBlueprint, AppRootWrapperBlueprint, ErrorDisplay, ExtensionBoundary, FeatureFlagState, IconBundleBlueprint, NavContentBlueprint, NavItemBlueprint, NotFoundErrorPage, PageBlueprint, Progress, RouterBlueprint, SessionState, SignInPageBlueprint, SwappableComponentBlueprint, ThemeBlueprint, TranslationBlueprint, alertApiRef, analyticsApiRef, appLanguageApiRef, appThemeApiRef, appTreeApiRef, atlassianAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, configApiRef, coreExtensionData, createApiFactory, createApiRef, createExtension, createExtensionBlueprint, createExtensionBlueprintParams, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, createSwappableComponent, createTranslationMessages, createTranslationRef, createTranslationResource, dialogApiRef, discoveryApiRef, errorApiRef, featureFlagsApiRef, fetchApiRef, githubAuthApiRef, gitlabAuthApiRef, googleAuthApiRef, iconsApiRef, identityApiRef, microsoftAuthApiRef, oauthRequestApiRef, oktaAuthApiRef, oneloginAuthApiRef, openshiftAuthApiRef, routeResolutionApiRef, storageApiRef, swappableComponentsApiRef, translationApiRef, useAnalytics, useApi, useApiHolder, useAppNode, useRouteRef, useRouteRefParams, useTranslationRef, vmwareCloudAuthApiRef, withApis };
|
|
3471
|
-
export type { AlertApi, AlertMessage, AnalyticsApi, AnalyticsContextValue, AnalyticsEvent, AnalyticsEventAttributes, AnalyticsImplementation, AnalyticsImplementationFactory, AnalyticsTracker, AnyApiFactory, AnyApiRef, AnyExtensionDataRef, AnyRouteRefParams, ApiFactory, ApiHolder, ApiRef, ApiRefConfig, AppLanguageApi, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTheme, AppThemeApi, AppTree, AppTreeApi, AuthProviderInfo, AuthRequestOptions, BackstageIdentityApi, BackstageIdentityResponse, BackstageUserIdentity, ConfigApi, ConfigurableExtensionDataRef, CreateExtensionBlueprintOptions, CreateExtensionOptions, CreateFrontendFeatureLoaderOptions, CreateFrontendModuleOptions, CreateSwappableComponentOptions, DialogApi, DialogApiDialog, DiscoveryApi, ErrorApi, ErrorApiError, ErrorApiErrorContext, ErrorDisplayProps, Extension, ExtensionAttachTo, ExtensionAttachToSpec, ExtensionBlueprint, ExtensionBlueprintDefineParams, ExtensionBlueprintParameters, ExtensionBlueprintParams, ExtensionBoundaryProps, ExtensionDataContainer, ExtensionDataRef, ExtensionDataRefToValue, ExtensionDataValue, ExtensionDefinition, ExtensionDefinitionAttachTo, ExtensionDefinitionParameters, ExtensionFactoryMiddleware, ExtensionInput, ExternalRouteRef, FeatureFlag, FeatureFlagConfig, FeatureFlagsApi, FeatureFlagsSaveOptions, FetchApi, FrontendFeature, FrontendFeatureLoader, FrontendModule, FrontendPlugin, FrontendPluginInfo, FrontendPluginInfoOptions, IconComponent, IconsApi, IdentityApi, NavContentComponent, NavContentComponentProps, NotFoundErrorPageProps, OAuthApi, OAuthRequestApi, OAuthRequester, OAuthRequesterOptions, OAuthScope, OpenIdConnectApi, OverridableExtensionDefinition, OverridableFrontendPlugin, PendingOAuthRequest, PluginOptions, PortableSchema, ProfileInfo, ProfileInfoApi, ProgressProps, ResolvedExtensionInput, ResolvedExtensionInputs, RouteFunc, RouteRef, RouteResolutionApi, SessionApi, SignInPageProps, StorageApi, StorageValueSnapshot, SubRouteRef, SwappableComponentRef, SwappableComponentsApi, TranslationApi, TranslationFunction, TranslationMessages, TranslationMessagesOptions, TranslationRef, TranslationRefOptions, TranslationResource, TranslationResourceOptions, TranslationSnapshot, TypesToApiRefs };
|
|
3317
|
+
export { AnalyticsContext, AnalyticsImplementationBlueprint, ApiBlueprint, AppRootElementBlueprint, ErrorDisplay, ExtensionBoundary, FeatureFlagState, NavItemBlueprint, NotFoundErrorPage, PageBlueprint, Progress, SessionState, alertApiRef, analyticsApiRef, appLanguageApiRef, appThemeApiRef, appTreeApiRef, atlassianAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, configApiRef, coreExtensionData, createApiFactory, createApiRef, createExtension, createExtensionBlueprint, createExtensionBlueprintParams, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, createSwappableComponent, createTranslationMessages, createTranslationRef, createTranslationResource, dialogApiRef, discoveryApiRef, errorApiRef, featureFlagsApiRef, fetchApiRef, githubAuthApiRef, gitlabAuthApiRef, googleAuthApiRef, iconsApiRef, identityApiRef, microsoftAuthApiRef, oauthRequestApiRef, oktaAuthApiRef, oneloginAuthApiRef, openshiftAuthApiRef, routeResolutionApiRef, storageApiRef, swappableComponentsApiRef, translationApiRef, useAnalytics, useApi, useApiHolder, useAppNode, useRouteRef, useRouteRefParams, useTranslationRef, vmwareCloudAuthApiRef, withApis };
|
|
3318
|
+
export type { AlertApi, AlertMessage, AnalyticsApi, AnalyticsContextValue, AnalyticsEvent, AnalyticsEventAttributes, AnalyticsImplementation, AnalyticsImplementationFactory, AnalyticsTracker, AnyApiFactory, AnyApiRef, AnyExtensionDataRef, AnyRouteRefParams, ApiFactory, ApiHolder, ApiRef, ApiRefConfig, AppLanguageApi, AppNode, AppNodeEdges, AppNodeInstance, AppNodeSpec, AppTheme, AppThemeApi, AppTree, AppTreeApi, AuthProviderInfo, AuthRequestOptions, BackstageIdentityApi, BackstageIdentityResponse, BackstageUserIdentity, ConfigApi, ConfigurableExtensionDataRef, CreateExtensionBlueprintOptions, CreateExtensionOptions, CreateFrontendFeatureLoaderOptions, CreateFrontendModuleOptions, CreateSwappableComponentOptions, DialogApi, DialogApiDialog, DiscoveryApi, ErrorApi, ErrorApiError, ErrorApiErrorContext, ErrorDisplayProps, Extension, ExtensionAttachTo, ExtensionAttachToSpec, ExtensionBlueprint, ExtensionBlueprintDefineParams, ExtensionBlueprintParameters, ExtensionBlueprintParams, ExtensionBoundaryProps, ExtensionDataContainer, ExtensionDataRef, ExtensionDataRefToValue, ExtensionDataValue, ExtensionDefinition, ExtensionDefinitionAttachTo, ExtensionDefinitionParameters, ExtensionFactoryMiddleware, ExtensionInput, ExternalRouteRef, FeatureFlag, FeatureFlagConfig, FeatureFlagsApi, FeatureFlagsSaveOptions, FetchApi, FrontendFeature, FrontendFeatureLoader, FrontendModule, FrontendPlugin, FrontendPluginInfo, FrontendPluginInfoOptions, IconComponent, IconsApi, IdentityApi, NotFoundErrorPageProps, OAuthApi, OAuthRequestApi, OAuthRequester, OAuthRequesterOptions, OAuthScope, OpenIdConnectApi, OverridableExtensionDefinition, OverridableFrontendPlugin, PendingOAuthRequest, PluginOptions, PortableSchema, ProfileInfo, ProfileInfoApi, ProgressProps, ResolvedExtensionInput, ResolvedExtensionInputs, RouteFunc, RouteRef, RouteResolutionApi, SessionApi, StorageApi, StorageValueSnapshot, SubRouteRef, SwappableComponentRef, SwappableComponentsApi, TranslationApi, TranslationFunction, TranslationMessages, TranslationMessagesOptions, TranslationRef, TranslationRefOptions, TranslationResource, TranslationResourceOptions, TranslationSnapshot, TypesToApiRefs };
|
package/dist/index.esm.js
CHANGED
|
@@ -25,16 +25,8 @@ export { createApiFactory } from './apis/system/helpers.esm.js';
|
|
|
25
25
|
export { AnalyticsImplementationBlueprint } from './blueprints/AnalyticsImplementationBlueprint.esm.js';
|
|
26
26
|
export { ApiBlueprint } from './blueprints/ApiBlueprint.esm.js';
|
|
27
27
|
export { AppRootElementBlueprint } from './blueprints/AppRootElementBlueprint.esm.js';
|
|
28
|
-
export { AppRootWrapperBlueprint } from './blueprints/AppRootWrapperBlueprint.esm.js';
|
|
29
|
-
export { IconBundleBlueprint } from './blueprints/IconBundleBlueprint.esm.js';
|
|
30
|
-
export { NavContentBlueprint } from './blueprints/NavContentBlueprint.esm.js';
|
|
31
28
|
export { NavItemBlueprint } from './blueprints/NavItemBlueprint.esm.js';
|
|
32
29
|
export { PageBlueprint } from './blueprints/PageBlueprint.esm.js';
|
|
33
|
-
export { RouterBlueprint } from './blueprints/RouterBlueprint.esm.js';
|
|
34
|
-
export { SignInPageBlueprint } from './blueprints/SignInPageBlueprint.esm.js';
|
|
35
|
-
export { ThemeBlueprint } from './blueprints/ThemeBlueprint.esm.js';
|
|
36
|
-
export { TranslationBlueprint } from './blueprints/TranslationBlueprint.esm.js';
|
|
37
|
-
export { SwappableComponentBlueprint } from './blueprints/SwappableComponentBlueprint.esm.js';
|
|
38
30
|
export { ExtensionBoundary } from './components/ExtensionBoundary.esm.js';
|
|
39
31
|
export { createSwappableComponent } from './components/createSwappableComponent.esm.js';
|
|
40
32
|
export { useAppNode } from './components/AppNodeProvider.esm.js';
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExtension.esm.js","sources":["../../src/wiring/createExtension.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ApiHolder, AppNode } from '../apis';\nimport { Expand } from '@backstage/types';\nimport {\n ResolvedInputValueOverrides,\n resolveInputOverrides,\n} from './resolveInputOverrides';\nimport {\n createExtensionDataContainer,\n OpaqueExtensionInput,\n} from '@internal/frontend';\nimport { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef';\nimport { ExtensionInput } from './createExtensionInput';\nimport type { z } from 'zod';\nimport { createSchemaFromZod } from '../schema/createSchemaFromZod';\nimport { OpaqueExtensionDefinition } from '@internal/frontend';\nimport { ExtensionDataContainer } from './types';\nimport {\n ExtensionBlueprint,\n ExtensionBlueprintDefineParams,\n} from './createExtensionBlueprint';\nimport { FrontendPlugin } from './createFrontendPlugin';\nimport { FrontendModule } from './createFrontendModule';\n\n/**\n * This symbol is used to pass parameter overrides from the extension override to the blueprint factory\n * @internal\n */\nexport const ctxParamsSymbol = Symbol('params');\n\n/**\n * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<TExtensionInput extends ExtensionInput> =\n TExtensionInput['extensionData'] extends Array<ExtensionDataRef>\n ? {\n node: AppNode;\n } & ExtensionDataContainer<TExtensionInput['extensionData'][number]>\n : never;\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends {\n [name in string]: ExtensionInput;\n },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]>>\n : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;\n};\n\ntype ToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype PopUnion<U> = ToIntersection<\n U extends any ? () => U : never\n> extends () => infer R\n ? [rest: Exclude<U, R>, next: R]\n : undefined;\n\n/** @ignore */\ntype JoinStringUnion<\n U,\n TDiv extends string = ', ',\n TResult extends string = '',\n> = PopUnion<U> extends [infer IRest extends string, infer INext extends string]\n ? TResult extends ''\n ? JoinStringUnion<IRest, TDiv, INext>\n : JoinStringUnion<IRest, TDiv, `${TResult}${TDiv}${INext}`>\n : TResult;\n\n/** @ignore */\nexport type RequiredExtensionIds<UExtensionData extends ExtensionDataRef> =\n UExtensionData extends any\n ? UExtensionData['config']['optional'] extends true\n ? never\n : UExtensionData['id']\n : never;\n\n/** @ignore */\nexport type VerifyExtensionFactoryOutput<\n UDeclaredOutput extends ExtensionDataRef,\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = [RequiredExtensionIds<UDeclaredOutput>] extends [UFactoryOutput['id']]\n ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']]\n ? {}\n : `Error: The extension factory has undeclared output(s): ${JoinStringUnion<\n Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>\n >}`\n : `Error: The extension factory is missing the following output(s): ${JoinStringUnion<\n Exclude<RequiredExtensionIds<UDeclaredOutput>, UFactoryOutput['id']>\n >}`;\n\n/** @ignore */\nexport type VerifyExtensionAttachTo<\n UOutput extends ExtensionDataRef,\n UParentInput extends ExtensionDataRef,\n> = ExtensionDataRef extends UParentInput\n ? {}\n : [RequiredExtensionIds<UParentInput>] extends [RequiredExtensionIds<UOutput>]\n ? {}\n : `Error: This parent extension input requires the following extension data, but it is not declared as guaranteed output of this extension: ${JoinStringUnion<\n Exclude<RequiredExtensionIds<UParentInput>, RequiredExtensionIds<UOutput>>\n >}`;\n\n/**\n * Specifies where an extension should attach in the extension tree.\n *\n * @remarks\n *\n * A standard attachment point declaration will specify the ID of the parent extension, as well as the name of the input to attach to.\n *\n * There are three more advanced forms that are available for more complex use-cases:\n *\n * 1. Relative attachment points: using the `relative` property instead of `id`, the attachment point is resolved relative to the current plugin.\n * 2. Extension input references: using a reference in code to another extension's input in the same plugin. These references are always relative.\n * 3. Array of attachment points: an array of attachment points can be used to clone and attach to multiple extensions at once.\n *\n * @example\n * ```ts\n * // Attach to a specific extension by full ID\n * { id: 'app/routes', input: 'routes' }\n *\n * // Attach to an extension in the same plugin by kind\n * { relative: { kind: 'page' }, input: 'actions' }\n *\n * // Attach to a specific input of another extension\n * const page = ParentBlueprint.make({ ... });\n * const child = ChildBlueprint.make({ attachTo: page.inputs.children });\n *\n * // Attach to multiple parents at once\n * [\n * { id: 'page/home', input: 'widgets' },\n * { relative: { kind: 'page' }, input: 'widgets' },\n * ]\n * ```\n *\n * @public\n */\nexport type ExtensionDefinitionAttachTo<\n UParentInputs extends ExtensionDataRef = ExtensionDataRef,\n> =\n | { id: string; input: string; relative?: never }\n | { relative: { kind?: string; name?: string }; input: string; id?: never }\n | ExtensionInput<UParentInputs>\n | Array<\n | { id: string; input: string; relative?: never }\n | {\n relative: { kind?: string; name?: string };\n input: string;\n id?: never;\n }\n | ExtensionInput<UParentInputs>\n >;\n\n/** @public */\nexport type CreateExtensionOptions<\n TKind extends string | undefined,\n TName extends string | undefined,\n UOutput extends ExtensionDataRef,\n TInputs extends { [inputName in string]: ExtensionInput },\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n UParentInputs extends ExtensionDataRef,\n> = {\n kind?: TKind;\n name?: TName;\n attachTo: ExtensionDefinitionAttachTo<UParentInputs> &\n VerifyExtensionAttachTo<UOutput, UParentInputs>;\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Iterable<UFactoryOutput>;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/** @public */\nexport type ExtensionDefinitionParameters = {\n kind?: string;\n name?: string;\n configInput?: { [K in string]: any };\n config?: { [K in string]: any };\n output?: ExtensionDataRef;\n inputs?: { [KName in string]: ExtensionInput };\n params?: object | ExtensionBlueprintDefineParams;\n};\n\n/**\n * Same as the one in `createExtensionBlueprint`, but with `ParamsFactory` inlined.\n * It can't be exported because it breaks API reports.\n * @ignore\n */\ntype AnyParamsInput<TParams extends object | ExtensionBlueprintDefineParams> =\n TParams extends ExtensionBlueprintDefineParams<infer IParams>\n ? IParams | ((define: TParams) => ReturnType<TParams>)\n :\n | TParams\n | ((\n define: ExtensionBlueprintDefineParams<TParams, TParams>,\n ) => ReturnType<ExtensionBlueprintDefineParams<TParams, TParams>>);\n\n/** @public */\nexport interface ExtensionDefinition<\n TParams extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,\n> {\n $$type: '@backstage/ExtensionDefinition';\n readonly T: TParams;\n}\n\n/** @public */\nexport interface OverridableExtensionDefinition<\n T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,\n> extends ExtensionDefinition<T> {\n /**\n * References to the inputs of this extension, which can be used to attach child extensions.\n */\n readonly inputs: {\n [K in keyof T['inputs']]: ExtensionInput<\n T['inputs'][K] extends ExtensionInput<infer IData> ? IData : never\n >;\n };\n\n override<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n UNewOutput extends ExtensionDataRef,\n TExtraInputs extends { [inputName in string]: ExtensionInput },\n TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,\n UParentInputs extends ExtensionDataRef,\n >(\n args: Expand<\n {\n attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &\n VerifyExtensionAttachTo<\n ExtensionDataRef extends UNewOutput\n ? NonNullable<T['output']>\n : UNewOutput,\n UParentInputs\n >;\n disabled?: boolean;\n inputs?: TExtraInputs & {\n [KName in keyof T['inputs']]?: `Error: Input '${KName &\n string}' is already defined in parent definition`;\n };\n output?: Array<UNewOutput>;\n config?: {\n schema: TExtensionConfigSchema & {\n [KName in keyof T['config']]?: `Error: Config key '${KName &\n string}' is already defined in parent schema`;\n };\n };\n factory?(\n originalFactory: <\n TFactoryParamsReturn extends AnyParamsInput<\n NonNullable<T['params']>\n >,\n >(\n context?: Expand<\n {\n config?: T['config'];\n inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;\n } & ([T['params']] extends [never]\n ? {}\n : {\n params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams\n ? TFactoryParamsReturn\n : T['params'] extends ExtensionBlueprintDefineParams\n ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'\n : Partial<T['params']>;\n })\n >,\n ) => ExtensionDataContainer<NonNullable<T['output']>>,\n context: {\n node: AppNode;\n apis: ApiHolder;\n config: T['config'] & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n } & ([T['params']] extends [never]\n ? {}\n : {\n params?: TParamsInput extends ExtensionBlueprintDefineParams\n ? TParamsInput\n : T['params'] extends ExtensionBlueprintDefineParams\n ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'\n : Partial<T['params']>;\n })\n > &\n VerifyExtensionFactoryOutput<\n ExtensionDataRef extends UNewOutput\n ? NonNullable<T['output']>\n : UNewOutput,\n UFactoryOutput\n >,\n ): OverridableExtensionDefinition<{\n kind: T['kind'];\n name: T['name'];\n output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;\n inputs: T['inputs'] & TExtraInputs;\n config: T['config'] & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n configInput: T['configInput'] &\n z.input<\n z.ZodObject<{\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n }>\n >;\n }>;\n}\n\n/**\n * @internal\n */\nfunction bindInputs(\n inputs: { [inputName in string]: ExtensionInput } | undefined,\n kind?: string,\n name?: string,\n) {\n if (!inputs) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(inputs).map(([inputName, input]) => [\n inputName,\n OpaqueExtensionInput.toInternal(input).withContext?.({\n kind,\n name,\n input: inputName,\n }) ?? input,\n ]),\n );\n}\n\n/**\n * Creates a new extension definition for installation in a Backstage app.\n *\n * @remarks\n *\n * This is a low-level function for creation of extensions with arbitrary inputs\n * and outputs and is typically only intended to be used for advanced overrides\n * or framework-level extensions. For most extension creation needs, it is\n * recommended to use existing {@link ExtensionBlueprint}s instead. You can find\n * blueprints both in the `@backstage/frontend-plugin-api` package as well as\n * other plugin libraries. There is also a list of\n * {@link https://backstage.io/docs/frontend-system/building-plugins/common-extension-blueprints | commonly used blueprints}\n * in the frontend system documentation.\n *\n * Extension definitions that are created with this function can be installed in\n * a Backstage app via a {@link FrontendPlugin} or {@link FrontendModule}.\n *\n * For more details on how extensions work, see the\n * {@link https://backstage.io/docs/frontend-system/architecture/extensions | documentation for extensions}.\n *\n * @example\n *\n * ```ts\n * const myExtension = createExtension({\n * name: 'example',\n * attachTo: { id: 'app', input: 'root' },\n * output: [coreExtensionData.reactElement],\n * factory() {\n * return [coreExtensionData.reactElement(<h1>Hello, world!</h1>)];\n * },\n * });\n * ```\n *\n * @public\n */\nexport function createExtension<\n UOutput extends ExtensionDataRef,\n TInputs extends { [inputName in string]: ExtensionInput },\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n const TKind extends string | undefined = undefined,\n const TName extends string | undefined = undefined,\n UParentInputs extends ExtensionDataRef = ExtensionDataRef,\n>(\n options: CreateExtensionOptions<\n TKind,\n TName,\n UOutput,\n TInputs,\n TConfigSchema,\n UFactoryOutput,\n UParentInputs\n >,\n): OverridableExtensionDefinition<{\n config: string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n configInput: string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >;\n // This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef\n output: UOutput extends ExtensionDataRef<\n infer IData,\n infer IId,\n infer IConfig\n >\n ? ExtensionDataRef<IData, IId, IConfig>\n : never;\n inputs: TInputs;\n params: never;\n kind: string | undefined extends TKind ? undefined : TKind;\n name: string | undefined extends TName ? undefined : TName;\n}> {\n const schemaDeclaration = options.config?.schema;\n const configSchema =\n schemaDeclaration &&\n createSchemaFromZod(innerZ =>\n innerZ.object(\n Object.fromEntries(\n Object.entries(schemaDeclaration).map(([k, v]) => [k, v(innerZ)]),\n ),\n ),\n );\n\n return OpaqueExtensionDefinition.createInstance('v2', {\n T: undefined as unknown as {\n config: string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n configInput: string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >;\n output: UOutput;\n inputs: TInputs;\n kind: string | undefined extends TKind ? undefined : TKind;\n name: string | undefined extends TName ? undefined : TName;\n },\n kind: options.kind,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: bindInputs(options.inputs, options.kind, options.name),\n output: options.output,\n configSchema,\n factory: options.factory,\n toString() {\n const parts: string[] = [];\n if (options.kind) {\n parts.push(`kind=${options.kind}`);\n }\n if (options.name) {\n parts.push(`name=${options.name}`);\n }\n const attachTo = [options.attachTo]\n .flat()\n .map(aAny => {\n const a = aAny as ExtensionDefinitionAttachTo;\n if (OpaqueExtensionInput.isType(a)) {\n const { context } = OpaqueExtensionInput.toInternal(a);\n if (!context) {\n return '<detached-input>';\n }\n let id = '<plugin>';\n if (context?.kind) {\n id = `${context?.kind}:${id}`;\n }\n if (context?.name) {\n id = `${id}/${context?.name}`;\n }\n return `${id}@${context.input}`;\n }\n if ('relative' in a && a.relative) {\n let id = '<plugin>';\n if (a.relative.kind) {\n id = `${a.relative.kind}:${id}`;\n }\n if (a.relative.name) {\n id = `${id}/${a.relative.name}`;\n }\n return `${id}@${a.input}`;\n }\n if ('id' in a) {\n return `${a.id}@${a.input}`;\n }\n throw new Error('Invalid attachment point specification');\n })\n .join('+');\n parts.push(`attachTo=${attachTo}`);\n return `ExtensionDefinition{${parts.join(',')}}`;\n },\n override(overrideOptions) {\n if (!Array.isArray(options.output)) {\n throw new Error(\n 'Cannot override an extension that is not declared using the new format with outputs as an array',\n );\n }\n\n // TODO(Rugvip): Making this a type check would be optimal, but it seems\n // like it's tricky to add that and still have the type\n // inference work correctly for the factory output.\n if (overrideOptions.output && !overrideOptions.factory) {\n throw new Error(\n 'Refused to override output without also overriding factory',\n );\n }\n // TODO(Rugvip): Similar to above, would be nice to error during type checking, but don't want to complicate the types too much\n if (overrideOptions.params && overrideOptions.factory) {\n throw new Error(\n 'Refused to override params and factory at the same time',\n );\n }\n\n return createExtension({\n kind: options.kind,\n name: options.name,\n attachTo: (overrideOptions.attachTo ??\n options.attachTo) as ExtensionDefinitionAttachTo,\n disabled: overrideOptions.disabled ?? options.disabled,\n inputs: bindInputs(\n {\n ...(options.inputs ?? {}),\n ...(overrideOptions.inputs ?? {}),\n },\n options.kind,\n options.name,\n ),\n output: (overrideOptions.output ??\n options.output) as ExtensionDataRef[],\n config:\n options.config || overrideOptions.config\n ? {\n schema: {\n ...options.config?.schema,\n ...overrideOptions.config?.schema,\n },\n }\n : undefined,\n factory: ({ node, apis, config, inputs }) => {\n if (!overrideOptions.factory) {\n return options.factory({\n node,\n apis,\n config: config as any,\n inputs: inputs as any,\n [ctxParamsSymbol as any]: overrideOptions.params,\n });\n }\n const parentResult = overrideOptions.factory(\n (innerContext): ExtensionDataContainer<UOutput> => {\n return createExtensionDataContainer<UOutput>(\n options.factory({\n node,\n apis,\n config: (innerContext?.config ?? config) as any,\n inputs: resolveInputOverrides(\n options.inputs,\n inputs,\n innerContext?.inputs,\n ) as any,\n [ctxParamsSymbol as any]: innerContext?.params,\n }) as Iterable<any>,\n 'original extension factory',\n options.output,\n );\n },\n {\n node,\n apis,\n config: config as any,\n inputs: inputs as any,\n },\n );\n\n if (\n typeof parentResult !== 'object' ||\n !parentResult?.[Symbol.iterator]\n ) {\n throw new Error(\n 'extension factory override did not provide an iterable object',\n );\n }\n\n const deduplicatedResult = new Map<\n string,\n ExtensionDataValue<any, any>\n >();\n for (const item of parentResult) {\n deduplicatedResult.set(item.id, item);\n }\n\n return deduplicatedResult.values();\n },\n }) as OverridableExtensionDefinition<any>;\n },\n });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createExtension.esm.js","sources":["../../src/wiring/createExtension.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ApiHolder, AppNode } from '../apis';\nimport { Expand } from '@backstage/types';\nimport {\n ResolvedInputValueOverrides,\n resolveInputOverrides,\n} from './resolveInputOverrides';\nimport {\n createExtensionDataContainer,\n OpaqueExtensionInput,\n} from '@internal/frontend';\nimport { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef';\nimport { ExtensionInput } from './createExtensionInput';\nimport type { z } from 'zod';\nimport { createSchemaFromZod } from '../schema/createSchemaFromZod';\nimport { OpaqueExtensionDefinition } from '@internal/frontend';\nimport { ExtensionDataContainer } from './types';\nimport {\n ExtensionBlueprint,\n ExtensionBlueprintDefineParams,\n} from './createExtensionBlueprint';\nimport { FrontendPlugin } from './createFrontendPlugin';\nimport { FrontendModule } from './createFrontendModule';\n\n/**\n * This symbol is used to pass parameter overrides from the extension override to the blueprint factory\n * @internal\n */\nexport const ctxParamsSymbol = Symbol('params');\n\n/**\n * Convert a single extension input into a matching resolved input.\n * @public\n */\nexport type ResolvedExtensionInput<TExtensionInput extends ExtensionInput> =\n TExtensionInput['extensionData'] extends Array<ExtensionDataRef>\n ? {\n node: AppNode;\n } & ExtensionDataContainer<TExtensionInput['extensionData'][number]>\n : never;\n\n/**\n * Converts an extension input map into a matching collection of resolved inputs.\n * @public\n */\nexport type ResolvedExtensionInputs<\n TInputs extends {\n [name in string]: ExtensionInput;\n },\n> = {\n [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton']\n ? Array<Expand<ResolvedExtensionInput<TInputs[InputName]>>>\n : false extends TInputs[InputName]['config']['optional']\n ? Expand<ResolvedExtensionInput<TInputs[InputName]>>\n : Expand<ResolvedExtensionInput<TInputs[InputName]> | undefined>;\n};\n\ntype ToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype PopUnion<U> = ToIntersection<\n U extends any ? () => U : never\n> extends () => infer R\n ? [rest: Exclude<U, R>, next: R]\n : undefined;\n\n/** @ignore */\ntype JoinStringUnion<\n U,\n TDiv extends string = ', ',\n TResult extends string = '',\n> = PopUnion<U> extends [infer IRest extends string, infer INext extends string]\n ? TResult extends ''\n ? JoinStringUnion<IRest, TDiv, INext>\n : JoinStringUnion<IRest, TDiv, `${TResult}${TDiv}${INext}`>\n : TResult;\n\n/** @ignore */\nexport type RequiredExtensionIds<UExtensionData extends ExtensionDataRef> =\n UExtensionData extends any\n ? UExtensionData['config']['optional'] extends true\n ? never\n : UExtensionData['id']\n : never;\n\n/** @ignore */\nexport type VerifyExtensionFactoryOutput<\n UDeclaredOutput extends ExtensionDataRef,\n UFactoryOutput extends ExtensionDataValue<any, any>,\n> = [RequiredExtensionIds<UDeclaredOutput>] extends [UFactoryOutput['id']]\n ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']]\n ? {}\n : `Error: The extension factory has undeclared output(s): ${JoinStringUnion<\n Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>\n >}`\n : `Error: The extension factory is missing the following output(s): ${JoinStringUnion<\n Exclude<RequiredExtensionIds<UDeclaredOutput>, UFactoryOutput['id']>\n >}`;\n\n/** @ignore */\nexport type VerifyExtensionAttachTo<\n UOutput extends ExtensionDataRef,\n UParentInput extends ExtensionDataRef,\n> = ExtensionDataRef extends UParentInput\n ? {}\n : [RequiredExtensionIds<UParentInput>] extends [RequiredExtensionIds<UOutput>]\n ? {}\n : `Error: This parent extension input requires the following extension data, but it is not declared as guaranteed output of this extension: ${JoinStringUnion<\n Exclude<RequiredExtensionIds<UParentInput>, RequiredExtensionIds<UOutput>>\n >}`;\n\n/**\n * Specifies where an extension should attach in the extension tree.\n *\n * @remarks\n *\n * A standard attachment point declaration will specify the ID of the parent extension, as well as the name of the input to attach to.\n *\n * There are three more advanced forms that are available for more complex use-cases:\n *\n * 1. Relative attachment points: using the `relative` property instead of `id`, the attachment point is resolved relative to the current plugin.\n * 2. Extension input references: using a reference in code to another extension's input in the same plugin. These references are always relative.\n * 3. Array of attachment points: an array of attachment points can be used to clone and attach to multiple extensions at once.\n *\n * @example\n * ```ts\n * // Attach to a specific extension by full ID\n * { id: 'app/routes', input: 'routes' }\n *\n * // Attach to an extension in the same plugin by kind\n * { relative: { kind: 'page' }, input: 'actions' }\n *\n * // Attach to a specific input of another extension\n * const page = ParentBlueprint.make({ ... });\n * const child = ChildBlueprint.make({ attachTo: page.inputs.children });\n *\n * // Attach to multiple parents at once (deprecated - use Utility APIs instead)\n * [\n * { id: 'page/home', input: 'widgets' },\n * { relative: { kind: 'page' }, input: 'widgets' },\n * ]\n * ```\n *\n * @public\n */\nexport type ExtensionDefinitionAttachTo<\n UParentInputs extends ExtensionDataRef = ExtensionDataRef,\n> =\n | { id: string; input: string; relative?: never }\n | { relative: { kind?: string; name?: string }; input: string; id?: never }\n | ExtensionInput<UParentInputs>\n /**\n * @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.\n */\n | Array<\n | { id: string; input: string; relative?: never }\n | {\n relative: { kind?: string; name?: string };\n input: string;\n id?: never;\n }\n | ExtensionInput<UParentInputs>\n >;\n\n/** @public */\nexport type CreateExtensionOptions<\n TKind extends string | undefined,\n TName extends string | undefined,\n UOutput extends ExtensionDataRef,\n TInputs extends { [inputName in string]: ExtensionInput },\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n UParentInputs extends ExtensionDataRef,\n> = {\n kind?: TKind;\n name?: TName;\n attachTo: ExtensionDefinitionAttachTo<UParentInputs> &\n VerifyExtensionAttachTo<UOutput, UParentInputs>;\n disabled?: boolean;\n inputs?: TInputs;\n output: Array<UOutput>;\n config?: {\n schema: TConfigSchema;\n };\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n inputs: Expand<ResolvedExtensionInputs<TInputs>>;\n }): Iterable<UFactoryOutput>;\n} & VerifyExtensionFactoryOutput<UOutput, UFactoryOutput>;\n\n/** @public */\nexport type ExtensionDefinitionParameters = {\n kind?: string;\n name?: string;\n configInput?: { [K in string]: any };\n config?: { [K in string]: any };\n output?: ExtensionDataRef;\n inputs?: { [KName in string]: ExtensionInput };\n params?: object | ExtensionBlueprintDefineParams;\n};\n\n/**\n * Same as the one in `createExtensionBlueprint`, but with `ParamsFactory` inlined.\n * It can't be exported because it breaks API reports.\n * @ignore\n */\ntype AnyParamsInput<TParams extends object | ExtensionBlueprintDefineParams> =\n TParams extends ExtensionBlueprintDefineParams<infer IParams>\n ? IParams | ((define: TParams) => ReturnType<TParams>)\n :\n | TParams\n | ((\n define: ExtensionBlueprintDefineParams<TParams, TParams>,\n ) => ReturnType<ExtensionBlueprintDefineParams<TParams, TParams>>);\n\n/** @public */\nexport interface ExtensionDefinition<\n TParams extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,\n> {\n $$type: '@backstage/ExtensionDefinition';\n readonly T: TParams;\n}\n\n/** @public */\nexport interface OverridableExtensionDefinition<\n T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters,\n> extends ExtensionDefinition<T> {\n /**\n * References to the inputs of this extension, which can be used to attach child extensions.\n */\n readonly inputs: {\n [K in keyof T['inputs']]: ExtensionInput<\n T['inputs'][K] extends ExtensionInput<infer IData> ? IData : never\n >;\n };\n\n override<\n TExtensionConfigSchema extends {\n [key in string]: (zImpl: typeof z) => z.ZodType;\n },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n UNewOutput extends ExtensionDataRef,\n TExtraInputs extends { [inputName in string]: ExtensionInput },\n TParamsInput extends AnyParamsInput<NonNullable<T['params']>>,\n UParentInputs extends ExtensionDataRef,\n >(\n args: Expand<\n {\n attachTo?: ExtensionDefinitionAttachTo<UParentInputs> &\n VerifyExtensionAttachTo<\n ExtensionDataRef extends UNewOutput\n ? NonNullable<T['output']>\n : UNewOutput,\n UParentInputs\n >;\n disabled?: boolean;\n inputs?: TExtraInputs & {\n [KName in keyof T['inputs']]?: `Error: Input '${KName &\n string}' is already defined in parent definition`;\n };\n output?: Array<UNewOutput>;\n config?: {\n schema: TExtensionConfigSchema & {\n [KName in keyof T['config']]?: `Error: Config key '${KName &\n string}' is already defined in parent schema`;\n };\n };\n factory?(\n originalFactory: <\n TFactoryParamsReturn extends AnyParamsInput<\n NonNullable<T['params']>\n >,\n >(\n context?: Expand<\n {\n config?: T['config'];\n inputs?: ResolvedInputValueOverrides<NonNullable<T['inputs']>>;\n } & ([T['params']] extends [never]\n ? {}\n : {\n params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams\n ? TFactoryParamsReturn\n : T['params'] extends ExtensionBlueprintDefineParams\n ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'\n : Partial<T['params']>;\n })\n >,\n ) => ExtensionDataContainer<NonNullable<T['output']>>,\n context: {\n node: AppNode;\n apis: ApiHolder;\n config: T['config'] & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;\n },\n ): Iterable<UFactoryOutput>;\n } & ([T['params']] extends [never]\n ? {}\n : {\n params?: TParamsInput extends ExtensionBlueprintDefineParams\n ? TParamsInput\n : T['params'] extends ExtensionBlueprintDefineParams\n ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`'\n : Partial<T['params']>;\n })\n > &\n VerifyExtensionFactoryOutput<\n ExtensionDataRef extends UNewOutput\n ? NonNullable<T['output']>\n : UNewOutput,\n UFactoryOutput\n >,\n ): OverridableExtensionDefinition<{\n kind: T['kind'];\n name: T['name'];\n output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;\n inputs: T['inputs'] & TExtraInputs;\n config: T['config'] & {\n [key in keyof TExtensionConfigSchema]: z.infer<\n ReturnType<TExtensionConfigSchema[key]>\n >;\n };\n configInput: T['configInput'] &\n z.input<\n z.ZodObject<{\n [key in keyof TExtensionConfigSchema]: ReturnType<\n TExtensionConfigSchema[key]\n >;\n }>\n >;\n }>;\n}\n\n/**\n * @internal\n */\nfunction bindInputs(\n inputs: { [inputName in string]: ExtensionInput } | undefined,\n kind?: string,\n name?: string,\n) {\n if (!inputs) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(inputs).map(([inputName, input]) => [\n inputName,\n OpaqueExtensionInput.toInternal(input).withContext?.({\n kind,\n name,\n input: inputName,\n }) ?? input,\n ]),\n );\n}\n\n/**\n * Creates a new extension definition for installation in a Backstage app.\n *\n * @remarks\n *\n * This is a low-level function for creation of extensions with arbitrary inputs\n * and outputs and is typically only intended to be used for advanced overrides\n * or framework-level extensions. For most extension creation needs, it is\n * recommended to use existing {@link ExtensionBlueprint}s instead. You can find\n * blueprints both in the `@backstage/frontend-plugin-api` package as well as\n * other plugin libraries. There is also a list of\n * {@link https://backstage.io/docs/frontend-system/building-plugins/common-extension-blueprints | commonly used blueprints}\n * in the frontend system documentation.\n *\n * Extension definitions that are created with this function can be installed in\n * a Backstage app via a {@link FrontendPlugin} or {@link FrontendModule}.\n *\n * For more details on how extensions work, see the\n * {@link https://backstage.io/docs/frontend-system/architecture/extensions | documentation for extensions}.\n *\n * @example\n *\n * ```ts\n * const myExtension = createExtension({\n * name: 'example',\n * attachTo: { id: 'app', input: 'root' },\n * output: [coreExtensionData.reactElement],\n * factory() {\n * return [coreExtensionData.reactElement(<h1>Hello, world!</h1>)];\n * },\n * });\n * ```\n *\n * @public\n */\nexport function createExtension<\n UOutput extends ExtensionDataRef,\n TInputs extends { [inputName in string]: ExtensionInput },\n TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType },\n UFactoryOutput extends ExtensionDataValue<any, any>,\n const TKind extends string | undefined = undefined,\n const TName extends string | undefined = undefined,\n UParentInputs extends ExtensionDataRef = ExtensionDataRef,\n>(\n options: CreateExtensionOptions<\n TKind,\n TName,\n UOutput,\n TInputs,\n TConfigSchema,\n UFactoryOutput,\n UParentInputs\n >,\n): OverridableExtensionDefinition<{\n config: string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;\n };\n configInput: string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >;\n // This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef\n output: UOutput extends ExtensionDataRef<\n infer IData,\n infer IId,\n infer IConfig\n >\n ? ExtensionDataRef<IData, IId, IConfig>\n : never;\n inputs: TInputs;\n params: never;\n kind: string | undefined extends TKind ? undefined : TKind;\n name: string | undefined extends TName ? undefined : TName;\n}> {\n const schemaDeclaration = options.config?.schema;\n const configSchema =\n schemaDeclaration &&\n createSchemaFromZod(innerZ =>\n innerZ.object(\n Object.fromEntries(\n Object.entries(schemaDeclaration).map(([k, v]) => [k, v(innerZ)]),\n ),\n ),\n );\n\n return OpaqueExtensionDefinition.createInstance('v2', {\n T: undefined as unknown as {\n config: string extends keyof TConfigSchema\n ? {}\n : {\n [key in keyof TConfigSchema]: z.infer<\n ReturnType<TConfigSchema[key]>\n >;\n };\n configInput: string extends keyof TConfigSchema\n ? {}\n : z.input<\n z.ZodObject<{\n [key in keyof TConfigSchema]: ReturnType<TConfigSchema[key]>;\n }>\n >;\n output: UOutput;\n inputs: TInputs;\n kind: string | undefined extends TKind ? undefined : TKind;\n name: string | undefined extends TName ? undefined : TName;\n },\n kind: options.kind,\n name: options.name,\n attachTo: options.attachTo,\n disabled: options.disabled ?? false,\n inputs: bindInputs(options.inputs, options.kind, options.name),\n output: options.output,\n configSchema,\n factory: options.factory,\n toString() {\n const parts: string[] = [];\n if (options.kind) {\n parts.push(`kind=${options.kind}`);\n }\n if (options.name) {\n parts.push(`name=${options.name}`);\n }\n const attachTo = [options.attachTo]\n .flat()\n .map(aAny => {\n const a = aAny as ExtensionDefinitionAttachTo;\n if (OpaqueExtensionInput.isType(a)) {\n const { context } = OpaqueExtensionInput.toInternal(a);\n if (!context) {\n return '<detached-input>';\n }\n let id = '<plugin>';\n if (context?.kind) {\n id = `${context?.kind}:${id}`;\n }\n if (context?.name) {\n id = `${id}/${context?.name}`;\n }\n return `${id}@${context.input}`;\n }\n if ('relative' in a && a.relative) {\n let id = '<plugin>';\n if (a.relative.kind) {\n id = `${a.relative.kind}:${id}`;\n }\n if (a.relative.name) {\n id = `${id}/${a.relative.name}`;\n }\n return `${id}@${a.input}`;\n }\n if ('id' in a) {\n return `${a.id}@${a.input}`;\n }\n throw new Error('Invalid attachment point specification');\n })\n .join('+');\n parts.push(`attachTo=${attachTo}`);\n return `ExtensionDefinition{${parts.join(',')}}`;\n },\n override(overrideOptions) {\n if (!Array.isArray(options.output)) {\n throw new Error(\n 'Cannot override an extension that is not declared using the new format with outputs as an array',\n );\n }\n\n // TODO(Rugvip): Making this a type check would be optimal, but it seems\n // like it's tricky to add that and still have the type\n // inference work correctly for the factory output.\n if (overrideOptions.output && !overrideOptions.factory) {\n throw new Error(\n 'Refused to override output without also overriding factory',\n );\n }\n // TODO(Rugvip): Similar to above, would be nice to error during type checking, but don't want to complicate the types too much\n if (overrideOptions.params && overrideOptions.factory) {\n throw new Error(\n 'Refused to override params and factory at the same time',\n );\n }\n\n return createExtension({\n kind: options.kind,\n name: options.name,\n attachTo: (overrideOptions.attachTo ??\n options.attachTo) as ExtensionDefinitionAttachTo,\n disabled: overrideOptions.disabled ?? options.disabled,\n inputs: bindInputs(\n {\n ...(options.inputs ?? {}),\n ...(overrideOptions.inputs ?? {}),\n },\n options.kind,\n options.name,\n ),\n output: (overrideOptions.output ??\n options.output) as ExtensionDataRef[],\n config:\n options.config || overrideOptions.config\n ? {\n schema: {\n ...options.config?.schema,\n ...overrideOptions.config?.schema,\n },\n }\n : undefined,\n factory: ({ node, apis, config, inputs }) => {\n if (!overrideOptions.factory) {\n return options.factory({\n node,\n apis,\n config: config as any,\n inputs: inputs as any,\n [ctxParamsSymbol as any]: overrideOptions.params,\n });\n }\n const parentResult = overrideOptions.factory(\n (innerContext): ExtensionDataContainer<UOutput> => {\n return createExtensionDataContainer<UOutput>(\n options.factory({\n node,\n apis,\n config: (innerContext?.config ?? config) as any,\n inputs: resolveInputOverrides(\n options.inputs,\n inputs,\n innerContext?.inputs,\n ) as any,\n [ctxParamsSymbol as any]: innerContext?.params,\n }) as Iterable<any>,\n 'original extension factory',\n options.output,\n );\n },\n {\n node,\n apis,\n config: config as any,\n inputs: inputs as any,\n },\n );\n\n if (\n typeof parentResult !== 'object' ||\n !parentResult?.[Symbol.iterator]\n ) {\n throw new Error(\n 'extension factory override did not provide an iterable object',\n );\n }\n\n const deduplicatedResult = new Map<\n string,\n ExtensionDataValue<any, any>\n >();\n for (const item of parentResult) {\n deduplicatedResult.set(item.id, item);\n }\n\n return deduplicatedResult.values();\n },\n }) as OverridableExtensionDefinition<any>;\n },\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -25,7 +25,8 @@ function createExtensionInput(extensionData, config) {
|
|
|
25
25
|
extensionData,
|
|
26
26
|
config: {
|
|
27
27
|
singleton: Boolean(config?.singleton),
|
|
28
|
-
optional: Boolean(config?.optional)
|
|
28
|
+
optional: Boolean(config?.optional),
|
|
29
|
+
internal: Boolean(config?.internal)
|
|
29
30
|
},
|
|
30
31
|
replaces: config?.replaces
|
|
31
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExtensionInput.esm.js","sources":["../../src/wiring/createExtensionInput.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ExtensionInputContext,\n OpaqueExtensionInput,\n} from '@internal/frontend';\nimport { ExtensionDataRef } from './createExtensionDataRef';\n\n/** @public */\nexport interface ExtensionInput<\n UExtensionData extends ExtensionDataRef<\n unknown,\n string,\n { optional?: true }\n > = ExtensionDataRef,\n TConfig extends {
|
|
1
|
+
{"version":3,"file":"createExtensionInput.esm.js","sources":["../../src/wiring/createExtensionInput.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ExtensionInputContext,\n OpaqueExtensionInput,\n} from '@internal/frontend';\nimport { ExtensionDataRef } from './createExtensionDataRef';\n\n/** @public */\nexport interface ExtensionInput<\n UExtensionData extends ExtensionDataRef<\n unknown,\n string,\n { optional?: true }\n > = ExtensionDataRef,\n TConfig extends {\n singleton: boolean;\n optional: boolean;\n internal?: boolean;\n } = {\n singleton: boolean;\n optional: boolean;\n internal?: boolean;\n },\n> {\n readonly $$type: '@backstage/ExtensionInput';\n readonly extensionData: Array<UExtensionData>;\n readonly config: TConfig;\n readonly replaces?: Array<{ id: string; input: string }>;\n}\n\n/**\n * Creates a new extension input to be passed to the input map of an extension.\n *\n * @remarks\n *\n * Extension inputs created with this function can be passed to any `inputs` map\n * as part of creating or overriding an extension.\n *\n * The array of extension data references defines the data this input expects.\n * If the required data is not provided by the attached extension, the\n * attachment will fail.\n *\n * The `config` object can be used to restrict the behavior and shape of the\n * input. By default an input will accept zero or more extensions from any\n * plugin. The following options are available:\n *\n * - `singleton`: If set to `true`, only one extension can be attached to the\n * input at a time. Additional extensions will trigger an app error and be\n * ignored.\n * - `optional`: If set to `true`, the input is optional and can be omitted,\n * this only has an effect if the `singleton` is set to `true`.\n * - `internal`: If set to `true`, only extensions from the same plugin will be\n * allowed to attach to this input. Other extensions will trigger an app error\n * and be ignored.\n *\n * @param extensionData - The array of extension data references that this input\n * expects.\n * @param config - The configuration object for the input.\n * @returns An extension input declaration.\n * @example\n * ```ts\n * const extension = createExtension({\n * attachTo: { id: 'example-parent', input: 'example-input' },\n * inputs: {\n * content: createExtensionInput([coreExtensionData.reactElement], {\n * singleton: true,\n * }),\n * },\n * output: [coreExtensionData.reactElement],\n * *factory({ inputs }) {\n * const content = inputs.content?.get(coreExtensionData.reactElement);\n * yield coreExtensionData.reactElement(<ContentWrapper>{content}</ContentWrapper>);\n * },\n * });\n * ```\n * @public\n */\nexport function createExtensionInput<\n UExtensionData extends ExtensionDataRef<unknown, string, { optional?: true }>,\n TConfig extends {\n singleton?: boolean;\n optional?: boolean;\n internal?: boolean;\n },\n>(\n extensionData: Array<UExtensionData>,\n config?: TConfig & { replaces?: Array<{ id: string; input: string }> },\n): ExtensionInput<\n UExtensionData,\n {\n singleton: TConfig['singleton'] extends true ? true : false;\n optional: TConfig['optional'] extends true ? true : false;\n internal: TConfig['internal'] extends true ? true : false;\n }\n> {\n if (process.env.NODE_ENV !== 'production') {\n if (Array.isArray(extensionData)) {\n const seen = new Set();\n const duplicates = [];\n for (const dataRef of extensionData) {\n if (seen.has(dataRef.id)) {\n duplicates.push(dataRef.id);\n } else {\n seen.add(dataRef.id);\n }\n }\n if (duplicates.length > 0) {\n throw new Error(\n `ExtensionInput may not have duplicate data refs: '${duplicates.join(\n \"', '\",\n )}'`,\n );\n }\n }\n }\n const baseOptions = {\n extensionData,\n config: {\n singleton: Boolean(config?.singleton) as TConfig['singleton'] extends true\n ? true\n : false,\n optional: Boolean(config?.optional) as TConfig['optional'] extends true\n ? true\n : false,\n internal: Boolean(config?.internal) as TConfig['internal'] extends true\n ? true\n : false,\n },\n replaces: config?.replaces,\n };\n\n function createInstance(parent?: ExtensionInputContext): ExtensionInput<\n UExtensionData,\n {\n singleton: TConfig['singleton'] extends true ? true : false;\n optional: TConfig['optional'] extends true ? true : false;\n internal: TConfig['internal'] extends true ? true : false;\n }\n > {\n return OpaqueExtensionInput.createInstance(undefined, {\n ...baseOptions,\n context: parent,\n withContext: createInstance,\n });\n }\n\n return createInstance();\n}\n"],"names":[],"mappings":";;AA4FO,SAAS,oBAAA,CAQd,eACA,MAAA,EAQA;AACA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,EAAc;AACzC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,aAAa,CAAA,EAAG;AAChC,MAAA,MAAM,IAAA,uBAAW,GAAA,EAAI;AACrB,MAAA,MAAM,aAAa,EAAC;AACpB,MAAA,KAAA,MAAW,WAAW,aAAA,EAAe;AACnC,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA,EAAG;AACxB,UAAA,UAAA,CAAW,IAAA,CAAK,QAAQ,EAAE,CAAA;AAAA,QAC5B,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,EAAE,CAAA;AAAA,QACrB;AAAA,MACF;AACA,MAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,qDAAqD,UAAA,CAAW,IAAA;AAAA,YAC9D;AAAA,WACD,CAAA,CAAA;AAAA,SACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,WAAA,GAAc;AAAA,IAClB,aAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,SAAA,EAAW,OAAA,CAAQ,MAAA,EAAQ,SAAS,CAAA;AAAA,MAGpC,QAAA,EAAU,OAAA,CAAQ,MAAA,EAAQ,QAAQ,CAAA;AAAA,MAGlC,QAAA,EAAU,OAAA,CAAQ,MAAA,EAAQ,QAAQ;AAAA,KAGpC;AAAA,IACA,UAAU,MAAA,EAAQ;AAAA,GACpB;AAEA,EAAA,SAAS,eAAe,MAAA,EAOtB;AACA,IAAA,OAAO,oBAAA,CAAqB,eAAe,MAAA,EAAW;AAAA,MACpD,GAAG,WAAA;AAAA,MACH,OAAA,EAAS,MAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,cAAA,EAAe;AACxB;;;;"}
|