@backstage/frontend-plugin-api 0.12.2-next.1 → 0.13.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 +50 -0
- package/dist/apis/definitions/AppTreeApi.esm.js.map +1 -1
- package/dist/components/createSwappableComponent.esm.js +1 -0
- package/dist/components/createSwappableComponent.esm.js.map +1 -1
- package/dist/frontend-internal/src/routing/OpaqueExternalRouteRef.esm.js +9 -0
- package/dist/frontend-internal/src/routing/OpaqueExternalRouteRef.esm.js.map +1 -0
- package/dist/frontend-internal/src/routing/OpaqueRouteRef.esm.js +9 -0
- package/dist/frontend-internal/src/routing/OpaqueRouteRef.esm.js.map +1 -0
- package/dist/frontend-internal/src/routing/OpaqueSubRouteRef.esm.js +9 -0
- package/dist/frontend-internal/src/routing/OpaqueSubRouteRef.esm.js.map +1 -0
- package/dist/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js.map +1 -1
- package/dist/frontend-internal/src/wiring/InternalExtensionInput.esm.js +9 -0
- package/dist/frontend-internal/src/wiring/InternalExtensionInput.esm.js.map +1 -0
- package/dist/index.d.ts +107 -32
- package/dist/routing/ExternalRouteRef.esm.js +36 -20
- package/dist/routing/ExternalRouteRef.esm.js.map +1 -1
- package/dist/routing/RouteRef.esm.js +34 -56
- package/dist/routing/RouteRef.esm.js.map +1 -1
- package/dist/routing/SubRouteRef.esm.js +21 -32
- package/dist/routing/SubRouteRef.esm.js.map +1 -1
- package/dist/wiring/createExtension.esm.js +58 -6
- package/dist/wiring/createExtension.esm.js.map +1 -1
- package/dist/wiring/createExtensionBlueprint.esm.js.map +1 -1
- package/dist/wiring/createExtensionInput.esm.js +11 -2
- package/dist/wiring/createExtensionInput.esm.js.map +1 -1
- package/dist/wiring/createFrontendPlugin.esm.js +2 -1
- package/dist/wiring/createFrontendPlugin.esm.js.map +1 -1
- package/dist/wiring/resolveExtensionDefinition.esm.js +49 -9
- package/dist/wiring/resolveExtensionDefinition.esm.js.map +1 -1
- package/dist/wiring/resolveInputOverrides.esm.js +2 -1
- package/dist/wiring/resolveInputOverrides.esm.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,55 @@
|
|
|
1
1
|
# @backstage/frontend-plugin-api
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7d87b4f: Renamed `ExtensionDefinition` to `OverridableExtensionDefinition` and introduced a slimmer `ExtensionDefinition` type that does not include override methods. The overridable type is generally used as an output type, while plain `ExtensionDefinition`s are used for input. This reduces type conflicts across different of `@backstage/frontend-plugin-api`, improving long-term compatibility.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 4d03f08: Internal refactor of route reference implementations with minor updates to the `toString` implementations.
|
|
12
|
+
- 7c6a66d: Added support for plugin-relative `attachTo` declarations for extension definitions. This allows for the creation of extension and extension blueprints that attach to other extensions of a particular `kind` in the same plugin, rather than needing to provide the exact extension ID. This is particularly useful when wanting to provide extension blueprints with a built-in hierarchy where the extensions created from one blueprint attach to extensions created from the other blueprint, for example:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// kind: 'tabbed-page'
|
|
16
|
+
const parentPage = TabbedPageBlueprint.make({
|
|
17
|
+
params: {....}
|
|
18
|
+
})
|
|
19
|
+
// attachTo: { kind: 'tabbed-page', input: 'tabs' }
|
|
20
|
+
const child1 = TabContentBlueprint.make({
|
|
21
|
+
name: 'tab1',
|
|
22
|
+
params: {....}
|
|
23
|
+
})
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- 878c251: Updated to `ExtensionInput` to make all type parameters optional.
|
|
27
|
+
- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility.
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/core-components@0.18.3
|
|
30
|
+
- @backstage/core-plugin-api@1.12.0
|
|
31
|
+
|
|
32
|
+
## 0.12.2-next.2
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- 7c6a66d: Added support for plugin-relative `attachTo` declarations for extension definitions. This allows for the creation of extension and extension blueprints that attach to other extensions of a particular `kind` in the same plugin, rather than needing to provide the exact extension ID. This is particularly useful when wanting to provide extension blueprints with a built-in hierarchy where the extensions created from one blueprint attach to extensions created from the other blueprint, for example:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// kind: 'tabbed-page'
|
|
40
|
+
const parentPage = TabbedPageBlueprint.make({
|
|
41
|
+
params: {....}
|
|
42
|
+
})
|
|
43
|
+
// attachTo: { kind: 'tabbed-page', input: 'tabs' }
|
|
44
|
+
const child1 = TabContentBlueprint.make({
|
|
45
|
+
name: 'tab1',
|
|
46
|
+
params: {....}
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Updated dependencies
|
|
51
|
+
- @backstage/core-components@0.18.3-next.2
|
|
52
|
+
|
|
3
53
|
## 0.12.2-next.1
|
|
4
54
|
|
|
5
55
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppTreeApi.esm.js","sources":["../../../src/apis/definitions/AppTreeApi.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 { createApiRef } from '@backstage/core-plugin-api';\nimport {
|
|
1
|
+
{"version":3,"file":"AppTreeApi.esm.js","sources":["../../../src/apis/definitions/AppTreeApi.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 { createApiRef } from '@backstage/core-plugin-api';\nimport { FrontendPlugin, Extension, ExtensionDataRef } from '../../wiring';\nimport { ExtensionAttachTo } from '../../wiring/resolveExtensionDefinition';\n\n/**\n * The specification for this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The specifications for a collection of app nodes is all the information needed\n * to build the tree and instantiate the nodes.\n */\nexport interface AppNodeSpec {\n readonly id: string;\n readonly attachTo: ExtensionAttachTo;\n readonly extension: Extension<unknown, unknown>;\n readonly disabled: boolean;\n readonly config?: unknown;\n readonly plugin: FrontendPlugin;\n}\n\n/**\n * The connections from this {@link AppNode} to other nodes.\n *\n * @public\n * @remarks\n *\n * The app node edges are resolved based on the app node specs, regardless of whether\n * adjacent nodes are disabled or not. If no parent attachment is present or\n */\nexport interface AppNodeEdges {\n readonly attachedTo?: { node: AppNode; input: string };\n readonly attachments: ReadonlyMap<string, AppNode[]>;\n}\n\n/**\n * The instance of this {@link AppNode} in the {@link AppTree}.\n *\n * @public\n * @remarks\n *\n * The app node instance is created when the `factory` function of an extension is called.\n * Instances will only be present for nodes in the app that are connected to the root\n * node and not disabled\n */\nexport interface AppNodeInstance {\n /** Returns a sequence of all extension data refs that were output by this instance */\n getDataRefs(): Iterable<ExtensionDataRef<unknown>>;\n /** Get the output data for a single extension data ref */\n getData<T>(ref: ExtensionDataRef<T>): T | undefined;\n}\n\n/**\n * A node in the {@link AppTree}.\n *\n * @public\n */\nexport interface AppNode {\n /** The specification for how this node should be instantiated */\n readonly spec: AppNodeSpec;\n /** The edges from this node to other nodes in the app tree */\n readonly edges: AppNodeEdges;\n /** The instance of this node, if it was instantiated */\n readonly instance?: AppNodeInstance;\n}\n\n/**\n * The app tree containing all {@link AppNode}s of the app.\n *\n * @public\n */\nexport interface AppTree {\n /** The root node of the app */\n readonly root: AppNode;\n /** A map of all nodes in the app by ID, including orphaned or disabled nodes */\n readonly nodes: ReadonlyMap<string /* id */, AppNode>;\n /** A sequence of all nodes with a parent that is not reachable from the app root node */\n readonly orphans: Iterable<AppNode>;\n}\n\n/**\n * The API for interacting with the {@link AppTree}.\n *\n * @public\n */\nexport interface AppTreeApi {\n /**\n * Get the {@link AppTree} for the app.\n */\n getTree(): { tree: AppTree };\n\n /**\n * Get all nodes in the app that are mounted at a given route path.\n */\n getNodesByRoutePath(routePath: string): { nodes: AppNode[] };\n}\n\n/**\n * The `ApiRef` of {@link AppTreeApi}.\n *\n * @public\n */\nexport const appTreeApiRef = createApiRef<AppTreeApi>({ id: 'core.app-tree' });\n"],"names":[],"mappings":";;AAuHO,MAAM,aAAA,GAAgB,YAAA,CAAyB,EAAE,EAAA,EAAI,iBAAiB;;;;"}
|
|
@@ -9,6 +9,7 @@ import '../apis/definitions/AnalyticsApi.esm.js';
|
|
|
9
9
|
import { lazy } from 'react';
|
|
10
10
|
import { OpaqueSwappableComponentRef } from '../frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js';
|
|
11
11
|
import '../frontend-internal/src/wiring/InternalExtensionDefinition.esm.js';
|
|
12
|
+
import '../frontend-internal/src/wiring/InternalExtensionInput.esm.js';
|
|
12
13
|
import '../frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
|
|
13
14
|
|
|
14
15
|
const useComponentRefApi = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSwappableComponent.esm.js","sources":["../../src/components/createSwappableComponent.tsx"],"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 { OpaqueSwappableComponentRef } from '@internal/frontend';\nimport { swappableComponentsApiRef, useApi } from '../apis';\nimport { lazy } from 'react';\n\n/** @public */\nexport type SwappableComponentRef<\n TInnerComponentProps extends {} = {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n TProps: TInnerComponentProps;\n TExternalProps: TExternalComponentProps;\n $$type: '@backstage/SwappableComponentRef';\n};\n\n/**\n * Options for creating an SwappableComponent.\n *\n * @public\n */\nexport type CreateSwappableComponentOptions<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n loader?:\n | (() => (props: TInnerComponentProps) => JSX.Element | null)\n | (() => Promise<(props: TInnerComponentProps) => JSX.Element | null>);\n transformProps?: (props: TExternalComponentProps) => TInnerComponentProps;\n};\n\nconst useComponentRefApi = () => {\n try {\n return useApi(swappableComponentsApiRef);\n } catch (e) {\n return undefined;\n }\n};\n\n/**\n * Creates a SwappableComponent that can be used to render the component, optionally overridden by the app.\n *\n * @public\n */\nexport function createSwappableComponent<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n>(\n options: CreateSwappableComponentOptions<\n TInnerComponentProps,\n TExternalComponentProps\n >,\n): {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n} {\n const FallbackComponent = (p: JSX.IntrinsicAttributes) => (\n <div data-testid={options.id} {...p} />\n );\n\n const ref = OpaqueSwappableComponentRef.createInstance('v1', {\n id: options.id,\n TProps: null as unknown as TInnerComponentProps,\n TExternalProps: null as unknown as TExternalComponentProps,\n toString() {\n return `SwappableComponentRef{id=${options.id}}`;\n },\n defaultComponent: lazy(async () => {\n const Component = (await options.loader?.()) ?? FallbackComponent;\n return { default: Component };\n }) as (typeof OpaqueSwappableComponentRef.TInternal)['defaultComponent'],\n transformProps:\n options.transformProps as (typeof OpaqueSwappableComponentRef.TInternal)['transformProps'],\n });\n\n const ComponentRefImpl = (props: TExternalComponentProps) => {\n const api = useComponentRefApi();\n\n if (!api) {\n const internalRef = OpaqueSwappableComponentRef.toInternal(ref);\n const Component = internalRef.defaultComponent;\n const innerProps = internalRef.transformProps?.(props) ?? props;\n return <Component {...innerProps} />;\n }\n\n const Component = api.getComponent<any>(ref);\n return <Component {...props} />;\n };\n\n Object.assign(ComponentRefImpl, { ref });\n\n return ComponentRefImpl as {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n };\n}\n"],"names":["Component"],"mappings":"
|
|
1
|
+
{"version":3,"file":"createSwappableComponent.esm.js","sources":["../../src/components/createSwappableComponent.tsx"],"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 { OpaqueSwappableComponentRef } from '@internal/frontend';\nimport { swappableComponentsApiRef, useApi } from '../apis';\nimport { lazy } from 'react';\n\n/** @public */\nexport type SwappableComponentRef<\n TInnerComponentProps extends {} = {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n TProps: TInnerComponentProps;\n TExternalProps: TExternalComponentProps;\n $$type: '@backstage/SwappableComponentRef';\n};\n\n/**\n * Options for creating an SwappableComponent.\n *\n * @public\n */\nexport type CreateSwappableComponentOptions<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n> = {\n id: string;\n loader?:\n | (() => (props: TInnerComponentProps) => JSX.Element | null)\n | (() => Promise<(props: TInnerComponentProps) => JSX.Element | null>);\n transformProps?: (props: TExternalComponentProps) => TInnerComponentProps;\n};\n\nconst useComponentRefApi = () => {\n try {\n return useApi(swappableComponentsApiRef);\n } catch (e) {\n return undefined;\n }\n};\n\n/**\n * Creates a SwappableComponent that can be used to render the component, optionally overridden by the app.\n *\n * @public\n */\nexport function createSwappableComponent<\n TInnerComponentProps extends {},\n TExternalComponentProps extends {} = TInnerComponentProps,\n>(\n options: CreateSwappableComponentOptions<\n TInnerComponentProps,\n TExternalComponentProps\n >,\n): {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n} {\n const FallbackComponent = (p: JSX.IntrinsicAttributes) => (\n <div data-testid={options.id} {...p} />\n );\n\n const ref = OpaqueSwappableComponentRef.createInstance('v1', {\n id: options.id,\n TProps: null as unknown as TInnerComponentProps,\n TExternalProps: null as unknown as TExternalComponentProps,\n toString() {\n return `SwappableComponentRef{id=${options.id}}`;\n },\n defaultComponent: lazy(async () => {\n const Component = (await options.loader?.()) ?? FallbackComponent;\n return { default: Component };\n }) as (typeof OpaqueSwappableComponentRef.TInternal)['defaultComponent'],\n transformProps:\n options.transformProps as (typeof OpaqueSwappableComponentRef.TInternal)['transformProps'],\n });\n\n const ComponentRefImpl = (props: TExternalComponentProps) => {\n const api = useComponentRefApi();\n\n if (!api) {\n const internalRef = OpaqueSwappableComponentRef.toInternal(ref);\n const Component = internalRef.defaultComponent;\n const innerProps = internalRef.transformProps?.(props) ?? props;\n return <Component {...innerProps} />;\n }\n\n const Component = api.getComponent<any>(ref);\n return <Component {...props} />;\n };\n\n Object.assign(ComponentRefImpl, { ref });\n\n return ComponentRefImpl as {\n (props: TExternalComponentProps): JSX.Element | null;\n ref: SwappableComponentRef<TInnerComponentProps, TExternalComponentProps>;\n };\n}\n"],"names":["Component"],"mappings":";;;;;;;;;;;;;;AA+CA,MAAM,qBAAqB,MAAM;AAC/B,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,yBAAyB,CAAA;AAAA,EACzC,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;AAOO,SAAS,yBAId,OAAA,EAOA;AACA,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAA,qBACzB,GAAA,CAAC,SAAI,aAAA,EAAa,OAAA,CAAQ,EAAA,EAAK,GAAG,CAAA,EAAG,CAAA;AAGvC,EAAA,MAAM,GAAA,GAAM,2BAAA,CAA4B,cAAA,CAAe,IAAA,EAAM;AAAA,IAC3D,IAAI,OAAA,CAAQ,EAAA;AAAA,IACZ,MAAA,EAAQ,IAAA;AAAA,IACR,cAAA,EAAgB,IAAA;AAAA,IAChB,QAAA,GAAW;AACT,MAAA,OAAO,CAAA,yBAAA,EAA4B,QAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,IAC/C,CAAA;AAAA,IACA,gBAAA,EAAkB,KAAK,YAAY;AACjC,MAAA,MAAM,SAAA,GAAa,MAAM,OAAA,CAAQ,MAAA,IAAS,IAAM,iBAAA;AAChD,MAAA,OAAO,EAAE,SAAS,SAAA,EAAU;AAAA,IAC9B,CAAC,CAAA;AAAA,IACD,gBACE,OAAA,CAAQ;AAAA,GACX,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,CAAC,KAAA,KAAmC;AAC3D,IAAA,MAAM,MAAM,kBAAA,EAAmB;AAE/B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,WAAA,GAAc,2BAAA,CAA4B,UAAA,CAAW,GAAG,CAAA;AAC9D,MAAA,MAAMA,aAAY,WAAA,CAAY,gBAAA;AAC9B,MAAA,MAAM,UAAA,GAAa,WAAA,CAAY,cAAA,GAAiB,KAAK,CAAA,IAAK,KAAA;AAC1D,MAAA,uBAAO,GAAA,CAACA,UAAAA,EAAA,EAAW,GAAG,UAAA,EAAY,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,YAAA,CAAkB,GAAG,CAAA;AAC3C,IAAA,uBAAO,GAAA,CAAC,SAAA,EAAA,EAAW,GAAG,KAAA,EAAO,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,EAAE,GAAA,EAAK,CAAA;AAEvC,EAAA,OAAO,gBAAA;AAIT;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
|
|
2
|
+
|
|
3
|
+
const OpaqueExternalRouteRef = OpaqueType.create({
|
|
4
|
+
type: "@backstage/ExternalRouteRef",
|
|
5
|
+
versions: ["v1"]
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { OpaqueExternalRouteRef };
|
|
9
|
+
//# sourceMappingURL=OpaqueExternalRouteRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpaqueExternalRouteRef.esm.js","sources":["../../../../../frontend-internal/src/routing/OpaqueExternalRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { ExternalRouteRef } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueExternalRouteRef = OpaqueType.create<{\n public: ExternalRouteRef;\n versions: {\n readonly version: 'v1';\n\n getParams(): string[];\n getDescription(): string;\n getDefaultTarget(): string | undefined;\n\n setId(id: string): void;\n };\n}>({\n type: '@backstage/ExternalRouteRef',\n versions: ['v1'],\n});\n"],"names":[],"mappings":";;AAmBO,MAAM,sBAAA,GAAyB,WAAW,MAAA,CAW9C;AAAA,EACD,IAAA,EAAM,6BAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpaqueRouteRef.esm.js","sources":["../../../../../frontend-internal/src/routing/OpaqueRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { RouteRef } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueRouteRef = OpaqueType.create<{\n public: RouteRef;\n versions: {\n readonly version: 'v1';\n\n getParams(): string[];\n getDescription(): string;\n\n alias: string | undefined;\n\n setId(id: string): void;\n };\n}>({\n type: '@backstage/RouteRef',\n versions: ['v1'],\n});\n"],"names":[],"mappings":";;AAmBO,MAAM,cAAA,GAAiB,WAAW,MAAA,CAYtC;AAAA,EACD,IAAA,EAAM,qBAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
|
|
2
|
+
|
|
3
|
+
const OpaqueSubRouteRef = OpaqueType.create({
|
|
4
|
+
type: "@backstage/SubRouteRef",
|
|
5
|
+
versions: ["v1"]
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { OpaqueSubRouteRef };
|
|
9
|
+
//# sourceMappingURL=OpaqueSubRouteRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpaqueSubRouteRef.esm.js","sources":["../../../../../frontend-internal/src/routing/OpaqueSubRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { RouteRef, SubRouteRef } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueSubRouteRef = OpaqueType.create<{\n public: SubRouteRef;\n versions: {\n readonly version: 'v1';\n\n getParams(): string[];\n getParent(): RouteRef;\n getDescription(): string;\n };\n}>({\n type: '@backstage/SubRouteRef',\n versions: ['v1'],\n});\n"],"names":[],"mappings":";;AAmBO,MAAM,iBAAA,GAAoB,WAAW,MAAA,CASzC;AAAA,EACD,IAAA,EAAM,wBAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InternalExtensionDefinition.esm.js","sources":["../../../../../frontend-internal/src/wiring/InternalExtensionDefinition.ts"],"sourcesContent":["/*\n * Copyright 2024 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 ApiHolder,\n AppNode,\n
|
|
1
|
+
{"version":3,"file":"InternalExtensionDefinition.esm.js","sources":["../../../../../frontend-internal/src/wiring/InternalExtensionDefinition.ts"],"sourcesContent":["/*\n * Copyright 2024 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 ApiHolder,\n AppNode,\n ExtensionDefinitionAttachTo,\n ExtensionDataValue,\n ExtensionDataRef,\n OverridableExtensionDefinition,\n ExtensionDefinitionParameters,\n ExtensionInput,\n PortableSchema,\n ResolvedExtensionInputs,\n} from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueExtensionDefinition = OpaqueType.create<{\n public: OverridableExtensionDefinition<ExtensionDefinitionParameters>;\n versions:\n | {\n readonly version: 'v1';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: ExtensionDefinitionAttachTo;\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<any, any>;\n readonly inputs: {\n [inputName in string]: {\n $$type: '@backstage/ExtensionInput';\n extensionData: {\n [name in string]: ExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n };\n readonly output: {\n [name in string]: ExtensionDataRef;\n };\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: object;\n inputs: {\n [inputName in string]: unknown;\n };\n }): {\n [inputName in string]: unknown;\n };\n }\n | {\n readonly version: 'v2';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: ExtensionDefinitionAttachTo;\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<any, any>;\n readonly inputs: { [inputName in string]: ExtensionInput };\n readonly output: Array<ExtensionDataRef>;\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: object;\n inputs: ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput;\n }>;\n }): Iterable<ExtensionDataValue<any, any>>;\n };\n}>({\n type: '@backstage/ExtensionDefinition',\n versions: ['v1', 'v2'],\n});\n"],"names":[],"mappings":";;AA8BO,MAAM,yBAAA,GAA4B,WAAW,MAAA,CAqDjD;AAAA,EACD,IAAA,EAAM,gCAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAA,EAAM,IAAI;AACvB,CAAC;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
|
|
2
|
+
|
|
3
|
+
const OpaqueExtensionInput = OpaqueType.create({
|
|
4
|
+
type: "@backstage/ExtensionInput",
|
|
5
|
+
versions: [void 0]
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { OpaqueExtensionInput };
|
|
9
|
+
//# sourceMappingURL=InternalExtensionInput.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InternalExtensionInput.esm.js","sources":["../../../../../frontend-internal/src/wiring/InternalExtensionInput.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { ExtensionInput } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport type ExtensionInputContext = {\n input: string;\n kind?: string;\n name?: string;\n};\n\nexport const OpaqueExtensionInput = OpaqueType.create<{\n public: ExtensionInput;\n versions: {\n readonly version: undefined;\n readonly context?: ExtensionInputContext;\n withContext(context: ExtensionInputContext): ExtensionInput;\n };\n}>({\n type: '@backstage/ExtensionInput',\n versions: [undefined],\n});\n"],"names":[],"mappings":";;AAyBO,MAAM,oBAAA,GAAuB,WAAW,MAAA,CAO5C;AAAA,EACD,IAAA,EAAM,2BAAA;AAAA,EACN,QAAA,EAAU,CAAC,MAAS;AACtB,CAAC;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -140,10 +140,10 @@ interface ExtensionInput<UExtensionData extends ExtensionDataRef<unknown, string
|
|
|
140
140
|
singleton: boolean;
|
|
141
141
|
optional: boolean;
|
|
142
142
|
}> {
|
|
143
|
-
$$type: '@backstage/ExtensionInput';
|
|
144
|
-
extensionData: Array<UExtensionData>;
|
|
145
|
-
config: TConfig;
|
|
146
|
-
replaces?: Array<{
|
|
143
|
+
readonly $$type: '@backstage/ExtensionInput';
|
|
144
|
+
readonly extensionData: Array<UExtensionData>;
|
|
145
|
+
readonly config: TConfig;
|
|
146
|
+
readonly replaces?: Array<{
|
|
147
147
|
id: string;
|
|
148
148
|
input: string;
|
|
149
149
|
}>;
|
|
@@ -245,6 +245,19 @@ type PortableSchema<TOutput, TInput = TOutput> = {
|
|
|
245
245
|
schema: JsonObject;
|
|
246
246
|
};
|
|
247
247
|
|
|
248
|
+
/** @public */
|
|
249
|
+
type ExtensionAttachTo = {
|
|
250
|
+
id: string;
|
|
251
|
+
input: string;
|
|
252
|
+
} | Array<{
|
|
253
|
+
id: string;
|
|
254
|
+
input: string;
|
|
255
|
+
}>;
|
|
256
|
+
/**
|
|
257
|
+
* @deprecated Use {@link ExtensionAttachTo} instead.
|
|
258
|
+
* @public
|
|
259
|
+
*/
|
|
260
|
+
type ExtensionAttachToSpec = ExtensionAttachTo;
|
|
248
261
|
/** @public */
|
|
249
262
|
interface Extension<TConfig, TConfigInput = TConfig> {
|
|
250
263
|
$$type: '@backstage/Extension';
|
|
@@ -387,7 +400,7 @@ interface ExternalRouteRef<TParams extends AnyRouteRefParams = AnyRouteRefParams
|
|
|
387
400
|
*/
|
|
388
401
|
declare function createExternalRouteRef<TParams extends {
|
|
389
402
|
[param in TParamKeys]: string;
|
|
390
|
-
} | undefined = undefined, TParamKeys extends string = string>(
|
|
403
|
+
} | undefined = undefined, TParamKeys extends string = string>(config?: {
|
|
391
404
|
/**
|
|
392
405
|
* The parameters that will be provided to the external route reference.
|
|
393
406
|
*/
|
|
@@ -500,7 +513,7 @@ interface OverridableFrontendPlugin<TRoutes extends {
|
|
|
500
513
|
} = {
|
|
501
514
|
[id in string]: ExtensionDefinition;
|
|
502
515
|
}> extends FrontendPlugin<TRoutes, TExternalRoutes> {
|
|
503
|
-
getExtension<TId extends keyof TExtensionMap>(id: TId): TExtensionMap[TId]
|
|
516
|
+
getExtension<TId extends keyof TExtensionMap>(id: TId): OverridableExtensionDefinition<TExtensionMap[TId]['T']>;
|
|
504
517
|
withOverrides(options: {
|
|
505
518
|
extensions: Array<ExtensionDefinition>;
|
|
506
519
|
/**
|
|
@@ -649,9 +662,9 @@ type CreateExtensionBlueprintOptions<TKind extends string, TParams extends objec
|
|
|
649
662
|
[key in string]: (zImpl: typeof z) => z.ZodType;
|
|
650
663
|
}, UFactoryOutput extends ExtensionDataValue<any, any>, TDataRefs extends {
|
|
651
664
|
[name in string]: ExtensionDataRef;
|
|
652
|
-
}> = {
|
|
665
|
+
}, UParentInputs extends ExtensionDataRef> = {
|
|
653
666
|
kind: TKind;
|
|
654
|
-
attachTo:
|
|
667
|
+
attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
|
655
668
|
disabled?: boolean;
|
|
656
669
|
inputs?: TInputs;
|
|
657
670
|
output: Array<UOutput>;
|
|
@@ -739,12 +752,12 @@ type AnyParamsInput$1<TParams extends object | ExtensionBlueprintDefineParams> =
|
|
|
739
752
|
*/
|
|
740
753
|
interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters> {
|
|
741
754
|
dataRefs: T['dataRefs'];
|
|
742
|
-
make<TName extends string | undefined, TParamsInput extends AnyParamsInput$1<NonNullable<T['params']
|
|
755
|
+
make<TName extends string | undefined, TParamsInput extends AnyParamsInput$1<NonNullable<T['params']>>, UParentInputs extends ExtensionDataRef>(args: {
|
|
743
756
|
name?: TName;
|
|
744
|
-
attachTo?:
|
|
757
|
+
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<NonNullable<T['output']>, UParentInputs>;
|
|
745
758
|
disabled?: boolean;
|
|
746
759
|
params: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput : T['params'] extends ExtensionBlueprintDefineParams ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `<blueprint>.make({ params: defineParams => defineParams(<params>) })`' : T['params'];
|
|
747
|
-
}):
|
|
760
|
+
}): OverridableExtensionDefinition<{
|
|
748
761
|
kind: T['kind'];
|
|
749
762
|
name: string | undefined extends TName ? undefined : TName;
|
|
750
763
|
config: T['config'];
|
|
@@ -763,9 +776,9 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
|
|
|
763
776
|
[key in string]: (zImpl: typeof z) => z.ZodType;
|
|
764
777
|
}, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, TExtraInputs extends {
|
|
765
778
|
[inputName in string]: ExtensionInput;
|
|
766
|
-
}>(args: {
|
|
779
|
+
}, UParentInputs extends ExtensionDataRef>(args: {
|
|
767
780
|
name?: TName;
|
|
768
|
-
attachTo?:
|
|
781
|
+
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UParentInputs>;
|
|
769
782
|
disabled?: boolean;
|
|
770
783
|
inputs?: TExtraInputs & {
|
|
771
784
|
[KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
|
|
@@ -787,7 +800,7 @@ interface ExtensionBlueprint<T extends ExtensionBlueprintParameters = ExtensionB
|
|
|
787
800
|
};
|
|
788
801
|
inputs: Expand<ResolvedExtensionInputs<T['inputs'] & TExtraInputs>>;
|
|
789
802
|
}): Iterable<UFactoryOutput> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>;
|
|
790
|
-
}):
|
|
803
|
+
}): OverridableExtensionDefinition<{
|
|
791
804
|
config: (string extends keyof TExtensionConfigSchema ? {} : {
|
|
792
805
|
[key in keyof TExtensionConfigSchema]: z.infer<ReturnType<TExtensionConfigSchema[key]>>;
|
|
793
806
|
}) & T['config'];
|
|
@@ -854,9 +867,9 @@ declare function createExtensionBlueprint<TParams extends object | ExtensionBlue
|
|
|
854
867
|
[inputName in string]: ExtensionInput;
|
|
855
868
|
}, TConfigSchema extends {
|
|
856
869
|
[key in string]: (zImpl: typeof z) => z.ZodType;
|
|
857
|
-
}, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, TDataRefs extends {
|
|
870
|
+
}, UFactoryOutput extends ExtensionDataValue<any, any>, TKind extends string, UParentInputs extends ExtensionDataRef, TDataRefs extends {
|
|
858
871
|
[name in string]: ExtensionDataRef;
|
|
859
|
-
} = never>(options: CreateExtensionBlueprintOptions<TKind, TParams, UOutput, TInputs, TConfigSchema, UFactoryOutput, TDataRefs>): ExtensionBlueprint<{
|
|
872
|
+
} = never>(options: CreateExtensionBlueprintOptions<TKind, TParams, UOutput, TInputs, TConfigSchema, UFactoryOutput, TDataRefs, UParentInputs>): ExtensionBlueprint<{
|
|
860
873
|
kind: TKind;
|
|
861
874
|
params: TParams;
|
|
862
875
|
output: UOutput extends ExtensionDataRef<infer IData, infer IId, infer IConfig> ? ExtensionDataRef<IData, IId, IConfig> : never;
|
|
@@ -891,24 +904,77 @@ type PopUnion<U> = ToIntersection<U extends any ? () => U : never> extends () =>
|
|
|
891
904
|
/** @ignore */
|
|
892
905
|
type JoinStringUnion<U, TDiv extends string = ', ', TResult extends string = ''> = PopUnion<U> extends [infer IRest extends string, infer INext extends string] ? TResult extends '' ? JoinStringUnion<IRest, TDiv, INext> : JoinStringUnion<IRest, TDiv, `${TResult}${TDiv}${INext}`> : TResult;
|
|
893
906
|
/** @ignore */
|
|
894
|
-
type
|
|
895
|
-
/** @
|
|
896
|
-
type
|
|
907
|
+
type RequiredExtensionIds<UExtensionData extends ExtensionDataRef> = UExtensionData extends any ? UExtensionData['config']['optional'] extends true ? never : UExtensionData['id'] : never;
|
|
908
|
+
/** @ignore */
|
|
909
|
+
type VerifyExtensionFactoryOutput<UDeclaredOutput extends ExtensionDataRef, UFactoryOutput extends ExtensionDataValue<any, any>> = [RequiredExtensionIds<UDeclaredOutput>] extends [UFactoryOutput['id']] ? [UFactoryOutput['id']] extends [UDeclaredOutput['id']] ? {} : `Error: The extension factory has undeclared output(s): ${JoinStringUnion<Exclude<UFactoryOutput['id'], UDeclaredOutput['id']>>}` : `Error: The extension factory is missing the following output(s): ${JoinStringUnion<Exclude<RequiredExtensionIds<UDeclaredOutput>, UFactoryOutput['id']>>}`;
|
|
910
|
+
/** @ignore */
|
|
911
|
+
type VerifyExtensionAttachTo<UOutput extends ExtensionDataRef, UParentInput extends ExtensionDataRef> = ExtensionDataRef extends UParentInput ? {} : [RequiredExtensionIds<UParentInput>] extends [RequiredExtensionIds<UOutput>] ? {} : `Error: This parent extension input requires the following extension data, but it is not declared as guaranteed output of this extension: ${JoinStringUnion<Exclude<RequiredExtensionIds<UParentInput>, RequiredExtensionIds<UOutput>>>}`;
|
|
912
|
+
/**
|
|
913
|
+
* Specifies where an extension should attach in the extension tree.
|
|
914
|
+
*
|
|
915
|
+
* @remarks
|
|
916
|
+
*
|
|
917
|
+
* A standard attachment point declaration will specify the ID of the parent extension, as well as the name of the input to attach to.
|
|
918
|
+
*
|
|
919
|
+
* There are three more advanced forms that are available for more complex use-cases:
|
|
920
|
+
*
|
|
921
|
+
* 1. Relative attachment points: using the `relative` property instead of `id`, the attachment point is resolved relative to the current plugin.
|
|
922
|
+
* 2. Extension input references: using a reference in code to another extension's input in the same plugin. These references are always relative.
|
|
923
|
+
* 3. Array of attachment points: an array of attachment points can be used to clone and attach to multiple extensions at once.
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* ```ts
|
|
927
|
+
* // Attach to a specific extension by full ID
|
|
928
|
+
* { id: 'app/routes', input: 'routes' }
|
|
929
|
+
*
|
|
930
|
+
* // Attach to an extension in the same plugin by kind
|
|
931
|
+
* { relative: { kind: 'page' }, input: 'actions' }
|
|
932
|
+
*
|
|
933
|
+
* // Attach to a specific input of another extension
|
|
934
|
+
* const page = ParentBlueprint.make({ ... });
|
|
935
|
+
* const child = ChildBlueprint.make({ attachTo: page.inputs.children });
|
|
936
|
+
*
|
|
937
|
+
* // Attach to multiple parents at once
|
|
938
|
+
* [
|
|
939
|
+
* { id: 'page/home', input: 'widgets' },
|
|
940
|
+
* { relative: { kind: 'page' }, input: 'widgets' },
|
|
941
|
+
* ]
|
|
942
|
+
* ```
|
|
943
|
+
*
|
|
944
|
+
* @public
|
|
945
|
+
*/
|
|
946
|
+
type ExtensionDefinitionAttachTo<UParentInputs extends ExtensionDataRef = ExtensionDataRef> = {
|
|
897
947
|
id: string;
|
|
898
948
|
input: string;
|
|
899
|
-
|
|
949
|
+
relative?: never;
|
|
950
|
+
} | {
|
|
951
|
+
relative: {
|
|
952
|
+
kind?: string;
|
|
953
|
+
name?: string;
|
|
954
|
+
};
|
|
955
|
+
input: string;
|
|
956
|
+
id?: never;
|
|
957
|
+
} | ExtensionInput<UParentInputs> | Array<{
|
|
900
958
|
id: string;
|
|
901
959
|
input: string;
|
|
902
|
-
|
|
960
|
+
relative?: never;
|
|
961
|
+
} | {
|
|
962
|
+
relative: {
|
|
963
|
+
kind?: string;
|
|
964
|
+
name?: string;
|
|
965
|
+
};
|
|
966
|
+
input: string;
|
|
967
|
+
id?: never;
|
|
968
|
+
} | ExtensionInput<UParentInputs>>;
|
|
903
969
|
/** @public */
|
|
904
970
|
type CreateExtensionOptions<TKind extends string | undefined, TName extends string | undefined, UOutput extends ExtensionDataRef, TInputs extends {
|
|
905
971
|
[inputName in string]: ExtensionInput;
|
|
906
972
|
}, TConfigSchema extends {
|
|
907
973
|
[key: string]: (zImpl: typeof z) => z.ZodType;
|
|
908
|
-
}, UFactoryOutput extends ExtensionDataValue<any, any
|
|
974
|
+
}, UFactoryOutput extends ExtensionDataValue<any, any>, UParentInputs extends ExtensionDataRef> = {
|
|
909
975
|
kind?: TKind;
|
|
910
976
|
name?: TName;
|
|
911
|
-
attachTo:
|
|
977
|
+
attachTo: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<UOutput, UParentInputs>;
|
|
912
978
|
disabled?: boolean;
|
|
913
979
|
inputs?: TInputs;
|
|
914
980
|
output: Array<UOutput>;
|
|
@@ -947,15 +1013,24 @@ type ExtensionDefinitionParameters = {
|
|
|
947
1013
|
*/
|
|
948
1014
|
type AnyParamsInput<TParams extends object | ExtensionBlueprintDefineParams> = TParams extends ExtensionBlueprintDefineParams<infer IParams> ? IParams | ((define: TParams) => ReturnType<TParams>) : TParams | ((define: ExtensionBlueprintDefineParams<TParams, TParams>) => ReturnType<ExtensionBlueprintDefineParams<TParams, TParams>>);
|
|
949
1015
|
/** @public */
|
|
950
|
-
|
|
1016
|
+
interface ExtensionDefinition<TParams extends ExtensionDefinitionParameters = ExtensionDefinitionParameters> {
|
|
951
1017
|
$$type: '@backstage/ExtensionDefinition';
|
|
952
|
-
readonly T:
|
|
1018
|
+
readonly T: TParams;
|
|
1019
|
+
}
|
|
1020
|
+
/** @public */
|
|
1021
|
+
interface OverridableExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters> extends ExtensionDefinition<T> {
|
|
1022
|
+
/**
|
|
1023
|
+
* References to the inputs of this extension, which can be used to attach child extensions.
|
|
1024
|
+
*/
|
|
1025
|
+
readonly inputs: {
|
|
1026
|
+
[K in keyof T['inputs']]: ExtensionInput<T['inputs'][K] extends ExtensionInput<infer IData> ? IData : never>;
|
|
1027
|
+
};
|
|
953
1028
|
override<TExtensionConfigSchema extends {
|
|
954
1029
|
[key in string]: (zImpl: typeof z) => z.ZodType;
|
|
955
1030
|
}, UFactoryOutput extends ExtensionDataValue<any, any>, UNewOutput extends ExtensionDataRef, TExtraInputs extends {
|
|
956
1031
|
[inputName in string]: ExtensionInput;
|
|
957
|
-
}, TParamsInput extends AnyParamsInput<NonNullable<T['params']
|
|
958
|
-
attachTo?:
|
|
1032
|
+
}, TParamsInput extends AnyParamsInput<NonNullable<T['params']>>, UParentInputs extends ExtensionDataRef>(args: Expand<{
|
|
1033
|
+
attachTo?: ExtensionDefinitionAttachTo<UParentInputs> & VerifyExtensionAttachTo<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UParentInputs>;
|
|
959
1034
|
disabled?: boolean;
|
|
960
1035
|
inputs?: TExtraInputs & {
|
|
961
1036
|
[KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`;
|
|
@@ -981,7 +1056,7 @@ type ExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefi
|
|
|
981
1056
|
}): Iterable<UFactoryOutput>;
|
|
982
1057
|
} & ([T['params']] extends [never] ? {} : {
|
|
983
1058
|
params?: TParamsInput extends ExtensionBlueprintDefineParams ? TParamsInput : T['params'] extends ExtensionBlueprintDefineParams ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams(<params>))`' : Partial<T['params']>;
|
|
984
|
-
})> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>):
|
|
1059
|
+
})> & VerifyExtensionFactoryOutput<ExtensionDataRef extends UNewOutput ? NonNullable<T['output']> : UNewOutput, UFactoryOutput>): OverridableExtensionDefinition<{
|
|
985
1060
|
kind: T['kind'];
|
|
986
1061
|
name: T['name'];
|
|
987
1062
|
output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput;
|
|
@@ -993,7 +1068,7 @@ type ExtensionDefinition<T extends ExtensionDefinitionParameters = ExtensionDefi
|
|
|
993
1068
|
[key in keyof TExtensionConfigSchema]: ReturnType<TExtensionConfigSchema[key]>;
|
|
994
1069
|
}>>;
|
|
995
1070
|
}>;
|
|
996
|
-
}
|
|
1071
|
+
}
|
|
997
1072
|
/**
|
|
998
1073
|
* Creates a new extension definition for installation in a Backstage app.
|
|
999
1074
|
*
|
|
@@ -1033,7 +1108,7 @@ declare function createExtension<UOutput extends ExtensionDataRef, TInputs exten
|
|
|
1033
1108
|
[inputName in string]: ExtensionInput;
|
|
1034
1109
|
}, TConfigSchema extends {
|
|
1035
1110
|
[key: string]: (zImpl: typeof z) => z.ZodType;
|
|
1036
|
-
}, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput>):
|
|
1111
|
+
}, UFactoryOutput extends ExtensionDataValue<any, any>, const TKind extends string | undefined = undefined, const TName extends string | undefined = undefined, UParentInputs extends ExtensionDataRef = ExtensionDataRef>(options: CreateExtensionOptions<TKind, TName, UOutput, TInputs, TConfigSchema, UFactoryOutput, UParentInputs>): OverridableExtensionDefinition<{
|
|
1037
1112
|
config: string extends keyof TConfigSchema ? {} : {
|
|
1038
1113
|
[key in keyof TConfigSchema]: z.infer<ReturnType<TConfigSchema[key]>>;
|
|
1039
1114
|
};
|
|
@@ -1077,7 +1152,7 @@ declare function createFrontendFeatureLoader(options: CreateFrontendFeatureLoade
|
|
|
1077
1152
|
*/
|
|
1078
1153
|
interface AppNodeSpec {
|
|
1079
1154
|
readonly id: string;
|
|
1080
|
-
readonly attachTo:
|
|
1155
|
+
readonly attachTo: ExtensionAttachTo;
|
|
1081
1156
|
readonly extension: Extension<unknown, unknown>;
|
|
1082
1157
|
readonly disabled: boolean;
|
|
1083
1158
|
readonly config?: unknown;
|
|
@@ -1944,4 +2019,4 @@ declare const SwappableComponentBlueprint: ExtensionBlueprint<{
|
|
|
1944
2019
|
};
|
|
1945
2020
|
}>;
|
|
1946
2021
|
|
|
1947
|
-
export { type AnalyticsApi, AnalyticsContext, type AnalyticsContextValue, type AnalyticsEvent, type AnalyticsEventAttributes, type AnalyticsImplementation, AnalyticsImplementationBlueprint, type AnalyticsImplementationFactory, type AnalyticsTracker, type AnyExtensionDataRef, type AnyRouteRefParams, ApiBlueprint, type AppNode, type AppNodeEdges, type AppNodeInstance, type AppNodeSpec, AppRootElementBlueprint, AppRootWrapperBlueprint, type AppTree, type AppTreeApi, type ConfigurableExtensionDataRef, type CreateExtensionBlueprintOptions, type CreateExtensionOptions, type CreateFrontendFeatureLoaderOptions, type CreateFrontendModuleOptions, type CreateSwappableComponentOptions, type DialogApi, type DialogApiDialog, ErrorDisplay, type ErrorDisplayProps, type Extension, type ExtensionAttachToSpec, type ExtensionBlueprint, type ExtensionBlueprintDefineParams, type ExtensionBlueprintParameters, type ExtensionBlueprintParams, ExtensionBoundary, type ExtensionBoundaryProps, type ExtensionDataContainer, type ExtensionDataRef, type ExtensionDataRefToValue, type ExtensionDataValue, type ExtensionDefinition, type ExtensionDefinitionParameters, type ExtensionFactoryMiddleware, type ExtensionInput, type ExternalRouteRef, type FeatureFlagConfig, type FrontendFeature, type FrontendFeatureLoader, type FrontendModule, type FrontendPlugin, type FrontendPluginInfo, type FrontendPluginInfoOptions, IconBundleBlueprint, type IconComponent, type IconsApi, NavContentBlueprint, type NavContentComponent, type NavContentComponentProps, NavItemBlueprint, NotFoundErrorPage, type NotFoundErrorPageProps, type OverridableFrontendPlugin, PageBlueprint, type PluginOptions, type PortableSchema, Progress, type ProgressProps, type ResolvedExtensionInput, type ResolvedExtensionInputs, type RouteFunc, type RouteRef, type RouteResolutionApi, RouterBlueprint, SignInPageBlueprint, type SubRouteRef, SwappableComponentBlueprint, type SwappableComponentRef, type SwappableComponentsApi, ThemeBlueprint, TranslationBlueprint, analyticsApiRef, appTreeApiRef, coreExtensionData, createExtension, createExtensionBlueprint, createExtensionBlueprintParams, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, createSwappableComponent, dialogApiRef, iconsApiRef, routeResolutionApiRef, swappableComponentsApiRef, useAnalytics, useAppNode, useRouteRef, useRouteRefParams };
|
|
2022
|
+
export { type AnalyticsApi, AnalyticsContext, type AnalyticsContextValue, type AnalyticsEvent, type AnalyticsEventAttributes, type AnalyticsImplementation, AnalyticsImplementationBlueprint, type AnalyticsImplementationFactory, type AnalyticsTracker, type AnyExtensionDataRef, type AnyRouteRefParams, ApiBlueprint, type AppNode, type AppNodeEdges, type AppNodeInstance, type AppNodeSpec, AppRootElementBlueprint, AppRootWrapperBlueprint, type AppTree, type AppTreeApi, type ConfigurableExtensionDataRef, type CreateExtensionBlueprintOptions, type CreateExtensionOptions, type CreateFrontendFeatureLoaderOptions, type CreateFrontendModuleOptions, type CreateSwappableComponentOptions, type DialogApi, type DialogApiDialog, ErrorDisplay, type ErrorDisplayProps, type Extension, type ExtensionAttachTo, type ExtensionAttachToSpec, type ExtensionBlueprint, type ExtensionBlueprintDefineParams, type ExtensionBlueprintParameters, type ExtensionBlueprintParams, ExtensionBoundary, type ExtensionBoundaryProps, type ExtensionDataContainer, type ExtensionDataRef, type ExtensionDataRefToValue, type ExtensionDataValue, type ExtensionDefinition, type ExtensionDefinitionAttachTo, type ExtensionDefinitionParameters, type ExtensionFactoryMiddleware, type ExtensionInput, type ExternalRouteRef, type FeatureFlagConfig, type FrontendFeature, type FrontendFeatureLoader, type FrontendModule, type FrontendPlugin, type FrontendPluginInfo, type FrontendPluginInfoOptions, IconBundleBlueprint, type IconComponent, type IconsApi, NavContentBlueprint, type NavContentComponent, type NavContentComponentProps, NavItemBlueprint, NotFoundErrorPage, type NotFoundErrorPageProps, type OverridableExtensionDefinition, type OverridableFrontendPlugin, PageBlueprint, type PluginOptions, type PortableSchema, Progress, type ProgressProps, type ResolvedExtensionInput, type ResolvedExtensionInputs, type RouteFunc, type RouteRef, type RouteResolutionApi, RouterBlueprint, SignInPageBlueprint, type SubRouteRef, SwappableComponentBlueprint, type SwappableComponentRef, type SwappableComponentsApi, ThemeBlueprint, TranslationBlueprint, analyticsApiRef, appTreeApiRef, coreExtensionData, createExtension, createExtensionBlueprint, createExtensionBlueprintParams, createExtensionDataRef, createExtensionInput, createExternalRouteRef, createFrontendFeatureLoader, createFrontendModule, createFrontendPlugin, createRouteRef, createSubRouteRef, createSwappableComponent, dialogApiRef, iconsApiRef, routeResolutionApiRef, swappableComponentsApiRef, useAnalytics, useAppNode, useRouteRef, useRouteRefParams };
|
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
import { RouteRefImpl } from './RouteRef.esm.js';
|
|
2
1
|
import { describeParentCallSite } from './describeParentCallSite.esm.js';
|
|
2
|
+
import { OpaqueExternalRouteRef } from '../frontend-internal/src/routing/OpaqueExternalRouteRef.esm.js';
|
|
3
|
+
import '../frontend-internal/src/routing/OpaqueRouteRef.esm.js';
|
|
4
|
+
import '../frontend-internal/src/routing/OpaqueSubRouteRef.esm.js';
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
function createExternalRouteRef(config) {
|
|
7
|
+
const params = config?.params ?? [];
|
|
8
|
+
const creationSite = describeParentCallSite();
|
|
9
|
+
let id = void 0;
|
|
10
|
+
return OpaqueExternalRouteRef.createInstance("v1", {
|
|
11
|
+
T: void 0,
|
|
12
|
+
getParams() {
|
|
13
|
+
return params;
|
|
14
|
+
},
|
|
15
|
+
getDescription() {
|
|
16
|
+
if (id) {
|
|
17
|
+
return id;
|
|
18
|
+
}
|
|
19
|
+
return `created at '${creationSite}'`;
|
|
20
|
+
},
|
|
21
|
+
getDefaultTarget() {
|
|
22
|
+
return config?.defaultTarget;
|
|
23
|
+
},
|
|
24
|
+
setId(newId) {
|
|
25
|
+
if (!newId) {
|
|
26
|
+
throw new Error(`ExternalRouteRef id must be a non-empty string`);
|
|
27
|
+
}
|
|
28
|
+
if (id && id !== newId) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`ExternalRouteRef was referenced twice as both '${id}' and '${newId}'`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
id = newId;
|
|
34
|
+
},
|
|
35
|
+
toString() {
|
|
36
|
+
return `externalRouteRef{id=${id},at='${creationSite}'}`;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
export { createExternalRouteRef };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExternalRouteRef.esm.js","sources":["../../src/routing/ExternalRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2020 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 {
|
|
1
|
+
{"version":3,"file":"ExternalRouteRef.esm.js","sources":["../../src/routing/ExternalRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2020 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 { OpaqueExternalRouteRef } from '@internal/frontend';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends ExternalRouteRef<TParams> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n getDefaultTarget(): string | undefined;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: ExternalRouteRef<TParams>): InternalExternalRouteRef<TParams> {\n const r = resource as InternalExternalRouteRef<TParams>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TParamKeys extends string = string,\n>(config?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * The route (typically in another plugin) that this should map to by default.\n *\n * The string is expected to be on the standard `<plugin id>.<route id>` form,\n * for example `techdocs.docRoot`.\n */\n defaultTarget?: string;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string }\n> {\n const params = (config?.params ?? []) as string[];\n const creationSite = describeParentCallSite();\n\n let id: string | undefined = undefined;\n\n return OpaqueExternalRouteRef.createInstance('v1', {\n T: undefined as unknown as TParams,\n getParams() {\n return params;\n },\n getDescription() {\n if (id) {\n return id;\n }\n return `created at '${creationSite}'`;\n },\n getDefaultTarget() {\n return config?.defaultTarget;\n },\n setId(newId: string) {\n if (!newId) {\n throw new Error(`ExternalRouteRef id must be a non-empty string`);\n }\n if (id && id !== newId) {\n throw new Error(\n `ExternalRouteRef was referenced twice as both '${id}' and '${newId}'`,\n );\n }\n id = newId;\n },\n toString(): string {\n return `externalRouteRef{id=${id},at='${creationSite}'}`;\n },\n });\n}\n"],"names":[],"mappings":";;;;;AAsEO,SAAS,uBAGd,MAAA,EAqBA;AACA,EAAA,MAAM,MAAA,GAAU,MAAA,EAAQ,MAAA,IAAU,EAAC;AACnC,EAAA,MAAM,eAAe,sBAAA,EAAuB;AAE5C,EAAA,IAAI,EAAA,GAAyB,MAAA;AAE7B,EAAA,OAAO,sBAAA,CAAuB,eAAe,IAAA,EAAM;AAAA,IACjD,CAAA,EAAG,MAAA;AAAA,IACH,SAAA,GAAY;AACV,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,cAAA,GAAiB;AACf,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,OAAO,EAAA;AAAA,MACT;AACA,MAAA,OAAO,eAAe,YAAY,CAAA,CAAA,CAAA;AAAA,IACpC,CAAA;AAAA,IACA,gBAAA,GAAmB;AACjB,MAAA,OAAO,MAAA,EAAQ,aAAA;AAAA,IACjB,CAAA;AAAA,IACA,MAAM,KAAA,EAAe;AACnB,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,MAAM,CAAA,8CAAA,CAAgD,CAAA;AAAA,MAClE;AACA,MAAA,IAAI,EAAA,IAAM,OAAO,KAAA,EAAO;AACtB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,+CAAA,EAAkD,EAAE,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,SACrE;AAAA,MACF;AACA,MAAA,EAAA,GAAK,KAAA;AAAA,IACP,CAAA;AAAA,IACA,QAAA,GAAmB;AACjB,MAAA,OAAO,CAAA,oBAAA,EAAuB,EAAE,CAAA,KAAA,EAAQ,YAAY,CAAA,EAAA,CAAA;AAAA,IACtD;AAAA,GACD,CAAA;AACH;;;;"}
|