@backstage/plugin-app 0.3.4-next.1 → 0.4.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @backstage/plugin-app
2
2
 
3
+ ## 0.4.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7edb810: **BREAKING**: Extensions created with the following blueprints must now be provided via an override or a module for the `app` plugin. Extensions from other plugins will now trigger a warning in the app and be ignored.
8
+
9
+ - `IconBundleBlueprint`
10
+ - `NavContentBlueprint`
11
+ - `RouterBlueprint`
12
+ - `SignInPageBlueprint`
13
+ - `SwappableComponentBlueprint`
14
+ - `ThemeBlueprint`
15
+ - `TranslationBlueprint`
16
+
17
+ ### Patch Changes
18
+
19
+ - 69d880e: Bump to latest zod to ensure it has the latest features
20
+ - Updated dependencies
21
+ - @backstage/core-components@0.18.6-next.0
22
+ - @backstage/frontend-plugin-api@0.14.0-next.0
23
+ - @backstage/core-plugin-api@1.12.2-next.0
24
+ - @backstage/plugin-app-react@0.1.1-next.0
25
+ - @backstage/integration-react@1.2.15-next.0
26
+ - @backstage/theme@0.7.1
27
+ - @backstage/types@1.2.2
28
+ - @backstage/version-bridge@1.0.11
29
+ - @backstage/plugin-permission-react@0.4.40-next.0
30
+
31
+ ## 0.3.4
32
+
33
+ ### Patch Changes
34
+
35
+ - 4554a4e: Implemented support for the new `PluginWrapperBlueprint` from `@backstage/frontend-plugin-api/alpha`.
36
+ - 9ccf84e: The following blueprints are being restricted to only be used in app plugin overrides and modules. They will now produce a deprecation warning when used outside of the app plugin:
37
+
38
+ - `AppRootWrapperBlueprint`
39
+ - `IconBundleBlueprint`
40
+ - `NavContentBlueprint`
41
+ - `RouterBlueprint`
42
+ - `SignInPageBlueprint`
43
+ - `SwappableComponentBlueprint`
44
+ - `ThemeBlueprint`
45
+ - `TranslationBlueprint`
46
+
47
+ - Updated dependencies
48
+ - @backstage/frontend-plugin-api@0.13.3
49
+ - @backstage/plugin-app-react@0.1.0
50
+ - @backstage/core-components@0.18.5
51
+ - @backstage/integration-react@1.2.14
52
+
3
53
  ## 0.3.4-next.1
4
54
 
5
55
  ### Patch Changes
