@backstage/frontend-app-api 0.10.6-next.0 → 0.11.0-next.2
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 +41 -0
- package/dist/frontend-internal/src/wiring/createExtensionDataContainer.esm.js +17 -0
- package/dist/frontend-internal/src/wiring/createExtensionDataContainer.esm.js.map +1 -0
- package/dist/index.d.ts +7 -9
- package/dist/tree/instantiateAppNodeTree.esm.js +19 -3
- package/dist/tree/instantiateAppNodeTree.esm.js.map +1 -1
- package/dist/wiring/createSpecializedApp.esm.js +42 -13
- package/dist/wiring/createSpecializedApp.esm.js.map +1 -1
- package/package.json +7 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @backstage/frontend-app-api
|
|
2
2
|
|
|
3
|
+
## 0.11.0-next.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- abcdf44: **BREAKING**: The returned object from `createSpecializedApp` no longer contains a `createRoot()` method, and it instead now contains `apis` and `tree`.
|
|
8
|
+
|
|
9
|
+
You can replace existing usage of `app.createRoot()` with the following:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const root = tree.root.instance?.getData(coreExtensionData.reactElement);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- 8250ffe: **BREAKING**: Dropped support for the removed opaque `@backstage/ExtensionOverrides` and `@backstage/BackstagePlugin` types.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 4d18b55: It's now possible to provide a middleware that wraps all extension factories by passing an `extensionFactoryMiddleware` to either `createApp()` or `createSpecializedApp()`.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @backstage/frontend-defaults@0.2.0-next.2
|
|
22
|
+
- @backstage/frontend-plugin-api@0.10.0-next.2
|
|
23
|
+
- @backstage/core-app-api@1.16.0-next.0
|
|
24
|
+
- @backstage/config@1.3.2
|
|
25
|
+
- @backstage/core-plugin-api@1.10.4
|
|
26
|
+
- @backstage/errors@1.2.7
|
|
27
|
+
- @backstage/types@1.2.1
|
|
28
|
+
- @backstage/version-bridge@1.0.11
|
|
29
|
+
|
|
30
|
+
## 0.10.6-next.1
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
- @backstage/config@1.3.2
|
|
36
|
+
- @backstage/core-app-api@1.15.5
|
|
37
|
+
- @backstage/core-plugin-api@1.10.4
|
|
38
|
+
- @backstage/errors@1.2.7
|
|
39
|
+
- @backstage/frontend-defaults@0.1.7-next.1
|
|
40
|
+
- @backstage/frontend-plugin-api@0.9.6-next.1
|
|
41
|
+
- @backstage/types@1.2.1
|
|
42
|
+
- @backstage/version-bridge@1.0.11
|
|
43
|
+
|
|
3
44
|
## 0.10.6-next.0
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function createExtensionDataContainer(values, declaredRefs) {
|
|
2
|
+
const container = /* @__PURE__ */ new Map();
|
|
3
|
+
for (const output of values) {
|
|
4
|
+
container.set(output.id, output);
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
get(ref) {
|
|
8
|
+
return container.get(ref.id)?.value;
|
|
9
|
+
},
|
|
10
|
+
[Symbol.iterator]() {
|
|
11
|
+
return container.values();
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { createExtensionDataContainer };
|
|
17
|
+
//# sourceMappingURL=createExtensionDataContainer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createExtensionDataContainer.esm.js","sources":["../../../../../frontend-internal/src/wiring/createExtensionDataContainer.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 AnyExtensionDataRef,\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionDataValue,\n} from '@backstage/frontend-plugin-api';\n\nexport function createExtensionDataContainer<UData extends AnyExtensionDataRef>(\n values: Iterable<\n UData extends ExtensionDataRef<infer IData, infer IId>\n ? ExtensionDataValue<IData, IId>\n : never\n >,\n declaredRefs?: ExtensionDataRef<any, any, any>[],\n): ExtensionDataContainer<UData> {\n const container = new Map<string, ExtensionDataValue<any, any>>();\n const verifyRefs =\n declaredRefs && new Map(declaredRefs.map(ref => [ref.id, ref]));\n\n for (const output of values) {\n if (verifyRefs) {\n if (!verifyRefs.delete(output.id)) {\n throw new Error(\n `extension data '${output.id}' was provided but not declared`,\n );\n }\n }\n container.set(output.id, output);\n }\n\n const remainingRefs =\n verifyRefs &&\n Array.from(verifyRefs.values()).filter(ref => !ref.config.optional);\n if (remainingRefs && remainingRefs.length > 0) {\n throw new Error(\n `missing required extension data value(s) '${remainingRefs\n .map(ref => ref.id)\n .join(', ')}'`,\n );\n }\n\n return {\n get(ref) {\n return container.get(ref.id)?.value;\n },\n [Symbol.iterator]() {\n return container.values();\n },\n } as ExtensionDataContainer<UData>;\n}\n"],"names":[],"mappings":"AAuBgB,SAAA,4BAAA,CACd,QAKA,YAC+B,EAAA;AAC/B,EAAM,MAAA,SAAA,uBAAgB,GAA0C,EAAA;AAIhE,EAAA,KAAA,MAAW,UAAU,MAAQ,EAAA;AAQ3B,IAAU,SAAA,CAAA,GAAA,CAAI,MAAO,CAAA,EAAA,EAAI,MAAM,CAAA;AAAA;AAcjC,EAAO,OAAA;AAAA,IACL,IAAI,GAAK,EAAA;AACP,MAAA,OAAO,SAAU,CAAA,GAAA,CAAI,GAAI,CAAA,EAAE,CAAG,EAAA,KAAA;AAAA,KAChC;AAAA,IACA,CAAC,MAAO,CAAA,QAAQ,CAAI,GAAA;AAClB,MAAA,OAAO,UAAU,MAAO,EAAA;AAAA;AAC1B,GACF;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ConfigApi } from '@backstage/core-plugin-api';
|
|
3
|
-
import { ExternalRouteRef, RouteRef, SubRouteRef, FrontendPlugin, FrontendModule } from '@backstage/frontend-plugin-api';
|
|
1
|
+
import { ExternalRouteRef, RouteRef, SubRouteRef, FrontendPlugin, FrontendModule, ExtensionFactoryMiddleware, AppTree } from '@backstage/frontend-plugin-api';
|
|
2
|
+
import { ConfigApi, ApiHolder } from '@backstage/core-plugin-api';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Extracts a union of the keys in a map whose value extends the given type
|
|
@@ -41,11 +40,7 @@ type CreateAppRouteBinder = <TExternalRoutes extends {
|
|
|
41
40
|
}>(externalRoutes: TExternalRoutes, targetRoutes: PartialKeys<TargetRouteMap<TExternalRoutes>, KeysWithType<TExternalRoutes, ExternalRouteRef<any>>>) => void;
|
|
42
41
|
|
|
43
42
|
/** @public */
|
|
44
|
-
type FrontendFeature = FrontendPlugin | FrontendModule
|
|
45
|
-
$$type: '@backstage/ExtensionOverrides';
|
|
46
|
-
} | {
|
|
47
|
-
$$type: '@backstage/BackstagePlugin';
|
|
48
|
-
};
|
|
43
|
+
type FrontendFeature = FrontendPlugin | FrontendModule;
|
|
49
44
|
|
|
50
45
|
/**
|
|
51
46
|
* Creates an empty app without any default features. This is a low-level API is
|
|
@@ -60,8 +55,11 @@ declare function createSpecializedApp(options?: {
|
|
|
60
55
|
bindRoutes?(context: {
|
|
61
56
|
bind: CreateAppRouteBinder;
|
|
62
57
|
}): void;
|
|
58
|
+
apis?: ApiHolder;
|
|
59
|
+
extensionFactoryMiddleware?: ExtensionFactoryMiddleware | ExtensionFactoryMiddleware[];
|
|
63
60
|
}): {
|
|
64
|
-
|
|
61
|
+
apis: ApiHolder;
|
|
62
|
+
tree: AppTree;
|
|
65
63
|
};
|
|
66
64
|
|
|
67
65
|
export { type CreateAppRouteBinder, type FrontendFeature, createSpecializedApp };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import mapValues from 'lodash/mapValues';
|
|
2
2
|
import { toInternalExtension } from '../frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js';
|
|
3
|
+
import { createExtensionDataContainer } from '../frontend-internal/src/wiring/createExtensionDataContainer.esm.js';
|
|
4
|
+
import '../frontend-internal/src/wiring/InternalExtensionDefinition.esm.js';
|
|
5
|
+
import '../frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
|
|
3
6
|
|
|
4
7
|
function resolveV1InputDataMap(dataMap, attachment, inputName) {
|
|
5
8
|
return mapValues(dataMap, (ref) => {
|
|
@@ -161,12 +164,24 @@ function createAppNodeInstance(options) {
|
|
|
161
164
|
extensionDataRefs.add(ref);
|
|
162
165
|
}
|
|
163
166
|
} else if (internalExtension.version === "v2") {
|
|
164
|
-
const
|
|
167
|
+
const context = {
|
|
165
168
|
node,
|
|
166
169
|
apis,
|
|
167
170
|
config: parsedConfig,
|
|
168
171
|
inputs: resolveV2Inputs(internalExtension.inputs, attachments)
|
|
169
|
-
}
|
|
172
|
+
};
|
|
173
|
+
const outputDataValues = options.extensionFactoryMiddleware ? createExtensionDataContainer(
|
|
174
|
+
options.extensionFactoryMiddleware((overrideContext) => {
|
|
175
|
+
return createExtensionDataContainer(
|
|
176
|
+
internalExtension.factory({
|
|
177
|
+
node: context.node,
|
|
178
|
+
apis: context.apis,
|
|
179
|
+
inputs: context.inputs,
|
|
180
|
+
config: overrideContext?.config ?? context.config
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
}, context)
|
|
184
|
+
) : internalExtension.factory(context);
|
|
170
185
|
const outputDataMap = /* @__PURE__ */ new Map();
|
|
171
186
|
for (const value of outputDataValues) {
|
|
172
187
|
if (outputDataMap.has(value.id)) {
|
|
@@ -214,7 +229,7 @@ function createAppNodeInstance(options) {
|
|
|
214
229
|
}
|
|
215
230
|
};
|
|
216
231
|
}
|
|
217
|
-
function instantiateAppNodeTree(rootNode, apis) {
|
|
232
|
+
function instantiateAppNodeTree(rootNode, apis, extensionFactoryMiddleware) {
|
|
218
233
|
function createInstance(node) {
|
|
219
234
|
if (node.instance) {
|
|
220
235
|
return node.instance;
|
|
@@ -236,6 +251,7 @@ function instantiateAppNodeTree(rootNode, apis) {
|
|
|
236
251
|
}
|
|
237
252
|
}
|
|
238
253
|
node.instance = createAppNodeInstance({
|
|
254
|
+
extensionFactoryMiddleware,
|
|
239
255
|
node,
|
|
240
256
|
apis,
|
|
241
257
|
attachments: instantiatedAttachments
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instantiateAppNodeTree.esm.js","sources":["../../src/tree/instantiateAppNodeTree.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 AnyExtensionDataRef,\n ApiHolder,\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionInput,\n ResolvedExtensionInputs,\n} from '@backstage/frontend-plugin-api';\nimport mapValues from 'lodash/mapValues';\nimport { AppNode, AppNodeInstance } from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nfunction resolveV1InputDataMap(\n dataMap: {\n [name in string]: AnyExtensionDataRef;\n },\n attachment: AppNode,\n inputName: string,\n) {\n return mapValues(dataMap, ref => {\n const value = attachment.instance?.getData(ref);\n if (value === undefined && !ref.config.optional) {\n const expected = Object.values(dataMap)\n .filter(r => !r.config.optional)\n .map(r => `'${r.id}'`)\n .join(', ');\n\n const provided = [...(attachment.instance?.getDataRefs() ?? [])]\n .map(r => `'${r.id}'`)\n .join(', ');\n\n throw new Error(\n `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n );\n }\n return value;\n });\n}\n\nfunction resolveInputDataContainer(\n extensionData: Array<AnyExtensionDataRef>,\n attachment: AppNode,\n inputName: string,\n): { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef> {\n const dataMap = new Map<string, unknown>();\n\n for (const ref of extensionData) {\n if (dataMap.has(ref.id)) {\n throw new Error(`Unexpected duplicate input data '${ref.id}'`);\n }\n const value = attachment.instance?.getData(ref);\n if (value === undefined && !ref.config.optional) {\n const expected = extensionData\n .filter(r => !r.config.optional)\n .map(r => `'${r.id}'`)\n .join(', ');\n\n const provided = [...(attachment.instance?.getDataRefs() ?? [])]\n .map(r => `'${r.id}'`)\n .join(', ');\n\n throw new Error(\n `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n );\n }\n\n dataMap.set(ref.id, value);\n }\n\n return {\n node: attachment,\n get(ref) {\n return dataMap.get(ref.id);\n },\n *[Symbol.iterator]() {\n for (const [id, value] of dataMap) {\n // TODO: Would be better to be able to create a new instance using the ref here instead\n yield {\n $$type: '@backstage/ExtensionDataValue',\n id,\n value,\n };\n }\n },\n } as { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef>;\n}\n\nfunction reportUndeclaredAttachments(\n id: string,\n inputMap: { [name in string]: unknown },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n const undeclaredAttachments = Array.from(attachments.entries()).filter(\n ([inputName]) => inputMap[inputName] === undefined,\n );\n\n const inputNames = Object.keys(inputMap);\n\n for (const [name, nodes] of undeclaredAttachments) {\n const pl = nodes.length > 1;\n // eslint-disable-next-line no-console\n console.warn(\n [\n `The extension${pl ? 's' : ''} '${nodes\n .map(n => n.spec.id)\n .join(\"', '\")}' ${pl ? 'are' : 'is'}`,\n `attached to the input '${name}' of the extension '${id}', but it`,\n inputNames.length === 0\n ? 'has no inputs'\n : `has no such input (candidates are '${inputNames.join(\"', '\")}')`,\n ].join(' '),\n );\n }\n}\n\nfunction resolveV1Inputs(\n inputMap: {\n [inputName in string]: {\n $$type: '@backstage/ExtensionInput';\n extensionData: {\n [name in string]: AnyExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n return mapValues(inputMap, (input, inputName) => {\n const attachedNodes = attachments.get(inputName) ?? [];\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id);\n throw Error(\n `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds.join(\n \"', '\",\n )}'`,\n );\n } else if (attachedNodes.length === 0) {\n if (input.config.optional) {\n return undefined;\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return {\n node: attachedNodes[0],\n output: resolveV1InputDataMap(\n input.extensionData,\n attachedNodes[0],\n inputName,\n ),\n };\n }\n\n return attachedNodes.map(attachment => ({\n node: attachment,\n output: resolveV1InputDataMap(input.extensionData, attachment, inputName),\n }));\n }) as {\n [inputName in string]: {\n node: AppNode;\n output: {\n [name in string]: unknown;\n };\n };\n };\n}\n\nfunction resolveV2Inputs(\n inputMap: {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n): ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n}> {\n return mapValues(inputMap, (input, inputName) => {\n const attachedNodes = attachments.get(inputName) ?? [];\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id);\n throw Error(\n `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds.join(\n \"', '\",\n )}'`,\n );\n } else if (attachedNodes.length === 0) {\n if (input.config.optional) {\n return undefined;\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return resolveInputDataContainer(\n input.extensionData,\n attachedNodes[0],\n inputName,\n );\n }\n\n return attachedNodes.map(attachment =>\n resolveInputDataContainer(input.extensionData, attachment, inputName),\n );\n }) as ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n }>;\n}\n\n/** @internal */\nexport function createAppNodeInstance(options: {\n node: AppNode;\n apis: ApiHolder;\n attachments: ReadonlyMap<string, AppNode[]>;\n}): AppNodeInstance {\n const { node, apis, attachments } = options;\n const { id, extension, config } = node.spec;\n const extensionData = new Map<string, unknown>();\n const extensionDataRefs = new Set<ExtensionDataRef<unknown>>();\n\n let parsedConfig: unknown;\n try {\n parsedConfig = extension.configSchema?.parse(config ?? {});\n } catch (e) {\n throw new Error(\n `Invalid configuration for extension '${id}'; caused by ${e}`,\n );\n }\n\n try {\n const internalExtension = toInternalExtension(extension);\n\n if (process.env.NODE_ENV !== 'production') {\n reportUndeclaredAttachments(id, internalExtension.inputs, attachments);\n }\n\n if (internalExtension.version === 'v1') {\n const namedOutputs = internalExtension.factory({\n node,\n apis,\n config: parsedConfig,\n inputs: resolveV1Inputs(internalExtension.inputs, attachments),\n });\n\n for (const [name, output] of Object.entries(namedOutputs)) {\n const ref = internalExtension.output[name];\n if (!ref) {\n throw new Error(`unknown output provided via '${name}'`);\n }\n if (extensionData.has(ref.id)) {\n throw new Error(\n `duplicate extension data '${ref.id}' received via output '${name}'`,\n );\n }\n extensionData.set(ref.id, output);\n extensionDataRefs.add(ref);\n }\n } else if (internalExtension.version === 'v2') {\n const outputDataValues = internalExtension.factory({\n node,\n apis,\n config: parsedConfig,\n inputs: resolveV2Inputs(internalExtension.inputs, attachments),\n });\n\n const outputDataMap = new Map<string, unknown>();\n for (const value of outputDataValues) {\n if (outputDataMap.has(value.id)) {\n throw new Error(`duplicate extension data output '${value.id}'`);\n }\n outputDataMap.set(value.id, value.value);\n }\n\n for (const ref of internalExtension.output) {\n const value = outputDataMap.get(ref.id);\n outputDataMap.delete(ref.id);\n if (value === undefined) {\n if (!ref.config.optional) {\n throw new Error(\n `missing required extension data output '${ref.id}'`,\n );\n }\n } else {\n extensionData.set(ref.id, value);\n extensionDataRefs.add(ref);\n }\n }\n\n if (outputDataMap.size > 0) {\n throw new Error(\n `unexpected output '${Array.from(outputDataMap.keys()).join(\n \"', '\",\n )}'`,\n );\n }\n } else {\n throw new Error(\n `unexpected extension version '${(internalExtension as any).version}'`,\n );\n }\n } catch (e) {\n throw new Error(\n `Failed to instantiate extension '${id}'${\n e.name === 'Error' ? `, ${e.message}` : `; caused by ${e.stack}`\n }`,\n );\n }\n\n return {\n getDataRefs() {\n return extensionDataRefs.values();\n },\n getData<T>(ref: ExtensionDataRef<T>): T | undefined {\n return extensionData.get(ref.id) as T | undefined;\n },\n };\n}\n\n/**\n * Starting at the provided node, instantiate all reachable nodes in the tree that have not been disabled.\n * @internal\n */\nexport function instantiateAppNodeTree(\n rootNode: AppNode,\n apis: ApiHolder,\n): void {\n function createInstance(node: AppNode): AppNodeInstance | undefined {\n if (node.instance) {\n return node.instance;\n }\n if (node.spec.disabled) {\n return undefined;\n }\n\n const instantiatedAttachments = new Map<string, AppNode[]>();\n\n for (const [input, children] of node.edges.attachments) {\n const instantiatedChildren = children.flatMap(child => {\n const childInstance = createInstance(child);\n if (!childInstance) {\n return [];\n }\n return [child];\n });\n if (instantiatedChildren.length > 0) {\n instantiatedAttachments.set(input, instantiatedChildren);\n }\n }\n\n (node as Mutable<AppNode>).instance = createAppNodeInstance({\n node,\n apis,\n attachments: instantiatedAttachments,\n });\n\n return node.instance;\n }\n\n createInstance(rootNode);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"instantiateAppNodeTree.esm.js","sources":["../../src/tree/instantiateAppNodeTree.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 AnyExtensionDataRef,\n ApiHolder,\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionFactoryMiddleware,\n ExtensionInput,\n ResolvedExtensionInputs,\n} from '@backstage/frontend-plugin-api';\nimport mapValues from 'lodash/mapValues';\nimport { AppNode, AppNodeInstance } from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\nimport { createExtensionDataContainer } from '@internal/frontend';\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nfunction resolveV1InputDataMap(\n dataMap: {\n [name in string]: AnyExtensionDataRef;\n },\n attachment: AppNode,\n inputName: string,\n) {\n return mapValues(dataMap, ref => {\n const value = attachment.instance?.getData(ref);\n if (value === undefined && !ref.config.optional) {\n const expected = Object.values(dataMap)\n .filter(r => !r.config.optional)\n .map(r => `'${r.id}'`)\n .join(', ');\n\n const provided = [...(attachment.instance?.getDataRefs() ?? [])]\n .map(r => `'${r.id}'`)\n .join(', ');\n\n throw new Error(\n `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n );\n }\n return value;\n });\n}\n\nfunction resolveInputDataContainer(\n extensionData: Array<AnyExtensionDataRef>,\n attachment: AppNode,\n inputName: string,\n): { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef> {\n const dataMap = new Map<string, unknown>();\n\n for (const ref of extensionData) {\n if (dataMap.has(ref.id)) {\n throw new Error(`Unexpected duplicate input data '${ref.id}'`);\n }\n const value = attachment.instance?.getData(ref);\n if (value === undefined && !ref.config.optional) {\n const expected = extensionData\n .filter(r => !r.config.optional)\n .map(r => `'${r.id}'`)\n .join(', ');\n\n const provided = [...(attachment.instance?.getDataRefs() ?? [])]\n .map(r => `'${r.id}'`)\n .join(', ');\n\n throw new Error(\n `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n );\n }\n\n dataMap.set(ref.id, value);\n }\n\n return {\n node: attachment,\n get(ref) {\n return dataMap.get(ref.id);\n },\n *[Symbol.iterator]() {\n for (const [id, value] of dataMap) {\n // TODO: Would be better to be able to create a new instance using the ref here instead\n yield {\n $$type: '@backstage/ExtensionDataValue',\n id,\n value,\n };\n }\n },\n } as { node: AppNode } & ExtensionDataContainer<AnyExtensionDataRef>;\n}\n\nfunction reportUndeclaredAttachments(\n id: string,\n inputMap: { [name in string]: unknown },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n const undeclaredAttachments = Array.from(attachments.entries()).filter(\n ([inputName]) => inputMap[inputName] === undefined,\n );\n\n const inputNames = Object.keys(inputMap);\n\n for (const [name, nodes] of undeclaredAttachments) {\n const pl = nodes.length > 1;\n // eslint-disable-next-line no-console\n console.warn(\n [\n `The extension${pl ? 's' : ''} '${nodes\n .map(n => n.spec.id)\n .join(\"', '\")}' ${pl ? 'are' : 'is'}`,\n `attached to the input '${name}' of the extension '${id}', but it`,\n inputNames.length === 0\n ? 'has no inputs'\n : `has no such input (candidates are '${inputNames.join(\"', '\")}')`,\n ].join(' '),\n );\n }\n}\n\nfunction resolveV1Inputs(\n inputMap: {\n [inputName in string]: {\n $$type: '@backstage/ExtensionInput';\n extensionData: {\n [name in string]: AnyExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n return mapValues(inputMap, (input, inputName) => {\n const attachedNodes = attachments.get(inputName) ?? [];\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id);\n throw Error(\n `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds.join(\n \"', '\",\n )}'`,\n );\n } else if (attachedNodes.length === 0) {\n if (input.config.optional) {\n return undefined;\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return {\n node: attachedNodes[0],\n output: resolveV1InputDataMap(\n input.extensionData,\n attachedNodes[0],\n inputName,\n ),\n };\n }\n\n return attachedNodes.map(attachment => ({\n node: attachment,\n output: resolveV1InputDataMap(input.extensionData, attachment, inputName),\n }));\n }) as {\n [inputName in string]: {\n node: AppNode;\n output: {\n [name in string]: unknown;\n };\n };\n };\n}\n\nfunction resolveV2Inputs(\n inputMap: {\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n): ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n}> {\n return mapValues(inputMap, (input, inputName) => {\n const attachedNodes = attachments.get(inputName) ?? [];\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id);\n throw Error(\n `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds.join(\n \"', '\",\n )}'`,\n );\n } else if (attachedNodes.length === 0) {\n if (input.config.optional) {\n return undefined;\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return resolveInputDataContainer(\n input.extensionData,\n attachedNodes[0],\n inputName,\n );\n }\n\n return attachedNodes.map(attachment =>\n resolveInputDataContainer(input.extensionData, attachment, inputName),\n );\n }) as ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n AnyExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n }>;\n}\n\n/** @internal */\nexport function createAppNodeInstance(options: {\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware;\n node: AppNode;\n apis: ApiHolder;\n attachments: ReadonlyMap<string, AppNode[]>;\n}): AppNodeInstance {\n const { node, apis, attachments } = options;\n const { id, extension, config } = node.spec;\n const extensionData = new Map<string, unknown>();\n const extensionDataRefs = new Set<ExtensionDataRef<unknown>>();\n\n let parsedConfig: { [x: string]: any };\n try {\n parsedConfig = extension.configSchema?.parse(config ?? {}) as {\n [x: string]: any;\n };\n } catch (e) {\n throw new Error(\n `Invalid configuration for extension '${id}'; caused by ${e}`,\n );\n }\n\n try {\n const internalExtension = toInternalExtension(extension);\n\n if (process.env.NODE_ENV !== 'production') {\n reportUndeclaredAttachments(id, internalExtension.inputs, attachments);\n }\n\n if (internalExtension.version === 'v1') {\n const namedOutputs = internalExtension.factory({\n node,\n apis,\n config: parsedConfig,\n inputs: resolveV1Inputs(internalExtension.inputs, attachments),\n });\n\n for (const [name, output] of Object.entries(namedOutputs)) {\n const ref = internalExtension.output[name];\n if (!ref) {\n throw new Error(`unknown output provided via '${name}'`);\n }\n if (extensionData.has(ref.id)) {\n throw new Error(\n `duplicate extension data '${ref.id}' received via output '${name}'`,\n );\n }\n extensionData.set(ref.id, output);\n extensionDataRefs.add(ref);\n }\n } else if (internalExtension.version === 'v2') {\n const context = {\n node,\n apis,\n config: parsedConfig,\n inputs: resolveV2Inputs(internalExtension.inputs, attachments),\n };\n const outputDataValues = options.extensionFactoryMiddleware\n ? createExtensionDataContainer(\n options.extensionFactoryMiddleware(overrideContext => {\n return createExtensionDataContainer(\n internalExtension.factory({\n node: context.node,\n apis: context.apis,\n inputs: context.inputs,\n config: overrideContext?.config ?? context.config,\n }),\n );\n }, context),\n )\n : internalExtension.factory(context);\n\n const outputDataMap = new Map<string, unknown>();\n for (const value of outputDataValues) {\n if (outputDataMap.has(value.id)) {\n throw new Error(`duplicate extension data output '${value.id}'`);\n }\n outputDataMap.set(value.id, value.value);\n }\n\n for (const ref of internalExtension.output) {\n const value = outputDataMap.get(ref.id);\n outputDataMap.delete(ref.id);\n if (value === undefined) {\n if (!ref.config.optional) {\n throw new Error(\n `missing required extension data output '${ref.id}'`,\n );\n }\n } else {\n extensionData.set(ref.id, value);\n extensionDataRefs.add(ref);\n }\n }\n\n if (outputDataMap.size > 0) {\n throw new Error(\n `unexpected output '${Array.from(outputDataMap.keys()).join(\n \"', '\",\n )}'`,\n );\n }\n } else {\n throw new Error(\n `unexpected extension version '${(internalExtension as any).version}'`,\n );\n }\n } catch (e) {\n throw new Error(\n `Failed to instantiate extension '${id}'${\n e.name === 'Error' ? `, ${e.message}` : `; caused by ${e.stack}`\n }`,\n );\n }\n\n return {\n getDataRefs() {\n return extensionDataRefs.values();\n },\n getData<T>(ref: ExtensionDataRef<T>): T | undefined {\n return extensionData.get(ref.id) as T | undefined;\n },\n };\n}\n\n/**\n * Starting at the provided node, instantiate all reachable nodes in the tree that have not been disabled.\n * @internal\n */\nexport function instantiateAppNodeTree(\n rootNode: AppNode,\n apis: ApiHolder,\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware,\n): void {\n function createInstance(node: AppNode): AppNodeInstance | undefined {\n if (node.instance) {\n return node.instance;\n }\n if (node.spec.disabled) {\n return undefined;\n }\n\n const instantiatedAttachments = new Map<string, AppNode[]>();\n\n for (const [input, children] of node.edges.attachments) {\n const instantiatedChildren = children.flatMap(child => {\n const childInstance = createInstance(child);\n if (!childInstance) {\n return [];\n }\n return [child];\n });\n if (instantiatedChildren.length > 0) {\n instantiatedAttachments.set(input, instantiatedChildren);\n }\n }\n\n (node as Mutable<AppNode>).instance = createAppNodeInstance({\n extensionFactoryMiddleware,\n node,\n apis,\n attachments: instantiatedAttachments,\n });\n\n return node.instance;\n }\n\n createInstance(rootNode);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { ConfigReader } from '@backstage/config';
|
|
3
|
-
import { createApiFactory, appTreeApiRef, routeResolutionApiRef,
|
|
2
|
+
import { createApiFactory, appTreeApiRef, routeResolutionApiRef, ApiBlueprint } from '@backstage/frontend-plugin-api';
|
|
4
3
|
import { configApiRef, identityApiRef, featureFlagsApiRef } from '@backstage/core-plugin-api';
|
|
5
4
|
import { ApiFactoryRegistry, ApiResolver } from '@backstage/core-app-api';
|
|
6
|
-
import { resolveExtensionDefinition } from '../frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js';
|
|
5
|
+
import { resolveExtensionDefinition, toInternalExtension } from '../frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js';
|
|
7
6
|
import { extractRouteInfoFromAppNode } from '../routing/extractRouteInfoFromAppNode.esm.js';
|
|
8
7
|
import { RouteResolver } from '../routing/RouteResolver.esm.js';
|
|
9
8
|
import { resolveRouteBindings } from '../routing/resolveRouteBindings.esm.js';
|
|
@@ -19,6 +18,7 @@ import { ApiRegistry } from '../core-app-api/src/apis/system/ApiRegistry.esm.js'
|
|
|
19
18
|
import { AppIdentityProxy } from '../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.esm.js';
|
|
20
19
|
import { matchRoutes } from 'react-router-dom';
|
|
21
20
|
import { OpaqueFrontendPlugin } from '../frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
|
|
21
|
+
import { createExtensionDataContainer } from '../frontend-internal/src/wiring/createExtensionDataContainer.esm.js';
|
|
22
22
|
|
|
23
23
|
function deduplicateFeatures(allFeatures) {
|
|
24
24
|
const features = Array.from(new Set(allFeatures));
|
|
@@ -121,7 +121,7 @@ function createSpecializedApp(options) {
|
|
|
121
121
|
appBasePath
|
|
122
122
|
);
|
|
123
123
|
const appIdentityProxy = new AppIdentityProxy();
|
|
124
|
-
const
|
|
124
|
+
const apis = options?.apis ?? createApiHolder({
|
|
125
125
|
factories,
|
|
126
126
|
staticFactories: [
|
|
127
127
|
createApiFactory(appTreeApiRef, appTreeApi),
|
|
@@ -130,7 +130,7 @@ function createSpecializedApp(options) {
|
|
|
130
130
|
createApiFactory(identityApiRef, appIdentityProxy)
|
|
131
131
|
]
|
|
132
132
|
});
|
|
133
|
-
const featureFlagApi =
|
|
133
|
+
const featureFlagApi = apis.get(featureFlagsApiRef);
|
|
134
134
|
if (featureFlagApi) {
|
|
135
135
|
for (const feature of features) {
|
|
136
136
|
if (OpaqueFrontendPlugin.isType(feature)) {
|
|
@@ -151,17 +151,15 @@ function createSpecializedApp(options) {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
instantiateAppNodeTree(
|
|
154
|
+
instantiateAppNodeTree(
|
|
155
|
+
tree.root,
|
|
156
|
+
apis,
|
|
157
|
+
mergeExtensionFactoryMiddleware(options?.extensionFactoryMiddleware)
|
|
158
|
+
);
|
|
155
159
|
const routeInfo = extractRouteInfoFromAppNode(tree.root);
|
|
156
160
|
routeResolutionApi.initialize(routeInfo);
|
|
157
161
|
appTreeApi.initialize(routeInfo);
|
|
158
|
-
|
|
159
|
-
const AppComponent = () => rootEl;
|
|
160
|
-
return {
|
|
161
|
-
createRoot() {
|
|
162
|
-
return /* @__PURE__ */ React.createElement(AppComponent, null);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
162
|
+
return { apis, tree };
|
|
165
163
|
}
|
|
166
164
|
function createApiFactories(options) {
|
|
167
165
|
const emptyApiHolder = ApiRegistry.from([]);
|
|
@@ -189,6 +187,37 @@ function createApiHolder(options) {
|
|
|
189
187
|
ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis());
|
|
190
188
|
return new ApiResolver(factoryRegistry);
|
|
191
189
|
}
|
|
190
|
+
function mergeExtensionFactoryMiddleware(middlewares) {
|
|
191
|
+
if (!middlewares) {
|
|
192
|
+
return void 0;
|
|
193
|
+
}
|
|
194
|
+
if (!Array.isArray(middlewares)) {
|
|
195
|
+
return middlewares;
|
|
196
|
+
}
|
|
197
|
+
if (middlewares.length <= 1) {
|
|
198
|
+
return middlewares[0];
|
|
199
|
+
}
|
|
200
|
+
return middlewares.reduce((prev, next) => {
|
|
201
|
+
if (!prev || !next) {
|
|
202
|
+
return prev ?? next;
|
|
203
|
+
}
|
|
204
|
+
return (orig, ctx) => {
|
|
205
|
+
const internalExt = toInternalExtension(ctx.node.spec.extension);
|
|
206
|
+
if (internalExt.version !== "v2") {
|
|
207
|
+
return orig();
|
|
208
|
+
}
|
|
209
|
+
return next((ctxOverrides) => {
|
|
210
|
+
return createExtensionDataContainer(
|
|
211
|
+
prev(orig, {
|
|
212
|
+
node: ctx.node,
|
|
213
|
+
apis: ctx.apis,
|
|
214
|
+
config: ctxOverrides?.config ?? ctx.config
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
}, ctx);
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
}
|
|
192
221
|
|
|
193
222
|
export { createSpecializedApp };
|
|
194
223
|
//# sourceMappingURL=createSpecializedApp.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSpecializedApp.esm.js","sources":["../../src/wiring/createSpecializedApp.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 React, { JSX } from 'react';\nimport { ConfigReader } from '@backstage/config';\nimport {\n ApiBlueprint,\n AppTree,\n AppTreeApi,\n appTreeApiRef,\n coreExtensionData,\n RouteRef,\n ExternalRouteRef,\n SubRouteRef,\n AnyRouteRefParams,\n RouteFunc,\n RouteResolutionApiResolveOptions,\n RouteResolutionApi,\n createApiFactory,\n routeResolutionApiRef,\n AppNode,\n} from '@backstage/frontend-plugin-api';\nimport {\n AnyApiFactory,\n ApiHolder,\n ConfigApi,\n configApiRef,\n featureFlagsApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport { ApiFactoryRegistry, ApiResolver } from '@backstage/core-app-api';\nimport { OpaqueFrontendPlugin } from '@internal/frontend';\n\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\n\nimport { extractRouteInfoFromAppNode } from '../routing/extractRouteInfoFromAppNode';\n\nimport { CreateAppRouteBinder } from '../routing';\nimport { RouteResolver } from '../routing/RouteResolver';\nimport { resolveRouteBindings } from '../routing/resolveRouteBindings';\nimport { collectRouteIds } from '../routing/collectRouteIds';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n toInternalFrontendModule,\n isInternalFrontendModule,\n} from '../../../frontend-plugin-api/src/wiring/createFrontendModule';\nimport { getBasePath } from '../routing/getBasePath';\nimport { Root } from '../extensions/Root';\nimport { resolveAppTree } from '../tree/resolveAppTree';\nimport { resolveAppNodeSpecs } from '../tree/resolveAppNodeSpecs';\nimport { readAppExtensionsConfig } from '../tree/readAppExtensionsConfig';\nimport { instantiateAppNodeTree } from '../tree/instantiateAppNodeTree';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ApiRegistry } from '../../../core-app-api/src/apis/system/ApiRegistry';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy';\nimport { BackstageRouteObject } from '../routing/types';\nimport { FrontendFeature, RouteInfo } from './types';\nimport { matchRoutes } from 'react-router-dom';\n\nfunction deduplicateFeatures(\n allFeatures: FrontendFeature[],\n): FrontendFeature[] {\n // Start by removing duplicates by reference\n const features = Array.from(new Set(allFeatures));\n\n // Plugins are deduplicated by ID, last one wins\n const seenIds = new Set<string>();\n return features\n .reverse()\n .filter(feature => {\n if (!OpaqueFrontendPlugin.isType(feature)) {\n return true;\n }\n if (seenIds.has(feature.id)) {\n return false;\n }\n seenIds.add(feature.id);\n return true;\n })\n .reverse();\n}\n\n// Helps delay callers from reaching out to the API before the app tree has been materialized\nclass AppTreeApiProxy implements AppTreeApi {\n #routeInfo?: RouteInfo;\n\n constructor(\n private readonly tree: AppTree,\n private readonly appBasePath: string,\n ) {}\n\n private checkIfInitialized() {\n if (!this.#routeInfo) {\n throw new Error(\n `You can't access the AppTreeApi during initialization of the app tree. Please move occurrences of this out of the initialization of the factory`,\n );\n }\n }\n\n getTree() {\n this.checkIfInitialized();\n\n return { tree: this.tree };\n }\n\n getNodesByRoutePath(sourcePath: string): { nodes: AppNode[] } {\n this.checkIfInitialized();\n\n let path = sourcePath;\n if (path.startsWith(this.appBasePath)) {\n path = path.slice(this.appBasePath.length);\n }\n\n const matchedRoutes = matchRoutes(this.#routeInfo!.routeObjects, path);\n\n const matchedAppNodes =\n matchedRoutes\n ?.filter(routeObj => !!routeObj.route.appNode)\n .map(routeObj => routeObj.route.appNode!) || [];\n\n return { nodes: matchedAppNodes };\n }\n\n initialize(routeInfo: RouteInfo) {\n this.#routeInfo = routeInfo;\n }\n}\n\n// Helps delay callers from reaching out to the API before the app tree has been materialized\nclass RouteResolutionApiProxy implements RouteResolutionApi {\n #delegate: RouteResolutionApi | undefined;\n #routeObjects: BackstageRouteObject[] | undefined;\n\n constructor(\n private readonly routeBindings: Map<\n ExternalRouteRef,\n RouteRef | SubRouteRef\n >,\n private readonly appBasePath: string,\n ) {}\n\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams>,\n options?: RouteResolutionApiResolveOptions,\n ): RouteFunc<TParams> | undefined {\n if (!this.#delegate) {\n throw new Error(\n `You can't access the RouteResolver during initialization of the app tree. Please move occurrences of this out of the initialization of the factory`,\n );\n }\n\n return this.#delegate.resolve(anyRouteRef, options);\n }\n\n initialize(routeInfo: RouteInfo) {\n this.#delegate = new RouteResolver(\n routeInfo.routePaths,\n routeInfo.routeParents,\n routeInfo.routeObjects,\n this.routeBindings,\n this.appBasePath,\n );\n this.#routeObjects = routeInfo.routeObjects;\n\n return routeInfo;\n }\n\n getRouteObjects() {\n return this.#routeObjects;\n }\n}\n/**\n * Creates an empty app without any default features. This is a low-level API is\n * intended for use in tests or specialized setups. Typically wou want to use\n * `createApp` from `@backstage/frontend-defaults` instead.\n *\n * @public\n */\nexport function createSpecializedApp(options?: {\n features?: FrontendFeature[];\n config?: ConfigApi;\n bindRoutes?(context: { bind: CreateAppRouteBinder }): void;\n}): { createRoot(): JSX.Element } {\n const config = options?.config ?? new ConfigReader({}, 'empty-config');\n const features = deduplicateFeatures(options?.features ?? []);\n\n const tree = resolveAppTree(\n 'root',\n resolveAppNodeSpecs({\n features,\n builtinExtensions: [\n resolveExtensionDefinition(Root, { namespace: 'root' }),\n ],\n parameters: readAppExtensionsConfig(config),\n forbidden: new Set(['root']),\n }),\n );\n\n const factories = createApiFactories({ tree });\n const appBasePath = getBasePath(config);\n const appTreeApi = new AppTreeApiProxy(tree, appBasePath);\n const routeResolutionApi = new RouteResolutionApiProxy(\n resolveRouteBindings(\n options?.bindRoutes,\n config,\n collectRouteIds(features),\n ),\n appBasePath,\n );\n\n const appIdentityProxy = new AppIdentityProxy();\n const apiHolder = createApiHolder({\n factories,\n staticFactories: [\n createApiFactory(appTreeApiRef, appTreeApi),\n createApiFactory(configApiRef, config),\n createApiFactory(routeResolutionApiRef, routeResolutionApi),\n createApiFactory(identityApiRef, appIdentityProxy),\n ],\n });\n\n const featureFlagApi = apiHolder.get(featureFlagsApiRef);\n if (featureFlagApi) {\n for (const feature of features) {\n if (OpaqueFrontendPlugin.isType(feature)) {\n OpaqueFrontendPlugin.toInternal(feature).featureFlags.forEach(flag =>\n featureFlagApi.registerFlag({\n name: flag.name,\n pluginId: feature.id,\n }),\n );\n }\n if (isInternalFrontendModule(feature)) {\n toInternalFrontendModule(feature).featureFlags.forEach(flag =>\n featureFlagApi.registerFlag({\n name: flag.name,\n pluginId: feature.pluginId,\n }),\n );\n }\n }\n }\n\n // Now instantiate the entire tree, which will skip anything that's already been instantiated\n instantiateAppNodeTree(tree.root, apiHolder);\n\n const routeInfo = extractRouteInfoFromAppNode(tree.root);\n\n routeResolutionApi.initialize(routeInfo);\n appTreeApi.initialize(routeInfo);\n\n const rootEl = tree.root.instance!.getData(coreExtensionData.reactElement);\n\n const AppComponent = () => rootEl;\n\n return {\n createRoot() {\n return <AppComponent />;\n },\n };\n}\n\nfunction createApiFactories(options: { tree: AppTree }): AnyApiFactory[] {\n const emptyApiHolder = ApiRegistry.from([]);\n const factories = new Array<AnyApiFactory>();\n\n for (const apiNode of options.tree.root.edges.attachments.get('apis') ?? []) {\n instantiateAppNodeTree(apiNode, emptyApiHolder);\n const apiFactory = apiNode.instance?.getData(ApiBlueprint.dataRefs.factory);\n if (!apiFactory) {\n throw new Error(\n `No API factory found in for extension ${apiNode.spec.id}`,\n );\n }\n factories.push(apiFactory);\n }\n\n return factories;\n}\n\nfunction createApiHolder(options: {\n factories: AnyApiFactory[];\n staticFactories: AnyApiFactory[];\n}): ApiHolder {\n const factoryRegistry = new ApiFactoryRegistry();\n\n for (const factory of options.factories.slice().reverse()) {\n factoryRegistry.register('default', factory);\n }\n\n for (const factory of options.staticFactories) {\n factoryRegistry.register('static', factory);\n }\n\n ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis());\n\n return new ApiResolver(factoryRegistry);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createSpecializedApp.esm.js","sources":["../../src/wiring/createSpecializedApp.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 { ConfigReader } from '@backstage/config';\nimport {\n ApiBlueprint,\n AppTree,\n AppTreeApi,\n appTreeApiRef,\n RouteRef,\n ExternalRouteRef,\n SubRouteRef,\n AnyRouteRefParams,\n RouteFunc,\n RouteResolutionApiResolveOptions,\n RouteResolutionApi,\n createApiFactory,\n routeResolutionApiRef,\n AppNode,\n ExtensionFactoryMiddleware,\n} from '@backstage/frontend-plugin-api';\nimport {\n AnyApiFactory,\n ApiHolder,\n ConfigApi,\n configApiRef,\n featureFlagsApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\nimport { ApiFactoryRegistry, ApiResolver } from '@backstage/core-app-api';\nimport {\n createExtensionDataContainer,\n OpaqueFrontendPlugin,\n} from '@internal/frontend';\n\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n resolveExtensionDefinition,\n toInternalExtension,\n} from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\n\nimport { extractRouteInfoFromAppNode } from '../routing/extractRouteInfoFromAppNode';\n\nimport { CreateAppRouteBinder } from '../routing';\nimport { RouteResolver } from '../routing/RouteResolver';\nimport { resolveRouteBindings } from '../routing/resolveRouteBindings';\nimport { collectRouteIds } from '../routing/collectRouteIds';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n toInternalFrontendModule,\n isInternalFrontendModule,\n} from '../../../frontend-plugin-api/src/wiring/createFrontendModule';\nimport { getBasePath } from '../routing/getBasePath';\nimport { Root } from '../extensions/Root';\nimport { resolveAppTree } from '../tree/resolveAppTree';\nimport { resolveAppNodeSpecs } from '../tree/resolveAppNodeSpecs';\nimport { readAppExtensionsConfig } from '../tree/readAppExtensionsConfig';\nimport { instantiateAppNodeTree } from '../tree/instantiateAppNodeTree';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ApiRegistry } from '../../../core-app-api/src/apis/system/ApiRegistry';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy';\nimport { BackstageRouteObject } from '../routing/types';\nimport { FrontendFeature, RouteInfo } from './types';\nimport { matchRoutes } from 'react-router-dom';\n\nfunction deduplicateFeatures(\n allFeatures: FrontendFeature[],\n): FrontendFeature[] {\n // Start by removing duplicates by reference\n const features = Array.from(new Set(allFeatures));\n\n // Plugins are deduplicated by ID, last one wins\n const seenIds = new Set<string>();\n return features\n .reverse()\n .filter(feature => {\n if (!OpaqueFrontendPlugin.isType(feature)) {\n return true;\n }\n if (seenIds.has(feature.id)) {\n return false;\n }\n seenIds.add(feature.id);\n return true;\n })\n .reverse();\n}\n\n// Helps delay callers from reaching out to the API before the app tree has been materialized\nclass AppTreeApiProxy implements AppTreeApi {\n #routeInfo?: RouteInfo;\n\n constructor(\n private readonly tree: AppTree,\n private readonly appBasePath: string,\n ) {}\n\n private checkIfInitialized() {\n if (!this.#routeInfo) {\n throw new Error(\n `You can't access the AppTreeApi during initialization of the app tree. Please move occurrences of this out of the initialization of the factory`,\n );\n }\n }\n\n getTree() {\n this.checkIfInitialized();\n\n return { tree: this.tree };\n }\n\n getNodesByRoutePath(sourcePath: string): { nodes: AppNode[] } {\n this.checkIfInitialized();\n\n let path = sourcePath;\n if (path.startsWith(this.appBasePath)) {\n path = path.slice(this.appBasePath.length);\n }\n\n const matchedRoutes = matchRoutes(this.#routeInfo!.routeObjects, path);\n\n const matchedAppNodes =\n matchedRoutes\n ?.filter(routeObj => !!routeObj.route.appNode)\n .map(routeObj => routeObj.route.appNode!) || [];\n\n return { nodes: matchedAppNodes };\n }\n\n initialize(routeInfo: RouteInfo) {\n this.#routeInfo = routeInfo;\n }\n}\n\n// Helps delay callers from reaching out to the API before the app tree has been materialized\nclass RouteResolutionApiProxy implements RouteResolutionApi {\n #delegate: RouteResolutionApi | undefined;\n #routeObjects: BackstageRouteObject[] | undefined;\n\n constructor(\n private readonly routeBindings: Map<\n ExternalRouteRef,\n RouteRef | SubRouteRef\n >,\n private readonly appBasePath: string,\n ) {}\n\n resolve<TParams extends AnyRouteRefParams>(\n anyRouteRef:\n | RouteRef<TParams>\n | SubRouteRef<TParams>\n | ExternalRouteRef<TParams>,\n options?: RouteResolutionApiResolveOptions,\n ): RouteFunc<TParams> | undefined {\n if (!this.#delegate) {\n throw new Error(\n `You can't access the RouteResolver during initialization of the app tree. Please move occurrences of this out of the initialization of the factory`,\n );\n }\n\n return this.#delegate.resolve(anyRouteRef, options);\n }\n\n initialize(routeInfo: RouteInfo) {\n this.#delegate = new RouteResolver(\n routeInfo.routePaths,\n routeInfo.routeParents,\n routeInfo.routeObjects,\n this.routeBindings,\n this.appBasePath,\n );\n this.#routeObjects = routeInfo.routeObjects;\n\n return routeInfo;\n }\n\n getRouteObjects() {\n return this.#routeObjects;\n }\n}\n\n/**\n * Creates an empty app without any default features. This is a low-level API is\n * intended for use in tests or specialized setups. Typically wou want to use\n * `createApp` from `@backstage/frontend-defaults` instead.\n *\n * @public\n */\nexport function createSpecializedApp(options?: {\n features?: FrontendFeature[];\n config?: ConfigApi;\n bindRoutes?(context: { bind: CreateAppRouteBinder }): void;\n apis?: ApiHolder;\n extensionFactoryMiddleware?:\n | ExtensionFactoryMiddleware\n | ExtensionFactoryMiddleware[];\n}): { apis: ApiHolder; tree: AppTree } {\n const config = options?.config ?? new ConfigReader({}, 'empty-config');\n const features = deduplicateFeatures(options?.features ?? []);\n\n const tree = resolveAppTree(\n 'root',\n resolveAppNodeSpecs({\n features,\n builtinExtensions: [\n resolveExtensionDefinition(Root, { namespace: 'root' }),\n ],\n parameters: readAppExtensionsConfig(config),\n forbidden: new Set(['root']),\n }),\n );\n\n const factories = createApiFactories({ tree });\n const appBasePath = getBasePath(config);\n const appTreeApi = new AppTreeApiProxy(tree, appBasePath);\n const routeResolutionApi = new RouteResolutionApiProxy(\n resolveRouteBindings(\n options?.bindRoutes,\n config,\n collectRouteIds(features),\n ),\n appBasePath,\n );\n\n const appIdentityProxy = new AppIdentityProxy();\n const apis =\n options?.apis ??\n createApiHolder({\n factories,\n staticFactories: [\n createApiFactory(appTreeApiRef, appTreeApi),\n createApiFactory(configApiRef, config),\n createApiFactory(routeResolutionApiRef, routeResolutionApi),\n createApiFactory(identityApiRef, appIdentityProxy),\n ],\n });\n\n const featureFlagApi = apis.get(featureFlagsApiRef);\n if (featureFlagApi) {\n for (const feature of features) {\n if (OpaqueFrontendPlugin.isType(feature)) {\n OpaqueFrontendPlugin.toInternal(feature).featureFlags.forEach(flag =>\n featureFlagApi.registerFlag({\n name: flag.name,\n pluginId: feature.id,\n }),\n );\n }\n if (isInternalFrontendModule(feature)) {\n toInternalFrontendModule(feature).featureFlags.forEach(flag =>\n featureFlagApi.registerFlag({\n name: flag.name,\n pluginId: feature.pluginId,\n }),\n );\n }\n }\n }\n\n // Now instantiate the entire tree, which will skip anything that's already been instantiated\n instantiateAppNodeTree(\n tree.root,\n apis,\n mergeExtensionFactoryMiddleware(options?.extensionFactoryMiddleware),\n );\n\n const routeInfo = extractRouteInfoFromAppNode(tree.root);\n\n routeResolutionApi.initialize(routeInfo);\n appTreeApi.initialize(routeInfo);\n\n return { apis, tree };\n}\n\nfunction createApiFactories(options: { tree: AppTree }): AnyApiFactory[] {\n const emptyApiHolder = ApiRegistry.from([]);\n const factories = new Array<AnyApiFactory>();\n\n for (const apiNode of options.tree.root.edges.attachments.get('apis') ?? []) {\n instantiateAppNodeTree(apiNode, emptyApiHolder);\n const apiFactory = apiNode.instance?.getData(ApiBlueprint.dataRefs.factory);\n if (!apiFactory) {\n throw new Error(\n `No API factory found in for extension ${apiNode.spec.id}`,\n );\n }\n factories.push(apiFactory);\n }\n\n return factories;\n}\n\nfunction createApiHolder(options: {\n factories: AnyApiFactory[];\n staticFactories: AnyApiFactory[];\n}): ApiHolder {\n const factoryRegistry = new ApiFactoryRegistry();\n\n for (const factory of options.factories.slice().reverse()) {\n factoryRegistry.register('default', factory);\n }\n\n for (const factory of options.staticFactories) {\n factoryRegistry.register('static', factory);\n }\n\n ApiResolver.validateFactories(factoryRegistry, factoryRegistry.getAllApis());\n\n return new ApiResolver(factoryRegistry);\n}\n\nfunction mergeExtensionFactoryMiddleware(\n middlewares?: ExtensionFactoryMiddleware | ExtensionFactoryMiddleware[],\n): ExtensionFactoryMiddleware | undefined {\n if (!middlewares) {\n return undefined;\n }\n if (!Array.isArray(middlewares)) {\n return middlewares;\n }\n if (middlewares.length <= 1) {\n return middlewares[0];\n }\n return middlewares.reduce((prev, next) => {\n if (!prev || !next) {\n return prev ?? next;\n }\n return (orig, ctx) => {\n const internalExt = toInternalExtension(ctx.node.spec.extension);\n if (internalExt.version !== 'v2') {\n return orig();\n }\n return next(ctxOverrides => {\n return createExtensionDataContainer(\n prev(orig, {\n node: ctx.node,\n apis: ctx.apis,\n config: ctxOverrides?.config ?? ctx.config,\n }),\n );\n }, ctx);\n };\n });\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/frontend-app-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-next.2",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "web-library"
|
|
6
6
|
},
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@backstage/config": "1.3.2",
|
|
36
|
-
"@backstage/core-app-api": "1.
|
|
36
|
+
"@backstage/core-app-api": "1.16.0-next.0",
|
|
37
37
|
"@backstage/core-plugin-api": "1.10.4",
|
|
38
38
|
"@backstage/errors": "1.2.7",
|
|
39
|
-
"@backstage/frontend-defaults": "0.
|
|
40
|
-
"@backstage/frontend-plugin-api": "0.
|
|
39
|
+
"@backstage/frontend-defaults": "0.2.0-next.2",
|
|
40
|
+
"@backstage/frontend-plugin-api": "0.10.0-next.2",
|
|
41
41
|
"@backstage/types": "1.2.1",
|
|
42
42
|
"@backstage/version-bridge": "1.0.11",
|
|
43
43
|
"lodash": "^4.17.21",
|
|
44
44
|
"zod": "^3.22.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@backstage/cli": "0.
|
|
48
|
-
"@backstage/plugin-app": "0.1.7-next.
|
|
49
|
-
"@backstage/test-utils": "1.7.
|
|
47
|
+
"@backstage/cli": "0.31.0-next.1",
|
|
48
|
+
"@backstage/plugin-app": "0.1.7-next.2",
|
|
49
|
+
"@backstage/test-utils": "1.7.6-next.0",
|
|
50
50
|
"@testing-library/jest-dom": "^6.0.0",
|
|
51
51
|
"@testing-library/react": "^16.0.0",
|
|
52
52
|
"@types/react": "^18.0.0",
|
|
@@ -66,12 +66,5 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"configSchema": "config.d.ts",
|
|
69
|
-
"typesVersions": {
|
|
70
|
-
"*": {
|
|
71
|
-
"index": [
|
|
72
|
-
"dist/index.d.ts"
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
69
|
"module": "./dist/index.esm.js"
|
|
77
70
|
}
|