@backstage/frontend-app-api 0.16.0-next.1 → 0.16.1

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js.map +1 -1
  3. package/dist/frontend-internal/src/wiring/InternalFrontendPlugin.esm.js.map +1 -1
  4. package/dist/frontend-plugin-api/src/wiring/createFrontendModule.esm.js.map +1 -1
  5. package/dist/frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js.map +1 -1
  6. package/dist/index.d.ts +145 -26
  7. package/dist/index.esm.js +1 -0
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/routing/RouteAliasResolver.esm.js +0 -2
  10. package/dist/routing/RouteAliasResolver.esm.js.map +1 -1
  11. package/dist/routing/RouteResolver.esm.js +1 -1
  12. package/dist/routing/resolveRouteBindings.esm.js +2 -0
  13. package/dist/routing/resolveRouteBindings.esm.js.map +1 -1
  14. package/dist/tree/instantiateAppNodeTree.esm.js +72 -15
  15. package/dist/tree/instantiateAppNodeTree.esm.js.map +1 -1
  16. package/dist/tree/resolveAppNodeSpecs.esm.js +50 -9
  17. package/dist/tree/resolveAppNodeSpecs.esm.js.map +1 -1
  18. package/dist/wiring/FrontendApiRegistry.esm.js +92 -0
  19. package/dist/wiring/FrontendApiRegistry.esm.js.map +1 -0
  20. package/dist/wiring/apiFactories.esm.js +185 -0
  21. package/dist/wiring/apiFactories.esm.js.map +1 -0
  22. package/dist/wiring/createErrorCollector.esm.js.map +1 -1
  23. package/dist/wiring/createPluginInfoAttacher.esm.js.map +1 -1
  24. package/dist/wiring/createSpecializedApp.esm.js +11 -285
  25. package/dist/wiring/createSpecializedApp.esm.js.map +1 -1
  26. package/dist/wiring/phaseApis.esm.js +161 -0
  27. package/dist/wiring/phaseApis.esm.js.map +1 -0
  28. package/dist/wiring/predicates.esm.js +116 -0
  29. package/dist/wiring/predicates.esm.js.map +1 -0
  30. package/dist/wiring/prepareSpecializedApp.esm.js +518 -0
  31. package/dist/wiring/prepareSpecializedApp.esm.js.map +1 -0
  32. package/dist/wiring/treeLifecycle.esm.js +186 -0
  33. package/dist/wiring/treeLifecycle.esm.js.map +1 -0
  34. package/package.json +16 -14
  35. package/dist/core-app-api/src/apis/system/ApiRegistry.esm.js +0 -50
  36. package/dist/core-app-api/src/apis/system/ApiRegistry.esm.js.map +0 -1