@@ -0,0 +1,55 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect, useMemo } from 'react';
3
+
4
+ class DefaultPluginWrapperApi {
5
+ constructor(pluginWrappers) {
6
+ this.pluginWrappers = pluginWrappers;
7
+ }
8
+ getPluginWrapper(pluginId) {
9
+ return this.pluginWrappers.get(pluginId);
10
+ }
11
+ static fromWrappers(wrappers) {
12
+ const loadersByPlugin = /* @__PURE__ */ new Map();
13
+ for (const wrapper of wrappers) {
14
+ let loaders = loadersByPlugin.get(wrapper.pluginId);
15
+ if (!loaders) {
16
+ loaders = [];
17
+ loadersByPlugin.set(wrapper.pluginId, loaders);
18
+ }
19
+ loaders.push(wrapper.loader);
20
+ }
21
+ const composedWrappers = /* @__PURE__ */ new Map();
22
+ for (const [pluginId, loaders] of loadersByPlugin) {
23
+ if (loaders.length === 0) {
24
+ continue;
25
+ }
26
+ const ComposedWrapper = (props) => {
27
+ const [loadedWrappers, setLoadedWrappers] = useState(void 0);
28
+ const [error, setError] = useState(void 0);
29
+ useEffect(() => {
30
+ Promise.all(loaders.map((loader) => loader())).then((results) => {
31
+ setLoadedWrappers(results.map((r) => r.component));
32
+ }).catch(setError);
33
+ }, []);
34
+ if (error) {
35
+ throw error;
36
+ }
37
+ return useMemo(() => {
38
+ if (!loadedWrappers) {
39
+ return null;
40
+ }
41
+ let current = props.children;
42
+ for (const Wrapper of loadedWrappers) {
43
+ current = /* @__PURE__ */ jsx(Wrapper, { children: current });
44
+ }
45
+ return current;
46
+ }, [loadedWrappers, props.children]);
47
+ };
48
+ composedWrappers.set(pluginId, ComposedWrapper);
49
+ }
50
+ return new DefaultPluginWrapperApi(composedWrappers);
51
+ }
52
+ }
53
+
54
+ export { DefaultPluginWrapperApi };
55
+ //# sourceMappingURL=DefaultPluginWrapperApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultPluginWrapperApi.esm.js","sources":["../../../src/apis/PluginWrapperApi/DefaultPluginWrapperApi.tsx"],"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 { PluginWrapperApi } from '@backstage/frontend-plugin-api/alpha';\nimport { ComponentType, ReactNode, useEffect, useMemo, useState } from 'react';\n\ntype WrapperInput = {\n loader: () => Promise<{ component: ComponentType<{ children: ReactNode }> }>;\n pluginId: string;\n};\n\n/**\n * Default implementation of PluginWrapperApi.\n *\n * @internal\n */\nexport class DefaultPluginWrapperApi implements PluginWrapperApi {\n constructor(\n private readonly pluginWrappers: Map<\n string,\n ComponentType<{ children: ReactNode }>\n >,\n ) {}\n\n getPluginWrapper(\n pluginId: string,\n ): ComponentType<{ children: ReactNode }> | undefined {\n return this.pluginWrappers.get(pluginId);\n }\n\n static fromWrappers(wrappers: Array<WrapperInput>): DefaultPluginWrapperApi {\n const loadersByPlugin = new Map<\n string,\n Array<\n () => Promise<{ component: ComponentType<{ children: ReactNode }> }>\n >\n >();\n\n for (const wrapper of wrappers) {\n let loaders = loadersByPlugin.get(wrapper.pluginId);\n if (!loaders) {\n loaders = [];\n loadersByPlugin.set(wrapper.pluginId, loaders);\n }\n loaders.push(wrapper.loader);\n }\n\n const composedWrappers = new Map<\n string,\n ComponentType<{ children: ReactNode }>\n >();\n\n for (const [pluginId, loaders] of loadersByPlugin) {\n if (loaders.length === 0) {\n continue;\n }\n\n const ComposedWrapper = (props: { children: ReactNode }) => {\n const [loadedWrappers, setLoadedWrappers] = useState<\n Array<ComponentType<{ children: ReactNode }>> | undefined\n >(undefined);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n Promise.all(loaders.map(loader => loader()))\n .then(results => {\n setLoadedWrappers(results.map(r => r.component));\n })\n .catch(setError);\n }, []);\n\n if (error) {\n throw error;\n }\n\n return useMemo(() => {\n if (!loadedWrappers) {\n return null;\n }\n\n let current = props.children;\n\n for (const Wrapper of loadedWrappers) {\n current = <Wrapper>{current}</Wrapper>;\n }\n\n return current;\n }, [loadedWrappers, props.children]);\n };\n\n composedWrappers.set(pluginId, ComposedWrapper);\n }\n\n return new DefaultPluginWrapperApi(composedWrappers);\n }\n}\n"],"names":[],"mappings":";;;AA6BO,MAAM,uBAAA,CAAoD;AAAA,EAC/D,YACmB,cAAA,EAIjB;AAJiB,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAAA,EAIhB;AAAA,EAEH,iBACE,QAAA,EACoD;AACpD,IAAA,OAAO,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,QAAQ,CAAA;AAAA,EACzC;AAAA,EAEA,OAAO,aAAa,QAAA,EAAwD;AAC1E,IAAA,MAAM,eAAA,uBAAsB,GAAA,EAK1B;AAEF,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,IAAI,OAAA,GAAU,eAAA,CAAgB,GAAA,CAAI,OAAA,CAAQ,QAAQ,CAAA;AAClD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAA,GAAU,EAAC;AACX,QAAA,eAAA,CAAgB,GAAA,CAAI,OAAA,CAAQ,QAAA,EAAU,OAAO,CAAA;AAAA,MAC/C;AACA,MAAA,OAAA,CAAQ,IAAA,CAAK,QAAQ,MAAM,CAAA;AAAA,IAC7B;AAEA,IAAA,MAAM,gBAAA,uBAAuB,GAAA,EAG3B;AAEF,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,OAAO,CAAA,IAAK,eAAA,EAAiB;AACjD,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAAmC;AAC1D,QAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAE1C,MAAS,CAAA;AACX,QAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAA4B,MAAS,CAAA;AAE/D,QAAA,SAAA,CAAU,MAAM;AACd,UAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,GAAA,CAAI,CAAA,MAAA,KAAU,QAAQ,CAAC,CAAA,CACxC,IAAA,CAAK,CAAA,OAAA,KAAW;AACf,YAAA,iBAAA,CAAkB,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,CAAC,CAAA;AAAA,UACjD,CAAC,CAAA,CACA,KAAA,CAAM,QAAQ,CAAA;AAAA,QACnB,CAAA,EAAG,EAAE,CAAA;AAEL,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,MAAM,KAAA;AAAA,QACR;AAEA,QAAA,OAAO,QAAQ,MAAM;AACnB,UAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,YAAA,OAAO,IAAA;AAAA,UACT;AAEA,UAAA,IAAI,UAAU,KAAA,CAAM,QAAA;AAEpB,UAAA,KAAA,MAAW,WAAW,cAAA,EAAgB;AACpC,YAAA,OAAA,mBAAU,GAAA,CAAC,WAAS,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,UAC9B;AAEA,UAAA,OAAO,OAAA;AAAA,QACT,CAAA,EAAG,CAAC,cAAA,EAAgB,KAAA,CAAM,QAAQ,CAAC,CAAA;AAAA,MACrC,CAAA;AAEA,MAAA,gBAAA,CAAiB,GAAA,CAAI,UAAU,eAAe,CAAA;AAAA,IAChD;AAEA,IAAA,OAAO,IAAI,wBAAwB,gBAAgB,CAAA;AAAA,EACrD;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSwappableComponentsApi.esm.js","sources":["../../../src/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.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 {\n SwappableComponentRef,\n SwappableComponentsApi,\n SwappableComponentBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { OpaqueSwappableComponentRef } from '@internal/frontend';\n\nimport { lazy } from 'react';\n\n/**\n * Implementation for the {@link SwappableComponentsApi}\n *\n * @internal\n */\nexport class DefaultSwappableComponentsApi implements SwappableComponentsApi {\n #components: Map<string, ((props: object) => JSX.Element | null) | undefined>;\n\n static fromComponents(\n components: Array<typeof SwappableComponentBlueprint.dataRefs.component.T>,\n ) {\n return new DefaultSwappableComponentsApi(\n new Map(\n components.map(entry => {\n return [\n entry.ref.id,\n entry.loader\n ? lazy(async () => ({\n default: await entry.loader!(),\n }))\n : undefined,\n ];\n }),\n ),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent(\n ref: SwappableComponentRef<any>,\n ): (props: object) => JSX.Element | null {\n const OverrideComponent = this.#components.get(ref.id);\n const { defaultComponent: DefaultComponent, transformProps } =\n OpaqueSwappableComponentRef.toInternal(ref);\n\n return (props: object) => {\n const innerProps = transformProps?.(props) ?? props;\n\n if (OverrideComponent) {\n return <OverrideComponent {...innerProps} />;\n }\n\n return <DefaultComponent {...innerProps} />;\n };\n }\n}\n"],"names":[],"mappings":";;;;;;;AA8BO,MAAM,6BAAA,CAAgE;AAAA,EAC3E,WAAA;AAAA,EAEA,OAAO,eACL,UAAA,EACA;AACA,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAI,GAAA;AAAA,QACF,UAAA,CAAW,IAAI,CAAA,KAAA,KAAS;AACtB,UAAA,OAAO;AAAA,YACL,MAAM,GAAA,CAAI,EAAA;AAAA,YACV,KAAA,CAAM,MAAA,GACF,IAAA,CAAK,aAAa;AAAA,cAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA;AAAQ,cAC7B,CAAA,GACF;AAAA,WACN;AAAA,QACF,CAAC;AAAA;AACH,KACF;AAAA,EACF;AAAA,EAEA,YAAY,UAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AAAA,EACrB;AAAA,EAEA,aACE,GAAA,EACuC;AACvC,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,EAAE,CAAA;AACrD,IAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAA,EAAkB,gBAAe,GACzD,2BAAA,CAA4B,WAAW,GAAG,CAAA;AAE5C,IAAA,OAAO,CAAC,KAAA,KAAkB;AACxB,MAAA,MAAM,UAAA,GAAa,cAAA,GAAiB,KAAK,CAAA,IAAK,KAAA;AAE9C,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAmB,GAAG,UAAA,EAAY,CAAA;AAAA,MAC5C;AAEA,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,UAAA,EAAY,CAAA;AAAA,IAC3C,CAAA;AAAA,EACF;AACF;;;;"}
1
+ {"version":3,"file":"DefaultSwappableComponentsApi.esm.js","sources":["../../../src/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.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 {\n SwappableComponentRef,\n SwappableComponentsApi,\n} from '@backstage/frontend-plugin-api';\nimport { SwappableComponentBlueprint } from '@backstage/plugin-app-react';\nimport { OpaqueSwappableComponentRef } from '@internal/frontend';\n\nimport { lazy } from 'react';\n\n/**\n * Implementation for the {@link SwappableComponentsApi}\n *\n * @internal\n */\nexport class DefaultSwappableComponentsApi implements SwappableComponentsApi {\n #components: Map<string, ((props: object) => JSX.Element | null) | undefined>;\n\n static fromComponents(\n components: Array<typeof SwappableComponentBlueprint.dataRefs.component.T>,\n ) {\n return new DefaultSwappableComponentsApi(\n new Map(\n components.map(entry => {\n return [\n entry.ref.id,\n entry.loader\n ? lazy(async () => ({\n default: await entry.loader!(),\n }))\n : undefined,\n ];\n }),\n ),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent(\n ref: SwappableComponentRef<any>,\n ): (props: object) => JSX.Element | null {\n const OverrideComponent = this.#components.get(ref.id);\n const { defaultComponent: DefaultComponent, transformProps } =\n OpaqueSwappableComponentRef.toInternal(ref);\n\n return (props: object) => {\n const innerProps = transformProps?.(props) ?? props;\n\n if (OverrideComponent) {\n return <OverrideComponent {...innerProps} />;\n }\n\n return <DefaultComponent {...innerProps} />;\n };\n }\n}\n"],"names":[],"mappings":";;;;;;;AA8BO,MAAM,6BAAA,CAAgE;AAAA,EAC3E,WAAA;AAAA,EAEA,OAAO,eACL,UAAA,EACA;AACA,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAI,GAAA;AAAA,QACF,UAAA,CAAW,IAAI,CAAA,KAAA,KAAS;AACtB,UAAA,OAAO;AAAA,YACL,MAAM,GAAA,CAAI,EAAA;AAAA,YACV,KAAA,CAAM,MAAA,GACF,IAAA,CAAK,aAAa;AAAA,cAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA;AAAQ,cAC7B,CAAA,GACF;AAAA,WACN;AAAA,QACF,CAAC;AAAA;AACH,KACF;AAAA,EACF;AAAA,EAEA,YAAY,UAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AAAA,EACrB;AAAA,EAEA,aACE,GAAA,EACuC;AACvC,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,EAAE,CAAA;AACrD,IAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAA,EAAkB,gBAAe,GACzD,2BAAA,CAA4B,WAAW,GAAG,CAAA;AAE5C,IAAA,OAAO,CAAC,KAAA,KAAkB;AACxB,MAAA,MAAM,UAAA,GAAa,cAAA,GAAiB,KAAK,CAAA,IAAK,KAAA;AAE9C,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAmB,GAAG,UAAA,EAAY,CAAA;AAAA,MAC5C;AAEA,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,UAAA,EAAY,CAAA;AAAA,IAC3C,CAAA;AAAA,EACF;AACF;;;;"}
@@ -1,5 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createExtension, coreExtensionData, createExtensionInput, NavContentBlueprint, NavItemBlueprint, useApi, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
2
+ import { createExtension, coreExtensionData, createExtensionInput, NavItemBlueprint, useApi, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
3
+ import { NavContentBlueprint } from '@backstage/plugin-app-react';
3
4
  import { Sidebar, SidebarItem } from '@backstage/core-components';
4
5
  import { useMemo } from 'react';
5
6
 
@@ -45,7 +46,8 @@ const AppNav = createExtension({
45
46
  items: createExtensionInput([NavItemBlueprint.dataRefs.target]),
46
47
  content: createExtensionInput([NavContentBlueprint.dataRefs.component], {
47
48
  singleton: true,
48
- optional: true
49
+ optional: true,
50
+ internal: true
49
51
  })
50
52
  },
51
53
  output: [coreExtensionData.reactElement],
@@ -1 +1 @@
1
- {"version":3,"file":"AppNav.esm.js","sources":["../../src/extensions/AppNav.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 {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n NavItemBlueprint,\n NavContentBlueprint,\n NavContentComponentProps,\n routeResolutionApiRef,\n IconComponent,\n RouteRef,\n useApi,\n NavContentComponent,\n} from '@backstage/frontend-plugin-api';\nimport { Sidebar, SidebarItem } from '@backstage/core-components';\nimport { useMemo } from 'react';\n\nfunction DefaultNavContent(props: NavContentComponentProps) {\n return (\n <Sidebar>\n {props.items.map((item, index) => (\n <SidebarItem\n to={item.to}\n icon={item.icon}\n text={item.text}\n key={index}\n />\n ))}\n </Sidebar>\n );\n}\n\n// This helps defer rendering until the app is being rendered, which is needed\n// because the RouteResolutionApi can't be called until the app has been fully initialized.\nfunction NavContentRenderer(props: {\n Content: NavContentComponent;\n items: Array<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n }>;\n}) {\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const items = useMemo(() => {\n return props.items.flatMap(item => {\n const link = routeResolutionApi.resolve(item.routeRef);\n if (!link) {\n // eslint-disable-next-line no-console\n console.warn(\n `NavItemBlueprint: unable to resolve route ref ${item.routeRef}`,\n );\n return [];\n }\n return [\n {\n to: link(),\n text: item.title,\n icon: item.icon,\n title: item.title,\n routeRef: item.routeRef,\n },\n ];\n });\n }, [props.items, routeResolutionApi]);\n\n return <props.Content items={items} />;\n}\n\nexport const AppNav = createExtension({\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput([NavItemBlueprint.dataRefs.target]),\n content: createExtensionInput([NavContentBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n *factory({ inputs }) {\n const Content =\n inputs.content?.get(NavContentBlueprint.dataRefs.component) ??\n DefaultNavContent;\n\n yield coreExtensionData.reactElement(\n <NavContentRenderer\n items={inputs.items.map(item =>\n item.get(NavItemBlueprint.dataRefs.target),\n )}\n Content={Content}\n />,\n );\n },\n});\n"],"names":[],"mappings":";;;;;AAgCA,SAAS,kBAAkB,KAAA,EAAiC;AAC1D,EAAA,2BACG,OAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,MAAM,GAAA,CAAI,CAAC,MAAM,KAAA,qBACtB,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK;AAAA,KAAA;AAAA,IACN;AAAA,GAER,CAAA,EACH,CAAA;AAEJ;AAIA,SAAS,mBAAmB,KAAA,EAOzB;AACD,EAAA,MAAM,kBAAA,GAAqB,OAAO,qBAAqB,CAAA;AAEvD,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM;AAC1B,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,CAAA,IAAA,KAAQ;AACjC,MAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA;AACrD,MAAA,IAAI,CAAC,IAAA,EAAM;AAET,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,8CAAA,EAAiD,KAAK,QAAQ,CAAA;AAAA,SAChE;AACA,QAAA,OAAO,EAAC;AAAA,MACV;AACA,MAAA,OAAO;AAAA,QACL;AAAA,UACE,IAAI,IAAA,EAAK;AAAA,UACT,MAAM,IAAA,CAAK,KAAA;AAAA,UACX,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,UAAU,IAAA,CAAK;AAAA;AACjB,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,KAAA,CAAM,KAAA,EAAO,kBAAkB,CAAC,CAAA;AAEpC,EAAA,uBAAO,GAAA,CAAC,KAAA,CAAM,OAAA,EAAN,EAAc,KAAA,EAAc,CAAA;AACtC;AAEO,MAAM,SAAS,eAAA,CAAgB;AAAA,EACpC,IAAA,EAAM,KAAA;AAAA,EACN,QAAA,EAAU,EAAE,EAAA,EAAI,YAAA,EAAc,OAAO,KAAA,EAAM;AAAA,EAC3C,MAAA,EAAQ;AAAA,IACN,OAAO,oBAAA,CAAqB,CAAC,gBAAA,CAAiB,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IAC9D,SAAS,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,EAAG;AAAA,MACtE,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,CAAC,OAAA,CAAQ,EAAE,MAAA,EAAO,EAAG;AACnB,IAAA,MAAM,UACJ,MAAA,CAAO,OAAA,EAAS,IAAI,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,IAC1D,iBAAA;AAEF,IAAA,MAAM,iBAAA,CAAkB,YAAA;AAAA,sBACtB,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,OAAO,KAAA,CAAM,GAAA;AAAA,YAAI,CAAA,IAAA,KACtB,IAAA,CAAK,GAAA,CAAI,gBAAA,CAAiB,SAAS,MAAM;AAAA,WAC3C;AAAA,UACA;AAAA;AAAA;AACF,KACF;AAAA,EACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"AppNav.esm.js","sources":["../../src/extensions/AppNav.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 {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n NavItemBlueprint,\n routeResolutionApiRef,\n IconComponent,\n RouteRef,\n useApi,\n} from '@backstage/frontend-plugin-api';\nimport {\n NavContentBlueprint,\n NavContentComponent,\n NavContentComponentProps,\n} from '@backstage/plugin-app-react';\nimport { Sidebar, SidebarItem } from '@backstage/core-components';\nimport { useMemo } from 'react';\n\nfunction DefaultNavContent(props: NavContentComponentProps) {\n return (\n <Sidebar>\n {props.items.map((item, index) => (\n <SidebarItem\n to={item.to}\n icon={item.icon}\n text={item.text}\n key={index}\n />\n ))}\n </Sidebar>\n );\n}\n\n// This helps defer rendering until the app is being rendered, which is needed\n// because the RouteResolutionApi can't be called until the app has been fully initialized.\nfunction NavContentRenderer(props: {\n Content: NavContentComponent;\n items: Array<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n }>;\n}) {\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const items = useMemo(() => {\n return props.items.flatMap(item => {\n const link = routeResolutionApi.resolve(item.routeRef);\n if (!link) {\n // eslint-disable-next-line no-console\n console.warn(\n `NavItemBlueprint: unable to resolve route ref ${item.routeRef}`,\n );\n return [];\n }\n return [\n {\n to: link(),\n text: item.title,\n icon: item.icon,\n title: item.title,\n routeRef: item.routeRef,\n },\n ];\n });\n }, [props.items, routeResolutionApi]);\n\n return <props.Content items={items} />;\n}\n\nexport const AppNav = createExtension({\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput([NavItemBlueprint.dataRefs.target]),\n content: createExtensionInput([NavContentBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n *factory({ inputs }) {\n const Content =\n inputs.content?.get(NavContentBlueprint.dataRefs.component) ??\n DefaultNavContent;\n\n yield coreExtensionData.reactElement(\n <NavContentRenderer\n items={inputs.items.map(item =>\n item.get(NavItemBlueprint.dataRefs.target),\n )}\n Content={Content}\n />,\n );\n },\n});\n"],"names":[],"mappings":";;;;;;AAkCA,SAAS,kBAAkB,KAAA,EAAiC;AAC1D,EAAA,2BACG,OAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,MAAM,GAAA,CAAI,CAAC,MAAM,KAAA,qBACtB,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK;AAAA,KAAA;AAAA,IACN;AAAA,GAER,CAAA,EACH,CAAA;AAEJ;AAIA,SAAS,mBAAmB,KAAA,EAOzB;AACD,EAAA,MAAM,kBAAA,GAAqB,OAAO,qBAAqB,CAAA;AAEvD,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM;AAC1B,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,CAAA,IAAA,KAAQ;AACjC,MAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA;AACrD,MAAA,IAAI,CAAC,IAAA,EAAM;AAET,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,8CAAA,EAAiD,KAAK,QAAQ,CAAA;AAAA,SAChE;AACA,QAAA,OAAO,EAAC;AAAA,MACV;AACA,MAAA,OAAO;AAAA,QACL;AAAA,UACE,IAAI,IAAA,EAAK;AAAA,UACT,MAAM,IAAA,CAAK,KAAA;AAAA,UACX,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,UAAU,IAAA,CAAK;AAAA;AACjB,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,CAAC,KAAA,CAAM,KAAA,EAAO,kBAAkB,CAAC,CAAA;AAEpC,EAAA,uBAAO,GAAA,CAAC,KAAA,CAAM,OAAA,EAAN,EAAc,KAAA,EAAc,CAAA;AACtC;AAEO,MAAM,SAAS,eAAA,CAAgB;AAAA,EACpC,IAAA,EAAM,KAAA;AAAA,EACN,QAAA,EAAU,EAAE,EAAA,EAAI,YAAA,EAAc,OAAO,KAAA,EAAM;AAAA,EAC3C,MAAA,EAAQ;AAAA,IACN,OAAO,oBAAA,CAAqB,CAAC,gBAAA,CAAiB,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,IAC9D,SAAS,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,EAAG;AAAA,MACtE,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,IAAA;AAAA,MACV,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,CAAC,OAAA,CAAQ,EAAE,MAAA,EAAO,EAAG;AACnB,IAAA,MAAM,UACJ,MAAA,CAAO,OAAA,EAAS,IAAI,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,IAC1D,iBAAA;AAEF,IAAA,MAAM,iBAAA,CAAkB,YAAA;AAAA,sBACtB,GAAA;AAAA,QAAC,kBAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,OAAO,KAAA,CAAM,GAAA;AAAA,YAAI,CAAA,IAAA,KACtB,IAAA,CAAK,GAAA,CAAI,gBAAA,CAAiB,SAAS,MAAM;AAAA,WAC3C;AAAA,UACA;AAAA;AAAA;AACF,KACF;AAAA,EACF;AACF,CAAC;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useState } from 'react';
3
- import { createExtension, coreExtensionData, createExtensionInput, discoveryApiRef, errorApiRef, fetchApiRef, AppRootWrapperBlueprint, RouterBlueprint, SignInPageBlueprint, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
3
+ import { createExtension, coreExtensionData, createExtensionInput, discoveryApiRef, errorApiRef, fetchApiRef, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
4
+ import { AppRootWrapperBlueprint, RouterBlueprint, SignInPageBlueprint } from '@backstage/plugin-app-react';
4
5
  import { identityApiRef, useApi, configApiRef } from '@backstage/core-plugin-api';
5
6
  import { isProtectedApp } from '../packages/core-app-api/src/app/isProtectedApp.esm.js';
6
7
  import { BrowserRouter } from 'react-router-dom';
@@ -13,19 +14,24 @@ const AppRoot = createExtension({
13
14
  inputs: {
14
15
  router: createExtensionInput([RouterBlueprint.dataRefs.component], {
15
16
  singleton: true,
16
- optional: true
17
+ optional: true,
18
+ internal: true
17
19
  }),
18
20
  signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {
19
21
  singleton: true,
20
- optional: true
22
+ optional: true,
23
+ internal: true
21
24
  }),
22
25
  children: createExtensionInput([coreExtensionData.reactElement], {
23
26
  singleton: true
24
27
  }),
25
28
  elements: createExtensionInput([coreExtensionData.reactElement]),
26
- wrappers: createExtensionInput([
27
- AppRootWrapperBlueprint.dataRefs.component
28
- ])
29
+ wrappers: createExtensionInput(
30
+ [AppRootWrapperBlueprint.dataRefs.component],
31
+ {
32
+ internal: true
33
+ }
34
+ )
29
35
  },
30
36
  output: [coreExtensionData.reactElement],
31
37
  factory({ inputs, apis }) {
@@ -54,7 +60,9 @@ const AppRoot = createExtension({
54
60
  );
55
61
  for (const wrapper of inputs.wrappers) {
56
62
  const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);
57
- content = /* @__PURE__ */ jsx(Component, { children: content });
63
+ if (Component) {
64
+ content = /* @__PURE__ */ jsx(Component, { children: content });
65
+ }
58
66
  }
59
67
  return [
60
68
  coreExtensionData.reactElement(
@@ -1 +1 @@
1
- {"version":3,"file":"AppRoot.esm.js","sources":["../../src/extensions/AppRoot.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 {\n ComponentType,\n PropsWithChildren,\n ReactNode,\n useState,\n JSX,\n} from 'react';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n DiscoveryApi,\n ErrorApi,\n FetchApi,\n IdentityApi,\n ProfileInfo,\n SignInPageProps,\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { isProtectedApp } from '../../../../packages/core-app-api/src/app/isProtectedApp';\nimport { BrowserRouter } from 'react-router-dom';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteTracker } from '../../../../packages/frontend-app-api/src/routing/RouteTracker';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { getBasePath } from '../../../../packages/frontend-app-api/src/routing/getBasePath';\n\nexport const AppRoot = createExtension({\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput([RouterBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n }),\n children: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n elements: createExtensionInput([coreExtensionData.reactElement]),\n wrappers: createExtensionInput([\n AppRootWrapperBlueprint.dataRefs.component,\n ]),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs, apis }) {\n if (isProtectedApp()) {\n const identityApi = apis.get(identityApiRef);\n if (!identityApi) {\n throw new Error('App requires an Identity API implementation');\n }\n const appIdentityProxy = toAppIdentityProxy(identityApi);\n const discoveryApi = apis.get(discoveryApiRef);\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n if (!discoveryApi || !errorApi || !fetchApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n appIdentityProxy.enableCookieAuth({\n discoveryApi,\n errorApi,\n fetchApi,\n });\n }\n\n let content: ReactNode = inputs.children.get(\n coreExtensionData.reactElement,\n );\n\n for (const wrapper of inputs.wrappers) {\n const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);\n content = <Component>{content}</Component>;\n }\n\n return [\n coreExtensionData.reactElement(\n <AppRouter\n SignInPageComponent={inputs.signInPage?.get(\n SignInPageBlueprint.dataRefs.component,\n )}\n RouterComponent={inputs.router?.get(\n RouterBlueprint.dataRefs.component,\n )}\n extraElements={inputs.elements?.map(el =>\n el.get(coreExtensionData.reactElement),\n )}\n >\n {content}\n </AppRouter>,\n ),\n ];\n },\n});\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\ntype AppIdentityProxy = IdentityApi & {\n enableCookieAuth(ctx: {\n errorApi: ErrorApi;\n fetchApi: FetchApi;\n discoveryApi: DiscoveryApi;\n }): void;\n setTarget(\n impl: IdentityApi & /* backwards compat stuff */ {\n getUserId?(): string;\n getIdToken?(): Promise<string | undefined>;\n getProfile?(): ProfileInfo;\n },\n options: { signOutTargetUrl: string },\n ): void;\n};\n\nfunction toAppIdentityProxy(identityApi: IdentityApi): AppIdentityProxy {\n if (!('enableCookieAuth' in identityApi)) {\n throw new Error('Unexpected Identity API implementation');\n }\n return identityApi as AppIdentityProxy;\n}\n\ntype RouteResolverProxy = {\n getRouteObjects(): any[];\n};\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n SignInPageComponent?: ComponentType<SignInPageProps>;\n RouterComponent?: (props: { children: ReactNode }) => JSX.Element | null;\n extraElements?: Array<JSX.Element>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const {\n children,\n SignInPageComponent,\n RouterComponent = DefaultRouter,\n extraElements = [],\n } = props;\n\n const configApi = useApi(configApiRef);\n const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef));\n const routeResolutionsApi = useApi(routeResolutionApiRef);\n const basePath = getBasePath(configApi);\n\n // TODO: Private access for now, probably replace with path -> node lookup method on the API\n if (!('getRouteObjects' in routeResolutionsApi)) {\n throw new Error('Unexpected route resolution API implementation');\n }\n const routeObjects = (\n routeResolutionsApi as RouteResolverProxy\n ).getRouteObjects();\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n {children}\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {children}\n </SignInPageWrapper>\n </RouterComponent>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppRoot.esm.js","sources":["../../src/extensions/AppRoot.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 {\n ComponentType,\n PropsWithChildren,\n ReactNode,\n useState,\n JSX,\n} from 'react';\nimport {\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n} from '@backstage/plugin-app-react';\nimport {\n DiscoveryApi,\n ErrorApi,\n FetchApi,\n IdentityApi,\n ProfileInfo,\n SignInPageProps,\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { isProtectedApp } from '../../../../packages/core-app-api/src/app/isProtectedApp';\nimport { BrowserRouter } from 'react-router-dom';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteTracker } from '../../../../packages/frontend-app-api/src/routing/RouteTracker';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { getBasePath } from '../../../../packages/frontend-app-api/src/routing/getBasePath';\n\nexport const AppRoot = createExtension({\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput([RouterBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n children: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n elements: createExtensionInput([coreExtensionData.reactElement]),\n wrappers: createExtensionInput(\n [AppRootWrapperBlueprint.dataRefs.component],\n {\n internal: true,\n },\n ),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs, apis }) {\n if (isProtectedApp()) {\n const identityApi = apis.get(identityApiRef);\n if (!identityApi) {\n throw new Error('App requires an Identity API implementation');\n }\n const appIdentityProxy = toAppIdentityProxy(identityApi);\n const discoveryApi = apis.get(discoveryApiRef);\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n if (!discoveryApi || !errorApi || !fetchApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n appIdentityProxy.enableCookieAuth({\n discoveryApi,\n errorApi,\n fetchApi,\n });\n }\n\n let content: ReactNode = inputs.children.get(\n coreExtensionData.reactElement,\n );\n\n for (const wrapper of inputs.wrappers) {\n const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);\n if (Component) {\n content = <Component>{content}</Component>;\n }\n }\n\n return [\n coreExtensionData.reactElement(\n <AppRouter\n SignInPageComponent={inputs.signInPage?.get(\n SignInPageBlueprint.dataRefs.component,\n )}\n RouterComponent={inputs.router?.get(\n RouterBlueprint.dataRefs.component,\n )}\n extraElements={inputs.elements?.map(el =>\n el.get(coreExtensionData.reactElement),\n )}\n >\n {content}\n </AppRouter>,\n ),\n ];\n },\n});\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\ntype AppIdentityProxy = IdentityApi & {\n enableCookieAuth(ctx: {\n errorApi: ErrorApi;\n fetchApi: FetchApi;\n discoveryApi: DiscoveryApi;\n }): void;\n setTarget(\n impl: IdentityApi & /* backwards compat stuff */ {\n getUserId?(): string;\n getIdToken?(): Promise<string | undefined>;\n getProfile?(): ProfileInfo;\n },\n options: { signOutTargetUrl: string },\n ): void;\n};\n\nfunction toAppIdentityProxy(identityApi: IdentityApi): AppIdentityProxy {\n if (!('enableCookieAuth' in identityApi)) {\n throw new Error('Unexpected Identity API implementation');\n }\n return identityApi as AppIdentityProxy;\n}\n\ntype RouteResolverProxy = {\n getRouteObjects(): any[];\n};\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n SignInPageComponent?: ComponentType<SignInPageProps>;\n RouterComponent?: (props: { children: ReactNode }) => JSX.Element | null;\n extraElements?: Array<JSX.Element>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const {\n children,\n SignInPageComponent,\n RouterComponent = DefaultRouter,\n extraElements = [],\n } = props;\n\n const configApi = useApi(configApiRef);\n const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef));\n const routeResolutionsApi = useApi(routeResolutionApiRef);\n const basePath = getBasePath(configApi);\n\n // TODO: Private access for now, probably replace with path -> node lookup method on the API\n if (!('getRouteObjects' in routeResolutionsApi)) {\n throw new Error('Unexpected route resolution API implementation');\n }\n const routeObjects = (\n routeResolutionsApi as RouteResolverProxy\n ).getRouteObjects();\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n {children}\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {children}\n </SignInPageWrapper>\n </RouterComponent>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,8 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { UnifiedThemeProvider, themes } from '@backstage/theme';
3
3
  import DarkIcon from '@material-ui/icons/Brightness2';
4
4
  import LightIcon from '@material-ui/icons/WbSunny';
5
- import { ApiBlueprint, createExtensionInput, appThemeApiRef, ThemeBlueprint } from '@backstage/frontend-plugin-api';
5
+ import { ApiBlueprint, createExtensionInput, appThemeApiRef } from '@backstage/frontend-plugin-api';
6
+ import { ThemeBlueprint } from '@backstage/plugin-app-react';
6
7
  import 'zen-observable';
7
8
  import '@backstage/core-plugin-api';
8
9
  import '../packages/core-app-api/src/apis/implementations/auth/saml/types.esm.js';
@@ -13,7 +14,8 @@ const AppThemeApi = ApiBlueprint.makeWithOverrides({
13
14
  name: "app-theme",
14
15
  inputs: {
15
16
  themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], {
16
- replaces: [{ id: "app", input: "themes" }]
17
+ replaces: [{ id: "app", input: "themes" }],
18
+ internal: true
17
19
  })
18
20
  },
19
21
  factory: (originalFactory, { inputs }) => {
@@ -21,9 +23,11 @@ const AppThemeApi = ApiBlueprint.makeWithOverrides({
21
23
  (defineParams) => defineParams({
22
24
  api: appThemeApiRef,
23
25
  deps: {},
24
- factory: () => AppThemeSelector.createWithStorage(
25
- inputs.themes.map((i) => i.get(ThemeBlueprint.dataRefs.theme))
26
- )
26
+ factory: () => {
27
+ return AppThemeSelector.createWithStorage(
28
+ inputs.themes.map((i) => i.get(ThemeBlueprint.dataRefs.theme))
29
+ );
30
+ }
27
31
  })
28
32
  );
29
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppThemeApi.esm.js","sources":["../../src/extensions/AppThemeApi.tsx"],"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 UnifiedThemeProvider,\n themes as builtinThemes,\n} from '@backstage/theme';\nimport DarkIcon from '@material-ui/icons/Brightness2';\nimport LightIcon from '@material-ui/icons/WbSunny';\nimport {\n createExtensionInput,\n ThemeBlueprint,\n ApiBlueprint,\n appThemeApiRef,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppThemeSelector } from '../../../../packages/core-app-api/src/apis/implementations';\n\n/**\n * Contains the themes installed into the app.\n */\nexport const AppThemeApi = ApiBlueprint.makeWithOverrides({\n name: 'app-theme',\n inputs: {\n themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], {\n replaces: [{ id: 'app', input: 'themes' }],\n }),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: appThemeApiRef,\n deps: {},\n factory: () =>\n AppThemeSelector.createWithStorage(\n inputs.themes.map(i => i.get(ThemeBlueprint.dataRefs.theme)),\n ),\n }),\n );\n },\n});\n\nexport const LightTheme = ThemeBlueprint.make({\n name: 'light',\n params: {\n theme: {\n id: 'light',\n title: 'Light Theme',\n variant: 'light',\n icon: <LightIcon />,\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={builtinThemes.light} children={children} />\n ),\n },\n },\n});\n\nexport const DarkTheme = ThemeBlueprint.make({\n name: 'dark',\n params: {\n theme: {\n id: 'dark',\n title: 'Dark Theme',\n variant: 'dark',\n icon: <DarkIcon />,\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={builtinThemes.dark} children={children} />\n ),\n },\n },\n});\n"],"names":["builtinThemes"],"mappings":";;;;;;;;;;;AAkCO,MAAM,WAAA,GAAc,aAAa,iBAAA,CAAkB;AAAA,EACxD,IAAA,EAAM,WAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,QAAQ,oBAAA,CAAqB,CAAC,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,EAAG;AAAA,MAC5D,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,UAAU;AAAA,KAC1C;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,cAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,OAAA,EAAS,MACP,gBAAA,CAAiB,iBAAA;AAAA,UACf,MAAA,CAAO,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,cAAA,CAAe,QAAA,CAAS,KAAK,CAAC;AAAA;AAC7D,OACH;AAAA,KACH;AAAA,EACF;AACF,CAAC;AAEM,MAAM,UAAA,GAAa,eAAe,IAAA,CAAK;AAAA,EAC5C,IAAA,EAAM,OAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,OAAA;AAAA,MACJ,KAAA,EAAO,aAAA;AAAA,MACP,OAAA,EAAS,OAAA;AAAA,MACT,IAAA,sBAAO,SAAA,EAAA,EAAU,CAAA;AAAA,MACjB,QAAA,EAAU,CAAC,EAAE,QAAA,EAAS,yBACnB,oBAAA,EAAA,EAAqB,KAAA,EAAOA,MAAA,CAAc,KAAA,EAAO,QAAA,EAAoB;AAAA;AAE1E;AAEJ,CAAC;AAEM,MAAM,SAAA,GAAY,eAAe,IAAA,CAAK;AAAA,EAC3C,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,MAAA;AAAA,MACJ,KAAA,EAAO,YAAA;AAAA,MACP,OAAA,EAAS,MAAA;AAAA,MACT,IAAA,sBAAO,QAAA,EAAA,EAAS,CAAA;AAAA,MAChB,QAAA,EAAU,CAAC,EAAE,QAAA,EAAS,yBACnB,oBAAA,EAAA,EAAqB,KAAA,EAAOA,MAAA,CAAc,IAAA,EAAM,QAAA,EAAoB;AAAA;AAEzE;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"AppThemeApi.esm.js","sources":["../../src/extensions/AppThemeApi.tsx"],"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 UnifiedThemeProvider,\n themes as builtinThemes,\n} from '@backstage/theme';\nimport DarkIcon from '@material-ui/icons/Brightness2';\nimport LightIcon from '@material-ui/icons/WbSunny';\nimport {\n createExtensionInput,\n ApiBlueprint,\n appThemeApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { ThemeBlueprint } from '@backstage/plugin-app-react';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppThemeSelector } from '../../../../packages/core-app-api/src/apis/implementations';\n\n/**\n * Contains the themes installed into the app.\n */\nexport const AppThemeApi = ApiBlueprint.makeWithOverrides({\n name: 'app-theme',\n inputs: {\n themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], {\n replaces: [{ id: 'app', input: 'themes' }],\n internal: true,\n }),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: appThemeApiRef,\n deps: {},\n factory: () => {\n return AppThemeSelector.createWithStorage(\n inputs.themes.map(i => i.get(ThemeBlueprint.dataRefs.theme)),\n );\n },\n }),\n );\n },\n});\n\nexport const LightTheme = ThemeBlueprint.make({\n name: 'light',\n params: {\n theme: {\n id: 'light',\n title: 'Light Theme',\n variant: 'light',\n icon: <LightIcon />,\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={builtinThemes.light} children={children} />\n ),\n },\n },\n});\n\nexport const DarkTheme = ThemeBlueprint.make({\n name: 'dark',\n params: {\n theme: {\n id: 'dark',\n title: 'Dark Theme',\n variant: 'dark',\n icon: <DarkIcon />,\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={builtinThemes.dark} children={children} />\n ),\n },\n },\n});\n"],"names":["builtinThemes"],"mappings":";;;;;;;;;;;;AAkCO,MAAM,WAAA,GAAc,aAAa,iBAAA,CAAkB;AAAA,EACxD,IAAA,EAAM,WAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,QAAQ,oBAAA,CAAqB,CAAC,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,EAAG;AAAA,MAC5D,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,UAAU,CAAA;AAAA,MACzC,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,cAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,gBAAA,CAAiB,iBAAA;AAAA,YACtB,MAAA,CAAO,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,cAAA,CAAe,QAAA,CAAS,KAAK,CAAC;AAAA,WAC7D;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;AAEM,MAAM,UAAA,GAAa,eAAe,IAAA,CAAK;AAAA,EAC5C,IAAA,EAAM,OAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,OAAA;AAAA,MACJ,KAAA,EAAO,aAAA;AAAA,MACP,OAAA,EAAS,OAAA;AAAA,MACT,IAAA,sBAAO,SAAA,EAAA,EAAU,CAAA;AAAA,MACjB,QAAA,EAAU,CAAC,EAAE,QAAA,EAAS,yBACnB,oBAAA,EAAA,EAAqB,KAAA,EAAOA,MAAA,CAAc,KAAA,EAAO,QAAA,EAAoB;AAAA;AAE1E;AAEJ,CAAC;AAEM,MAAM,SAAA,GAAY,eAAe,IAAA,CAAK;AAAA,EAC3C,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO;AAAA,MACL,EAAA,EAAI,MAAA;AAAA,MACJ,KAAA,EAAO,YAAA;AAAA,MACP,OAAA,EAAS,MAAA;AAAA,MACT,IAAA,sBAAO,QAAA,EAAA,EAAS,CAAA;AAAA,MAChB,QAAA,EAAU,CAAC,EAAE,QAAA,EAAS,yBACnB,oBAAA,EAAA,EAAqB,KAAA,EAAOA,MAAA,CAAc,IAAA,EAAM,QAAA,EAAoB;AAAA;AAEzE;AAEJ,CAAC;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { SignInPageBlueprint } from '@backstage/frontend-plugin-api';
2
+ import { SignInPageBlueprint } from '@backstage/plugin-app-react';
3
3
  import { SignInPage } from '@backstage/core-components';
4
4
 
5
5
  const DefaultSignInPage = SignInPageBlueprint.make({
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSignInPage.esm.js","sources":["../../src/extensions/DefaultSignInPage.tsx"],"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 */\nimport { SignInPageBlueprint } from '@backstage/frontend-plugin-api';\nimport { SignInPage } from '@backstage/core-components';\n\nexport const DefaultSignInPage = SignInPageBlueprint.make({\n params: {\n loader: async () => props =>\n <SignInPage {...props} providers={['guest']} />,\n },\n});\n"],"names":[],"mappings":";;;;AAkBO,MAAM,iBAAA,GAAoB,oBAAoB,IAAA,CAAK;AAAA,EACxD,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,YAAY,CAAA,KAAA,qBAClB,GAAA,CAAC,UAAA,EAAA,EAAY,GAAG,KAAA,EAAO,SAAA,EAAW,CAAC,OAAO,CAAA,EAAG;AAAA;AAEnD,CAAC;;;;"}
1
+ {"version":3,"file":"DefaultSignInPage.esm.js","sources":["../../src/extensions/DefaultSignInPage.tsx"],"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 */\nimport { SignInPageBlueprint } from '@backstage/plugin-app-react';\nimport { SignInPage } from '@backstage/core-components';\n\nexport const DefaultSignInPage = SignInPageBlueprint.make({\n params: {\n loader: async () => props =>\n <SignInPage {...props} providers={['guest']} />,\n },\n});\n"],"names":[],"mappings":";;;;AAkBO,MAAM,iBAAA,GAAoB,oBAAoB,IAAA,CAAK;AAAA,EACxD,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,YAAY,CAAA,KAAA,qBAClB,GAAA,CAAC,UAAA,EAAA,EAAY,GAAG,KAAA,EAAO,SAAA,EAAW,CAAC,OAAO,CAAA,EAAG;AAAA;AAEnD,CAAC;;;;"}
@@ -1,4 +1,5 @@
1
- import { ApiBlueprint, createExtensionInput, iconsApiRef, IconBundleBlueprint } from '@backstage/frontend-plugin-api';
1
+ import { ApiBlueprint, createExtensionInput, iconsApiRef } from '@backstage/frontend-plugin-api';
2
+ import { IconBundleBlueprint } from '@backstage/plugin-app-react';
2
3
  import { DefaultIconsApi } from '../packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js';
3
4
  import '../packages/app-defaults/src/defaults/apis.esm.js';
4
5
  import 'react/jsx-runtime';
@@ -14,7 +15,8 @@ const IconsApi = ApiBlueprint.makeWithOverrides({
14
15
  name: "icons",
15
16
  inputs: {
16
17
  icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons], {
17
- replaces: [{ id: "app", input: "icons" }]
18
+ replaces: [{ id: "app", input: "icons" }],
19
+ internal: true
18
20
  })
19
21
  },
20
22
  factory: (originalFactory, { inputs }) => {
@@ -22,9 +24,11 @@ const IconsApi = ApiBlueprint.makeWithOverrides({
22
24
  (defineParams) => defineParams({
23
25
  api: iconsApiRef,
24
26
  deps: {},
25
- factory: () => new DefaultIconsApi(
26
- inputs.icons.map((i) => i.get(IconBundleBlueprint.dataRefs.icons)).reduce((acc, bundle) => ({ ...acc, ...bundle }), icons)
27
- )
27
+ factory: () => {
28
+ return new DefaultIconsApi(
29
+ inputs.icons.map((i) => i.get(IconBundleBlueprint.dataRefs.icons)).reduce((acc, bundle) => ({ ...acc, ...bundle }), icons)
30
+ );
31
+ }
28
32
  })
29
33
  );
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"IconsApi.esm.js","sources":["../../src/extensions/IconsApi.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 createExtensionInput,\n IconBundleBlueprint,\n ApiBlueprint,\n iconsApiRef,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { DefaultIconsApi } from '../../../../packages/frontend-app-api/src/apis/implementations/IconsApi';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { icons as defaultIcons } from '../../../../packages/app-defaults/src/defaults';\n\n/**\n * Contains the shareable icons installed into the app.\n */\nexport const IconsApi = ApiBlueprint.makeWithOverrides({\n name: 'icons',\n inputs: {\n icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons], {\n replaces: [{ id: 'app', input: 'icons' }],\n }),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: iconsApiRef,\n deps: {},\n factory: () =>\n new DefaultIconsApi(\n inputs.icons\n .map(i => i.get(IconBundleBlueprint.dataRefs.icons))\n .reduce((acc, bundle) => ({ ...acc, ...bundle }), defaultIcons),\n ),\n }),\n );\n },\n});\n"],"names":["defaultIcons"],"mappings":";;;;;;;;;;;;AA8BO,MAAM,QAAA,GAAW,aAAa,iBAAA,CAAkB;AAAA,EACrD,IAAA,EAAM,OAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,OAAO,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,KAAK,CAAA,EAAG;AAAA,MAChE,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,SAAS;AAAA,KACzC;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,WAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,OAAA,EAAS,MACP,IAAI,eAAA;AAAA,UACF,MAAA,CAAO,MACJ,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,mBAAA,CAAoB,SAAS,KAAK,CAAC,EAClD,MAAA,CAAO,CAAC,KAAK,MAAA,MAAY,EAAE,GAAG,GAAA,EAAK,GAAG,MAAA,EAAO,CAAA,EAAIA,KAAY;AAAA;AAClE,OACH;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"IconsApi.esm.js","sources":["../../src/extensions/IconsApi.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 createExtensionInput,\n ApiBlueprint,\n iconsApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { IconBundleBlueprint } from '@backstage/plugin-app-react';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { DefaultIconsApi } from '../../../../packages/frontend-app-api/src/apis/implementations/IconsApi';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { icons as defaultIcons } from '../../../../packages/app-defaults/src/defaults';\n\n/**\n * Contains the shareable icons installed into the app.\n */\nexport const IconsApi = ApiBlueprint.makeWithOverrides({\n name: 'icons',\n inputs: {\n icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons], {\n replaces: [{ id: 'app', input: 'icons' }],\n internal: true,\n }),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: iconsApiRef,\n deps: {},\n factory: () => {\n return new DefaultIconsApi(\n inputs.icons\n .map(i => i.get(IconBundleBlueprint.dataRefs.icons))\n .reduce((acc, bundle) => ({ ...acc, ...bundle }), defaultIcons),\n );\n },\n }),\n );\n },\n});\n"],"names":["defaultIcons"],"mappings":";;;;;;;;;;;;;AA8BO,MAAM,QAAA,GAAW,aAAa,iBAAA,CAAkB;AAAA,EACrD,IAAA,EAAM,OAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,OAAO,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,KAAK,CAAA,EAAG;AAAA,MAChE,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,SAAS,CAAA;AAAA,MACxC,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,WAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,IAAI,eAAA;AAAA,YACT,MAAA,CAAO,MACJ,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,mBAAA,CAAoB,SAAS,KAAK,CAAC,EAClD,MAAA,CAAO,CAAC,KAAK,MAAA,MAAY,EAAE,GAAG,GAAA,EAAK,GAAG,MAAA,EAAO,CAAA,EAAIA,KAAY;AAAA,WAClE;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
@@ -0,0 +1,29 @@
1
+ import { pluginWrapperApiRef, PluginWrapperBlueprint } from '@backstage/frontend-plugin-api/alpha';
2
+ import { ApiBlueprint, createExtensionInput } from '@backstage/frontend-plugin-api';
3
+ import { DefaultPluginWrapperApi } from '../apis/PluginWrapperApi/DefaultPluginWrapperApi.esm.js';
4
+
5
+ const PluginWrapperApi = ApiBlueprint.makeWithOverrides({
6
+ name: "plugin-wrapper",
7
+ inputs: {
8
+ wrappers: createExtensionInput([PluginWrapperBlueprint.dataRefs.wrapper])
9
+ },
10
+ factory: (originalFactory, { inputs }) => {
11
+ return originalFactory(
12
+ (defineParams) => defineParams({
13
+ api: pluginWrapperApiRef,
14
+ deps: {},
15
+ factory: () => {
16
+ return DefaultPluginWrapperApi.fromWrappers(
17
+ inputs.wrappers.map((wrapperInput) => ({
18
+ loader: wrapperInput.get(PluginWrapperBlueprint.dataRefs.wrapper),
19
+ pluginId: wrapperInput.node.spec.plugin.id ?? "app"
20
+ }))
21
+ );
22
+ }
23
+ })
24
+ );
25
+ }
26
+ });
27
+
28
+ export { PluginWrapperApi };
29
+ //# sourceMappingURL=PluginWrapperApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginWrapperApi.esm.js","sources":["../../src/extensions/PluginWrapperApi.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 PluginWrapperBlueprint,\n pluginWrapperApiRef,\n} from '@backstage/frontend-plugin-api/alpha';\nimport {\n createExtensionInput,\n ApiBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { DefaultPluginWrapperApi } from '../apis/PluginWrapperApi';\n\n/**\n * Contains the plugin wrappers installed into the app.\n */\nexport const PluginWrapperApi = ApiBlueprint.makeWithOverrides({\n name: 'plugin-wrapper',\n inputs: {\n wrappers: createExtensionInput([PluginWrapperBlueprint.dataRefs.wrapper]),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: pluginWrapperApiRef,\n deps: {},\n factory: () => {\n return DefaultPluginWrapperApi.fromWrappers(\n inputs.wrappers.map(wrapperInput => ({\n loader: wrapperInput.get(PluginWrapperBlueprint.dataRefs.wrapper),\n pluginId: wrapperInput.node.spec.plugin.id ?? 'app',\n })),\n );\n },\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA6BO,MAAM,gBAAA,GAAmB,aAAa,iBAAA,CAAkB;AAAA,EAC7D,IAAA,EAAM,gBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,UAAU,oBAAA,CAAqB,CAAC,sBAAA,CAAuB,QAAA,CAAS,OAAO,CAAC;AAAA,GAC1E;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,mBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,uBAAA,CAAwB,YAAA;AAAA,YAC7B,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,CAAA,YAAA,MAAiB;AAAA,cACnC,MAAA,EAAQ,YAAA,CAAa,GAAA,CAAI,sBAAA,CAAuB,SAAS,OAAO,CAAA;AAAA,cAChE,QAAA,EAAU,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,OAAO,EAAA,IAAM;AAAA,aAChD,CAAE;AAAA,WACJ;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
@@ -1,12 +1,16 @@
1
- import { ApiBlueprint, createExtensionInput, swappableComponentsApiRef, SwappableComponentBlueprint } from '@backstage/frontend-plugin-api';
1
+ import { ApiBlueprint, createExtensionInput, swappableComponentsApiRef } from '@backstage/frontend-plugin-api';
2
+ import { SwappableComponentBlueprint } from '@backstage/plugin-app-react';
2
3
  import { DefaultSwappableComponentsApi } from '../apis/SwappableComponentsApi/DefaultSwappableComponentsApi.esm.js';
3
4
 
4
5
  const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({
5
6
  name: "swappable-components",
6
7
  inputs: {
7
- components: createExtensionInput([
8
- SwappableComponentBlueprint.dataRefs.component
9
- ])
8
+ components: createExtensionInput(
9
+ [SwappableComponentBlueprint.dataRefs.component],
10
+ {
11
+ internal: true
12
+ }
13
+ )
10
14
  },
11
15
  factory: (originalFactory, { inputs }) => {
12
16
  return originalFactory(
@@ -14,19 +18,8 @@ const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({
14
18
  api: swappableComponentsApiRef,
15
19
  deps: {},
16
20
  factory: () => {
17
- const nonAppExtensions = inputs.components.filter(
18
- (i) => i.node.spec.plugin?.id !== "app"
19
- );
20
- if (nonAppExtensions.length > 0) {
21
- console.warn(
22
- `SwappableComponents should only be installed as an extension in the app plugin. You can either use appPlugin.override(), or provide a module for the app-plugin with the extension there instead. Invalid extensions: ${nonAppExtensions.map((i) => i.node.spec.id).join(", ")}`
23
- );
24
- }
25
- const appExtensions = inputs.components.filter(
26
- (i) => i.node.spec.plugin?.id === "app"
27
- );
28
21
  return DefaultSwappableComponentsApi.fromComponents(
29
- appExtensions.map(
22
+ inputs.components.map(
30
23
  (i) => i.get(SwappableComponentBlueprint.dataRefs.component)
31
24
  )
32
25
  );
@@ -1 +1 @@
1
- {"version":3,"file":"SwappableComponentsApi.esm.js","sources":["../../src/extensions/SwappableComponentsApi.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 SwappableComponentBlueprint,\n createExtensionInput,\n ApiBlueprint,\n swappableComponentsApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { DefaultSwappableComponentsApi } from '../apis/SwappableComponentsApi';\n\n/**\n * Contains the shareable components installed into the app.\n */\nexport const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({\n name: 'swappable-components',\n inputs: {\n components: createExtensionInput([\n SwappableComponentBlueprint.dataRefs.component,\n ]),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: swappableComponentsApiRef,\n deps: {},\n factory: () => {\n const nonAppExtensions = inputs.components.filter(\n i => i.node.spec.plugin?.id !== 'app',\n );\n\n if (nonAppExtensions.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `SwappableComponents should only be installed as an extension in the app plugin. You can either use appPlugin.override(), or provide a module for the app-plugin with the extension there instead. Invalid extensions: ${nonAppExtensions\n .map(i => i.node.spec.id)\n .join(', ')}`,\n );\n }\n\n const appExtensions = inputs.components.filter(\n i => i.node.spec.plugin?.id === 'app',\n );\n\n return DefaultSwappableComponentsApi.fromComponents(\n appExtensions.map(i =>\n i.get(SwappableComponentBlueprint.dataRefs.component),\n ),\n );\n },\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;AA2BO,MAAM,sBAAA,GAAyB,aAAa,iBAAA,CAAkB;AAAA,EACnE,IAAA,EAAM,sBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,YAAY,oBAAA,CAAqB;AAAA,MAC/B,4BAA4B,QAAA,CAAS;AAAA,KACtC;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,yBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,MAAM,gBAAA,GAAmB,OAAO,UAAA,CAAW,MAAA;AAAA,YACzC,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,QAAQ,EAAA,KAAO;AAAA,WAClC;AAEA,UAAA,IAAI,gBAAA,CAAiB,SAAS,CAAA,EAAG;AAE/B,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,CAAA,sNAAA,EAAyN,gBAAA,CACtN,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,CACvB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,aACf;AAAA,UACF;AAEA,UAAA,MAAM,aAAA,GAAgB,OAAO,UAAA,CAAW,MAAA;AAAA,YACtC,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,QAAQ,EAAA,KAAO;AAAA,WAClC;AAEA,UAAA,OAAO,6BAAA,CAA8B,cAAA;AAAA,YACnC,aAAA,CAAc,GAAA;AAAA,cAAI,CAAA,CAAA,KAChB,CAAA,CAAE,GAAA,CAAI,2BAAA,CAA4B,SAAS,SAAS;AAAA;AACtD,WACF;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"SwappableComponentsApi.esm.js","sources":["../../src/extensions/SwappableComponentsApi.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 createExtensionInput,\n ApiBlueprint,\n swappableComponentsApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { SwappableComponentBlueprint } from '@backstage/plugin-app-react';\nimport { DefaultSwappableComponentsApi } from '../apis/SwappableComponentsApi';\n\n/**\n * Contains the shareable components installed into the app.\n */\nexport const SwappableComponentsApi = ApiBlueprint.makeWithOverrides({\n name: 'swappable-components',\n inputs: {\n components: createExtensionInput(\n [SwappableComponentBlueprint.dataRefs.component],\n {\n internal: true,\n },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: swappableComponentsApiRef,\n deps: {},\n factory: () => {\n return DefaultSwappableComponentsApi.fromComponents(\n inputs.components.map(i =>\n i.get(SwappableComponentBlueprint.dataRefs.component),\n ),\n );\n },\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA2BO,MAAM,sBAAA,GAAyB,aAAa,iBAAA,CAAkB;AAAA,EACnE,IAAA,EAAM,sBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,UAAA,EAAY,oBAAA;AAAA,MACV,CAAC,2BAAA,CAA4B,QAAA,CAAS,SAAS,CAAA;AAAA,MAC/C;AAAA,QACE,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,yBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,6BAAA,CAA8B,cAAA;AAAA,YACnC,OAAO,UAAA,CAAW,GAAA;AAAA,cAAI,CAAA,CAAA,KACpB,CAAA,CAAE,GAAA,CAAI,2BAAA,CAA4B,SAAS,SAAS;AAAA;AACtD,WACF;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
@@ -1,4 +1,5 @@
1
- import { ApiBlueprint, createExtensionInput, TranslationBlueprint } from '@backstage/frontend-plugin-api';
1
+ import { ApiBlueprint, createExtensionInput } from '@backstage/frontend-plugin-api';
2
+ import { TranslationBlueprint } from '@backstage/plugin-app-react';
2
3
  import { appLanguageApiRef, translationApiRef } from '@backstage/core-plugin-api/alpha';
3
4
  import { I18nextTranslationApi } from '../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js';
4
5
 
@@ -7,7 +8,7 @@ const TranslationsApi = ApiBlueprint.makeWithOverrides({
7
8
  inputs: {
8
9
  translations: createExtensionInput(
9
10
  [TranslationBlueprint.dataRefs.translation],
10
- { replaces: [{ id: "app", input: "translations" }] }
11
+ { replaces: [{ id: "app", input: "translations" }], internal: true }
11
12
  )
12
13
  },
13
14
  factory: (originalFactory, { inputs }) => {
@@ -15,12 +16,14 @@ const TranslationsApi = ApiBlueprint.makeWithOverrides({
15
16
  (defineParams) => defineParams({
16
17
  api: translationApiRef,
17
18
  deps: { languageApi: appLanguageApiRef },
18
- factory: ({ languageApi }) => I18nextTranslationApi.create({
19
- languageApi,
20
- resources: inputs.translations.map(
21
- (i) => i.get(TranslationBlueprint.dataRefs.translation)
22
- )
23
- })
19
+ factory: ({ languageApi }) => {
20
+ return I18nextTranslationApi.create({
21
+ languageApi,
22
+ resources: inputs.translations.map(
23
+ (i) => i.get(TranslationBlueprint.dataRefs.translation)
24
+ )
25
+ });
26
+ }
24
27
  })
25
28
  );
26
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TranslationsApi.esm.js","sources":["../../src/extensions/TranslationsApi.tsx"],"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 */\nimport {\n ApiBlueprint,\n TranslationBlueprint,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport {\n appLanguageApiRef,\n translationApiRef,\n} from '@backstage/core-plugin-api/alpha';\n\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { I18nextTranslationApi } from '../../../../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi';\n\n/**\n * Contains translations that are installed in the app.\n */\nexport const TranslationsApi = ApiBlueprint.makeWithOverrides({\n name: 'translations',\n inputs: {\n translations: createExtensionInput(\n [TranslationBlueprint.dataRefs.translation],\n { replaces: [{ id: 'app', input: 'translations' }] },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: translationApiRef,\n deps: { languageApi: appLanguageApiRef },\n factory: ({ languageApi }) =>\n I18nextTranslationApi.create({\n languageApi,\n resources: inputs.translations.map(i =>\n i.get(TranslationBlueprint.dataRefs.translation),\n ),\n }),\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;AA+BO,MAAM,eAAA,GAAkB,aAAa,iBAAA,CAAkB;AAAA,EAC5D,IAAA,EAAM,cAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,YAAA,EAAc,oBAAA;AAAA,MACZ,CAAC,oBAAA,CAAqB,QAAA,CAAS,WAAW,CAAA;AAAA,MAC1C,EAAE,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,cAAA,EAAgB,CAAA;AAAE;AACrD,GACF;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,iBAAA;AAAA,QACL,IAAA,EAAM,EAAE,WAAA,EAAa,iBAAA,EAAkB;AAAA,QACvC,SAAS,CAAC,EAAE,WAAA,EAAY,KACtB,sBAAsB,MAAA,CAAO;AAAA,UAC3B,WAAA;AAAA,UACA,SAAA,EAAW,OAAO,YAAA,CAAa,GAAA;AAAA,YAAI,CAAA,CAAA,KACjC,CAAA,CAAE,GAAA,CAAI,oBAAA,CAAqB,SAAS,WAAW;AAAA;AACjD,SACD;AAAA,OACJ;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"TranslationsApi.esm.js","sources":["../../src/extensions/TranslationsApi.tsx"],"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 */\nimport {\n ApiBlueprint,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { TranslationBlueprint } from '@backstage/plugin-app-react';\nimport {\n appLanguageApiRef,\n translationApiRef,\n} from '@backstage/core-plugin-api/alpha';\n\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { I18nextTranslationApi } from '../../../../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi';\n\n/**\n * Contains translations that are installed in the app.\n */\nexport const TranslationsApi = ApiBlueprint.makeWithOverrides({\n name: 'translations',\n inputs: {\n translations: createExtensionInput(\n [TranslationBlueprint.dataRefs.translation],\n { replaces: [{ id: 'app', input: 'translations' }], internal: true },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: translationApiRef,\n deps: { languageApi: appLanguageApiRef },\n factory: ({ languageApi }) => {\n return I18nextTranslationApi.create({\n languageApi,\n resources: inputs.translations.map(i =>\n i.get(TranslationBlueprint.dataRefs.translation),\n ),\n });\n },\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;;;AA+BO,MAAM,eAAA,GAAkB,aAAa,iBAAA,CAAkB;AAAA,EAC5D,IAAA,EAAM,cAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,YAAA,EAAc,oBAAA;AAAA,MACZ,CAAC,oBAAA,CAAqB,QAAA,CAAS,WAAW,CAAA;AAAA,MAC1C,EAAE,QAAA,EAAU,CAAC,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,cAAA,EAAgB,CAAA,EAAG,QAAA,EAAU,IAAA;AAAK;AACrE,GACF;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,iBAAA;AAAA,QACL,IAAA,EAAM,EAAE,WAAA,EAAa,iBAAA,EAAkB;AAAA,QACvC,OAAA,EAAS,CAAC,EAAE,WAAA,EAAY,KAAM;AAC5B,UAAA,OAAO,sBAAsB,MAAA,CAAO;AAAA,YAClC,WAAA;AAAA,YACA,SAAA,EAAW,OAAO,YAAA,CAAa,GAAA;AAAA,cAAI,CAAA,CAAA,KACjC,CAAA,CAAE,GAAA,CAAI,oBAAA,CAAqB,SAAS,WAAW;AAAA;AACjD,WACD,CAAA;AAAA,QACH;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
@@ -1,5 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { SwappableComponentBlueprint, Progress as Progress$2, NotFoundErrorPage as NotFoundErrorPage$1, ErrorDisplay as ErrorDisplay$1 } from '@backstage/frontend-plugin-api';
2
+ import { Progress as Progress$2, NotFoundErrorPage as NotFoundErrorPage$1, ErrorDisplay as ErrorDisplay$1 } from '@backstage/frontend-plugin-api';
3
+ import { SwappableComponentBlueprint } from '@backstage/plugin-app-react';
3
4
  import { Progress as Progress$1, ErrorPage, ErrorPanel } from '@backstage/core-components';
4
5
  import Button from '@material-ui/core/Button';
5
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n NotFoundErrorPage as SwappableNotFoundErrorPage,\n Progress as SwappableProgress,\n ErrorDisplay as SwappableErrorDisplay,\n SwappableComponentBlueprint,\n} from '@backstage/frontend-plugin-api';\n\nimport {\n ErrorPage,\n ErrorPanel,\n Progress as ProgressComponent,\n} from '@backstage/core-components';\nimport Button from '@material-ui/core/Button';\n\nexport const Progress = SwappableComponentBlueprint.make({\n name: 'core-progress',\n params: define =>\n define({\n component: SwappableProgress,\n loader: () => ProgressComponent,\n }),\n});\n\nexport const NotFoundErrorPage = SwappableComponentBlueprint.make({\n name: 'core-not-found-error-page',\n params: define =>\n define({\n component: SwappableNotFoundErrorPage,\n loader: () => () =>\n <ErrorPage status=\"404\" statusMessage=\"PAGE NOT FOUND\" />,\n }),\n});\n\nexport const ErrorDisplay = SwappableComponentBlueprint.make({\n name: 'core-error-display',\n params: define =>\n define({\n component: SwappableErrorDisplay,\n loader: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n },\n }),\n});\n"],"names":["SwappableProgress","ProgressComponent","SwappableNotFoundErrorPage","SwappableErrorDisplay"],"mappings":";;;;;AA6BO,MAAM,QAAA,GAAW,4BAA4B,IAAA,CAAK;AAAA,EACvD,IAAA,EAAM,eAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWA,UAAA;AAAA,IACX,QAAQ,MAAMC;AAAA,GACf;AACL,CAAC;AAEM,MAAM,iBAAA,GAAoB,4BAA4B,IAAA,CAAK;AAAA,EAChE,IAAA,EAAM,2BAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,mBAAA;AAAA,IACX,MAAA,EAAQ,MAAM,sBACZ,GAAA,CAAC,aAAU,MAAA,EAAO,KAAA,EAAM,eAAc,gBAAA,EAAiB;AAAA,GAC1D;AACL,CAAC;AAEM,MAAM,YAAA,GAAe,4BAA4B,IAAA,CAAK;AAAA,EAC3D,IAAA,EAAM,oBAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,cAAA;AAAA,IACX,MAAA,EAAQ,MAAM,CAAA,KAAA,KAAS;AACrB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAW,GAAI,KAAA;AACtC,MAAA,MAAM,KAAA,GAAQ,CAAA,SAAA,EAAY,MAAA,EAAQ,EAAE,CAAA,CAAA;AACpC,MAAA,uBACE,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAc,KAAA,EAAc,eAAA,EAAe,IAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,UAAA,EAAW,OAAA,EAAS,UAAA,EAAY,mBAEhD,CAAA,EACF,CAAA;AAAA,IAEJ;AAAA,GACD;AACL,CAAC;;;;"}
1
+ {"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n NotFoundErrorPage as SwappableNotFoundErrorPage,\n Progress as SwappableProgress,\n ErrorDisplay as SwappableErrorDisplay,\n} from '@backstage/frontend-plugin-api';\nimport { SwappableComponentBlueprint } from '@backstage/plugin-app-react';\nimport {\n ErrorPage,\n ErrorPanel,\n Progress as ProgressComponent,\n} from '@backstage/core-components';\nimport Button from '@material-ui/core/Button';\n\nexport const Progress = SwappableComponentBlueprint.make({\n name: 'core-progress',\n params: define =>\n define({\n component: SwappableProgress,\n loader: () => ProgressComponent,\n }),\n});\n\nexport const NotFoundErrorPage = SwappableComponentBlueprint.make({\n name: 'core-not-found-error-page',\n params: define =>\n define({\n component: SwappableNotFoundErrorPage,\n loader: () => () =>\n <ErrorPage status=\"404\" statusMessage=\"PAGE NOT FOUND\" />,\n }),\n});\n\nexport const ErrorDisplay = SwappableComponentBlueprint.make({\n name: 'core-error-display',\n params: define =>\n define({\n component: SwappableErrorDisplay,\n loader: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n },\n }),\n});\n"],"names":["SwappableProgress","ProgressComponent","SwappableNotFoundErrorPage","SwappableErrorDisplay"],"mappings":";;;;;;AA4BO,MAAM,QAAA,GAAW,4BAA4B,IAAA,CAAK;AAAA,EACvD,IAAA,EAAM,eAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWA,UAAA;AAAA,IACX,QAAQ,MAAMC;AAAA,GACf;AACL,CAAC;AAEM,MAAM,iBAAA,GAAoB,4BAA4B,IAAA,CAAK;AAAA,EAChE,IAAA,EAAM,2BAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,mBAAA;AAAA,IACX,MAAA,EAAQ,MAAM,sBACZ,GAAA,CAAC,aAAU,MAAA,EAAO,KAAA,EAAM,eAAc,gBAAA,EAAiB;AAAA,GAC1D;AACL,CAAC;AAEM,MAAM,YAAA,GAAe,4BAA4B,IAAA,CAAK;AAAA,EAC3D,IAAA,EAAM,oBAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,cAAA;AAAA,IACX,MAAA,EAAQ,MAAM,CAAA,KAAA,KAAS;AACrB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAW,GAAI,KAAA;AACtC,MAAA,MAAM,KAAA,GAAQ,CAAA,SAAA,EAAY,MAAA,EAAQ,EAAE,CAAA,CAAA;AACpC,MAAA,uBACE,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAc,KAAA,EAAc,eAAA,EAAe,IAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,UAAA,EAAW,OAAA,EAAS,UAAA,EAAY,mBAEhD,CAAA,EACF,CAAA;AAAA,IAEJ;AAAA,GACD;AACL,CAAC;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as _backstage_plugin_app_react from '@backstage/plugin-app-react';
1
2
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
2
3
  import * as react from 'react';
3
4
 
@@ -11,6 +12,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
11
12
  root: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
12
13
  singleton: true;
13
14
  optional: false;
15
+ internal: false;
14
16
  }>;
15
17
  };
16
18
  params: never;
@@ -25,10 +27,12 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
25
27
  nav: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
26
28
  singleton: true;
27
29
  optional: false;
30
+ internal: false;
28
31
  }>;
29
32
  content: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
30
33
  singleton: true;
31
34
  optional: false;
35
+ internal: false;
32
36
  }>;
33
37
  };
34
38
  params: never;
@@ -47,10 +51,12 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
47
51
  }, "core.nav-item.target", {}>, {
48
52
  singleton: false;
49
53
  optional: false;
54
+ internal: false;
50
55
  }>;
51
- content: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.NavContentComponent, "core.nav-content.component", {}>, {
56
+ content: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_plugin_app_react.NavContentComponent, "core.nav-content.component", {}>, {
52
57
  singleton: true;
53
58
  optional: true;
59
+ internal: true;
54
60
  }>;
55
61
  };
56
62
  params: never;
@@ -67,24 +73,29 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
67
73
  }) => JSX.Element | null, "app.router.wrapper", {}>, {
68
74
  singleton: true;
69
75
  optional: true;
76
+ internal: true;
70
77
  }>;
71
- signInPage: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>, {
78
+ signInPage: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.ComponentType<_backstage_plugin_app_react.SignInPageProps>, "core.sign-in-page.component", {}>, {
72
79
  singleton: true;
73
80
  optional: true;
81
+ internal: true;
74
82
  }>;
75
83
  children: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
76
84
  singleton: true;
77
85
  optional: false;
86
+ internal: false;
78
87
  }>;
79
88
  elements: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
80
89
  singleton: false;
81
90
  optional: false;
91
+ internal: false;
82
92
  }>;
83
93
  wrappers: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: {
84
94
  children: react.ReactNode;
85
95
  }) => JSX.Element | null, "app.root.wrapper", {}>, {
86
96
  singleton: false;
87
97
  optional: false;
98
+ internal: true;
88
99
  }>;
89
100
  };
90
101
  params: never;
@@ -101,6 +112,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
101
112
  }>, {
102
113
  singleton: false;
103
114
  optional: false;
115
+ internal: false;
104
116
  }>;
105
117
  };
106
118
  params: never;
@@ -124,6 +136,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
124
136
  implementations: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AnalyticsImplementationFactory<{}>, "core.analytics.factory", {}>, {
125
137
  singleton: false;
126
138
  optional: false;
139
+ internal: false;
127
140
  }>;
128
141
  };
129
142
  kind: "api";
@@ -153,6 +166,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
153
166
  themes: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.AppTheme, "core.theme.theme", {}>, {
154
167
  singleton: false;
155
168
  optional: false;
169
+ internal: true;
156
170
  }>;
157
171
  };
158
172
  kind: "api";
@@ -277,6 +291,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
277
291
  }, "core.icons", {}>, {
278
292
  singleton: false;
279
293
  optional: false;
294
+ internal: true;
280
295
  }>;
281
296
  };
282
297
  kind: "api";
@@ -337,6 +352,25 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
337
352
  inputs: {};
338
353
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
339
354
  }>;
355
+ "api:app/plugin-wrapper": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
356
+ config: {};
357
+ configInput: {};
358
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
359
+ inputs: {
360
+ wrappers: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<{
361
+ component: react.ComponentType<{
362
+ children: react.ReactNode;
363
+ }>;
364
+ }>, "core.plugin-wrapper.loader", {}>, {
365
+ singleton: false;
366
+ optional: false;
367
+ internal: false;
368
+ }>;
369
+ };
370
+ kind: "api";
371
+ name: "plugin-wrapper";
372
+ params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
373
+ }>;
340
374
  "api:app/scm-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
341
375
  kind: "api";
342
376
  name: "scm-auth";
@@ -375,6 +409,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
375
409
  }, "core.swappableComponent", {}>, {
376
410
  singleton: false;
377
411
  optional: false;
412
+ internal: true;
378
413
  }>;
379
414
  };
380
415
  kind: "api";
@@ -391,6 +426,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
391
426
  }, boolean>, "core.translation.translation", {}>, {
392
427
  singleton: false;
393
428
  optional: false;
429
+ internal: true;
394
430
  }>;
395
431
  };
396
432
  kind: "api";
@@ -522,10 +558,10 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
522
558
  name: undefined;
523
559
  config: {};
524
560
  configInput: {};
525
- output: _backstage_frontend_plugin_api.ExtensionDataRef<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>;
561
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<react.ComponentType<_backstage_plugin_app_react.SignInPageProps>, "core.sign-in-page.component", {}>;
526
562
  inputs: {};
527
563
  params: {
528
- loader: () => Promise<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>>;
564
+ loader: () => Promise<react.ComponentType<_backstage_plugin_app_react.SignInPageProps>>;
529
565
  };
530
566
  }>;
531
567
  "theme:app/dark": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
@@ -15,6 +15,7 @@ import { DefaultSignInPage } from './extensions/DefaultSignInPage.esm.js';
15
15
  import { dialogDisplayAppRootElement } from './extensions/DialogDisplay.esm.js';
16
16
  import { oauthRequestDialogAppRootElement, alertDisplayAppRootElement } from './extensions/elements.esm.js';
17
17
  import { Progress, NotFoundErrorPage, ErrorDisplay } from './extensions/components.esm.js';
18
+ import { PluginWrapperApi } from './extensions/PluginWrapperApi.esm.js';
18
19
  import { apis } from './defaultApis.esm.js';
19
20
 
20
21
  const appPlugin = createFrontendPlugin({
@@ -34,6 +35,7 @@ const appPlugin = createFrontendPlugin({
34
35
  SwappableComponentsApi,
35
36
  IconsApi,
36
37
  FeatureFlagsApi,
38
+ PluginWrapperApi,
37
39
  TranslationsApi,
38
40
  DefaultSignInPage,
39
41
  oauthRequestDialogAppRootElement,
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n DefaultSignInPage,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n pluginId: 'app',\n info: { packageJson: () => import('../package.json') },\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA2CO,MAAM,YAAY,oBAAA,CAAqB;AAAA,EAC5C,QAAA,EAAU,KAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,mCAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY;AAAA,IACV,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,sBAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAA;AAAA,IACA,gCAAA;AAAA,IACA,0BAAA;AAAA,IACA,2BAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n PluginWrapperApi,\n TranslationsApi,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n DefaultSignInPage,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n pluginId: 'app',\n info: { packageJson: () => import('../package.json') },\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n PluginWrapperApi,\n TranslationsApi,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA4CO,MAAM,YAAY,oBAAA,CAAqB;AAAA,EAC5C,QAAA,EAAU,KAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,mCAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY;AAAA,IACV,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,sBAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,gBAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAA;AAAA,IACA,gCAAA;AAAA,IACA,0BAAA;AAAA,IACA,2BAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
@@ -1,12 +1,13 @@
1
1
  var name = "@backstage/plugin-app";
2
- var version = "0.3.4-next.1";
2
+ var version = "0.4.0-next.0";
3
3
  var backstage = {
4
4
  role: "frontend-plugin",
5
5
  pluginId: "app",
6
6
  pluginPackages: [
7
7
  "@backstage/plugin-app",
8
8
  "@backstage/plugin-app-backend",
9
- "@backstage/plugin-app-node"
9
+ "@backstage/plugin-app-node",
10
+ "@backstage/plugin-app-react"
10
11
  ]
11
12
  };
12
13
  var publishConfig = {
@@ -53,6 +54,7 @@ var dependencies = {
53
54
  "@backstage/core-plugin-api": "workspace:^",
54
55
  "@backstage/frontend-plugin-api": "workspace:^",
55
56
  "@backstage/integration-react": "workspace:^",
57
+ "@backstage/plugin-app-react": "workspace:^",
56
58
  "@backstage/plugin-permission-react": "workspace:^",
57
59
  "@backstage/theme": "workspace:^",
58
60
  "@backstage/types": "workspace:^",
@@ -62,7 +64,7 @@ var dependencies = {
62
64
  "@material-ui/lab": "^4.0.0-alpha.61",
63
65
  "@react-hookz/web": "^24.0.0",
64
66
  "react-use": "^17.2.4",
65
- zod: "^3.22.4"
67
+ zod: "^3.25.76"
66
68
  };
67
69
  var devDependencies = {
68
70
  "@backstage/cli": "workspace:^",
@@ -1 +1 @@
1
- {"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@backstage/plugin-app",
3
- "version": "0.3.4-next.1",
3
+ "version": "0.4.0-next.0",
4
4
  "backstage": {
5
5
  "role": "frontend-plugin",
6
6
  "pluginId": "app",
7
7
  "pluginPackages": [
8
8
  "@backstage/plugin-app",
9
9
  "@backstage/plugin-app-backend",
10
- "@backstage/plugin-app-node"
10
+ "@backstage/plugin-app-node",
11
+ "@backstage/plugin-app-react"
11
12
  ],
12
13
  "features": {
13
14
  ".": "@backstage/FrontendPlugin"
@@ -62,11 +63,12 @@
62
63
  "test": "backstage-cli package test"
63
64
  },
64
65
  "dependencies": {
65
- "@backstage/core-components": "0.18.5-next.0",
66
- "@backstage/core-plugin-api": "1.12.1",
67
- "@backstage/frontend-plugin-api": "0.13.2",
68
- "@backstage/integration-react": "1.2.14-next.0",
69
- "@backstage/plugin-permission-react": "0.4.39",
66
+ "@backstage/core-components": "0.18.6-next.0",
67
+ "@backstage/core-plugin-api": "1.12.2-next.0",
68
+ "@backstage/frontend-plugin-api": "0.14.0-next.0",
69
+ "@backstage/integration-react": "1.2.15-next.0",
70
+ "@backstage/plugin-app-react": "0.1.1-next.0",
71
+ "@backstage/plugin-permission-react": "0.4.40-next.0",
70
72
  "@backstage/theme": "0.7.1",
71
73
  "@backstage/types": "1.2.2",
72
74
  "@backstage/version-bridge": "1.0.11",
@@ -75,14 +77,14 @@
75
77
  "@material-ui/lab": "^4.0.0-alpha.61",
76
78
  "@react-hookz/web": "^24.0.0",
77
79
  "react-use": "^17.2.4",
78
- "zod": "^3.22.4"
80
+ "zod": "^3.25.76"
79
81
  },
80
82
  "devDependencies": {
81
- "@backstage/cli": "0.35.2-next.1",
82
- "@backstage/dev-utils": "1.1.19-next.2",
83
- "@backstage/frontend-defaults": "0.3.5-next.1",
84
- "@backstage/frontend-test-utils": "0.4.3-next.0",
85
- "@backstage/test-utils": "1.7.14",
83
+ "@backstage/cli": "0.35.3-next.0",
84
+ "@backstage/dev-utils": "1.1.20-next.0",
85
+ "@backstage/frontend-defaults": "0.3.6-next.0",
86
+ "@backstage/frontend-test-utils": "0.4.5-next.0",
87
+ "@backstage/test-utils": "1.7.15-next.0",
86
88
  "@testing-library/jest-dom": "^6.0.0",
87
89
  "@testing-library/react": "^16.0.0",
88
90
  "@testing-library/user-event": "^14.0.0",