@backstage/frontend-app-api 0.6.4 → 0.6.5-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js +53 -0
- package/dist/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js.map +1 -0
- package/dist/apis/implementations/IconsApi/DefaultIconsApi.esm.js +35 -0
- package/dist/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map +1 -0
- package/dist/app/src/components/Root/LogoFull.esm.js +33 -0
- package/dist/app/src/components/Root/LogoFull.esm.js.map +1 -0
- package/dist/app/src/components/Root/LogoIcon.esm.js +33 -0
- package/dist/app/src/components/Root/LogoIcon.esm.js.map +1 -0
- package/dist/app-defaults/src/defaults/apis.esm.js +221 -0
- package/dist/app-defaults/src/defaults/apis.esm.js.map +1 -0
- package/dist/app-defaults/src/defaults/components.esm.js +46 -0
- package/dist/app-defaults/src/defaults/components.esm.js.map +1 -0
- package/dist/app-defaults/src/defaults/icons.esm.js +51 -0
- package/dist/app-defaults/src/defaults/icons.esm.js.map +1 -0
- package/dist/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js +114 -0
- package/dist/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js.map +1 -0
- package/dist/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js +84 -0
- package/dist/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js.map +1 -0
- package/dist/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.esm.js +128 -0
- package/dist/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.esm.js.map +1 -0
- package/dist/core-app-api/src/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js +105 -0
- package/dist/core-app-api/src/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js.map +1 -0
- package/dist/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js +275 -0
- package/dist/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js.map +1 -0
- package/dist/core-app-api/src/app/AppThemeProvider.esm.js +60 -0
- package/dist/core-app-api/src/app/AppThemeProvider.esm.js.map +1 -0
- package/dist/core-app-api/src/app/defaultConfigLoader.esm.js +33 -0
- package/dist/core-app-api/src/app/defaultConfigLoader.esm.js.map +1 -0
- package/dist/core-app-api/src/app/isProtectedApp.esm.js +9 -0
- package/dist/core-app-api/src/app/isProtectedApp.esm.js.map +1 -0
- package/dist/core-app-api/src/app/overrideBaseUrlConfigs.esm.js +50 -0
- package/dist/core-app-api/src/app/overrideBaseUrlConfigs.esm.js.map +1 -0
- package/dist/core-app-api/src/lib/subjects.esm.js +75 -0
- package/dist/core-app-api/src/lib/subjects.esm.js.map +1 -0
- package/dist/core-plugin-api/src/translation/TranslationRef.esm.js +13 -0
- package/dist/core-plugin-api/src/translation/TranslationRef.esm.js.map +1 -0
- package/dist/core-plugin-api/src/translation/TranslationResource.esm.js +13 -0
- package/dist/core-plugin-api/src/translation/TranslationResource.esm.js.map +1 -0
- package/dist/extensions/App.esm.js +39 -0
- package/dist/extensions/App.esm.js.map +1 -0
- package/dist/extensions/AppLayout.esm.js +34 -0
- package/dist/extensions/AppLayout.esm.js.map +1 -0
- package/dist/extensions/AppNav.esm.js +63 -0
- package/dist/extensions/AppNav.esm.js.map +1 -0
- package/dist/extensions/AppRoot.esm.js +125 -0
- package/dist/extensions/AppRoot.esm.js.map +1 -0
- package/dist/extensions/AppRoutes.esm.js +43 -0
- package/dist/extensions/AppRoutes.esm.js.map +1 -0
- package/dist/extensions/components.esm.js +52 -0
- package/dist/extensions/components.esm.js.map +1 -0
- package/dist/extensions/elements.esm.js +26 -0
- package/dist/extensions/elements.esm.js.map +1 -0
- package/dist/extensions/themes.esm.js +23 -0
- package/dist/extensions/themes.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/routing/ExternalRouteRef.esm.js +13 -0
- package/dist/frontend-plugin-api/src/routing/ExternalRouteRef.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/routing/RouteRef.esm.js +13 -0
- package/dist/frontend-plugin-api/src/routing/RouteRef.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/routing/SubRouteRef.esm.js +13 -0
- package/dist/frontend-plugin-api/src/routing/SubRouteRef.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/wiring/createExtension.esm.js +17 -0
- package/dist/frontend-plugin-api/src/wiring/createExtension.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/wiring/createExtensionOverrides.esm.js +17 -0
- package/dist/frontend-plugin-api/src/wiring/createExtensionOverrides.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/wiring/createPlugin.esm.js +15 -0
- package/dist/frontend-plugin-api/src/wiring/createPlugin.esm.js.map +1 -0
- package/dist/frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js +41 -0
- package/dist/frontend-plugin-api/src/wiring/resolveExtensionDefinition.esm.js.map +1 -0
- package/dist/index.esm.js +1 -3030
- package/dist/index.esm.js.map +1 -1
- package/dist/routing/RouteResolver.esm.js +133 -0
- package/dist/routing/RouteResolver.esm.js.map +1 -0
- package/dist/routing/RouteTracker.esm.js +73 -0
- package/dist/routing/RouteTracker.esm.js.map +1 -0
- package/dist/routing/collectRouteIds.esm.js +40 -0
- package/dist/routing/collectRouteIds.esm.js.map +1 -0
- package/dist/routing/extractRouteInfoFromAppNode.esm.js +85 -0
- package/dist/routing/extractRouteInfoFromAppNode.esm.js.map +1 -0
- package/dist/routing/getBasePath.esm.js +13 -0
- package/dist/routing/getBasePath.esm.js.map +1 -0
- package/dist/routing/resolveRouteBindings.esm.js +66 -0
- package/dist/routing/resolveRouteBindings.esm.js.map +1 -0
- package/dist/routing/toLegacyPlugin.esm.js +35 -0
- package/dist/routing/toLegacyPlugin.esm.js.map +1 -0
- package/dist/tree/createAppTree.esm.js +21 -0
- package/dist/tree/createAppTree.esm.js.map +1 -0
- package/dist/tree/instantiateAppNodeTree.esm.js +146 -0
- package/dist/tree/instantiateAppNodeTree.esm.js.map +1 -0
- package/dist/tree/readAppExtensionsConfig.esm.js +106 -0
- package/dist/tree/readAppExtensionsConfig.esm.js.map +1 -0
- package/dist/tree/resolveAppNodeSpecs.esm.js +168 -0
- package/dist/tree/resolveAppNodeSpecs.esm.js.map +1 -0
- package/dist/tree/resolveAppTree.esm.js +97 -0
- package/dist/tree/resolveAppTree.esm.js.map +1 -0
- package/dist/wiring/InternalAppContext.esm.js +6 -0
- package/dist/wiring/InternalAppContext.esm.js.map +1 -0
- package/dist/wiring/createApp.esm.js +285 -0
- package/dist/wiring/createApp.esm.js.map +1 -0
- package/dist/wiring/discovery.esm.js +56 -0
- package/dist/wiring/discovery.esm.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function toInternalTranslationResource(resource) {
|
|
2
|
+
const r = resource;
|
|
3
|
+
if (r.$$type !== "@backstage/TranslationResource") {
|
|
4
|
+
throw new Error(`Invalid translation resource, bad type '${r.$$type}'`);
|
|
5
|
+
}
|
|
6
|
+
if (r.version !== "v1") {
|
|
7
|
+
throw new Error(`Invalid translation resource, bad version '${r.version}'`);
|
|
8
|
+
}
|
|
9
|
+
return r;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { toInternalTranslationResource };
|
|
13
|
+
//# sourceMappingURL=TranslationResource.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TranslationResource.esm.js","sources":["../../../../../core-plugin-api/src/translation/TranslationResource.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n TranslationMessages,\n TranslationRef,\n} from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport interface TranslationResource<TId extends string = string> {\n $$type: '@backstage/TranslationResource';\n id: TId;\n}\n\n/** @internal */\nexport type InternalTranslationResourceLoader = () => Promise<{\n messages: { [key in string]: string | null };\n}>;\n\n/** @internal */\nexport interface InternalTranslationResource<TId extends string = string>\n extends TranslationResource<TId> {\n version: 'v1';\n resources: Array<{\n language: string;\n loader: InternalTranslationResourceLoader;\n }>;\n}\n\n/** @internal */\nexport function toInternalTranslationResource<TId extends string>(\n resource: TranslationResource<TId>,\n): InternalTranslationResource<TId> {\n const r = resource as InternalTranslationResource<TId>;\n if (r.$$type !== '@backstage/TranslationResource') {\n throw new Error(`Invalid translation resource, bad type '${r.$$type}'`);\n }\n if (r.version !== 'v1') {\n throw new Error(`Invalid translation resource, bad version '${r.version}'`);\n }\n\n return r;\n}\n\n/** @alpha */\nexport interface TranslationResourceOptions<\n TId extends string,\n TMessages extends { [key in string]: string },\n TTranslations extends {\n [language in string]: () => Promise<{\n default:\n | TranslationMessages<TId>\n | { [key in keyof TMessages]: string | null };\n }>;\n },\n> {\n ref: TranslationRef<TId, TMessages>;\n\n translations: TTranslations;\n}\n\n/** @alpha */\nexport function createTranslationResource<\n TId extends string,\n TMessages extends { [key in string]: string },\n TTranslations extends {\n [language in string]: () => Promise<{\n default:\n | TranslationMessages<TId>\n | { [key in keyof TMessages]: string | null };\n }>;\n },\n>(\n options: TranslationResourceOptions<TId, TMessages, TTranslations>,\n): TranslationResource<TId> {\n return {\n $$type: '@backstage/TranslationResource',\n version: 'v1',\n id: options.ref.id,\n resources: Object.entries(options.translations).map(\n ([language, loader]) => ({\n language,\n loader: () =>\n loader().then(m => {\n const value = m.default;\n return {\n messages:\n value?.$$type === '@backstage/TranslationMessages'\n ? value.messages\n : value,\n };\n }),\n }),\n ),\n } as InternalTranslationResource<TId>;\n}\n"],"names":[],"mappings":"AA2CO,SAAS,8BACd,QACkC,EAAA;AAClC,EAAA,MAAM,CAAI,GAAA,QAAA,CAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,gCAAkC,EAAA;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAA2C,wCAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GACxE;AACA,EAAI,IAAA,CAAA,CAAE,YAAY,IAAM,EAAA;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAA8C,2CAAA,EAAA,CAAA,CAAE,OAAO,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GAC5E;AAEA,EAAO,OAAA,CAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createExtension, createExtensionInput, createApiExtension, createThemeExtension, createComponentExtension, createTranslationExtension, coreExtensionData, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
3
|
+
|
|
4
|
+
const App = createExtension({
|
|
5
|
+
namespace: "app",
|
|
6
|
+
attachTo: { id: "root", input: "default" },
|
|
7
|
+
// ignored
|
|
8
|
+
inputs: {
|
|
9
|
+
apis: createExtensionInput({
|
|
10
|
+
api: createApiExtension.factoryDataRef
|
|
11
|
+
}),
|
|
12
|
+
themes: createExtensionInput({
|
|
13
|
+
theme: createThemeExtension.themeDataRef
|
|
14
|
+
}),
|
|
15
|
+
components: createExtensionInput({
|
|
16
|
+
component: createComponentExtension.componentDataRef
|
|
17
|
+
}),
|
|
18
|
+
translations: createExtensionInput({
|
|
19
|
+
translation: createTranslationExtension.translationDataRef
|
|
20
|
+
}),
|
|
21
|
+
root: createExtensionInput(
|
|
22
|
+
{
|
|
23
|
+
element: coreExtensionData.reactElement
|
|
24
|
+
},
|
|
25
|
+
{ singleton: true }
|
|
26
|
+
)
|
|
27
|
+
},
|
|
28
|
+
output: {
|
|
29
|
+
root: coreExtensionData.reactElement
|
|
30
|
+
},
|
|
31
|
+
factory({ node, inputs }) {
|
|
32
|
+
return {
|
|
33
|
+
root: /* @__PURE__ */ React.createElement(ExtensionBoundary, { node }, inputs.root.output.element)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export { App };
|
|
39
|
+
//# sourceMappingURL=App.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.esm.js","sources":["../../src/extensions/App.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n ExtensionBoundary,\n coreExtensionData,\n createApiExtension,\n createComponentExtension,\n createExtension,\n createExtensionInput,\n createThemeExtension,\n createTranslationExtension,\n} from '@backstage/frontend-plugin-api';\n\nexport const App = createExtension({\n namespace: 'app',\n attachTo: { id: 'root', input: 'default' }, // ignored\n inputs: {\n apis: createExtensionInput({\n api: createApiExtension.factoryDataRef,\n }),\n themes: createExtensionInput({\n theme: createThemeExtension.themeDataRef,\n }),\n components: createExtensionInput({\n component: createComponentExtension.componentDataRef,\n }),\n translations: createExtensionInput({\n translation: createTranslationExtension.translationDataRef,\n }),\n root: createExtensionInput(\n {\n element: coreExtensionData.reactElement,\n },\n { singleton: true },\n ),\n },\n output: {\n root: coreExtensionData.reactElement,\n },\n factory({ node, inputs }) {\n return {\n root: (\n <ExtensionBoundary node={node}>\n {inputs.root.output.element}\n </ExtensionBoundary>\n ),\n };\n },\n});\n"],"names":[],"mappings":";;;AA4BO,MAAM,MAAM,eAAgB,CAAA;AAAA,EACjC,SAAW,EAAA,KAAA;AAAA,EACX,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,SAAU,EAAA;AAAA;AAAA,EACzC,MAAQ,EAAA;AAAA,IACN,MAAM,oBAAqB,CAAA;AAAA,MACzB,KAAK,kBAAmB,CAAA,cAAA;AAAA,KACzB,CAAA;AAAA,IACD,QAAQ,oBAAqB,CAAA;AAAA,MAC3B,OAAO,oBAAqB,CAAA,YAAA;AAAA,KAC7B,CAAA;AAAA,IACD,YAAY,oBAAqB,CAAA;AAAA,MAC/B,WAAW,wBAAyB,CAAA,gBAAA;AAAA,KACrC,CAAA;AAAA,IACD,cAAc,oBAAqB,CAAA;AAAA,MACjC,aAAa,0BAA2B,CAAA,kBAAA;AAAA,KACzC,CAAA;AAAA,IACD,IAAM,EAAA,oBAAA;AAAA,MACJ;AAAA,QACE,SAAS,iBAAkB,CAAA,YAAA;AAAA,OAC7B;AAAA,MACA,EAAE,WAAW,IAAK,EAAA;AAAA,KACpB;AAAA,GACF;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,MAAM,iBAAkB,CAAA,YAAA;AAAA,GAC1B;AAAA,EACA,OAAQ,CAAA,EAAE,IAAM,EAAA,MAAA,EAAU,EAAA;AACxB,IAAO,OAAA;AAAA,MACL,sBACG,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,QAChB,MAAO,CAAA,IAAA,CAAK,OAAO,OACtB,CAAA;AAAA,KAEJ,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createExtension, createExtensionInput, coreExtensionData } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { SidebarPage } from '@backstage/core-components';
|
|
4
|
+
|
|
5
|
+
const AppLayout = createExtension({
|
|
6
|
+
namespace: "app",
|
|
7
|
+
name: "layout",
|
|
8
|
+
attachTo: { id: "app/root", input: "children" },
|
|
9
|
+
inputs: {
|
|
10
|
+
nav: createExtensionInput(
|
|
11
|
+
{
|
|
12
|
+
element: coreExtensionData.reactElement
|
|
13
|
+
},
|
|
14
|
+
{ singleton: true }
|
|
15
|
+
),
|
|
16
|
+
content: createExtensionInput(
|
|
17
|
+
{
|
|
18
|
+
element: coreExtensionData.reactElement
|
|
19
|
+
},
|
|
20
|
+
{ singleton: true }
|
|
21
|
+
)
|
|
22
|
+
},
|
|
23
|
+
output: {
|
|
24
|
+
element: coreExtensionData.reactElement
|
|
25
|
+
},
|
|
26
|
+
factory({ inputs }) {
|
|
27
|
+
return {
|
|
28
|
+
element: /* @__PURE__ */ React.createElement(SidebarPage, null, inputs.nav.output.element, inputs.content.output.element)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export { AppLayout };
|
|
34
|
+
//# sourceMappingURL=AppLayout.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppLayout.esm.js","sources":["../../src/extensions/AppLayout.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { SidebarPage } from '@backstage/core-components';\n\nexport const AppLayout = createExtension({\n namespace: 'app',\n name: 'layout',\n attachTo: { id: 'app/root', input: 'children' },\n inputs: {\n nav: createExtensionInput(\n {\n element: coreExtensionData.reactElement,\n },\n { singleton: true },\n ),\n content: createExtensionInput(\n {\n element: coreExtensionData.reactElement,\n },\n { singleton: true },\n ),\n },\n output: {\n element: coreExtensionData.reactElement,\n },\n factory({ inputs }) {\n return {\n element: (\n <SidebarPage>\n {inputs.nav.output.element}\n {inputs.content.output.element}\n </SidebarPage>\n ),\n };\n },\n});\n"],"names":[],"mappings":";;;;AAwBO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,UAAW,EAAA;AAAA,EAC9C,MAAQ,EAAA;AAAA,IACN,GAAK,EAAA,oBAAA;AAAA,MACH;AAAA,QACE,SAAS,iBAAkB,CAAA,YAAA;AAAA,OAC7B;AAAA,MACA,EAAE,WAAW,IAAK,EAAA;AAAA,KACpB;AAAA,IACA,OAAS,EAAA,oBAAA;AAAA,MACP;AAAA,QACE,SAAS,iBAAkB,CAAA,YAAA;AAAA,OAC7B;AAAA,MACA,EAAE,WAAW,IAAK,EAAA;AAAA,KACpB;AAAA,GACF;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,SAAS,iBAAkB,CAAA,YAAA;AAAA,GAC7B;AAAA,EACA,OAAA,CAAQ,EAAE,MAAA,EAAU,EAAA;AAClB,IAAO,OAAA;AAAA,MACL,OAAA,kBACG,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAA,EACE,MAAO,CAAA,GAAA,CAAI,OAAO,OAClB,EAAA,MAAA,CAAO,OAAQ,CAAA,MAAA,CAAO,OACzB,CAAA;AAAA,KAEJ,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createExtension, createExtensionInput, createNavItemExtension, createNavLogoExtension, coreExtensionData, useRouteRef } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
4
|
+
import { sidebarConfig, Sidebar, SidebarDivider, useSidebarOpenState, Link, SidebarItem } from '@backstage/core-components';
|
|
5
|
+
import LogoIcon from '../app/src/components/Root/LogoIcon.esm.js';
|
|
6
|
+
import LogoFull from '../app/src/components/Root/LogoFull.esm.js';
|
|
7
|
+
|
|
8
|
+
const useSidebarLogoStyles = makeStyles({
|
|
9
|
+
root: {
|
|
10
|
+
width: sidebarConfig.drawerWidthClosed,
|
|
11
|
+
height: 3 * sidebarConfig.logoHeight,
|
|
12
|
+
display: "flex",
|
|
13
|
+
flexFlow: "row nowrap",
|
|
14
|
+
alignItems: "center",
|
|
15
|
+
marginBottom: -14
|
|
16
|
+
},
|
|
17
|
+
link: {
|
|
18
|
+
width: sidebarConfig.drawerWidthClosed,
|
|
19
|
+
marginLeft: 24
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const SidebarLogo = (props) => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const classes = useSidebarLogoStyles();
|
|
25
|
+
const { isOpen } = useSidebarOpenState();
|
|
26
|
+
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Link, { to: "/", underline: "none", className: classes.link, "aria-label": "Home" }, isOpen ? (_a = props == null ? void 0 : props.logoFull) != null ? _a : /* @__PURE__ */ React.createElement(LogoFull, null) : (_b = props == null ? void 0 : props.logoIcon) != null ? _b : /* @__PURE__ */ React.createElement(LogoIcon, null)));
|
|
27
|
+
};
|
|
28
|
+
const SidebarNavItem = (props) => {
|
|
29
|
+
const { icon: Icon, title, routeRef } = props;
|
|
30
|
+
const to = useRouteRef(routeRef)();
|
|
31
|
+
return /* @__PURE__ */ React.createElement(SidebarItem, { to, icon: Icon, text: title });
|
|
32
|
+
};
|
|
33
|
+
const AppNav = createExtension({
|
|
34
|
+
namespace: "app",
|
|
35
|
+
name: "nav",
|
|
36
|
+
attachTo: { id: "app/layout", input: "nav" },
|
|
37
|
+
inputs: {
|
|
38
|
+
items: createExtensionInput({
|
|
39
|
+
target: createNavItemExtension.targetDataRef
|
|
40
|
+
}),
|
|
41
|
+
logos: createExtensionInput(
|
|
42
|
+
{
|
|
43
|
+
elements: createNavLogoExtension.logoElementsDataRef
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
singleton: true,
|
|
47
|
+
optional: true
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
},
|
|
51
|
+
output: {
|
|
52
|
+
element: coreExtensionData.reactElement
|
|
53
|
+
},
|
|
54
|
+
factory({ inputs }) {
|
|
55
|
+
var _a;
|
|
56
|
+
return {
|
|
57
|
+
element: /* @__PURE__ */ React.createElement(Sidebar, null, /* @__PURE__ */ React.createElement(SidebarLogo, { ...(_a = inputs.logos) == null ? void 0 : _a.output.elements }), /* @__PURE__ */ React.createElement(SidebarDivider, null), inputs.items.map((item, index) => /* @__PURE__ */ React.createElement(SidebarNavItem, { ...item.output.target, key: index })))
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
export { AppNav };
|
|
63
|
+
//# sourceMappingURL=AppNav.esm.js.map
|
|
@@ -0,0 +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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n useRouteRef,\n createNavItemExtension,\n createNavLogoExtension,\n} from '@backstage/frontend-plugin-api';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Sidebar,\n useSidebarOpenState,\n Link,\n sidebarConfig,\n SidebarDivider,\n SidebarItem,\n} from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoIcon from '../../../app/src/components/Root/LogoIcon';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoFull from '../../../app/src/components/Root/LogoFull';\n\nconst useSidebarLogoStyles = makeStyles({\n root: {\n width: sidebarConfig.drawerWidthClosed,\n height: 3 * sidebarConfig.logoHeight,\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n marginBottom: -14,\n },\n link: {\n width: sidebarConfig.drawerWidthClosed,\n marginLeft: 24,\n },\n});\n\nconst SidebarLogo = (\n props: (typeof createNavLogoExtension.logoElementsDataRef)['T'],\n) => {\n const classes = useSidebarLogoStyles();\n const { isOpen } = useSidebarOpenState();\n\n return (\n <div className={classes.root}>\n <Link to=\"/\" underline=\"none\" className={classes.link} aria-label=\"Home\">\n {isOpen\n ? props?.logoFull ?? <LogoFull />\n : props?.logoIcon ?? <LogoIcon />}\n </Link>\n </div>\n );\n};\n\nconst SidebarNavItem = (\n props: (typeof createNavItemExtension.targetDataRef)['T'],\n) => {\n const { icon: Icon, title, routeRef } = props;\n const to = useRouteRef(routeRef)();\n // TODO: Support opening modal, for example, the search one\n return <SidebarItem to={to} icon={Icon} text={title} />;\n};\n\nexport const AppNav = createExtension({\n namespace: 'app',\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput({\n target: createNavItemExtension.targetDataRef,\n }),\n logos: createExtensionInput(\n {\n elements: createNavLogoExtension.logoElementsDataRef,\n },\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n output: {\n element: coreExtensionData.reactElement,\n },\n factory({ inputs }) {\n return {\n element: (\n <Sidebar>\n <SidebarLogo {...inputs.logos?.output.elements} />\n <SidebarDivider />\n {inputs.items.map((item, index) => (\n <SidebarNavItem {...item.output.target} key={index} />\n ))}\n </Sidebar>\n ),\n };\n },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React, { Fragment, useContext, useState } from 'react';
|
|
2
|
+
import { createExtension, createExtensionInput, createRouterExtension, createSignInPageExtension, coreExtensionData, createAppRootWrapperExtension } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
4
|
+
import { InternalAppContext } from '../wiring/InternalAppContext.esm.js';
|
|
5
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
6
|
+
import { RouteTracker } from '../routing/RouteTracker.esm.js';
|
|
7
|
+
import { getBasePath } from '../routing/getBasePath.esm.js';
|
|
8
|
+
|
|
9
|
+
const AppRoot = createExtension({
|
|
10
|
+
namespace: "app",
|
|
11
|
+
name: "root",
|
|
12
|
+
attachTo: { id: "app", input: "root" },
|
|
13
|
+
inputs: {
|
|
14
|
+
router: createExtensionInput(
|
|
15
|
+
{ component: createRouterExtension.componentDataRef },
|
|
16
|
+
{ singleton: true, optional: true }
|
|
17
|
+
),
|
|
18
|
+
signInPage: createExtensionInput(
|
|
19
|
+
{ component: createSignInPageExtension.componentDataRef },
|
|
20
|
+
{ singleton: true, optional: true }
|
|
21
|
+
),
|
|
22
|
+
children: createExtensionInput(
|
|
23
|
+
{ element: coreExtensionData.reactElement },
|
|
24
|
+
{ singleton: true }
|
|
25
|
+
),
|
|
26
|
+
elements: createExtensionInput({
|
|
27
|
+
element: coreExtensionData.reactElement
|
|
28
|
+
}),
|
|
29
|
+
wrappers: createExtensionInput({
|
|
30
|
+
component: createAppRootWrapperExtension.componentDataRef
|
|
31
|
+
})
|
|
32
|
+
},
|
|
33
|
+
output: {
|
|
34
|
+
element: coreExtensionData.reactElement
|
|
35
|
+
},
|
|
36
|
+
factory({ inputs }) {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
let content = /* @__PURE__ */ React.createElement(React.Fragment, null, inputs.elements.map((el) => /* @__PURE__ */ React.createElement(Fragment, { key: el.node.spec.id }, el.output.element)), inputs.children.output.element);
|
|
39
|
+
for (const wrapper of inputs.wrappers) {
|
|
40
|
+
content = /* @__PURE__ */ React.createElement(wrapper.output.component, null, content);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
element: /* @__PURE__ */ React.createElement(
|
|
44
|
+
AppRouter,
|
|
45
|
+
{
|
|
46
|
+
SignInPageComponent: (_a = inputs.signInPage) == null ? void 0 : _a.output.component,
|
|
47
|
+
RouterComponent: (_b = inputs.router) == null ? void 0 : _b.output.component
|
|
48
|
+
},
|
|
49
|
+
content
|
|
50
|
+
)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
function SignInPageWrapper({
|
|
55
|
+
component: Component,
|
|
56
|
+
appIdentityProxy,
|
|
57
|
+
children
|
|
58
|
+
}) {
|
|
59
|
+
const [identityApi, setIdentityApi] = useState();
|
|
60
|
+
const configApi = useApi(configApiRef);
|
|
61
|
+
const basePath = getBasePath(configApi);
|
|
62
|
+
if (!identityApi) {
|
|
63
|
+
return /* @__PURE__ */ React.createElement(Component, { onSignInSuccess: setIdentityApi });
|
|
64
|
+
}
|
|
65
|
+
appIdentityProxy.setTarget(identityApi, {
|
|
66
|
+
signOutTargetUrl: basePath || "/"
|
|
67
|
+
});
|
|
68
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
69
|
+
}
|
|
70
|
+
function DefaultRouter(props) {
|
|
71
|
+
const configApi = useApi(configApiRef);
|
|
72
|
+
const basePath = getBasePath(configApi);
|
|
73
|
+
return /* @__PURE__ */ React.createElement(BrowserRouter, { basename: basePath }, props.children);
|
|
74
|
+
}
|
|
75
|
+
function AppRouter(props) {
|
|
76
|
+
const {
|
|
77
|
+
children,
|
|
78
|
+
SignInPageComponent,
|
|
79
|
+
RouterComponent = DefaultRouter
|
|
80
|
+
} = props;
|
|
81
|
+
const configApi = useApi(configApiRef);
|
|
82
|
+
const basePath = getBasePath(configApi);
|
|
83
|
+
const internalAppContext = useContext(InternalAppContext);
|
|
84
|
+
if (!internalAppContext) {
|
|
85
|
+
throw new Error("AppRouter must be rendered within the AppProvider");
|
|
86
|
+
}
|
|
87
|
+
const { routeObjects, appIdentityProxy } = internalAppContext;
|
|
88
|
+
if (!SignInPageComponent) {
|
|
89
|
+
appIdentityProxy.setTarget(
|
|
90
|
+
{
|
|
91
|
+
getUserId: () => "guest",
|
|
92
|
+
getIdToken: async () => void 0,
|
|
93
|
+
getProfile: () => ({
|
|
94
|
+
email: "guest@example.com",
|
|
95
|
+
displayName: "Guest"
|
|
96
|
+
}),
|
|
97
|
+
getProfileInfo: async () => ({
|
|
98
|
+
email: "guest@example.com",
|
|
99
|
+
displayName: "Guest"
|
|
100
|
+
}),
|
|
101
|
+
getBackstageIdentity: async () => ({
|
|
102
|
+
type: "user",
|
|
103
|
+
userEntityRef: "user:default/guest",
|
|
104
|
+
ownershipEntityRefs: ["user:default/guest"]
|
|
105
|
+
}),
|
|
106
|
+
getCredentials: async () => ({}),
|
|
107
|
+
signOut: async () => {
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{ signOutTargetUrl: basePath || "/" }
|
|
111
|
+
);
|
|
112
|
+
return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), children);
|
|
113
|
+
}
|
|
114
|
+
return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), /* @__PURE__ */ React.createElement(
|
|
115
|
+
SignInPageWrapper,
|
|
116
|
+
{
|
|
117
|
+
component: SignInPageComponent,
|
|
118
|
+
appIdentityProxy
|
|
119
|
+
},
|
|
120
|
+
children
|
|
121
|
+
));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { AppRoot, AppRouter };
|
|
125
|
+
//# sourceMappingURL=AppRoot.esm.js.map
|
|
@@ -0,0 +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 React, {\n ComponentType,\n Fragment,\n PropsWithChildren,\n ReactNode,\n useContext,\n useState,\n} from 'react';\nimport {\n coreExtensionData,\n createAppRootWrapperExtension,\n createExtension,\n createExtensionInput,\n createRouterExtension,\n createSignInPageExtension,\n} from '@backstage/frontend-plugin-api';\nimport {\n IdentityApi,\n SignInPageProps,\n configApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { InternalAppContext } from '../wiring/InternalAppContext';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy';\nimport { BrowserRouter } from 'react-router-dom';\nimport { RouteTracker } from '../routing/RouteTracker';\nimport { getBasePath } from '../routing/getBasePath';\n\nexport const AppRoot = createExtension({\n namespace: 'app',\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput(\n { component: createRouterExtension.componentDataRef },\n { singleton: true, optional: true },\n ),\n signInPage: createExtensionInput(\n { component: createSignInPageExtension.componentDataRef },\n { singleton: true, optional: true },\n ),\n children: createExtensionInput(\n { element: coreExtensionData.reactElement },\n { singleton: true },\n ),\n elements: createExtensionInput({\n element: coreExtensionData.reactElement,\n }),\n wrappers: createExtensionInput({\n component: createAppRootWrapperExtension.componentDataRef,\n }),\n },\n output: {\n element: coreExtensionData.reactElement,\n },\n factory({ inputs }) {\n let content: React.ReactNode = (\n <>\n {inputs.elements.map(el => (\n <Fragment key={el.node.spec.id}>{el.output.element}</Fragment>\n ))}\n {inputs.children.output.element}\n </>\n );\n\n for (const wrapper of inputs.wrappers) {\n content = <wrapper.output.component>{content}</wrapper.output.component>;\n }\n\n return {\n element: (\n <AppRouter\n SignInPageComponent={inputs.signInPage?.output.component}\n RouterComponent={inputs.router?.output.component}\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\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n SignInPageComponent?: ComponentType<SignInPageProps>;\n RouterComponent?: ComponentType<PropsWithChildren<{}>>;\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 } = props;\n\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n const internalAppContext = useContext(InternalAppContext);\n if (!internalAppContext) {\n throw new Error('AppRouter must be rendered within the AppProvider');\n }\n const { routeObjects, appIdentityProxy } = internalAppContext;\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 <RouteTracker routeObjects={routeObjects} />\n {children}\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\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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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createExtension, createExtensionInput, coreExtensionData, useComponentRef, coreComponentRefs } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { useRoutes } from 'react-router-dom';
|
|
4
|
+
|
|
5
|
+
const AppRoutes = createExtension({
|
|
6
|
+
namespace: "app",
|
|
7
|
+
name: "routes",
|
|
8
|
+
attachTo: { id: "app/layout", input: "content" },
|
|
9
|
+
inputs: {
|
|
10
|
+
routes: createExtensionInput({
|
|
11
|
+
path: coreExtensionData.routePath,
|
|
12
|
+
ref: coreExtensionData.routeRef.optional(),
|
|
13
|
+
element: coreExtensionData.reactElement
|
|
14
|
+
})
|
|
15
|
+
},
|
|
16
|
+
output: {
|
|
17
|
+
element: coreExtensionData.reactElement
|
|
18
|
+
},
|
|
19
|
+
factory({ inputs }) {
|
|
20
|
+
const Routes = () => {
|
|
21
|
+
const NotFoundErrorPage = useComponentRef(
|
|
22
|
+
coreComponentRefs.notFoundErrorPage
|
|
23
|
+
);
|
|
24
|
+
const element = useRoutes([
|
|
25
|
+
...inputs.routes.map((route) => ({
|
|
26
|
+
path: `${route.output.path}/*`,
|
|
27
|
+
element: route.output.element
|
|
28
|
+
})),
|
|
29
|
+
{
|
|
30
|
+
path: "*",
|
|
31
|
+
element: /* @__PURE__ */ React.createElement(NotFoundErrorPage, null)
|
|
32
|
+
}
|
|
33
|
+
]);
|
|
34
|
+
return element;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
element: /* @__PURE__ */ React.createElement(Routes, null)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export { AppRoutes };
|
|
43
|
+
//# sourceMappingURL=AppRoutes.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppRoutes.esm.js","sources":["../../src/extensions/AppRoutes.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n coreComponentRefs,\n useComponentRef,\n} from '@backstage/frontend-plugin-api';\nimport { useRoutes } from 'react-router-dom';\n\nexport const AppRoutes = createExtension({\n namespace: 'app',\n name: 'routes',\n attachTo: { id: 'app/layout', input: 'content' },\n inputs: {\n routes: createExtensionInput({\n path: coreExtensionData.routePath,\n ref: coreExtensionData.routeRef.optional(),\n element: coreExtensionData.reactElement,\n }),\n },\n output: {\n element: coreExtensionData.reactElement,\n },\n factory({ inputs }) {\n const Routes = () => {\n const NotFoundErrorPage = useComponentRef(\n coreComponentRefs.notFoundErrorPage,\n );\n\n const element = useRoutes([\n ...inputs.routes.map(route => ({\n path: `${route.output.path}/*`,\n element: route.output.element,\n })),\n {\n path: '*',\n element: <NotFoundErrorPage />,\n },\n ]);\n\n return element;\n };\n\n return {\n element: <Routes />,\n };\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,YAAA,EAAc,OAAO,SAAU,EAAA;AAAA,EAC/C,MAAQ,EAAA;AAAA,IACN,QAAQ,oBAAqB,CAAA;AAAA,MAC3B,MAAM,iBAAkB,CAAA,SAAA;AAAA,MACxB,GAAA,EAAK,iBAAkB,CAAA,QAAA,CAAS,QAAS,EAAA;AAAA,MACzC,SAAS,iBAAkB,CAAA,YAAA;AAAA,KAC5B,CAAA;AAAA,GACH;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,SAAS,iBAAkB,CAAA,YAAA;AAAA,GAC7B;AAAA,EACA,OAAA,CAAQ,EAAE,MAAA,EAAU,EAAA;AAClB,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,iBAAoB,GAAA,eAAA;AAAA,QACxB,iBAAkB,CAAA,iBAAA;AAAA,OACpB,CAAA;AAEA,MAAA,MAAM,UAAU,SAAU,CAAA;AAAA,QACxB,GAAG,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,CAAU,KAAA,MAAA;AAAA,UAC7B,IAAM,EAAA,CAAA,EAAG,KAAM,CAAA,MAAA,CAAO,IAAI,CAAA,EAAA,CAAA;AAAA,UAC1B,OAAA,EAAS,MAAM,MAAO,CAAA,OAAA;AAAA,SACtB,CAAA,CAAA;AAAA,QACF;AAAA,UACE,IAAM,EAAA,GAAA;AAAA,UACN,OAAA,sCAAU,iBAAkB,EAAA,IAAA,CAAA;AAAA,SAC9B;AAAA,OACD,CAAA,CAAA;AAED,MAAO,OAAA,OAAA,CAAA;AAAA,KACT,CAAA;AAEA,IAAO,OAAA;AAAA,MACL,OAAA,sCAAU,MAAO,EAAA,IAAA,CAAA;AAAA,KACnB,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Button from '@material-ui/core/Button';
|
|
3
|
+
import { createComponentExtension, coreComponentRefs } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { ErrorPanel } from '@backstage/core-components';
|
|
5
|
+
import '../app-defaults/src/defaults/apis.esm.js';
|
|
6
|
+
import { components } from '../app-defaults/src/defaults/components.esm.js';
|
|
7
|
+
import '@material-ui/icons/Apartment';
|
|
8
|
+
import '@material-ui/icons/BrokenImage';
|
|
9
|
+
import '@material-ui/icons/Category';
|
|
10
|
+
import '@material-ui/icons/CreateNewFolder';
|
|
11
|
+
import '@material-ui/icons/Subject';
|
|
12
|
+
import '@material-ui/icons/Search';
|
|
13
|
+
import '@material-ui/icons/Chat';
|
|
14
|
+
import '@material-ui/icons/Dashboard';
|
|
15
|
+
import '@material-ui/icons/Description';
|
|
16
|
+
import '@material-ui/icons/Email';
|
|
17
|
+
import '@material-ui/icons/Extension';
|
|
18
|
+
import '@material-ui/icons/GitHub';
|
|
19
|
+
import '@material-ui/icons/Help';
|
|
20
|
+
import '@material-ui/icons/LocationOn';
|
|
21
|
+
import '@material-ui/icons/Memory';
|
|
22
|
+
import '@material-ui/icons/MenuBook';
|
|
23
|
+
import '@material-ui/icons/People';
|
|
24
|
+
import '@material-ui/icons/Person';
|
|
25
|
+
import '@material-ui/icons/Warning';
|
|
26
|
+
import '@material-ui/icons/Storage';
|
|
27
|
+
import '@material-ui/icons/FeaturedPlayList';
|
|
28
|
+
import '@backstage/theme';
|
|
29
|
+
import '@material-ui/icons/Brightness2';
|
|
30
|
+
import '@material-ui/icons/WbSunny';
|
|
31
|
+
|
|
32
|
+
const DefaultProgressComponent = createComponentExtension({
|
|
33
|
+
ref: coreComponentRefs.progress,
|
|
34
|
+
loader: { sync: () => components.Progress }
|
|
35
|
+
});
|
|
36
|
+
const DefaultNotFoundErrorPageComponent = createComponentExtension({
|
|
37
|
+
ref: coreComponentRefs.notFoundErrorPage,
|
|
38
|
+
loader: { sync: () => components.NotFoundErrorPage }
|
|
39
|
+
});
|
|
40
|
+
const DefaultErrorBoundaryComponent = createComponentExtension({
|
|
41
|
+
ref: coreComponentRefs.errorBoundaryFallback,
|
|
42
|
+
loader: {
|
|
43
|
+
sync: () => (props) => {
|
|
44
|
+
const { plugin, error, resetError } = props;
|
|
45
|
+
const title = `Error in ${plugin == null ? void 0 : plugin.id}`;
|
|
46
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title, error, defaultExpanded: true }, /* @__PURE__ */ React.createElement(Button, { variant: "outlined", onClick: resetError }, "Retry"));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export { DefaultErrorBoundaryComponent, DefaultNotFoundErrorPageComponent, DefaultProgressComponent };
|
|
52
|
+
//# sourceMappingURL=components.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\n// TODO: Dependency on MUI should be removed from core packages\nimport Button from '@material-ui/core/Button';\n\nimport {\n createComponentExtension,\n coreComponentRefs,\n} from '@backstage/frontend-plugin-api';\nimport { ErrorPanel } from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { components as defaultComponents } from '../../../app-defaults/src/defaults';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\n\nexport const DefaultProgressComponent = createComponentExtension({\n ref: coreComponentRefs.progress,\n loader: { sync: () => defaultComponents.Progress },\n});\n\nexport const DefaultNotFoundErrorPageComponent = createComponentExtension({\n ref: coreComponentRefs.notFoundErrorPage,\n loader: { sync: () => defaultComponents.NotFoundErrorPage },\n});\n\nexport const DefaultErrorBoundaryComponent = createComponentExtension({\n ref: coreComponentRefs.errorBoundaryFallback,\n loader: {\n sync: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n\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":["defaultComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BO,MAAM,2BAA2B,wBAAyB,CAAA;AAAA,EAC/D,KAAK,iBAAkB,CAAA,QAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,QAAS,EAAA;AACnD,CAAC,EAAA;AAEM,MAAM,oCAAoC,wBAAyB,CAAA;AAAA,EACxE,KAAK,iBAAkB,CAAA,iBAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,iBAAkB,EAAA;AAC5D,CAAC,EAAA;AAEM,MAAM,gCAAgC,wBAAyB,CAAA;AAAA,EACpE,KAAK,iBAAkB,CAAA,qBAAA;AAAA,EACvB,MAAQ,EAAA;AAAA,IACN,IAAA,EAAM,MAAM,CAAS,KAAA,KAAA;AACnB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAO,EAAA,UAAA,EAAe,GAAA,KAAA,CAAA;AACtC,MAAM,MAAA,KAAA,GAAQ,CAAY,SAAA,EAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAQ,EAAE,CAAA,CAAA,CAAA;AAEpC,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,KAAc,EAAA,KAAA,EAAc,eAAe,EAAA,IAAA,EAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,OAAQ,EAAA,UAAA,EAAW,OAAS,EAAA,UAAA,EAAA,EAAY,OAEhD,CACF,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { OAuthRequestDialog, AlertDisplay } from '@backstage/core-components';
|
|
2
|
+
import { createAppRootElementExtension, createSchemaFromZod } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
const oauthRequestDialogAppRootElement = createAppRootElementExtension({
|
|
6
|
+
namespace: "app",
|
|
7
|
+
name: "oauth-request-dialog",
|
|
8
|
+
element: /* @__PURE__ */ React.createElement(OAuthRequestDialog, null)
|
|
9
|
+
});
|
|
10
|
+
const alertDisplayAppRootElement = createAppRootElementExtension({
|
|
11
|
+
namespace: "app",
|
|
12
|
+
name: "alert-display",
|
|
13
|
+
configSchema: createSchemaFromZod(
|
|
14
|
+
(z) => z.object({
|
|
15
|
+
transientTimeoutMs: z.number().default(5e3),
|
|
16
|
+
anchorOrigin: z.object({
|
|
17
|
+
vertical: z.enum(["top", "bottom"]).default("top"),
|
|
18
|
+
horizontal: z.enum(["left", "center", "right"]).default("center")
|
|
19
|
+
}).default({})
|
|
20
|
+
})
|
|
21
|
+
),
|
|
22
|
+
element: ({ config }) => /* @__PURE__ */ React.createElement(AlertDisplay, { ...config })
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export { alertDisplayAppRootElement, oauthRequestDialogAppRootElement };
|
|
26
|
+
//# sourceMappingURL=elements.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elements.esm.js","sources":["../../src/extensions/elements.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 { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';\nimport {\n createAppRootElementExtension,\n createSchemaFromZod,\n} from '@backstage/frontend-plugin-api';\nimport React from 'react';\n\nexport const oauthRequestDialogAppRootElement = createAppRootElementExtension({\n namespace: 'app',\n name: 'oauth-request-dialog',\n element: <OAuthRequestDialog />,\n});\n\nexport const alertDisplayAppRootElement = createAppRootElementExtension({\n namespace: 'app',\n name: 'alert-display',\n configSchema: createSchemaFromZod(z =>\n z.object({\n transientTimeoutMs: z.number().default(5000),\n anchorOrigin: z\n .object({\n vertical: z.enum(['top', 'bottom']).default('top'),\n horizontal: z.enum(['left', 'center', 'right']).default('center'),\n })\n .default({}),\n }),\n ),\n element: ({ config }) => <AlertDisplay {...config} />,\n});\n"],"names":[],"mappings":";;;;AAuBO,MAAM,mCAAmC,6BAA8B,CAAA;AAAA,EAC5E,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,sBAAA;AAAA,EACN,OAAA,sCAAU,kBAAmB,EAAA,IAAA,CAAA;AAC/B,CAAC,EAAA;AAEM,MAAM,6BAA6B,6BAA8B,CAAA;AAAA,EACtE,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,eAAA;AAAA,EACN,YAAc,EAAA,mBAAA;AAAA,IAAoB,CAAA,CAAA,KAChC,EAAE,MAAO,CAAA;AAAA,MACP,kBAAoB,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,GAAI,CAAA;AAAA,MAC3C,YAAA,EAAc,EACX,MAAO,CAAA;AAAA,QACN,QAAA,EAAU,EAAE,IAAK,CAAA,CAAC,OAAO,QAAQ,CAAC,CAAE,CAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACjD,UAAA,EAAY,CAAE,CAAA,IAAA,CAAK,CAAC,MAAA,EAAQ,UAAU,OAAO,CAAC,CAAE,CAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,OACjE,CAAA,CACA,OAAQ,CAAA,EAAE,CAAA;AAAA,KACd,CAAA;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,EAAE,MAAA,uBAAc,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAc,GAAG,MAAQ,EAAA,CAAA;AACrD,CAAC;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { UnifiedThemeProvider, themes } from '@backstage/theme';
|
|
3
|
+
import DarkIcon from '@material-ui/icons/Brightness2';
|
|
4
|
+
import LightIcon from '@material-ui/icons/WbSunny';
|
|
5
|
+
import { createThemeExtension } from '@backstage/frontend-plugin-api';
|
|
6
|
+
|
|
7
|
+
const LightTheme = createThemeExtension({
|
|
8
|
+
id: "light",
|
|
9
|
+
title: "Light Theme",
|
|
10
|
+
variant: "light",
|
|
11
|
+
icon: /* @__PURE__ */ React.createElement(LightIcon, null),
|
|
12
|
+
Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes.light, children })
|
|
13
|
+
});
|
|
14
|
+
const DarkTheme = createThemeExtension({
|
|
15
|
+
id: "dark",
|
|
16
|
+
title: "Dark Theme",
|
|
17
|
+
variant: "dark",
|
|
18
|
+
icon: /* @__PURE__ */ React.createElement(DarkIcon, null),
|
|
19
|
+
Provider: ({ children }) => /* @__PURE__ */ React.createElement(UnifiedThemeProvider, { theme: themes.dark, children })
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export { DarkTheme, LightTheme };
|
|
23
|
+
//# sourceMappingURL=themes.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.esm.js","sources":["../../src/extensions/themes.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\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 { createThemeExtension } from '@backstage/frontend-plugin-api';\n\nexport const LightTheme = createThemeExtension({\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\nexport const DarkTheme = createThemeExtension({\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"],"names":["builtinThemes"],"mappings":";;;;;;AAyBO,MAAM,aAAa,oBAAqB,CAAA;AAAA,EAC7C,EAAI,EAAA,OAAA;AAAA,EACJ,KAAO,EAAA,aAAA;AAAA,EACP,OAAS,EAAA,OAAA;AAAA,EACT,IAAA,sCAAO,SAAU,EAAA,IAAA,CAAA;AAAA,EACjB,QAAA,EAAU,CAAC,EAAE,QAAS,EAAA,yCACnB,oBAAqB,EAAA,EAAA,KAAA,EAAOA,MAAc,CAAA,KAAA,EAAO,QAAoB,EAAA,CAAA;AAE1E,CAAC,EAAA;AAEM,MAAM,YAAY,oBAAqB,CAAA;AAAA,EAC5C,EAAI,EAAA,MAAA;AAAA,EACJ,KAAO,EAAA,YAAA;AAAA,EACP,OAAS,EAAA,MAAA;AAAA,EACT,IAAA,sCAAO,QAAS,EAAA,IAAA,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,EAAE,QAAS,EAAA,yCACnB,oBAAqB,EAAA,EAAA,KAAA,EAAOA,MAAc,CAAA,IAAA,EAAM,QAAoB,EAAA,CAAA;AAEzE,CAAC;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function toInternalExternalRouteRef(resource) {
|
|
2
|
+
const r = resource;
|
|
3
|
+
if (r.$$type !== "@backstage/ExternalRouteRef") {
|
|
4
|
+
throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);
|
|
5
|
+
}
|
|
6
|
+
return r;
|
|
7
|
+
}
|
|
8
|
+
function isExternalRouteRef(opaque) {
|
|
9
|
+
return opaque.$$type === "@backstage/ExternalRouteRef";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { isExternalRouteRef, toInternalExternalRouteRef };
|
|
13
|
+
//# sourceMappingURL=ExternalRouteRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExternalRouteRef.esm.js","sources":["../../../../../frontend-plugin-api/src/routing/ExternalRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RouteRefImpl } from './RouteRef';\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface ExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> {\n readonly $$type: '@backstage/ExternalRouteRef';\n readonly T: TParams;\n readonly optional: TOptional;\n}\n\n/** @internal */\nexport interface InternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n> extends ExternalRouteRef<TParams, TOptional> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n getDefaultTarget(): string | undefined;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalExternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n TOptional extends boolean = boolean,\n>(\n resource: ExternalRouteRef<TParams, TOptional>,\n): InternalExternalRouteRef<TParams, TOptional> {\n const r = resource as InternalExternalRouteRef<TParams, TOptional>;\n if (r.$$type !== '@backstage/ExternalRouteRef') {\n throw new Error(`Invalid ExternalRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isExternalRouteRef(opaque: {\n $$type: string;\n}): opaque is ExternalRouteRef {\n return opaque.$$type === '@backstage/ExternalRouteRef';\n}\n\n/** @internal */\nclass ExternalRouteRefImpl\n extends RouteRefImpl\n implements InternalExternalRouteRef\n{\n readonly $$type = '@backstage/ExternalRouteRef' as any;\n\n constructor(\n readonly optional: boolean,\n readonly params: string[] = [],\n readonly defaultTarget: string | undefined,\n creationSite: string,\n ) {\n super(params, creationSite);\n }\n\n getDefaultTarget() {\n return this.defaultTarget;\n }\n}\n\n/**\n * Creates a route descriptor, to be later bound to a concrete route by the app. Used to implement cross-plugin route references.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @param options - Description of the route reference to be created.\n * @public\n */\nexport function createExternalRouteRef<\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TOptional extends boolean = false,\n TParamKeys extends string = string,\n>(options?: {\n /**\n * The parameters that will be provided to the external route reference.\n */\n readonly params?: string extends TParamKeys\n ? (keyof TParams)[]\n : TParamKeys[];\n\n /**\n * Whether or not this route is optional, defaults to false.\n *\n * Optional external routes are not required to be bound in the app, and\n * if they aren't, `useExternalRouteRef` will return `undefined`.\n */\n optional?: TOptional;\n\n /**\n * The route (typically in another plugin) that this should map to by default.\n *\n * The string is expected to be on the standard `<plugin id>.<route id>` form,\n * for example `techdocs.docRoot`.\n */\n defaultTarget?: string;\n}): ExternalRouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string },\n TOptional\n> {\n return new ExternalRouteRefImpl(\n Boolean(options?.optional),\n options?.params as string[] | undefined,\n options?.defaultTarget,\n describeParentCallSite(),\n ) as ExternalRouteRef<any, any>;\n}\n"],"names":[],"mappings":"AAoDO,SAAS,2BAId,QAC8C,EAAA;AAC9C,EAAA,MAAM,CAAI,GAAA,QAAA,CAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,6BAA+B,EAAA;AAC9C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAuC,oCAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GACpE;AAEA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAGO,SAAS,mBAAmB,MAEJ,EAAA;AAC7B,EAAA,OAAO,OAAO,MAAW,KAAA,6BAAA,CAAA;AAC3B;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function toInternalRouteRef(resource) {
|
|
2
|
+
const r = resource;
|
|
3
|
+
if (r.$$type !== "@backstage/RouteRef") {
|
|
4
|
+
throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);
|
|
5
|
+
}
|
|
6
|
+
return r;
|
|
7
|
+
}
|
|
8
|
+
function isRouteRef(opaque) {
|
|
9
|
+
return opaque.$$type === "@backstage/RouteRef";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { isRouteRef, toInternalRouteRef };
|
|
13
|
+
//# sourceMappingURL=RouteRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteRef.esm.js","sources":["../../../../../frontend-plugin-api/src/routing/RouteRef.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { describeParentCallSite } from './describeParentCallSite';\nimport { AnyRouteRefParams } from './types';\n\n/**\n * Absolute route reference.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface RouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/RouteRef';\n readonly T: TParams;\n}\n\n/** @internal */\nexport interface InternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends RouteRef<TParams> {\n readonly version: 'v1';\n getParams(): string[];\n getDescription(): string;\n\n setId(id: string): void;\n}\n\n/** @internal */\nexport function toInternalRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: RouteRef<TParams>): InternalRouteRef<TParams> {\n const r = resource as InternalRouteRef<TParams>;\n if (r.$$type !== '@backstage/RouteRef') {\n throw new Error(`Invalid RouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isRouteRef(opaque: { $$type: string }): opaque is RouteRef {\n return opaque.$$type === '@backstage/RouteRef';\n}\n\n/** @internal */\nexport class RouteRefImpl implements InternalRouteRef {\n readonly $$type = '@backstage/RouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #id?: string;\n #params: string[];\n #creationSite: string;\n\n constructor(readonly params: string[] = [], creationSite: string) {\n this.#params = params;\n this.#creationSite = creationSite;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getDescription(): string {\n if (this.#id) {\n return this.#id;\n }\n return `created at '${this.#creationSite}'`;\n }\n\n get #name() {\n return this.$$type.slice('@backstage/'.length);\n }\n\n setId(id: string): void {\n if (!id) {\n throw new Error(`${this.#name} id must be a non-empty string`);\n }\n if (this.#id) {\n throw new Error(\n `${this.#name} was referenced twice as both '${this.#id}' and '${id}'`,\n );\n }\n this.#id = id;\n }\n\n toString(): string {\n return `${this.#name}{${this.getDescription()}}`;\n }\n}\n\n/**\n * Create a {@link RouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createRouteRef<\n // Params is the type that we care about and the one to be embedded in the route ref.\n // For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}\n TParams extends { [param in TParamKeys]: string } | undefined = undefined,\n TParamKeys extends string = string,\n>(config?: {\n /** A list of parameter names that the path that this route ref is bound to must contain */\n readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[];\n}): RouteRef<\n keyof TParams extends never\n ? undefined\n : string extends TParamKeys\n ? TParams\n : { [param in TParamKeys]: string }\n> {\n return new RouteRefImpl(\n config?.params as string[] | undefined,\n describeParentCallSite(),\n ) as RouteRef<any>;\n}\n"],"names":[],"mappings":"AA+CO,SAAS,mBAEd,QAAwD,EAAA;AACxD,EAAA,MAAM,CAAI,GAAA,QAAA,CAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,qBAAuB,EAAA;AACtC,IAAA,MAAM,IAAI,KAAA,CAAM,CAA+B,4BAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GAC5D;AAEA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAGO,SAAS,WAAW,MAAgD,EAAA;AACzE,EAAA,OAAO,OAAO,MAAW,KAAA,qBAAA,CAAA;AAC3B;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function toInternalSubRouteRef(resource) {
|
|
2
|
+
const r = resource;
|
|
3
|
+
if (r.$$type !== "@backstage/SubRouteRef") {
|
|
4
|
+
throw new Error(`Invalid SubRouteRef, bad type '${r.$$type}'`);
|
|
5
|
+
}
|
|
6
|
+
return r;
|
|
7
|
+
}
|
|
8
|
+
function isSubRouteRef(opaque) {
|
|
9
|
+
return opaque.$$type === "@backstage/SubRouteRef";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { isSubRouteRef, toInternalSubRouteRef };
|
|
13
|
+
//# sourceMappingURL=SubRouteRef.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubRouteRef.esm.js","sources":["../../../../../frontend-plugin-api/src/routing/SubRouteRef.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RouteRef, toInternalRouteRef } from './RouteRef';\nimport { AnyRouteRefParams } from './types';\n\n// Should match the pattern in react-router\nconst PARAM_PATTERN = /^\\w+$/;\n\n/**\n * Descriptor of a route relative to an absolute {@link RouteRef}.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/plugins/composability#routing-system}.\n *\n * @public\n */\nexport interface SubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> {\n readonly $$type: '@backstage/SubRouteRef';\n\n readonly T: TParams;\n\n readonly path: string;\n}\n\n/** @internal */\nexport interface InternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n> extends SubRouteRef<TParams> {\n readonly version: 'v1';\n\n getParams(): string[];\n getParent(): RouteRef;\n getDescription(): string;\n}\n\n/** @internal */\nexport function toInternalSubRouteRef<\n TParams extends AnyRouteRefParams = AnyRouteRefParams,\n>(resource: SubRouteRef<TParams>): InternalSubRouteRef<TParams> {\n const r = resource as InternalSubRouteRef<TParams>;\n if (r.$$type !== '@backstage/SubRouteRef') {\n throw new Error(`Invalid SubRouteRef, bad type '${r.$$type}'`);\n }\n\n return r;\n}\n\n/** @internal */\nexport function isSubRouteRef(opaque: {\n $$type: string;\n}): opaque is SubRouteRef {\n return opaque.$$type === '@backstage/SubRouteRef';\n}\n\n/** @internal */\nexport class SubRouteRefImpl<TParams extends AnyRouteRefParams>\n implements SubRouteRef<TParams>\n{\n readonly $$type = '@backstage/SubRouteRef';\n readonly version = 'v1';\n declare readonly T: never;\n\n #params: string[];\n #parent: RouteRef;\n\n constructor(readonly path: string, params: string[], parent: RouteRef) {\n this.#params = params;\n this.#parent = parent;\n }\n\n getParams(): string[] {\n return this.#params;\n }\n\n getParent(): RouteRef {\n return this.#parent;\n }\n\n getDescription(): string {\n const parent = toInternalRouteRef(this.#parent);\n return `at ${this.path} with parent ${parent.getDescription()}`;\n }\n\n toString(): string {\n return `SubRouteRef{${this.getDescription()}}`;\n }\n}\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamPart<S extends string> = S extends `:${infer Param}` ? Param : never;\n\n/**\n * Used in {@link PathParams} type declaration.\n * @ignore\n */\ntype ParamNames<S extends string> = S extends `${infer Part}/${infer Rest}`\n ? ParamPart<Part> | ParamNames<Rest>\n : ParamPart<S>;\n/**\n * This utility type helps us infer a Param object type from a string path\n * For example, `/foo/:bar/:baz` inferred to `{ bar: string, baz: string }`\n * @ignore\n */\ntype PathParams<S extends string> = { [name in ParamNames<S>]: string };\n\n/**\n * Merges a param object type with an optional params type into a params object.\n * @ignore\n */\ntype MergeParams<\n P1 extends { [param in string]: string },\n P2 extends AnyRouteRefParams,\n> = (P1[keyof P1] extends never ? {} : P1) & (P2 extends undefined ? {} : P2);\n\n/**\n * Convert empty params to undefined.\n * @ignore\n */\ntype TrimEmptyParams<Params extends { [param in string]: string }> =\n keyof Params extends never ? undefined : Params;\n\n/**\n * Creates a SubRouteRef type given the desired parameters and parent route parameters.\n * The parameters types are merged together while ensuring that there is no overlap between the two.\n *\n * @ignore\n */\ntype MakeSubRouteRef<\n Params extends { [param in string]: string },\n ParentParams extends AnyRouteRefParams,\n> = keyof Params & keyof ParentParams extends never\n ? SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>\n : never;\n\n/**\n * Create a {@link SubRouteRef} from a route descriptor.\n *\n * @param config - Description of the route reference to be created.\n * @public\n */\nexport function createSubRouteRef<\n Path extends string,\n ParentParams extends AnyRouteRefParams = never,\n>(config: {\n path: Path;\n parent: RouteRef<ParentParams>;\n}): MakeSubRouteRef<PathParams<Path>, ParentParams> {\n const { path, parent } = config;\n type Params = PathParams<Path>;\n\n const internalParent = toInternalRouteRef(parent);\n const parentParams = internalParent.getParams();\n\n // Collect runtime parameters from the path, e.g. ['bar', 'baz'] from '/foo/:bar/:baz'\n const pathParams = path\n .split('/')\n .filter(p => p.startsWith(':'))\n .map(p => p.substring(1));\n const params = [...parentParams, ...pathParams];\n\n if (parentParams.some(p => pathParams.includes(p as string))) {\n throw new Error(\n 'SubRouteRef may not have params that overlap with its parent',\n );\n }\n if (!path.startsWith('/')) {\n throw new Error(`SubRouteRef path must start with '/', got '${path}'`);\n }\n if (path.endsWith('/')) {\n throw new Error(`SubRouteRef path must not end with '/', got '${path}'`);\n }\n for (const param of pathParams) {\n if (!PARAM_PATTERN.test(param)) {\n throw new Error(`SubRouteRef path has invalid param, got '${param}'`);\n }\n }\n\n // We ensure that the type of the return type is sane here\n const subRouteRef = new SubRouteRefImpl(\n path,\n params as string[],\n parent,\n ) as SubRouteRef<TrimEmptyParams<MergeParams<Params, ParentParams>>>;\n\n // But skip type checking of the return value itself, because the conditional\n // type checking of the parent parameter overlap is tricky to express.\n return subRouteRef as any;\n}\n"],"names":[],"mappings":"AAqDO,SAAS,sBAEd,QAA8D,EAAA;AAC9D,EAAA,MAAM,CAAI,GAAA,QAAA,CAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,wBAA0B,EAAA;AACzC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAkC,+BAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,GAC/D;AAEA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAGO,SAAS,cAAc,MAEJ,EAAA;AACxB,EAAA,OAAO,OAAO,MAAW,KAAA,wBAAA,CAAA;AAC3B;;;;"}
|