@@ -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 ApiHolder,\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionInput,\n ResolvedExtensionInputs,\n} from '@backstage/frontend-plugin-api';\nimport { ExtensionFactoryMiddleware } from '../wiring/types';\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';\nimport { ErrorCollector } from '../wiring/createErrorCollector';\n\nconst INSTANTIATION_FAILED = new Error('Instantiation failed');\n\n/**\n * Like `array.map`, but if `INSTANTIATION_FAILED` is thrown, the iteration will continue but afterwards re-throw `INSTANTIATION_FAILED`\n * @returns\n */\nfunction mapWithFailures<T, U>(\n iterable: Iterable<T>,\n callback: (item: T) => U,\n options?: { ignoreFailures?: boolean },\n): U[] {\n let failed = false;\n const results = [];\n for (const item of iterable) {\n try {\n results.push(callback(item));\n } catch (error) {\n if (error === INSTANTIATION_FAILED) {\n failed = true;\n } else {\n throw error;\n }\n }\n }\n if (failed && !options?.ignoreFailures) {\n throw INSTANTIATION_FAILED;\n }\n return results;\n}\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nfunction resolveV1InputDataMap(\n dataMap: {\n [name in string]: ExtensionDataRef;\n },\n attachment: AppNode,\n inputName: string,\n) {\n return Object.fromEntries(\n mapWithFailures(Object.entries(dataMap), ([key, 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 [key, value];\n }),\n );\n}\n\nfunction resolveInputDataContainer(\n extensionData: Array<ExtensionDataRef>,\n attachment: AppNode,\n inputName: string,\n collector: ErrorCollector<{ node: AppNode; inputName: string }>,\n): { node: AppNode } & ExtensionDataContainer<ExtensionDataRef> {\n const dataMap = new Map<string, unknown>();\n\n mapWithFailures(extensionData, ref => {\n if (dataMap.has(ref.id)) {\n collector.report({\n code: 'EXTENSION_INPUT_DATA_IGNORED',\n message: `Unexpected duplicate input data '${ref.id}'`,\n });\n return;\n }\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 collector.child({ node: attachment }).report({\n code: 'EXTENSION_INPUT_DATA_MISSING',\n message: `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n });\n throw INSTANTIATION_FAILED;\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<ExtensionDataRef>;\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]: ExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n return Object.fromEntries(\n mapWithFailures(Object.entries(inputMap), ([inputName, input]) => {\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 [inputName, undefined];\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return [\n inputName,\n {\n node: attachedNodes[0],\n output: resolveV1InputDataMap(\n input.extensionData,\n attachedNodes[0],\n inputName,\n ),\n },\n ];\n }\n\n return [\n inputName,\n attachedNodes.map(attachment => ({\n node: attachment,\n output: resolveV1InputDataMap(\n input.extensionData,\n attachment,\n inputName,\n ),\n })),\n ];\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: { [inputName in string]: ExtensionInput },\n attachments: ReadonlyMap<string, AppNode[]>,\n parentCollector: ErrorCollector<{ node: AppNode }>,\n node: AppNode,\n): ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }> {\n return mapValues(inputMap, (input, inputName) => {\n const allAttachedNodes = attachments.get(inputName) ?? [];\n const collector = parentCollector.child({ inputName });\n const inputPluginId = node.spec.plugin.pluginId;\n\n const attachedNodes = input.config.internal\n ? allAttachedNodes.filter(attachment => {\n const attachmentPluginId = attachment.spec.plugin.pluginId;\n if (attachmentPluginId !== inputPluginId) {\n collector.report({\n code: 'EXTENSION_INPUT_INTERNAL_IGNORED',\n message:\n `extension '${attachment.spec.id}' from plugin '${attachmentPluginId}' attached to input '${inputName}' on '${node.spec.id}' was ignored, ` +\n `the input is marked as internal and attached extensions must therefore be provided via an override or a module for the '${inputPluginId}' plugin, not the '${attachmentPluginId}' plugin`,\n context: {\n extensionId: attachment.spec.id,\n plugin: attachment.spec.plugin,\n },\n });\n return false;\n }\n return true;\n })\n : allAttachedNodes;\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id).join(\"', '\");\n collector.report({\n code: 'EXTENSION_ATTACHMENT_CONFLICT',\n message: `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds}'`,\n });\n throw INSTANTIATION_FAILED;\n } else if (attachedNodes.length === 0) {\n if (!input.config.optional) {\n collector.report({\n code: 'EXTENSION_ATTACHMENT_MISSING',\n message: `input '${inputName}' is required but was not received`,\n });\n throw INSTANTIATION_FAILED;\n }\n return undefined;\n }\n try {\n return resolveInputDataContainer(\n input.extensionData,\n attachedNodes[0],\n inputName,\n collector,\n );\n } catch (error) {\n if (error === INSTANTIATION_FAILED) {\n if (input.config.optional) {\n return undefined;\n }\n collector.report({\n code: 'EXTENSION_ATTACHMENT_MISSING',\n message: `input '${inputName}' is required but it failed to be instantiated`,\n });\n }\n throw error;\n }\n }\n\n return mapWithFailures(\n attachedNodes,\n attachment =>\n resolveInputDataContainer(\n input.extensionData,\n attachment,\n inputName,\n collector,\n ),\n { ignoreFailures: true },\n );\n }) as ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }>;\n}\n\n/** @internal */\nexport function createAppNodeInstance(options: {\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware;\n node: AppNode;\n apis: ApiHolder;\n attachments: ReadonlyMap<string, AppNode[]>;\n collector: ErrorCollector;\n}): AppNodeInstance | undefined {\n const { node, apis, attachments } = options;\n const collector = options.collector.child({ node });\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 collector.report({\n code: 'EXTENSION_CONFIGURATION_INVALID',\n message: `Invalid configuration for extension '${id}'; caused by ${e}`,\n });\n return undefined;\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(\n internalExtension.inputs,\n attachments,\n collector,\n node,\n ),\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 'extension factory',\n );\n }, context),\n 'extension factory middleware',\n )\n : internalExtension.factory(context);\n\n if (\n typeof outputDataValues !== 'object' ||\n !outputDataValues?.[Symbol.iterator]\n ) {\n throw new Error('extension factory did not provide an iterable object');\n }\n\n const outputDataMap = new Map<string, unknown>();\n mapWithFailures(outputDataValues, value => {\n if (outputDataMap.has(value.id)) {\n collector.report({\n code: 'EXTENSION_OUTPUT_CONFLICT',\n message: `extension factory output duplicate data '${value.id}'`,\n context: {\n dataRefId: value.id,\n },\n });\n throw INSTANTIATION_FAILED;\n } else {\n outputDataMap.set(value.id, value.value);\n }\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 collector.report({\n code: 'EXTENSION_OUTPUT_MISSING',\n message: `missing required extension data output '${ref.id}'`,\n context: {\n dataRefId: ref.id,\n },\n });\n throw INSTANTIATION_FAILED;\n }\n } else {\n extensionData.set(ref.id, value);\n extensionDataRefs.add(ref);\n }\n }\n\n if (outputDataMap.size > 0) {\n for (const dataRefId of outputDataMap.keys()) {\n // TODO: Make this a warning\n collector.report({\n code: 'EXTENSION_OUTPUT_IGNORED',\n message: `unexpected output '${dataRefId}'`,\n context: {\n dataRefId: dataRefId,\n },\n });\n }\n }\n } else {\n collector.report({\n code: 'EXTENSION_INVALID',\n message: `unexpected extension version '${\n (internalExtension as any).version\n }'`,\n });\n throw INSTANTIATION_FAILED;\n }\n } catch (e) {\n if (e !== INSTANTIATION_FAILED) {\n collector.report({\n code: 'EXTENSION_FACTORY_ERROR',\n message: `Failed to instantiate extension '${id}'${\n e.name === 'Error' ? `, ${e.message}` : `; caused by ${e}`\n }`,\n });\n }\n return undefined;\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 collector: ErrorCollector,\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware,\n): boolean {\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 collector,\n });\n\n return node.instance;\n }\n\n return createInstance(rootNode) !== undefined;\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 ApiHolder,\n ExtensionDataContainer,\n ExtensionDataRef,\n ExtensionInput,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ResolvedExtensionInputs } from '../../../frontend-plugin-api/src/wiring/createExtension';\nimport { ExtensionFactoryMiddleware } from '../wiring/types';\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';\nimport { ErrorCollector } from '../wiring/createErrorCollector';\nimport { evaluateFilterPredicate } from '@backstage/filter-predicates';\n\nconst INSTANTIATION_FAILED = new Error('Instantiation failed');\n\n/**\n * Like `array.map`, but if `INSTANTIATION_FAILED` is thrown, the iteration will continue but afterwards re-throw `INSTANTIATION_FAILED`\n * @returns\n */\nfunction mapWithFailures<T, U>(\n iterable: Iterable<T>,\n callback: (item: T) => U,\n options?: { ignoreFailures?: boolean },\n): U[] {\n let failed = false;\n const results = [];\n for (const item of iterable) {\n try {\n results.push(callback(item));\n } catch (error) {\n if (error === INSTANTIATION_FAILED) {\n failed = true;\n } else {\n throw error;\n }\n }\n }\n if (failed && !options?.ignoreFailures) {\n throw INSTANTIATION_FAILED;\n }\n return results;\n}\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\ntype InstantiateAppNodeSubtreeOptions = {\n rootNode: AppNode;\n apis: ApiHolder;\n collector: ErrorCollector;\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware;\n stopAtAttachment?(ctx: { node: AppNode; input: string }): boolean;\n skipChild?(ctx: { node: AppNode; input: string; child: AppNode }): boolean;\n onMissingApi?(ctx: { node: AppNode; apiRefId: string }): void;\n predicateContext?: Record<string, unknown>;\n reuseExistingInstances?: boolean;\n writeNodeInstances?: boolean;\n};\n\nfunction resolveV1InputDataMap(\n dataMap: {\n [name in string]: ExtensionDataRef;\n },\n attachment: AppNode,\n inputName: string,\n) {\n return Object.fromEntries(\n mapWithFailures(Object.entries(dataMap), ([key, 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 [key, value];\n }),\n );\n}\n\nfunction resolveInputDataContainer(\n extensionData: Array<ExtensionDataRef>,\n attachment: AppNode,\n inputName: string,\n collector: ErrorCollector<{ node: AppNode; inputName: string }>,\n): { node: AppNode } & ExtensionDataContainer<ExtensionDataRef> {\n const dataMap = new Map<string, unknown>();\n\n mapWithFailures(extensionData, ref => {\n if (dataMap.has(ref.id)) {\n collector.report({\n code: 'EXTENSION_INPUT_DATA_IGNORED',\n message: `Unexpected duplicate input data '${ref.id}'`,\n });\n return;\n }\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 collector.child({ node: attachment }).report({\n code: 'EXTENSION_INPUT_DATA_MISSING',\n message: `extension '${attachment.spec.id}' could not be attached because its output data (${provided}) does not match what the input '${inputName}' requires (${expected})`,\n });\n throw INSTANTIATION_FAILED;\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<ExtensionDataRef>;\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]: ExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n },\n attachments: ReadonlyMap<string, AppNode[]>,\n) {\n return Object.fromEntries(\n mapWithFailures(Object.entries(inputMap), ([inputName, input]) => {\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 [inputName, undefined];\n }\n throw Error(`input '${inputName}' is required but was not received`);\n }\n return [\n inputName,\n {\n node: attachedNodes[0],\n output: resolveV1InputDataMap(\n input.extensionData,\n attachedNodes[0],\n inputName,\n ),\n },\n ];\n }\n\n return [\n inputName,\n attachedNodes.map(attachment => ({\n node: attachment,\n output: resolveV1InputDataMap(\n input.extensionData,\n attachment,\n inputName,\n ),\n })),\n ];\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: { [inputName in string]: ExtensionInput },\n attachments: ReadonlyMap<string, AppNode[]>,\n parentCollector: ErrorCollector<{ node: AppNode }>,\n node: AppNode,\n): ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }> {\n return mapValues(inputMap, (input, inputName) => {\n const allAttachedNodes = attachments.get(inputName) ?? [];\n const collector = parentCollector.child({ inputName });\n const inputPluginId = node.spec.plugin.pluginId;\n\n const attachedNodes = input.config.internal\n ? allAttachedNodes.filter(attachment => {\n const attachmentPluginId = attachment.spec.plugin.pluginId;\n if (attachmentPluginId !== inputPluginId) {\n collector.report({\n code: 'EXTENSION_INPUT_INTERNAL_IGNORED',\n message:\n `extension '${attachment.spec.id}' from plugin '${attachmentPluginId}' attached to input '${inputName}' on '${node.spec.id}' was ignored, ` +\n `the input is marked as internal and attached extensions must therefore be provided via an override or a module for the '${inputPluginId}' plugin, not the '${attachmentPluginId}' plugin`,\n context: {\n extensionId: attachment.spec.id,\n plugin: attachment.spec.plugin,\n },\n });\n return false;\n }\n return true;\n })\n : allAttachedNodes;\n\n if (input.config.singleton) {\n if (attachedNodes.length > 1) {\n const attachedNodeIds = attachedNodes.map(e => e.spec.id).join(\"', '\");\n collector.report({\n code: 'EXTENSION_ATTACHMENT_CONFLICT',\n message: `expected ${\n input.config.optional ? 'at most' : 'exactly'\n } one '${inputName}' input but received multiple: '${attachedNodeIds}'`,\n });\n throw INSTANTIATION_FAILED;\n } else if (attachedNodes.length === 0) {\n if (!input.config.optional) {\n collector.report({\n code: 'EXTENSION_ATTACHMENT_MISSING',\n message: `input '${inputName}' is required but was not received`,\n });\n throw INSTANTIATION_FAILED;\n }\n return undefined;\n }\n try {\n return resolveInputDataContainer(\n input.extensionData,\n attachedNodes[0],\n inputName,\n collector,\n );\n } catch (error) {\n if (error === INSTANTIATION_FAILED) {\n if (input.config.optional) {\n return undefined;\n }\n collector.report({\n code: 'EXTENSION_ATTACHMENT_MISSING',\n message: `input '${inputName}' is required but it failed to be instantiated`,\n });\n }\n throw error;\n }\n }\n\n return mapWithFailures(\n attachedNodes,\n attachment =>\n resolveInputDataContainer(\n input.extensionData,\n attachment,\n inputName,\n collector,\n ),\n { ignoreFailures: true },\n );\n }) as ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput }>;\n}\n\n/** @internal */\nexport function createAppNodeInstance(options: {\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware;\n node: AppNode;\n apis: ApiHolder;\n attachments: ReadonlyMap<string, AppNode[]>;\n collector: ErrorCollector;\n onMissingApi?(ctx: { node: AppNode; apiRefId: string }): void;\n}): AppNodeInstance | undefined {\n const { node, apis, attachments } = options;\n const collector = options.collector.child({ node });\n const { id, extension, config } = node.spec;\n const extensionData = new Map<string, unknown>();\n const extensionDataRefs = new Set<ExtensionDataRef<unknown>>();\n const scopedApis: ApiHolder =\n options.onMissingApi === undefined\n ? apis\n : {\n get(apiRef) {\n const api = apis.get(apiRef);\n if (api === undefined) {\n options.onMissingApi?.({\n node,\n apiRefId: apiRef.id,\n });\n }\n return api;\n },\n };\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 collector.report({\n code: 'EXTENSION_CONFIGURATION_INVALID',\n message: `Invalid configuration for extension '${id}'; caused by ${e}`,\n });\n return undefined;\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: scopedApis,\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: scopedApis,\n config: parsedConfig,\n inputs: resolveV2Inputs(\n internalExtension.inputs,\n attachments,\n collector,\n node,\n ),\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 'extension factory',\n );\n }, context),\n 'extension factory middleware',\n )\n : internalExtension.factory(context);\n\n if (\n typeof outputDataValues !== 'object' ||\n !outputDataValues?.[Symbol.iterator]\n ) {\n throw new Error('extension factory did not provide an iterable object');\n }\n\n const outputDataMap = new Map<string, unknown>();\n mapWithFailures(outputDataValues, value => {\n if (outputDataMap.has(value.id)) {\n collector.report({\n code: 'EXTENSION_OUTPUT_CONFLICT',\n message: `extension factory output duplicate data '${value.id}'`,\n context: {\n dataRefId: value.id,\n },\n });\n throw INSTANTIATION_FAILED;\n } else {\n outputDataMap.set(value.id, value.value);\n }\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 collector.report({\n code: 'EXTENSION_OUTPUT_MISSING',\n message: `missing required extension data output '${ref.id}'`,\n context: {\n dataRefId: ref.id,\n },\n });\n throw INSTANTIATION_FAILED;\n }\n } else {\n extensionData.set(ref.id, value);\n extensionDataRefs.add(ref);\n }\n }\n\n if (outputDataMap.size > 0) {\n for (const dataRefId of outputDataMap.keys()) {\n // TODO: Make this a warning\n collector.report({\n code: 'EXTENSION_OUTPUT_IGNORED',\n message: `unexpected output '${dataRefId}'`,\n context: {\n dataRefId: dataRefId,\n },\n });\n }\n }\n } else {\n collector.report({\n code: 'EXTENSION_INVALID',\n message: `unexpected extension version '${\n (internalExtension as any).version\n }'`,\n });\n throw INSTANTIATION_FAILED;\n }\n } catch (e) {\n if (e !== INSTANTIATION_FAILED) {\n collector.report({\n code: 'EXTENSION_FACTORY_ERROR',\n message: `Failed to instantiate extension '${id}'${\n e.name === 'Error' ? `, ${e.message}` : `; caused by ${e}`\n }`,\n });\n }\n return undefined;\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 a subtree without necessarily\n * mutating the original app tree.\n *\n * @internal\n */\nexport function instantiateAppNodeSubtree(\n options: InstantiateAppNodeSubtreeOptions,\n): AppNode | undefined {\n const instantiatedNodes = new WeakMap<AppNode, AppNode | null>();\n\n function createInstance(node: AppNode): AppNode | undefined {\n if (instantiatedNodes.has(node)) {\n return instantiatedNodes.get(node) ?? undefined;\n }\n if (options.reuseExistingInstances !== false && node.instance) {\n instantiatedNodes.set(node, node);\n return node;\n }\n if (node.spec.disabled) {\n instantiatedNodes.set(node, null);\n return undefined;\n }\n if (\n options.predicateContext !== undefined &&\n node.spec.if !== undefined &&\n !evaluateFilterPredicate(node.spec.if, options.predicateContext)\n ) {\n instantiatedNodes.set(node, null);\n return undefined;\n }\n\n const instantiatedAttachments = new Map<string, AppNode[]>();\n\n for (const [input, children] of node.edges.attachments) {\n if (options.stopAtAttachment?.({ node, input })) {\n continue;\n }\n const instantiatedChildren = children.flatMap(child => {\n if (options.skipChild?.({ node, input, child })) {\n return [];\n }\n const childNode = createInstance(child);\n return childNode ? [childNode] : [];\n });\n if (instantiatedChildren.length > 0) {\n instantiatedAttachments.set(input, instantiatedChildren);\n }\n }\n\n const instance = createAppNodeInstance({\n extensionFactoryMiddleware: options.extensionFactoryMiddleware,\n node,\n apis: options.apis,\n attachments: instantiatedAttachments,\n collector: options.collector,\n onMissingApi: options.onMissingApi,\n });\n if (!instance) {\n instantiatedNodes.set(node, null);\n return undefined;\n }\n\n if (options.writeNodeInstances === false) {\n const detachedNode: AppNode = {\n spec: node.spec,\n edges: node.edges,\n instance,\n };\n instantiatedNodes.set(node, detachedNode);\n return detachedNode;\n }\n\n (node as Mutable<AppNode>).instance = instance;\n instantiatedNodes.set(node, node);\n return node;\n }\n\n return createInstance(options.rootNode);\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 collector: ErrorCollector,\n extensionFactoryMiddleware?: ExtensionFactoryMiddleware,\n optionsOrPredicateContext?:\n | {\n stopAtAttachment?(ctx: { node: AppNode; input: string }): boolean;\n skipChild?(ctx: {\n node: AppNode;\n input: string;\n child: AppNode;\n }): boolean;\n onMissingApi?(ctx: { node: AppNode; apiRefId: string }): void;\n predicateContext?: Record<string, unknown>;\n }\n | Record<string, unknown>,\n): boolean {\n const options: {\n stopAtAttachment?(ctx: { node: AppNode; input: string }): boolean;\n skipChild?(ctx: { node: AppNode; input: string; child: AppNode }): boolean;\n onMissingApi?(ctx: { node: AppNode; apiRefId: string }): void;\n predicateContext?: Record<string, unknown>;\n } =\n optionsOrPredicateContext &&\n ('stopAtAttachment' in optionsOrPredicateContext ||\n 'skipChild' in optionsOrPredicateContext ||\n 'onMissingApi' in optionsOrPredicateContext ||\n 'predicateContext' in optionsOrPredicateContext)\n ? optionsOrPredicateContext\n : {\n predicateContext: optionsOrPredicateContext,\n };\n\n return (\n instantiateAppNodeSubtree({\n rootNode,\n apis,\n collector,\n extensionFactoryMiddleware,\n stopAtAttachment: options.stopAtAttachment,\n skipChild: options.skipChild,\n onMissingApi: options.onMissingApi,\n predicateContext: options.predicateContext,\n }) !== undefined\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAiCA,MAAM,oBAAA,GAAuB,IAAI,KAAA,CAAM,sBAAsB,CAAA;AAM7D,SAAS,eAAA,CACP,QAAA,EACA,QAAA,EACA,OAAA,EACK;AACL,EAAA,IAAI,MAAA,GAAS,KAAA;AACb,EAAA,MAAM,UAAU,EAAC;AACjB,EAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,UAAU,oBAAA,EAAsB;AAClC,QAAA,MAAA,GAAS,IAAA;AAAA,MACX,CAAA,MAAO;AACL,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,MAAA,IAAU,CAAC,OAAA,EAAS,cAAA,EAAgB;AACtC,IAAA,MAAM,oBAAA;AAAA,EACR;AACA,EAAA,OAAO,OAAA;AACT;AAmBA,SAAS,qBAAA,CACP,OAAA,EAGA,UAAA,EACA,SAAA,EACA;AACA,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,eAAA,CAAgB,OAAO,OAAA,CAAQ,OAAO,GAAG,CAAC,CAAC,GAAA,EAAK,GAAG,CAAA,KAAM;AACvD,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,QAAA,EAAU,OAAA,CAAQ,GAAG,CAAA;AAC9C,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,CAAC,GAAA,CAAI,OAAO,QAAA,EAAU;AAC/C,QAAA,MAAM,QAAA,GAAW,OAAO,MAAA,CAAO,OAAO,EACnC,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,QAAQ,CAAA,CAC9B,GAAA,CAAI,OAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,CAAA,CAAG,CAAA,CACpB,KAAK,IAAI,CAAA;AAEZ,QAAA,MAAM,WAAW,CAAC,GAAI,WAAW,QAAA,EAAU,WAAA,MAAiB,EAAG,CAAA,CAC5D,GAAA,CAAI,OAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,CAAA,CAAG,CAAA,CACpB,KAAK,IAAI,CAAA;AAEZ,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,WAAA,EAAc,WAAW,IAAA,CAAK,EAAE,oDAAoD,QAAQ,CAAA,iCAAA,EAAoC,SAAS,CAAA,YAAA,EAAe,QAAQ,CAAA,CAAA;AAAA,SAClK;AAAA,MACF;AACA,MAAA,OAAO,CAAC,KAAK,KAAK,CAAA;AAAA,IACpB,CAAC;AAAA,GACH;AACF;AAEA,SAAS,yBAAA,CACP,aAAA,EACA,UAAA,EACA,SAAA,EACA,SAAA,EAC8D;AAC9D,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqB;AAEzC,EAAA,eAAA,CAAgB,eAAe,CAAA,GAAA,KAAO;AACpC,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AACvB,MAAA,SAAA,CAAU,MAAA,CAAO;AAAA,QACf,IAAA,EAAM,8BAAA;AAAA,QACN,OAAA,EAAS,CAAA,iCAAA,EAAoC,GAAA,CAAI,EAAE,CAAA,CAAA;AAAA,OACpD,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,QAAA,EAAU,OAAA,CAAQ,GAAG,CAAA;AAC9C,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,CAAC,GAAA,CAAI,OAAO,QAAA,EAAU;AAC/C,MAAA,MAAM,WAAW,aAAA,CACd,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,EAAE,MAAA,CAAO,QAAQ,CAAA,CAC9B,GAAA,CAAI,OAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,CAAA,CAAG,CAAA,CACpB,KAAK,IAAI,CAAA;AAEZ,MAAA,MAAM,WAAW,CAAC,GAAI,WAAW,QAAA,EAAU,WAAA,MAAiB,EAAG,CAAA,CAC5D,GAAA,CAAI,OAAK,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,CAAA,CAAG,CAAA,CACpB,KAAK,IAAI,CAAA;AAEZ,MAAA,SAAA,CAAU,MAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAE,MAAA,CAAO;AAAA,QAC3C,IAAA,EAAM,8BAAA;AAAA,QACN,OAAA,EAAS,CAAA,WAAA,EAAc,UAAA,CAAW,IAAA,CAAK,EAAE,oDAAoD,QAAQ,CAAA,iCAAA,EAAoC,SAAS,CAAA,YAAA,EAAe,QAAQ,CAAA,CAAA;AAAA,OAC1K,CAAA;AACD,MAAA,MAAM,oBAAA;AAAA,IACR;AAEA,IAAA,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAAA,EAC3B,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,IAAI,GAAA,EAAK;AACP,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAA,IAC3B,CAAA;AAAA,IACA,EAAE,MAAA,CAAO,QAAQ,CAAA,GAAI;AACnB,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,CAAA,IAAK,OAAA,EAAS;AAEjC,QAAA,MAAM;AAAA,UACJ,MAAA,EAAQ,+BAAA;AAAA,UACR,EAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AACF;AAEA,SAAS,2BAAA,CACP,EAAA,EACA,QAAA,EACA,WAAA,EACA;AACA,EAAA,MAAM,wBAAwB,KAAA,CAAM,IAAA,CAAK,WAAA,CAAY,OAAA,EAAS,CAAA,CAAE,MAAA;AAAA,IAC9D,CAAC,CAAC,SAAS,CAAA,KAAM,QAAA,CAAS,SAAS,CAAA,KAAM;AAAA,GAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA;AAEvC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,CAAA,IAAK,qBAAA,EAAuB;AACjD,IAAA,MAAM,EAAA,GAAK,MAAM,MAAA,GAAS,CAAA;AAE1B,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,QACE,gBAAgB,EAAA,GAAK,GAAA,GAAM,EAAE,CAAA,EAAA,EAAK,KAAA,CAC/B,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,CAAK,EAAE,EAClB,IAAA,CAAK,MAAM,CAAC,CAAA,EAAA,EAAK,EAAA,GAAK,QAAQ,IAAI,CAAA,CAAA;AAAA,QACrC,CAAA,uBAAA,EAA0B,IAAI,CAAA,oBAAA,EAAuB,EAAE,CAAA,SAAA,CAAA;AAAA,QACvD,UAAA,CAAW,WAAW,CAAA,GAClB,eAAA,GACA,sCAAsC,UAAA,CAAW,IAAA,CAAK,MAAM,CAAC,CAAA,EAAA;AAAA,OACnE,CAAE,KAAK,GAAG;AAAA,KACZ;AAAA,EACF;AACF;AAEA,SAAS,eAAA,CACP,UASA,WAAA,EACA;AACA,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,eAAA,CAAgB,OAAO,OAAA,CAAQ,QAAQ,GAAG,CAAC,CAAC,SAAA,EAAW,KAAK,CAAA,KAAM;AAChE,MAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,GAAA,CAAI,SAAS,KAAK,EAAC;AAErD,MAAA,IAAI,KAAA,CAAM,OAAO,SAAA,EAAW;AAC1B,QAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,UAAA,MAAM,kBAAkB,aAAA,CAAc,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,EAAE,CAAA;AACxD,UAAA,MAAM,KAAA;AAAA,YACJ,CAAA,SAAA,EACE,MAAM,MAAA,CAAO,QAAA,GAAW,YAAY,SACtC,CAAA,MAAA,EAAS,SAAS,CAAA,gCAAA,EAAmC,eAAA,CAAgB,IAAA;AAAA,cACnE;AAAA,aACD,CAAA,CAAA;AAAA,WACH;AAAA,QACF,CAAA,MAAA,IAAW,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG;AACrC,UAAA,IAAI,KAAA,CAAM,OAAO,QAAA,EAAU;AACzB,YAAA,OAAO,CAAC,WAAW,MAAS,CAAA;AAAA,UAC9B;AACA,UAAA,MAAM,KAAA,CAAM,CAAA,OAAA,EAAU,SAAS,CAAA,kCAAA,CAAoC,CAAA;AAAA,QACrE;AACA,QAAA,OAAO;AAAA,UACL,SAAA;AAAA,UACA;AAAA,YACE,IAAA,EAAM,cAAc,CAAC,CAAA;AAAA,YACrB,MAAA,EAAQ,qBAAA;AAAA,cACN,KAAA,CAAM,aAAA;AAAA,cACN,cAAc,CAAC,CAAA;AAAA,cACf;AAAA;AACF;AACF,SACF;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,SAAA;AAAA,QACA,aAAA,CAAc,IAAI,CAAA,UAAA,MAAe;AAAA,UAC/B,IAAA,EAAM,UAAA;AAAA,UACN,MAAA,EAAQ,qBAAA;AAAA,YACN,KAAA,CAAM,aAAA;AAAA,YACN,UAAA;AAAA,YACA;AAAA;AACF,SACF,CAAE;AAAA,OACJ;AAAA,IACF,CAAC;AAAA,GACH;AAQF;AAEA,SAAS,eAAA,CACP,QAAA,EACA,WAAA,EACA,eAAA,EACA,IAAA,EACoE;AACpE,EAAA,OAAO,SAAA,CAAU,QAAA,EAAU,CAAC,KAAA,EAAO,SAAA,KAAc;AAC/C,IAAA,MAAM,gBAAA,GAAmB,WAAA,CAAY,GAAA,CAAI,SAAS,KAAK,EAAC;AACxD,IAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,EAAE,WAAW,CAAA;AACrD,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,QAAA;AAEvC,IAAA,MAAM,gBAAgB,KAAA,CAAM,MAAA,CAAO,QAAA,GAC/B,gBAAA,CAAiB,OAAO,CAAA,UAAA,KAAc;AACpC,MAAA,MAAM,kBAAA,GAAqB,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,QAAA;AAClD,MAAA,IAAI,uBAAuB,aAAA,EAAe;AACxC,QAAA,SAAA,CAAU,MAAA,CAAO;AAAA,UACf,IAAA,EAAM,kCAAA;AAAA,UACN,SACE,CAAA,WAAA,EAAc,UAAA,CAAW,IAAA,CAAK,EAAE,kBAAkB,kBAAkB,CAAA,qBAAA,EAAwB,SAAS,CAAA,MAAA,EAAS,KAAK,IAAA,CAAK,EAAE,CAAA,uIAAA,EACC,aAAa,sBAAsB,kBAAkB,CAAA,QAAA,CAAA;AAAA,UAClL,OAAA,EAAS;AAAA,YACP,WAAA,EAAa,WAAW,IAAA,CAAK,EAAA;AAAA,YAC7B,MAAA,EAAQ,WAAW,IAAA,CAAK;AAAA;AAC1B,SACD,CAAA;AACD,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA,GACD,gBAAA;AAEJ,IAAA,IAAI,KAAA,CAAM,OAAO,SAAA,EAAW;AAC1B,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,QAAA,MAAM,eAAA,GAAkB,cAAc,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,IAAA,CAAK,EAAE,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AACrE,QAAA,SAAA,CAAU,MAAA,CAAO;AAAA,UACf,IAAA,EAAM,+BAAA;AAAA,UACN,OAAA,EAAS,CAAA,SAAA,EACP,KAAA,CAAM,MAAA,CAAO,QAAA,GAAW,YAAY,SACtC,CAAA,MAAA,EAAS,SAAS,CAAA,gCAAA,EAAmC,eAAe,CAAA,CAAA;AAAA,SACrE,CAAA;AACD,QAAA,MAAM,oBAAA;AAAA,MACR,CAAA,MAAA,IAAW,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG;AACrC,QAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU;AAC1B,UAAA,SAAA,CAAU,MAAA,CAAO;AAAA,YACf,IAAA,EAAM,8BAAA;AAAA,YACN,OAAA,EAAS,UAAU,SAAS,CAAA,kCAAA;AAAA,WAC7B,CAAA;AACD,UAAA,MAAM,oBAAA;AAAA,QACR;AACA,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,IAAI;AACF,QAAA,OAAO,yBAAA;AAAA,UACL,KAAA,CAAM,aAAA;AAAA,UACN,cAAc,CAAC,CAAA;AAAA,UACf,SAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,UAAU,oBAAA,EAAsB;AAClC,UAAA,IAAI,KAAA,CAAM,OAAO,QAAA,EAAU;AACzB,YAAA,OAAO,MAAA;AAAA,UACT;AACA,UAAA,SAAA,CAAU,MAAA,CAAO;AAAA,YACf,IAAA,EAAM,8BAAA;AAAA,YACN,OAAA,EAAS,UAAU,SAAS,CAAA,8CAAA;AAAA,WAC7B,CAAA;AAAA,QACH;AACA,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF;AAEA,IAAA,OAAO,eAAA;AAAA,MACL,aAAA;AAAA,MACA,CAAA,UAAA,KACE,yBAAA;AAAA,QACE,KAAA,CAAM,aAAA;AAAA,QACN,UAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AAAA,MACF,EAAE,gBAAgB,IAAA;AAAK,KACzB;AAAA,EACF,CAAC,CAAA;AACH;AAGO,SAAS,sBAAsB,OAAA,EAON;AAC9B,EAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,WAAA,EAAY,GAAI,OAAA;AACpC,EAAA,MAAM,YAAY,OAAA,CAAQ,SAAA,CAAU,KAAA,CAAM,EAAE,MAAM,CAAA;AAClD,EAAA,MAAM,EAAE,EAAA,EAAI,SAAA,EAAW,MAAA,KAAW,IAAA,CAAK,IAAA;AACvC,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAqB;AAC/C,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAA+B;AAC7D,EAAA,MAAM,UAAA,GACJ,OAAA,CAAQ,YAAA,KAAiB,MAAA,GACrB,IAAA,GACA;AAAA,IACE,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAC3B,MAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,QAAA,OAAA,CAAQ,YAAA,GAAe;AAAA,UACrB,IAAA;AAAA,UACA,UAAU,MAAA,CAAO;AAAA,SAClB,CAAA;AAAA,MACH;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,GACF;AAEN,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI;AACF,IAAA,YAAA,GAAe,SAAA,CAAU,YAAA,EAAc,KAAA,CAAM,MAAA,IAAU,EAAE,CAAA;AAAA,EAG3D,SAAS,CAAA,EAAG;AACV,IAAA,SAAA,CAAU,MAAA,CAAO;AAAA,MACf,IAAA,EAAM,iCAAA;AAAA,MACN,OAAA,EAAS,CAAA,qCAAA,EAAwC,EAAE,CAAA,aAAA,EAAgB,CAAC,CAAA;AAAA,KACrE,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,iBAAA,GAAoB,oBAAoB,SAAS,CAAA;AAEvD,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,EAAc;AACzC,MAAA,2BAAA,CAA4B,EAAA,EAAI,iBAAA,CAAkB,MAAA,EAAQ,WAAW,CAAA;AAAA,IACvE;AAEA,IAAA,IAAI,iBAAA,CAAkB,YAAY,IAAA,EAAM;AACtC,MAAA,MAAM,YAAA,GAAe,kBAAkB,OAAA,CAAQ;AAAA,QAC7C,IAAA;AAAA,QACA,IAAA,EAAM,UAAA;AAAA,QACN,MAAA,EAAQ,YAAA;AAAA,QACR,MAAA,EAAQ,eAAA,CAAgB,iBAAA,CAAkB,MAAA,EAAQ,WAAW;AAAA,OAC9D,CAAA;AAED,MAAA,KAAA,MAAW,CAAC,IAAA,EAAM,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,EAAG;AACzD,QAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,MAAA,CAAO,IAAI,CAAA;AACzC,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,QACzD;AACA,QAAA,IAAI,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AAC7B,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,CAAA,0BAAA,EAA6B,GAAA,CAAI,EAAE,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAA;AAAA,WACnE;AAAA,QACF;AACA,QAAA,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,MAAM,CAAA;AAChC,QAAA,iBAAA,CAAkB,IAAI,GAAG,CAAA;AAAA,MAC3B;AAAA,IACF,CAAA,MAAA,IAAW,iBAAA,CAAkB,OAAA,KAAY,IAAA,EAAM;AAC7C,MAAA,MAAM,OAAA,GAAU;AAAA,QACd,IAAA;AAAA,QACA,IAAA,EAAM,UAAA;AAAA,QACN,MAAA,EAAQ,YAAA;AAAA,QACR,MAAA,EAAQ,eAAA;AAAA,UACN,iBAAA,CAAkB,MAAA;AAAA,UAClB,WAAA;AAAA,UACA,SAAA;AAAA,UACA;AAAA;AACF,OACF;AACA,MAAA,MAAM,gBAAA,GAAmB,QAAQ,0BAAA,GAC7B,4BAAA;AAAA,QACE,OAAA,CAAQ,2BAA2B,CAAA,eAAA,KAAmB;AACpD,UAAA,OAAO,4BAAA;AAAA,YACL,kBAAkB,OAAA,CAAQ;AAAA,cACxB,MAAM,OAAA,CAAQ,IAAA;AAAA,cACd,MAAM,OAAA,CAAQ,IAAA;AAAA,cACd,QAAQ,OAAA,CAAQ,MAAA;AAAA,cAChB,MAAA,EAAQ,eAAA,EAAiB,MAAA,IAAU,OAAA,CAAQ;AAAA,aAC5C,CAAA;AAAA,YACD;AAAA,WACF;AAAA,QACF,GAAG,OAAO,CAAA;AAAA,QACV;AAAA,OACF,GACA,iBAAA,CAAkB,OAAA,CAAQ,OAAO,CAAA;AAErC,MAAA,IACE,OAAO,gBAAA,KAAqB,QAAA,IAC5B,CAAC,gBAAA,GAAmB,MAAA,CAAO,QAAQ,CAAA,EACnC;AACA,QAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,MACxE;AAEA,MAAA,MAAM,aAAA,uBAAoB,GAAA,EAAqB;AAC/C,MAAA,eAAA,CAAgB,kBAAkB,CAAA,KAAA,KAAS;AACzC,QAAA,IAAI,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AAC/B,UAAA,SAAA,CAAU,MAAA,CAAO;AAAA,YACf,IAAA,EAAM,2BAAA;AAAA,YACN,OAAA,EAAS,CAAA,yCAAA,EAA4C,KAAA,CAAM,EAAE,CAAA,CAAA,CAAA;AAAA,YAC7D,OAAA,EAAS;AAAA,cACP,WAAW,KAAA,CAAM;AAAA;AACnB,WACD,CAAA;AACD,UAAA,MAAM,oBAAA;AAAA,QACR,CAAA,MAAO;AACL,UAAA,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,KAAK,CAAA;AAAA,QACzC;AAAA,MACF,CAAC,CAAA;AAED,MAAA,KAAA,MAAW,GAAA,IAAO,kBAAkB,MAAA,EAAQ;AAC1C,QAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AACtC,QAAA,aAAA,CAAc,MAAA,CAAO,IAAI,EAAE,CAAA;AAC3B,QAAA,IAAI,UAAU,KAAA,CAAA,EAAW;AACvB,UAAA,IAAI,CAAC,GAAA,CAAI,MAAA,CAAO,QAAA,EAAU;AACxB,YAAA,SAAA,CAAU,MAAA,CAAO;AAAA,cACf,IAAA,EAAM,0BAAA;AAAA,cACN,OAAA,EAAS,CAAA,wCAAA,EAA2C,GAAA,CAAI,EAAE,CAAA,CAAA,CAAA;AAAA,cAC1D,OAAA,EAAS;AAAA,gBACP,WAAW,GAAA,CAAI;AAAA;AACjB,aACD,CAAA;AACD,YAAA,MAAM,oBAAA;AAAA,UACR;AAAA,QACF,CAAA,MAAO;AACL,UAAA,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC/B,UAAA,iBAAA,CAAkB,IAAI,GAAG,CAAA;AAAA,QAC3B;AAAA,MACF;AAEA,MAAA,IAAI,aAAA,CAAc,OAAO,CAAA,EAAG;AAC1B,QAAA,KAAA,MAAW,SAAA,IAAa,aAAA,CAAc,IAAA,EAAK,EAAG;AAE5C,UAAA,SAAA,CAAU,MAAA,CAAO;AAAA,YACf,IAAA,EAAM,0BAAA;AAAA,YACN,OAAA,EAAS,sBAAsB,SAAS,CAAA,CAAA,CAAA;AAAA,YACxC,OAAA,EAAS;AAAA,cACP;AAAA;AACF,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,SAAA,CAAU,MAAA,CAAO;AAAA,QACf,IAAA,EAAM,mBAAA;AAAA,QACN,OAAA,EAAS,CAAA,8BAAA,EACN,iBAAA,CAA0B,OAC7B,CAAA,CAAA;AAAA,OACD,CAAA;AACD,MAAA,MAAM,oBAAA;AAAA,IACR;AAAA,EACF,SAAS,CAAA,EAAG;AACV,IAAA,IAAI,MAAM,oBAAA,EAAsB;AAC9B,MAAA,SAAA,CAAU,MAAA,CAAO;AAAA,QACf,IAAA,EAAM,yBAAA;AAAA,QACN,OAAA,EAAS,CAAA,iCAAA,EAAoC,EAAE,CAAA,CAAA,EAC7C,CAAA,CAAE,IAAA,KAAS,OAAA,GAAU,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAA,GAAK,CAAA,YAAA,EAAe,CAAC,CAAA,CAC1D,CAAA;AAAA,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,WAAA,GAAc;AACZ,MAAA,OAAO,kBAAkB,MAAA,EAAO;AAAA,IAClC,CAAA;AAAA,IACA,QAAW,GAAA,EAAyC;AAClD,MAAA,OAAO,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA;AAAA,IACjC;AAAA,GACF;AACF;AAQO,SAAS,0BACd,OAAA,EACqB;AACrB,EAAA,MAAM,iBAAA,uBAAwB,OAAA,EAAiC;AAE/D,EAAA,SAAS,eAAe,IAAA,EAAoC;AAC1D,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC/B,MAAA,OAAO,iBAAA,CAAkB,GAAA,CAAI,IAAI,CAAA,IAAK,MAAA;AAAA,IACxC;AACA,IAAA,IAAI,OAAA,CAAQ,sBAAA,KAA2B,KAAA,IAAS,IAAA,CAAK,QAAA,EAAU;AAC7D,MAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,IAAI,CAAA;AAChC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,CAAK,KAAK,QAAA,EAAU;AACtB,MAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,IAAI,CAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IACE,OAAA,CAAQ,gBAAA,KAAqB,MAAA,IAC7B,IAAA,CAAK,KAAK,EAAA,KAAO,MAAA,IACjB,CAAC,uBAAA,CAAwB,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,OAAA,CAAQ,gBAAgB,CAAA,EAC/D;AACA,MAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,IAAI,CAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,MAAM,uBAAA,uBAA8B,GAAA,EAAuB;AAE3D,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,QAAQ,CAAA,IAAK,IAAA,CAAK,MAAM,WAAA,EAAa;AACtD,MAAA,IAAI,QAAQ,gBAAA,GAAmB,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,EAAG;AAC/C,QAAA;AAAA,MACF;AACA,MAAA,MAAM,oBAAA,GAAuB,QAAA,CAAS,OAAA,CAAQ,CAAA,KAAA,KAAS;AACrD,QAAA,IAAI,QAAQ,SAAA,GAAY,EAAE,MAAM,KAAA,EAAO,KAAA,EAAO,CAAA,EAAG;AAC/C,UAAA,OAAO,EAAC;AAAA,QACV;AACA,QAAA,MAAM,SAAA,GAAY,eAAe,KAAK,CAAA;AACtC,QAAA,OAAO,SAAA,GAAY,CAAC,SAAS,CAAA,GAAI,EAAC;AAAA,MACpC,CAAC,CAAA;AACD,MAAA,IAAI,oBAAA,CAAqB,SAAS,CAAA,EAAG;AACnC,QAAA,uBAAA,CAAwB,GAAA,CAAI,OAAO,oBAAoB,CAAA;AAAA,MACzD;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,qBAAA,CAAsB;AAAA,MACrC,4BAA4B,OAAA,CAAQ,0BAAA;AAAA,MACpC,IAAA;AAAA,MACA,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,WAAA,EAAa,uBAAA;AAAA,MACb,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,cAAc,OAAA,CAAQ;AAAA,KACvB,CAAA;AACD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,IAAI,CAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,OAAA,CAAQ,uBAAuB,KAAA,EAAO;AACxC,MAAA,MAAM,YAAA,GAAwB;AAAA,QAC5B,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ;AAAA,OACF;AACA,MAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,YAAY,CAAA;AACxC,MAAA,OAAO,YAAA;AAAA,IACT;AAEA,IAAC,KAA0B,QAAA,GAAW,QAAA;AACtC,IAAA,iBAAA,CAAkB,GAAA,CAAI,MAAM,IAAI,CAAA;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,cAAA,CAAe,QAAQ,QAAQ,CAAA;AACxC;AAMO,SAAS,sBAAA,CACd,QAAA,EACA,IAAA,EACA,SAAA,EACA,4BACA,yBAAA,EAYS;AACT,EAAA,MAAM,OAAA,GAMJ,yBAAA,KACC,kBAAA,IAAsB,yBAAA,IACrB,WAAA,IAAe,6BACf,cAAA,IAAkB,yBAAA,IAClB,kBAAA,IAAsB,yBAAA,CAAA,GACpB,yBAAA,GACA;AAAA,IACE,gBAAA,EAAkB;AAAA,GACpB;AAEN,EAAA,OACE,yBAAA,CAA0B;AAAA,IACxB,QAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA;AAAA,IACA,0BAAA;AAAA,IACA,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,IAC1B,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,kBAAkB,OAAA,CAAQ;AAAA,GAC3B,CAAA,KAAM,MAAA;AAEX;;;;"}
@@ -9,6 +9,21 @@ function normalizePlugin(plugin) {
9
9
  }
10
10
  return plugin;
11
11
  }
12
+ function combinePredicates(left, right) {
13
+ if (!left) {
14
+ return right;
15
+ }
16
+ if (!right) {
17
+ return left;
18
+ }
19
+ return { $all: [left, right] };
20
+ }
21
+ function getExtensionPredicate(options) {
22
+ if (options.internalExtension.version === "v2") {
23
+ return options.internalExtension.if;
24
+ }
25
+ return void 0;
26
+ }
12
27
  function resolveAppNodeSpecs(options) {
13
28
  const {
14
29
  builtinExtensions = [],
@@ -34,20 +49,39 @@ function resolveAppNodeSpecs(options) {
34
49
  return true;
35
50
  };
36
51
  const pluginExtensions = plugins.flatMap((plugin) => {
37
- return OpaqueFrontendPlugin.toInternal(plugin).extensions.map((extension) => ({
38
- ...extension,
39
- plugin
40
- })).filter(filterForbidden);
52
+ const internalPlugin = OpaqueFrontendPlugin.toInternal(plugin);
53
+ return internalPlugin.extensions.map((extension) => {
54
+ const internalExtension = toInternalExtension(extension);
55
+ return {
56
+ ...internalExtension,
57
+ plugin,
58
+ if: combinePredicates(
59
+ internalPlugin.if,
60
+ internalExtension.version === "v2" ? internalExtension.if : void 0
61
+ )
62
+ };
63
+ }).filter(filterForbidden);
41
64
  });
42
- const moduleExtensions = modules.flatMap(
43
- (mod) => toInternalFrontendModule(mod).extensions.flatMap((extension) => {
65
+ const moduleExtensions = modules.flatMap((mod) => {
66
+ const internalModule = toInternalFrontendModule(mod);
67
+ return internalModule.extensions.flatMap((extension) => {
68
+ const internalExtension = toInternalExtension(extension);
44
69
  const plugin = plugins.find((p) => p.pluginId === mod.pluginId);
45
70
  if (!plugin) {
46
71
  return [];
47
72
  }
48
- return [{ ...extension, plugin }];
49
- }).filter(filterForbidden)
50
- );
73
+ return [
74
+ {
75
+ ...internalExtension,
76
+ plugin,
77
+ if: combinePredicates(
78
+ internalModule.if,
79
+ internalExtension.version === "v2" ? internalExtension.if : void 0
80
+ )
81
+ }
82
+ ];
83
+ }).filter(filterForbidden);
84
+ });
51
85
  const appPlugin = plugins.find((plugin) => plugin.pluginId === "app") ?? createFrontendPlugin({
52
86
  pluginId: "app"
53
87
  });
@@ -61,6 +95,7 @@ function resolveAppNodeSpecs(options) {
61
95
  source: plugin,
62
96
  attachTo: internalExtension.attachTo,
63
97
  disabled: internalExtension.disabled,
98
+ if: getExtensionPredicate({ internalExtension }),
64
99
  config: void 0
65
100
  }
66
101
  };
@@ -74,6 +109,7 @@ function resolveAppNodeSpecs(options) {
74
109
  plugin: appPlugin,
75
110
  attachTo: internalExtension.attachTo,
76
111
  disabled: internalExtension.disabled,
112
+ if: getExtensionPredicate({ internalExtension }),
77
113
  config: void 0
78
114
  }
79
115
  };
@@ -88,6 +124,9 @@ function resolveAppNodeSpecs(options) {
88
124
  configuredExtensions[index].extension = internalExtension;
89
125
  configuredExtensions[index].params.attachTo = internalExtension.attachTo;
90
126
  configuredExtensions[index].params.disabled = internalExtension.disabled;
127
+ configuredExtensions[index].params.if = getExtensionPredicate({
128
+ internalExtension
129
+ });
91
130
  } else {
92
131
  configuredExtensions.push({
93
132
  extension: internalExtension,
@@ -96,6 +135,7 @@ function resolveAppNodeSpecs(options) {
96
135
  source: extension.plugin,
97
136
  attachTo: internalExtension.attachTo,
98
137
  disabled: internalExtension.disabled,
138
+ if: getExtensionPredicate({ internalExtension }),
99
139
  config: void 0
100
140
  }
101
141
  });
@@ -165,6 +205,7 @@ function resolveAppNodeSpecs(options) {
165
205
  attachTo: param.params.attachTo,
166
206
  extension: param.extension,
167
207
  disabled: param.params.disabled,
208
+ if: param.params.if,
168
209
  plugin: param.params.plugin,
169
210
  source: param.params.source,
170
211
  config: param.params.config
@@ -1 +1 @@
1
- {"version":3,"file":"resolveAppNodeSpecs.esm.js","sources":["../../src/tree/resolveAppNodeSpecs.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 createFrontendPlugin,\n Extension,\n FrontendFeature,\n FrontendPlugin,\n} from '@backstage/frontend-plugin-api';\nimport { ExtensionParameters } from './readAppExtensionsConfig';\nimport { AppNodeSpec } from '@backstage/frontend-plugin-api';\nimport { OpaqueFrontendPlugin } from '@internal/frontend';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n isInternalFrontendModule,\n toInternalFrontendModule,\n} from '../../../frontend-plugin-api/src/wiring/createFrontendModule';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\nimport { ErrorCollector } from '../wiring/createErrorCollector';\n\nfunction normalizePlugin(plugin: FrontendPlugin): FrontendPlugin {\n // Ensure pluginId is always set for plugins in the app\n if (!plugin.pluginId && 'id' in plugin && typeof plugin.id === 'string') {\n (plugin as any).pluginId = plugin.id;\n }\n return plugin;\n}\n\n/** @internal */\nexport function resolveAppNodeSpecs(options: {\n features?: FrontendFeature[];\n builtinExtensions?: Extension<any, any>[];\n parameters?: Array<ExtensionParameters>;\n forbidden?: Set<string>;\n collector: ErrorCollector;\n}): AppNodeSpec[] {\n const {\n builtinExtensions = [],\n parameters = [],\n forbidden = new Set(),\n features = [],\n collector,\n } = options;\n\n const plugins = features\n .filter(OpaqueFrontendPlugin.isType)\n .map(normalizePlugin);\n const modules = features.filter(isInternalFrontendModule);\n\n const filterForbidden = (\n extension: Extension<any, any> & { plugin: FrontendPlugin },\n ) => {\n if (forbidden.has(extension.id)) {\n collector.report({\n code: 'EXTENSION_IGNORED',\n message: `It is forbidden to override the '${extension.id}' extension, attempted by the '${extension.plugin.pluginId}' plugin`,\n context: {\n plugin: extension.plugin,\n extensionId: extension.id,\n },\n });\n return false;\n }\n return true;\n };\n\n const pluginExtensions = plugins.flatMap(plugin => {\n return OpaqueFrontendPlugin.toInternal(plugin)\n .extensions.map(extension => ({\n ...extension,\n plugin,\n }))\n .filter(filterForbidden);\n });\n const moduleExtensions = modules.flatMap(mod =>\n toInternalFrontendModule(mod)\n .extensions.flatMap(extension => {\n // Modules for plugins that are not installed are ignored\n const plugin = plugins.find(p => p.pluginId === mod.pluginId);\n if (!plugin) {\n return [];\n }\n\n return [{ ...extension, plugin }];\n })\n .filter(filterForbidden),\n );\n\n const appPlugin =\n plugins.find(plugin => plugin.pluginId === 'app') ??\n createFrontendPlugin({\n pluginId: 'app',\n });\n\n const configuredExtensions = [\n ...pluginExtensions.map(({ plugin, ...extension }) => {\n const internalExtension = toInternalExtension(extension);\n return {\n extension: internalExtension,\n params: {\n plugin,\n source: plugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n config: undefined as unknown,\n },\n };\n }),\n ...builtinExtensions.map(extension => {\n const internalExtension = toInternalExtension(extension);\n return {\n extension: internalExtension,\n params: {\n source: appPlugin,\n plugin: appPlugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n config: undefined as unknown,\n },\n };\n }),\n ];\n\n // Install all module overrides\n for (const extension of moduleExtensions) {\n const internalExtension = toInternalExtension(extension);\n\n // Check if our override is overriding an extension that already exists\n const index = configuredExtensions.findIndex(\n e => e.extension.id === extension.id,\n );\n if (index !== -1) {\n // Only implementation, attachment point and default disabled status are overridden, the source is kept\n configuredExtensions[index].extension = internalExtension;\n configuredExtensions[index].params.attachTo = internalExtension.attachTo;\n configuredExtensions[index].params.disabled = internalExtension.disabled;\n } else {\n // Add the extension as a new one when not overriding an existing one\n configuredExtensions.push({\n extension: internalExtension,\n params: {\n plugin: extension.plugin,\n source: extension.plugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n config: undefined,\n },\n });\n }\n }\n\n const seenExtensionIds = new Set<string>();\n const deduplicatedExtensions = configuredExtensions.filter(\n ({ extension, params }) => {\n if (seenExtensionIds.has(extension.id)) {\n collector.report({\n code: 'EXTENSION_IGNORED',\n message: `The '${extension.id}' extension from the '${params.plugin.pluginId}' plugin is a duplicate and will be ignored`,\n context: {\n plugin: params.plugin,\n extensionId: extension.id,\n },\n });\n return false;\n }\n seenExtensionIds.add(extension.id);\n return true;\n },\n );\n\n const order = new Map<string, (typeof deduplicatedExtensions)[number]>();\n for (const overrideParam of parameters) {\n const extensionId = overrideParam.id;\n\n if (forbidden.has(extensionId)) {\n collector.report({\n code: 'INVALID_EXTENSION_CONFIG_KEY',\n message: `Configuration of the '${extensionId}' extension is forbidden`,\n context: {\n extensionId,\n },\n });\n continue;\n }\n\n const existing = deduplicatedExtensions.find(\n e => e.extension.id === extensionId,\n );\n if (existing) {\n if (overrideParam.attachTo) {\n existing.params.attachTo = overrideParam.attachTo;\n }\n if (overrideParam.config) {\n // TODO: merge config?\n existing.params.config = overrideParam.config;\n }\n if (\n Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)\n ) {\n existing.params.disabled = Boolean(overrideParam.disabled);\n }\n order.set(extensionId, existing);\n } else {\n collector.report({\n code: 'INVALID_EXTENSION_CONFIG_KEY',\n message: `Extension ${extensionId} does not exist`,\n context: {\n extensionId,\n },\n });\n }\n }\n\n const orderedExtensions = [\n ...order.values(),\n ...deduplicatedExtensions.filter(e => !order.has(e.extension.id)),\n ];\n\n return orderedExtensions.map(param => ({\n id: param.extension.id,\n attachTo: param.params.attachTo,\n extension: param.extension,\n disabled: param.params.disabled,\n plugin: param.params.plugin,\n source: param.params.source,\n config: param.params.config,\n }));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolveAppNodeSpecs.esm.js","sources":["../../src/tree/resolveAppNodeSpecs.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 createFrontendPlugin,\n Extension,\n FrontendFeature,\n FrontendPlugin,\n} from '@backstage/frontend-plugin-api';\nimport { FilterPredicate } from '@backstage/filter-predicates';\nimport { ExtensionParameters } from './readAppExtensionsConfig';\nimport { AppNodeSpec } from '@backstage/frontend-plugin-api';\nimport { OpaqueFrontendPlugin } from '@internal/frontend';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n isInternalFrontendModule,\n toInternalFrontendModule,\n} from '../../../frontend-plugin-api/src/wiring/createFrontendModule';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition';\nimport { ErrorCollector } from '../wiring/createErrorCollector';\n\nfunction normalizePlugin(plugin: FrontendPlugin): FrontendPlugin {\n // Ensure pluginId is always set for plugins in the app\n if (!plugin.pluginId && 'id' in plugin && typeof plugin.id === 'string') {\n (plugin as any).pluginId = plugin.id;\n }\n return plugin;\n}\n\nfunction combinePredicates(\n left: FilterPredicate | undefined,\n right: FilterPredicate | undefined,\n) {\n if (!left) {\n return right;\n }\n if (!right) {\n return left;\n }\n\n return { $all: [left, right] };\n}\n\nfunction getExtensionPredicate(options: {\n internalExtension: ReturnType<typeof toInternalExtension>;\n}) {\n if (options.internalExtension.version === 'v2') {\n return options.internalExtension.if;\n }\n return undefined;\n}\n\n/** @internal */\nexport function resolveAppNodeSpecs(options: {\n features?: FrontendFeature[];\n builtinExtensions?: Extension<any, any>[];\n parameters?: Array<ExtensionParameters>;\n forbidden?: Set<string>;\n collector: ErrorCollector;\n}): AppNodeSpec[] {\n const {\n builtinExtensions = [],\n parameters = [],\n forbidden = new Set(),\n features = [],\n collector,\n } = options;\n\n const plugins = features\n .filter(OpaqueFrontendPlugin.isType)\n .map(normalizePlugin);\n const modules = features.filter(isInternalFrontendModule);\n\n const filterForbidden = (\n extension: Extension<any, any> & { plugin: FrontendPlugin },\n ) => {\n if (forbidden.has(extension.id)) {\n collector.report({\n code: 'EXTENSION_IGNORED',\n message: `It is forbidden to override the '${extension.id}' extension, attempted by the '${extension.plugin.pluginId}' plugin`,\n context: {\n plugin: extension.plugin,\n extensionId: extension.id,\n },\n });\n return false;\n }\n return true;\n };\n\n const pluginExtensions = plugins.flatMap(plugin => {\n const internalPlugin = OpaqueFrontendPlugin.toInternal(plugin);\n return internalPlugin.extensions\n .map(extension => {\n const internalExtension = toInternalExtension(extension);\n return {\n ...internalExtension,\n plugin,\n if: combinePredicates(\n internalPlugin.if,\n internalExtension.version === 'v2'\n ? internalExtension.if\n : undefined,\n ),\n };\n })\n .filter(filterForbidden);\n });\n const moduleExtensions = modules.flatMap(mod => {\n const internalModule = toInternalFrontendModule(mod);\n return internalModule.extensions\n .flatMap(extension => {\n const internalExtension = toInternalExtension(extension);\n\n // Modules for plugins that are not installed are ignored\n const plugin = plugins.find(p => p.pluginId === mod.pluginId);\n if (!plugin) {\n return [];\n }\n\n return [\n {\n ...internalExtension,\n plugin,\n if: combinePredicates(\n internalModule.if,\n internalExtension.version === 'v2'\n ? internalExtension.if\n : undefined,\n ),\n },\n ];\n })\n .filter(filterForbidden);\n });\n\n const appPlugin =\n plugins.find(plugin => plugin.pluginId === 'app') ??\n createFrontendPlugin({\n pluginId: 'app',\n });\n\n const configuredExtensions = [\n ...pluginExtensions.map(({ plugin, ...extension }) => {\n const internalExtension = toInternalExtension(extension);\n return {\n extension: internalExtension,\n params: {\n plugin,\n source: plugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n if: getExtensionPredicate({ internalExtension }),\n config: undefined as unknown,\n },\n };\n }),\n ...builtinExtensions.map(extension => {\n const internalExtension = toInternalExtension(extension);\n return {\n extension: internalExtension,\n params: {\n source: appPlugin,\n plugin: appPlugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n if: getExtensionPredicate({ internalExtension }),\n config: undefined as unknown,\n },\n };\n }),\n ];\n\n // Install all module overrides\n for (const extension of moduleExtensions) {\n const internalExtension = toInternalExtension(extension);\n\n // Check if our override is overriding an extension that already exists\n const index = configuredExtensions.findIndex(\n e => e.extension.id === extension.id,\n );\n if (index !== -1) {\n // Only implementation, attachment point and default disabled status are overridden, the source is kept\n configuredExtensions[index].extension = internalExtension;\n configuredExtensions[index].params.attachTo = internalExtension.attachTo;\n configuredExtensions[index].params.disabled = internalExtension.disabled;\n configuredExtensions[index].params.if = getExtensionPredicate({\n internalExtension,\n });\n } else {\n // Add the extension as a new one when not overriding an existing one\n configuredExtensions.push({\n extension: internalExtension,\n params: {\n plugin: extension.plugin,\n source: extension.plugin,\n attachTo: internalExtension.attachTo,\n disabled: internalExtension.disabled,\n if: getExtensionPredicate({ internalExtension }),\n config: undefined,\n },\n });\n }\n }\n\n const seenExtensionIds = new Set<string>();\n const deduplicatedExtensions = configuredExtensions.filter(\n ({ extension, params }) => {\n if (seenExtensionIds.has(extension.id)) {\n collector.report({\n code: 'EXTENSION_IGNORED',\n message: `The '${extension.id}' extension from the '${params.plugin.pluginId}' plugin is a duplicate and will be ignored`,\n context: {\n plugin: params.plugin,\n extensionId: extension.id,\n },\n });\n return false;\n }\n seenExtensionIds.add(extension.id);\n return true;\n },\n );\n\n const order = new Map<string, (typeof deduplicatedExtensions)[number]>();\n for (const overrideParam of parameters) {\n const extensionId = overrideParam.id;\n\n if (forbidden.has(extensionId)) {\n collector.report({\n code: 'INVALID_EXTENSION_CONFIG_KEY',\n message: `Configuration of the '${extensionId}' extension is forbidden`,\n context: {\n extensionId,\n },\n });\n continue;\n }\n\n const existing = deduplicatedExtensions.find(\n e => e.extension.id === extensionId,\n );\n if (existing) {\n if (overrideParam.attachTo) {\n existing.params.attachTo = overrideParam.attachTo;\n }\n if (overrideParam.config) {\n // TODO: merge config?\n existing.params.config = overrideParam.config;\n }\n if (\n Boolean(existing.params.disabled) !== Boolean(overrideParam.disabled)\n ) {\n existing.params.disabled = Boolean(overrideParam.disabled);\n }\n order.set(extensionId, existing);\n } else {\n collector.report({\n code: 'INVALID_EXTENSION_CONFIG_KEY',\n message: `Extension ${extensionId} does not exist`,\n context: {\n extensionId,\n },\n });\n }\n }\n\n const orderedExtensions = [\n ...order.values(),\n ...deduplicatedExtensions.filter(e => !order.has(e.extension.id)),\n ];\n\n return orderedExtensions.map(param => ({\n id: param.extension.id,\n attachTo: param.params.attachTo,\n extension: param.extension,\n disabled: param.params.disabled,\n if: param.params.if,\n plugin: param.params.plugin,\n source: param.params.source,\n config: param.params.config,\n }));\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ class FrontendApiRegistry {
2
+ factories = /* @__PURE__ */ new Map();
3
+ register(factory) {
4
+ if (this.factories.has(factory.api.id)) {
5
+ return false;
6
+ }
7
+ this.factories.set(factory.api.id, factory);
8
+ return true;
9
+ }
10
+ registerAll(factories) {
11
+ for (const factory of factories) {
12
+ this.register(factory);
13
+ }
14
+ }
15
+ set(factory) {
16
+ this.factories.set(factory.api.id, factory);
17
+ }
18
+ setAll(factories) {
19
+ for (const factory of factories) {
20
+ this.set(factory);
21
+ }
22
+ }
23
+ get(api) {
24
+ const factory = this.factories.get(api.id);
25
+ if (!factory) {
26
+ return void 0;
27
+ }
28
+ return factory;
29
+ }
30
+ getAllApis() {
31
+ const refs = /* @__PURE__ */ new Set();
32
+ for (const factory of this.factories.values()) {
33
+ refs.add(factory.api);
34
+ }
35
+ return refs;
36
+ }
37
+ }
38
+ class FrontendApiResolver {
39
+ apis = /* @__PURE__ */ new Map();
40
+ primaryRegistry;
41
+ secondaryRegistry;
42
+ fallbackApis;
43
+ constructor(options) {
44
+ this.primaryRegistry = options.primaryRegistry;
45
+ this.secondaryRegistry = options.secondaryRegistry;
46
+ this.fallbackApis = options.fallbackApis;
47
+ }
48
+ get(ref) {
49
+ return this.load(ref);
50
+ }
51
+ isMaterialized(apiRefId) {
52
+ return this.apis.has(apiRefId);
53
+ }
54
+ invalidate(apiRefIds) {
55
+ if (apiRefIds === void 0) {
56
+ this.apis.clear();
57
+ return;
58
+ }
59
+ for (const apiRefId of apiRefIds) {
60
+ this.apis.delete(apiRefId);
61
+ }
62
+ }
63
+ load(ref, loading = []) {
64
+ const existing = this.apis.get(ref.id);
65
+ if (this.apis.has(ref.id)) {
66
+ return existing;
67
+ }
68
+ const factory = this.primaryRegistry?.get(ref) ?? this.secondaryRegistry?.get(ref);
69
+ if (!factory) {
70
+ return this.fallbackApis?.get(ref);
71
+ }
72
+ if (loading.includes(factory.api)) {
73
+ throw new Error(`Circular dependency of api factory for ${factory.api}`);
74
+ }
75
+ const deps = {};
76
+ for (const [key, depRef] of Object.entries(factory.deps)) {
77
+ const dep = this.load(depRef, [...loading, factory.api]);
78
+ if (dep === void 0) {
79
+ throw new Error(
80
+ `No API factory available for dependency ${depRef} of dependent ${factory.api}`
81
+ );
82
+ }
83
+ deps[key] = dep;
84
+ }
85
+ const api = factory.factory(deps);
86
+ this.apis.set(ref.id, api);
87
+ return api;
88
+ }
89
+ }
90
+
91
+ export { FrontendApiRegistry, FrontendApiResolver };
92
+ //# sourceMappingURL=FrontendApiRegistry.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrontendApiRegistry.esm.js","sources":["../../src/wiring/FrontendApiRegistry.ts"],"sourcesContent":["/*\n * Copyright 2026 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 AnyApiFactory,\n AnyApiRef,\n ApiFactory,\n ApiHolder,\n ApiRef,\n} from '@backstage/frontend-plugin-api';\n\nexport class FrontendApiRegistry {\n private readonly factories = new Map<string, AnyApiFactory>();\n\n register(factory: AnyApiFactory) {\n if (this.factories.has(factory.api.id)) {\n return false;\n }\n\n this.factories.set(factory.api.id, factory);\n return true;\n }\n\n registerAll(factories: AnyApiFactory[]) {\n for (const factory of factories) {\n this.register(factory);\n }\n }\n\n set(factory: AnyApiFactory) {\n this.factories.set(factory.api.id, factory);\n }\n\n setAll(factories: Iterable<AnyApiFactory>) {\n for (const factory of factories) {\n this.set(factory);\n }\n }\n\n get<T>(\n api: ApiRef<T>,\n ): ApiFactory<T, T, { [name: string]: unknown }> | undefined {\n const factory = this.factories.get(api.id);\n if (!factory) {\n return undefined;\n }\n\n return factory as ApiFactory<T, T, { [name: string]: unknown }>;\n }\n\n getAllApis() {\n const refs = new Set<AnyApiRef>();\n for (const factory of this.factories.values()) {\n refs.add(factory.api);\n }\n return refs;\n }\n}\n\nexport class FrontendApiResolver implements ApiHolder {\n private readonly apis = new Map<string, unknown>();\n private readonly primaryRegistry?: FrontendApiRegistry;\n private readonly secondaryRegistry?: FrontendApiRegistry;\n private readonly fallbackApis?: ApiHolder;\n\n constructor(options: {\n primaryRegistry?: FrontendApiRegistry;\n secondaryRegistry?: FrontendApiRegistry;\n fallbackApis?: ApiHolder;\n }) {\n this.primaryRegistry = options.primaryRegistry;\n this.secondaryRegistry = options.secondaryRegistry;\n this.fallbackApis = options.fallbackApis;\n }\n\n get<T>(ref: ApiRef<T>): T | undefined {\n return this.load(ref);\n }\n\n isMaterialized(apiRefId: string) {\n return this.apis.has(apiRefId);\n }\n\n invalidate(apiRefIds?: Iterable<string>) {\n if (apiRefIds === undefined) {\n this.apis.clear();\n return;\n }\n\n for (const apiRefId of apiRefIds) {\n this.apis.delete(apiRefId);\n }\n }\n\n private load<T>(ref: ApiRef<T>, loading: AnyApiRef[] = []): T | undefined {\n const existing = this.apis.get(ref.id);\n if (this.apis.has(ref.id)) {\n return existing as T;\n }\n\n const factory =\n this.primaryRegistry?.get(ref) ?? this.secondaryRegistry?.get(ref);\n if (!factory) {\n return this.fallbackApis?.get(ref);\n }\n\n if (loading.includes(factory.api)) {\n throw new Error(`Circular dependency of api factory for ${factory.api}`);\n }\n\n const deps = {} as { [name: string]: unknown };\n for (const [key, depRef] of Object.entries(factory.deps)) {\n const dep = this.load(depRef, [...loading, factory.api]);\n if (dep === undefined) {\n throw new Error(\n `No API factory available for dependency ${depRef} of dependent ${factory.api}`,\n );\n }\n deps[key] = dep;\n }\n\n const api = factory.factory(deps);\n this.apis.set(ref.id, api);\n return api as T;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { featureFlagsApiRef, ApiBlueprint } from '@backstage/frontend-plugin-api';
2
+ import { instantiateAppNodeSubtree } from '../tree/instantiateAppNodeTree.esm.js';
3
+ import { isInternalFrontendModule, toInternalFrontendModule } from '../frontend-plugin-api/src/wiring/createFrontendModule.esm.js';
4
+ import { OpaqueFrontendPlugin } from '../frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
5
+
6
+ function registerFeatureFlagDeclarationsInHolder(apis, features) {
7
+ const featureFlagApi = apis.get(featureFlagsApiRef);
8
+ if (featureFlagApi) {
9
+ registerFeatureFlagDeclarations(featureFlagApi, features);
10
+ }
11
+ }
12
+ function wrapFeatureFlagApiFactory(factory, features) {
13
+ if (factory.api.id !== featureFlagsApiRef.id) {
14
+ return factory;
15
+ }
16
+ return {
17
+ ...factory,
18
+ factory(deps) {
19
+ const featureFlagApi = factory.factory(
20
+ deps
21
+ );
22
+ registerFeatureFlagDeclarations(featureFlagApi, features);
23
+ return featureFlagApi;
24
+ }
25
+ };
26
+ }
27
+ function syncFinalApiFactories(options) {
28
+ const finalApiEntries = collectApiFactoryEntries({
29
+ apiNodes: options.deferredApiNodes,
30
+ collector: options.collector,
31
+ predicateContext: options.predicateContext,
32
+ entries: new Map(options.bootstrapApiFactoryEntries)
33
+ });
34
+ const changedEntries = Array.from(finalApiEntries.values()).filter((entry) => {
35
+ const bootstrapEntry = options.bootstrapApiFactoryEntries.get(
36
+ entry.factory.api.id
37
+ );
38
+ if (!bootstrapEntry) {
39
+ return true;
40
+ }
41
+ if (bootstrapEntry.factory === entry.factory) {
42
+ return false;
43
+ }
44
+ if (options.apiResolver.isMaterialized(entry.factory.api.id)) {
45
+ options.collector.report({
46
+ code: "EXTENSION_BOOTSTRAP_API_OVERRIDE_IGNORED",
47
+ message: `Extension '${entry.node.spec.id}' tried to override API '${entry.factory.api.id}' after it had already been materialized during bootstrap. The bootstrap implementation was kept and the deferred override was ignored.`,
48
+ context: {
49
+ node: entry.node,
50
+ apiRefId: entry.factory.api.id,
51
+ bootstrapNode: bootstrapEntry.node,
52
+ pluginId: entry.pluginId,
53
+ bootstrapPluginId: bootstrapEntry.pluginId
54
+ }
55
+ });
56
+ return false;
57
+ }
58
+ return true;
59
+ });
60
+ const changedFactories = changedEntries.map(
61
+ (entry) => wrapFeatureFlagApiFactory(entry.factory, options.features)
62
+ );
63
+ options.appApiRegistry.setAll(changedFactories);
64
+ options.apiResolver.invalidate(
65
+ changedFactories.map((factory) => factory.api.id)
66
+ );
67
+ for (const bootstrapAccess of options.bootstrapMissingApiAccesses.values()) {
68
+ if (options.bootstrapApiFactoryEntries.has(bootstrapAccess.apiRefId) || !finalApiEntries.has(bootstrapAccess.apiRefId)) {
69
+ continue;
70
+ }
71
+ options.collector.report({
72
+ code: "EXTENSION_BOOTSTRAP_API_UNAVAILABLE",
73
+ message: `Extension '${bootstrapAccess.node.spec.id}' tried to access API '${bootstrapAccess.apiRefId}' during bootstrap before it was available. That API became available during finalization, so bootstrap-visible extensions must not depend on deferred APIs.`,
74
+ context: {
75
+ node: bootstrapAccess.node,
76
+ apiRefId: bootstrapAccess.apiRefId
77
+ }
78
+ });
79
+ }
80
+ }
81
+ const EMPTY_API_HOLDER = {
82
+ get() {
83
+ return void 0;
84
+ }
85
+ };
86
+ function registerFeatureFlagDeclarations(featureFlagApi, features) {
87
+ for (const feature of features) {
88
+ if (OpaqueFrontendPlugin.isType(feature)) {
89
+ OpaqueFrontendPlugin.toInternal(feature).featureFlags.forEach(
90
+ (flag) => featureFlagApi.registerFlag({
91
+ name: flag.name,
92
+ description: flag.description,
93
+ pluginId: feature.id
94
+ })
95
+ );
96
+ }
97
+ if (isInternalFrontendModule(feature)) {
98
+ toInternalFrontendModule(feature).featureFlags.forEach(
99
+ (flag) => featureFlagApi.registerFlag({
100
+ name: flag.name,
101
+ description: flag.description,
102
+ pluginId: feature.pluginId
103
+ })
104
+ );
105
+ }
106
+ }
107
+ }
108
+ function collectApiFactoryEntries(options) {
109
+ const factoriesById = options.entries ?? /* @__PURE__ */ new Map();
110
+ for (const apiNode of options.apiNodes) {
111
+ const detachedApiNode = instantiateAppNodeSubtree({
112
+ rootNode: apiNode,
113
+ apis: EMPTY_API_HOLDER,
114
+ collector: options.collector,
115
+ predicateContext: options.predicateContext,
116
+ writeNodeInstances: false,
117
+ reuseExistingInstances: false
118
+ });
119
+ if (!detachedApiNode) {
120
+ continue;
121
+ }
122
+ const apiFactory = detachedApiNode.instance?.getData(
123
+ ApiBlueprint.dataRefs.factory
124
+ );
125
+ if (apiFactory) {
126
+ const apiRefId = apiFactory.api.id;
127
+ const ownerId = getApiOwnerId(apiRefId);
128
+ const pluginId = apiNode.spec.plugin.pluginId ?? "app";
129
+ const existingFactory = factoriesById.get(apiRefId);
130
+ if (existingFactory && existingFactory.pluginId !== pluginId) {
131
+ const shouldReplace = ownerId === pluginId && existingFactory.pluginId !== ownerId;
132
+ const acceptedPluginId = shouldReplace ? pluginId : existingFactory.pluginId;
133
+ const rejectedPluginId = shouldReplace ? existingFactory.pluginId : pluginId;
134
+ options.collector.report({
135
+ code: "API_FACTORY_CONFLICT",
136
+ message: `API '${apiRefId}' is already provided by plugin '${acceptedPluginId}', cannot also be provided by '${rejectedPluginId}'.`,
137
+ context: {
138
+ node: apiNode,
139
+ apiRefId,
140
+ pluginId: rejectedPluginId,
141
+ existingPluginId: acceptedPluginId
142
+ }
143
+ });
144
+ if (shouldReplace) {
145
+ factoriesById.set(apiRefId, {
146
+ pluginId,
147
+ node: apiNode,
148
+ factory: apiFactory
149
+ });
150
+ }
151
+ continue;
152
+ }
153
+ factoriesById.set(apiRefId, {
154
+ pluginId,
155
+ node: apiNode,
156
+ factory: apiFactory
157
+ });
158
+ } else {
159
+ options.collector.report({
160
+ code: "API_EXTENSION_INVALID",
161
+ message: `API extension '${apiNode.spec.id}' did not output an API factory`,
162
+ context: {
163
+ node: apiNode
164
+ }
165
+ });
166
+ }
167
+ }
168
+ return factoriesById;
169
+ }
170
+ function getApiOwnerId(apiRefId) {
171
+ const [prefix, ...rest] = apiRefId.split(".");
172
+ if (!prefix) {
173
+ return apiRefId;
174
+ }
175
+ if (prefix === "core") {
176
+ return "app";
177
+ }
178
+ if (prefix === "plugin" && rest[0]) {
179
+ return rest[0];
180
+ }
181
+ return prefix;
182
+ }
183
+
184
+ export { collectApiFactoryEntries, registerFeatureFlagDeclarationsInHolder, syncFinalApiFactories, wrapFeatureFlagApiFactory };
185
+ //# sourceMappingURL=apiFactories.esm.js.map