@backstage/core-app-api 1.19.6-next.0 → 1.19.6

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,28 @@
1
1
  # @backstage/core-app-api
2
2
 
3
+ ## 1.19.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 12d8afe: Added `BUIProvider` from `@backstage/ui` to the app shell provider tree, enabling BUI components to fire analytics events through the Backstage analytics system.
8
+ - 59752a2: Deprecated `AlertApiForwarder` in favor of the new `ToastApi`. The `AlertApiForwarder` now emits a console warning on first use, guiding developers to migrate to `ToastApi` from `@backstage/frontend-plugin-api`.
9
+ - 0452d02: Add optional `description` field to plugin-level feature flags.
10
+ - 42f8c9b: Added `BUIProvider` inside the legacy app router to enable client-side routing for all BUI components.
11
+ - a49a40d: Updated dependency `zod` to `^3.25.76 || ^4.0.0` & migrated to `/v3` or `/v4` imports.
12
+ - Updated dependencies
13
+ - @backstage/ui@0.13.0
14
+ - @backstage/core-plugin-api@1.12.4
15
+
16
+ ## 1.19.6-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 12d8afe: Added `BUIProvider` from `@backstage/ui` to the app shell provider tree, enabling BUI components to fire analytics events through the Backstage analytics system.
21
+ - 0452d02: Add optional `description` field to plugin-level feature flags.
22
+ - Updated dependencies
23
+ - @backstage/ui@0.13.0-next.2
24
+ - @backstage/core-plugin-api@1.12.4-next.1
25
+
3
26
  ## 1.19.6-next.0
4
27
 
5
28
  ### Patch Changes
@@ -5,7 +5,14 @@ class AlertApiForwarder {
5
5
  subject = new PublishSubject();
6
6
  recentAlerts = [];
7
7
  maxBufferSize = 10;
8
+ hasWarnedDeprecation = false;
8
9
  post(alert) {
10
+ if (!this.hasWarnedDeprecation) {
11
+ this.hasWarnedDeprecation = true;
12
+ console.warn(
13
+ 'AlertApi is deprecated and will be removed in a future release. Please migrate to ToastApi from @backstage/frontend-plugin-api. ToastApi provides richer features including title/description, links, icons, and per-toast timeouts. Example: toastApi.post({ title: "Saved!", status: "success", timeout: 5000 })'
14
+ );
15
+ }
9
16
  this.recentAlerts.push(alert);
10
17
  if (this.recentAlerts.length > this.maxBufferSize) {
11
18
  this.recentAlerts.shift();
@@ -1 +1 @@
1
- {"version":3,"file":"AlertApiForwarder.esm.js","sources":["../../../../src/apis/implementations/AlertApi/AlertApiForwarder.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 { AlertApi, AlertMessage } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * Base implementation for the AlertApi that simply forwards alerts to consumers.\n *\n * Recent alerts are buffered and replayed to new subscribers to prevent\n * missing alerts that were posted before subscription.\n *\n * @public\n */\nexport class AlertApiForwarder implements AlertApi {\n private readonly subject = new PublishSubject<AlertMessage>();\n private readonly recentAlerts: AlertMessage[] = [];\n private readonly maxBufferSize = 10;\n\n post(alert: AlertMessage) {\n this.recentAlerts.push(alert);\n if (this.recentAlerts.length > this.maxBufferSize) {\n this.recentAlerts.shift();\n }\n this.subject.next(alert);\n }\n\n alert$(): Observable<AlertMessage> {\n return new ObservableImpl<AlertMessage>(subscriber => {\n for (const alert of this.recentAlerts) {\n subscriber.next(alert);\n }\n return this.subject.subscribe(subscriber);\n });\n }\n}\n"],"names":[],"mappings":";;;AA6BO,MAAM,iBAAA,CAAsC;AAAA,EAChC,OAAA,GAAU,IAAI,cAAA,EAA6B;AAAA,EAC3C,eAA+B,EAAC;AAAA,EAChC,aAAA,GAAgB,EAAA;AAAA,EAEjC,KAAK,KAAA,EAAqB;AACxB,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,GAAS,IAAA,CAAK,aAAA,EAAe;AACjD,MAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AAAA,IAC1B;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACzB;AAAA,EAEA,MAAA,GAAmC;AACjC,IAAA,OAAO,IAAI,eAA6B,CAAA,UAAA,KAAc;AACpD,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,YAAA,EAAc;AACrC,QAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AAAA,MACvB;AACA,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,UAAU,CAAA;AAAA,IAC1C,CAAC,CAAA;AAAA,EACH;AACF;;;;"}
1
+ {"version":3,"file":"AlertApiForwarder.esm.js","sources":["../../../../src/apis/implementations/AlertApi/AlertApiForwarder.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 { AlertApi, AlertMessage } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * Base implementation for the AlertApi that simply forwards alerts to consumers.\n *\n * Recent alerts are buffered and replayed to new subscribers to prevent\n * missing alerts that were posted before subscription.\n *\n * @public\n * @deprecated Use ToastApi instead. AlertApi will be removed in a future release.\n */\nexport class AlertApiForwarder implements AlertApi {\n private readonly subject = new PublishSubject<AlertMessage>();\n private readonly recentAlerts: AlertMessage[] = [];\n private readonly maxBufferSize = 10;\n private hasWarnedDeprecation = false;\n\n post(alert: AlertMessage) {\n if (!this.hasWarnedDeprecation) {\n this.hasWarnedDeprecation = true;\n // eslint-disable-next-line no-console\n console.warn(\n 'AlertApi is deprecated and will be removed in a future release. ' +\n 'Please migrate to ToastApi from @backstage/frontend-plugin-api. ' +\n 'ToastApi provides richer features including title/description, links, icons, and per-toast timeouts. ' +\n 'Example: toastApi.post({ title: \"Saved!\", status: \"success\", timeout: 5000 })',\n );\n }\n this.recentAlerts.push(alert);\n if (this.recentAlerts.length > this.maxBufferSize) {\n this.recentAlerts.shift();\n }\n this.subject.next(alert);\n }\n\n alert$(): Observable<AlertMessage> {\n return new ObservableImpl<AlertMessage>(subscriber => {\n for (const alert of this.recentAlerts) {\n subscriber.next(alert);\n }\n return this.subject.subscribe(subscriber);\n });\n }\n}\n"],"names":[],"mappings":";;;AA8BO,MAAM,iBAAA,CAAsC;AAAA,EAChC,OAAA,GAAU,IAAI,cAAA,EAA6B;AAAA,EAC3C,eAA+B,EAAC;AAAA,EAChC,aAAA,GAAgB,EAAA;AAAA,EACzB,oBAAA,GAAuB,KAAA;AAAA,EAE/B,KAAK,KAAA,EAAqB;AACxB,IAAA,IAAI,CAAC,KAAK,oBAAA,EAAsB;AAC9B,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAE5B,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OAIF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,GAAS,IAAA,CAAK,aAAA,EAAe;AACjD,MAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AAAA,IAC1B;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACzB;AAAA,EAEA,MAAA,GAAmC;AACjC,IAAA,OAAO,IAAI,eAA6B,CAAA,UAAA,KAAc;AACpD,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,YAAA,EAAc;AACrC,QAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AAAA,MACvB;AACA,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,UAAU,CAAA;AAAA,IAC1C,CAAC,CAAA;AAAA,EACH;AACF;;;;"}
@@ -1,4 +1,4 @@
1
- import { z } from 'zod';
1
+ import { z } from 'zod/v3';
2
2
 
3
3
  const samlSessionSchema = z.object({
4
4
  profile: z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"types.esm.js","sources":["../../../../../src/apis/implementations/auth/saml/types.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 {\n BackstageIdentityResponse,\n ProfileInfo,\n} from '@backstage/core-plugin-api';\nimport { z } from 'zod';\n\n/** @internal */\nexport type SamlSession = {\n profile: ProfileInfo;\n backstageIdentity: BackstageIdentityResponse;\n};\n\n/** @internal */\nexport const samlSessionSchema: z.ZodSchema<SamlSession> = z.object({\n profile: z.object({\n email: z.string().optional(),\n displayName: z.string().optional(),\n picture: z.string().optional(),\n }),\n backstageIdentity: z.object({\n token: z.string(),\n identity: z.object({\n type: z.literal('user'),\n userEntityRef: z.string(),\n ownershipEntityRefs: z.array(z.string()),\n }),\n }),\n});\n"],"names":[],"mappings":";;AA6BO,MAAM,iBAAA,GAA8C,EAAE,MAAA,CAAO;AAAA,EAClE,OAAA,EAAS,EAAE,MAAA,CAAO;AAAA,IAChB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACjC,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC9B,CAAA;AAAA,EACD,iBAAA,EAAmB,EAAE,MAAA,CAAO;AAAA,IAC1B,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,MACjB,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,MACtB,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,MACxB,mBAAA,EAAqB,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ;AAAA,KACxC;AAAA,GACF;AACH,CAAC;;;;"}
1
+ {"version":3,"file":"types.esm.js","sources":["../../../../../src/apis/implementations/auth/saml/types.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 {\n BackstageIdentityResponse,\n ProfileInfo,\n} from '@backstage/core-plugin-api';\nimport { z } from 'zod/v3';\n\n/** @internal */\nexport type SamlSession = {\n profile: ProfileInfo;\n backstageIdentity: BackstageIdentityResponse;\n};\n\n/** @internal */\nexport const samlSessionSchema: z.ZodSchema<SamlSession> = z.object({\n profile: z.object({\n email: z.string().optional(),\n displayName: z.string().optional(),\n picture: z.string().optional(),\n }),\n backstageIdentity: z.object({\n token: z.string(),\n identity: z.object({\n type: z.literal('user'),\n userEntityRef: z.string(),\n ownershipEntityRefs: z.array(z.string()),\n }),\n }),\n});\n"],"names":[],"mappings":";;AA6BO,MAAM,iBAAA,GAA8C,EAAE,MAAA,CAAO;AAAA,EAClE,OAAA,EAAS,EAAE,MAAA,CAAO;AAAA,IAChB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACjC,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC9B,CAAA;AAAA,EACD,iBAAA,EAAmB,EAAE,MAAA,CAAO;AAAA,IAC1B,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,MACjB,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,MACtB,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,MACxB,mBAAA,EAAqB,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ;AAAA,KACxC;AAAA,GACF;AACH,CAAC;;;;"}
@@ -5,11 +5,12 @@ import { ApiProvider } from '../apis/system/ApiProvider.esm.js';
5
5
  import { ApiResolver } from '../apis/system/ApiResolver.esm.js';
6
6
  import { ApiFactoryRegistry } from '../apis/system/ApiFactoryRegistry.esm.js';
7
7
  import 'zen-observable';
8
- import { appThemeApiRef, configApiRef, identityApiRef, featureFlagsApiRef, errorApiRef, fetchApiRef, discoveryApiRef } from '@backstage/core-plugin-api';
8
+ import { appThemeApiRef, configApiRef, identityApiRef, featureFlagsApiRef, errorApiRef, fetchApiRef, discoveryApiRef, useAnalytics } from '@backstage/core-plugin-api';
9
9
  import '../apis/implementations/auth/saml/types.esm.js';
10
10
  import { AppThemeSelector } from '../apis/implementations/AppThemeApi/AppThemeSelector.esm.js';
11
11
  import { ConfigReader } from '@backstage/config';
12
12
  import { LocalStorageFeatureFlags } from '../apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js';
13
+ import { BUIProvider } from '@backstage/ui';
13
14
  import { appLanguageApiRef, translationApiRef } from '@backstage/core-plugin-api/alpha';
14
15
  import { traverseElementTree, childDiscoverer, routeElementDiscoverer } from '../extensions/traversal.esm.js';
15
16
  import { pluginCollector } from '../plugins/collectors.esm.js';
@@ -204,6 +205,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
204
205
  for (const flag of plugin.getFeatureFlags()) {
205
206
  featureFlagsApi.registerFlag({
206
207
  name: flag.name,
208
+ description: flag.description,
207
209
  pluginId: plugin.getId()
208
210
  });
209
211
  }
@@ -244,7 +246,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
244
246
  discoveryApi
245
247
  });
246
248
  }
247
- return /* @__PURE__ */ jsx(ApiProvider, { apis, children: /* @__PURE__ */ jsx(AppContextProvider, { appContext, children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(
249
+ return /* @__PURE__ */ jsx(ApiProvider, { apis, children: /* @__PURE__ */ jsx(BUIProvider, { useAnalytics, children: /* @__PURE__ */ jsx(AppContextProvider, { appContext, children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(
248
250
  RoutingProvider,
249
251
  {
250
252
  routePaths: routing.paths,
@@ -263,7 +265,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
263
265
  }
264
266
  )
265
267
  }
266
- ) }) }) });
268
+ ) }) }) }) });
267
269
  };
268
270
  return Provider;
269
271
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppManager.esm.js","sources":["../../src/app/AppManager.tsx"],"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 { Config } from '@backstage/config';\nimport {\n ComponentType,\n PropsWithChildren,\n Suspense,\n useMemo,\n useRef,\n} from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n ApiProvider,\n AppThemeSelector,\n ConfigReader,\n LocalStorageFeatureFlags,\n} from '../apis';\nimport {\n AnyApiFactory,\n ApiHolder,\n IconComponent,\n AppTheme,\n appThemeApiRef,\n configApiRef,\n AppThemeApi,\n ConfigApi,\n featureFlagsApiRef,\n identityApiRef,\n BackstagePlugin,\n FeatureFlag,\n fetchApiRef,\n discoveryApiRef,\n errorApiRef,\n} from '@backstage/core-plugin-api';\nimport {\n AppLanguageApi,\n appLanguageApiRef,\n translationApiRef,\n TranslationMessages,\n TranslationResource,\n} from '@backstage/core-plugin-api/alpha';\nimport { ApiFactoryRegistry, ApiResolver } from '../apis/system';\nimport {\n childDiscoverer,\n routeElementDiscoverer,\n traverseElementTree,\n} from '../extensions/traversal';\nimport { pluginCollector } from '../plugins/collectors';\nimport {\n featureFlagCollector,\n routingV1Collector,\n routingV2Collector,\n} from '../routing/collectors';\nimport { RoutingProvider } from '../routing/RoutingProvider';\nimport {\n validateRouteParameters,\n validateRouteBindings,\n} from '../routing/validation';\nimport { AppContextProvider } from './AppContext';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\nimport {\n AppComponents,\n AppConfigLoader,\n AppContext,\n AppOptions,\n BackstageApp,\n} from './types';\nimport { AppThemeProvider } from './AppThemeProvider';\nimport { defaultConfigLoader } from './defaultConfigLoader';\nimport { ApiRegistry } from '../apis/system/ApiRegistry';\nimport { resolveRouteBindings } from './resolveRouteBindings';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { InternalAppContext } from './InternalAppContext';\nimport { AppRouter, getBasePath } from './AppRouter';\nimport { AppLanguageSelector } from '../apis/implementations/AppLanguageApi';\nimport { I18nextTranslationApi } from '../apis/implementations/TranslationApi';\nimport { overrideBaseUrlConfigs } from './overrideBaseUrlConfigs';\nimport { isProtectedApp } from './isProtectedApp';\n\ntype CompatiblePlugin =\n | BackstagePlugin\n | (Omit<BackstagePlugin, 'getFeatureFlags'> & {\n output(): Array<{ type: 'feature-flag'; name: string }>;\n });\n\nfunction useConfigLoader(\n configLoader: AppConfigLoader | undefined,\n components: AppComponents,\n appThemeApi: AppThemeApi,\n): { api: ConfigApi } | { node: JSX.Element } {\n // Keeping this synchronous when a config loader isn't set simplifies tests a lot\n const hasConfig = Boolean(configLoader);\n const config = useAsync(configLoader || (() => Promise.resolve([])));\n\n let noConfigNode = undefined;\n\n if (hasConfig && config.loading) {\n const { Progress } = components;\n noConfigNode = <Progress />;\n } else if (config.error) {\n const { BootErrorPage } = components;\n noConfigNode = <BootErrorPage step=\"load-config\" error={config.error} />;\n }\n\n const { ThemeProvider = AppThemeProvider } = components;\n\n // Before the config is loaded we can't use a router, so exit early\n if (noConfigNode) {\n return {\n node: (\n <ApiProvider apis={ApiRegistry.with(appThemeApiRef, appThemeApi)}>\n <ThemeProvider>{noConfigNode}</ThemeProvider>\n </ApiProvider>\n ),\n };\n }\n\n const configReader = ConfigReader.fromConfigs(\n config.value?.length ? overrideBaseUrlConfigs(config.value) : [],\n );\n\n return { api: configReader };\n}\n\nclass AppContextImpl implements AppContext {\n constructor(private readonly app: AppManager) {}\n\n getPlugins(): BackstagePlugin[] {\n return this.app.getPlugins();\n }\n\n getSystemIcon(key: string): IconComponent | undefined {\n return this.app.getSystemIcon(key);\n }\n\n getSystemIcons(): Record<string, IconComponent> {\n return this.app.getSystemIcons();\n }\n\n getComponents(): AppComponents {\n return this.app.getComponents();\n }\n}\n\nexport class AppManager implements BackstageApp {\n private apiHolder?: ApiHolder;\n private configApi?: ConfigApi;\n\n private readonly apis: Iterable<AnyApiFactory>;\n private readonly icons: NonNullable<AppOptions['icons']>;\n private readonly plugins: Set<CompatiblePlugin>;\n private readonly featureFlags: (FeatureFlag &\n Omit<FeatureFlag, 'pluginId'>)[];\n private readonly components: AppComponents;\n private readonly themes: AppTheme[];\n private readonly configLoader?: AppConfigLoader;\n private readonly defaultApis: Iterable<AnyApiFactory>;\n private readonly bindRoutes: AppOptions['bindRoutes'];\n private readonly appLanguageApi: AppLanguageApi;\n private readonly appThemeApi: AppThemeApi;\n private readonly translationResources: Array<\n TranslationResource | TranslationMessages\n >;\n\n private readonly appIdentityProxy = new AppIdentityProxy();\n private readonly apiFactoryRegistry: ApiFactoryRegistry;\n\n constructor(options: AppOptions) {\n this.apis = options.apis ?? [];\n this.icons = options.icons;\n this.plugins = new Set((options.plugins as CompatiblePlugin[]) ?? []);\n this.featureFlags = options.featureFlags ?? [];\n this.components = options.components;\n this.themes = options.themes as AppTheme[];\n this.configLoader = options.configLoader ?? defaultConfigLoader;\n this.defaultApis = options.defaultApis ?? [];\n this.bindRoutes = options.bindRoutes;\n this.apiFactoryRegistry = new ApiFactoryRegistry();\n this.appLanguageApi = AppLanguageSelector.createWithStorage({\n defaultLanguage: options.__experimentalTranslations?.defaultLanguage,\n availableLanguages:\n options.__experimentalTranslations?.availableLanguages,\n });\n // Create a single AppThemeSelector instance to be shared between\n // the loading phase and the main app, avoiding duplicate event listeners\n this.appThemeApi = AppThemeSelector.createWithStorage(this.themes);\n this.translationResources =\n options.__experimentalTranslations?.resources ?? [];\n }\n\n getPlugins(): BackstagePlugin[] {\n return Array.from(this.plugins) as BackstagePlugin[];\n }\n\n getSystemIcon(key: string): IconComponent | undefined {\n return this.icons[key];\n }\n\n getSystemIcons(): Record<string, IconComponent> {\n return this.icons;\n }\n\n getComponents(): AppComponents {\n return this.components;\n }\n\n createRoot(element: JSX.Element): ComponentType<PropsWithChildren<{}>> {\n const AppProvider = this.getProvider();\n const AppRoot = () => {\n return <AppProvider>{element}</AppProvider>;\n };\n return AppRoot;\n }\n\n #getProviderCalled = false;\n getProvider(): ComponentType<PropsWithChildren<{}>> {\n if (this.#getProviderCalled) {\n throw new Error(\n 'app.getProvider() or app.createRoot() has already been called, and can only be called once',\n );\n }\n this.#getProviderCalled = true;\n\n const appContext = new AppContextImpl(this);\n\n // We only bind and validate routes once\n let routeBindings: ReturnType<typeof resolveRouteBindings>;\n // Store and keep throwing the same error if we encounter one\n let routeValidationError: Error | undefined = undefined;\n\n const Provider = ({ children }: PropsWithChildren<{}>) => {\n const needsFeatureFlagRegistrationRef = useRef(true);\n // Use the shared AppThemeSelector instance created in the constructor\n // to avoid creating duplicate event listeners and subscriptions\n const appThemeApi = this.appThemeApi;\n\n const { routing, featureFlags } = useMemo(() => {\n const usesReactRouterBeta = isReactRouterBeta();\n if (usesReactRouterBeta) {\n // eslint-disable-next-line no-console\n console.warn(`\nDEPRECATION WARNING: React Router Beta is deprecated and support for it will be removed in a future release.\n Please migrate to use React Router v6 stable.\n See https://backstage.io/docs/tutorials/react-router-stable-migration\n`);\n }\n\n const result = traverseElementTree({\n root: children,\n discoverers: [childDiscoverer, routeElementDiscoverer],\n collectors: {\n routing: usesReactRouterBeta\n ? routingV1Collector\n : routingV2Collector,\n collectedPlugins: pluginCollector,\n featureFlags: featureFlagCollector,\n },\n });\n\n // TODO(Rugvip): Restructure the public API so that we can get an immediate view of\n // the app, rather than having to wait for the provider to render.\n // For now we need to push the additional plugins we find during\n // collection and then make sure we initialize things afterwards.\n result.collectedPlugins.forEach(plugin => this.plugins.add(plugin));\n this.verifyPlugins(this.plugins);\n\n // Initialize APIs once all plugins are available\n this.getApiHolder();\n return result;\n }, [children]);\n\n const loadedConfig = useConfigLoader(\n this.configLoader,\n this.components,\n appThemeApi,\n );\n\n const hasConfigApi = 'api' in loadedConfig;\n if (hasConfigApi) {\n const { api } = loadedConfig as { api: Config };\n this.configApi = api;\n }\n\n if ('node' in loadedConfig) {\n // Loading or error\n return loadedConfig.node;\n }\n\n if (routeValidationError) {\n throw routeValidationError;\n } else if (!routeBindings) {\n try {\n routeBindings = resolveRouteBindings(\n this.bindRoutes,\n loadedConfig.api,\n this.plugins,\n );\n\n validateRouteParameters(routing.paths, routing.parents);\n validateRouteBindings(routeBindings, this.plugins);\n } catch (error) {\n routeValidationError = error;\n throw error;\n }\n }\n\n // We can't register feature flags just after the element traversal, because the\n // config API isn't available yet and implementations frequently depend on it.\n // Instead we make it happen immediately, to make sure all flags are available\n // for the first render.\n if (hasConfigApi && needsFeatureFlagRegistrationRef.current) {\n needsFeatureFlagRegistrationRef.current = false;\n\n const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!;\n\n if (featureFlagsApi) {\n for (const flag of this.featureFlags) {\n featureFlagsApi.registerFlag({\n ...flag,\n pluginId: '',\n });\n }\n for (const plugin of this.plugins.values()) {\n if ('getFeatureFlags' in plugin) {\n for (const flag of plugin.getFeatureFlags()) {\n featureFlagsApi.registerFlag({\n name: flag.name,\n pluginId: plugin.getId(),\n });\n }\n } else {\n for (const output of plugin.output()) {\n if (output.type === 'feature-flag') {\n featureFlagsApi.registerFlag({\n name: output.name,\n pluginId: plugin.getId(),\n });\n }\n }\n }\n }\n\n // Go through the featureFlags returned from the traversal and\n // register those now the configApi has been loaded\n const registeredFlags = featureFlagsApi.getRegisteredFlags();\n const flagNames = new Set(registeredFlags.map(f => f.name));\n for (const name of featureFlags) {\n // Prevents adding duplicate feature flags\n if (!flagNames.has(name)) {\n featureFlagsApi.registerFlag({ name, pluginId: '' });\n }\n }\n }\n }\n\n const { ThemeProvider = AppThemeProvider, Progress } = this.components;\n\n const apis = this.getApiHolder();\n\n if (isProtectedApp()) {\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n const discoveryApi = apis.get(discoveryApiRef);\n if (!errorApi || !fetchApi || !discoveryApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n this.appIdentityProxy.enableCookieAuth({\n errorApi,\n fetchApi,\n discoveryApi,\n });\n }\n\n return (\n <ApiProvider apis={apis}>\n <AppContextProvider appContext={appContext}>\n <ThemeProvider>\n <RoutingProvider\n routePaths={routing.paths}\n routeParents={routing.parents}\n routeObjects={routing.objects}\n routeBindings={routeBindings}\n basePath={getBasePath(loadedConfig.api)}\n >\n <InternalAppContext.Provider\n value={{\n routeObjects: routing.objects,\n appIdentityProxy: this.appIdentityProxy,\n }}\n >\n <Suspense fallback={<Progress />}>{children}</Suspense>\n </InternalAppContext.Provider>\n </RoutingProvider>\n </ThemeProvider>\n </AppContextProvider>\n </ApiProvider>\n );\n };\n return Provider;\n }\n\n getRouter(): ComponentType<PropsWithChildren<{}>> {\n return AppRouter;\n }\n\n private getApiHolder(): ApiHolder {\n if (this.apiHolder) {\n // Register additional plugins if they have been added.\n // Routes paths, objects and others are already updated in the provider when children of it change\n for (const plugin of this.plugins) {\n for (const factory of plugin.getApis()) {\n if (!this.apiFactoryRegistry.get(factory.api)) {\n this.apiFactoryRegistry.register('default', factory);\n }\n }\n }\n ApiResolver.validateFactories(\n this.apiFactoryRegistry,\n this.apiFactoryRegistry.getAllApis(),\n );\n return this.apiHolder;\n }\n this.apiFactoryRegistry.register('static', {\n api: appThemeApiRef,\n deps: {},\n // Use the shared AppThemeSelector instance to avoid duplicate event listeners\n factory: () => this.appThemeApi,\n });\n this.apiFactoryRegistry.register('static', {\n api: configApiRef,\n deps: {},\n factory: () => {\n if (!this.configApi) {\n throw new Error(\n 'Tried to access config API before config was loaded',\n );\n }\n return this.configApi;\n },\n });\n this.apiFactoryRegistry.register('static', {\n api: identityApiRef,\n deps: {},\n factory: () => this.appIdentityProxy,\n });\n this.apiFactoryRegistry.register('static', {\n api: appLanguageApiRef,\n deps: {},\n factory: () => this.appLanguageApi,\n });\n\n // The translation API is registered as a default API so that it can be overridden.\n // It will be up to the implementer of the new API to register translation resources.\n this.apiFactoryRegistry.register('default', {\n api: translationApiRef,\n deps: { languageApi: appLanguageApiRef },\n factory: ({ languageApi }) =>\n I18nextTranslationApi.create({\n languageApi,\n resources: this.translationResources,\n }),\n });\n\n // It's possible to replace the feature flag API, but since we must have at least\n // one implementation we add it here directly instead of through the defaultApis.\n this.apiFactoryRegistry.register('default', {\n api: featureFlagsApiRef,\n deps: {},\n factory: () => new LocalStorageFeatureFlags(),\n });\n for (const factory of this.defaultApis) {\n this.apiFactoryRegistry.register('default', factory);\n }\n\n for (const plugin of this.plugins) {\n for (const factory of plugin.getApis()) {\n if (!this.apiFactoryRegistry.register('default', factory)) {\n throw new Error(\n `Plugin ${plugin.getId()} tried to register duplicate or forbidden API factory for ${\n factory.api\n }`,\n );\n }\n }\n }\n\n for (const factory of this.apis) {\n if (!this.apiFactoryRegistry.register('app', factory)) {\n throw new Error(\n `Duplicate or forbidden API factory for ${factory.api} in app`,\n );\n }\n }\n\n ApiResolver.validateFactories(\n this.apiFactoryRegistry,\n this.apiFactoryRegistry.getAllApis(),\n );\n\n this.apiHolder = new ApiResolver(this.apiFactoryRegistry);\n return this.apiHolder;\n }\n\n private verifyPlugins(plugins: Iterable<CompatiblePlugin>) {\n const pluginIds = new Set<string>();\n\n for (const plugin of plugins) {\n const id = plugin.getId();\n if (pluginIds.has(id)) {\n throw new Error(`Duplicate plugin found '${id}'`);\n }\n pluginIds.add(id);\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppManager.esm.js","sources":["../../src/app/AppManager.tsx"],"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 { Config } from '@backstage/config';\nimport {\n ComponentType,\n PropsWithChildren,\n Suspense,\n useMemo,\n useRef,\n} from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n ApiProvider,\n AppThemeSelector,\n ConfigReader,\n LocalStorageFeatureFlags,\n} from '../apis';\nimport {\n AnyApiFactory,\n ApiHolder,\n IconComponent,\n AppTheme,\n appThemeApiRef,\n configApiRef,\n AppThemeApi,\n ConfigApi,\n featureFlagsApiRef,\n identityApiRef,\n BackstagePlugin,\n FeatureFlag,\n fetchApiRef,\n discoveryApiRef,\n errorApiRef,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport { BUIProvider } from '@backstage/ui';\nimport {\n AppLanguageApi,\n appLanguageApiRef,\n translationApiRef,\n TranslationMessages,\n TranslationResource,\n} from '@backstage/core-plugin-api/alpha';\nimport { ApiFactoryRegistry, ApiResolver } from '../apis/system';\nimport {\n childDiscoverer,\n routeElementDiscoverer,\n traverseElementTree,\n} from '../extensions/traversal';\nimport { pluginCollector } from '../plugins/collectors';\nimport {\n featureFlagCollector,\n routingV1Collector,\n routingV2Collector,\n} from '../routing/collectors';\nimport { RoutingProvider } from '../routing/RoutingProvider';\nimport {\n validateRouteParameters,\n validateRouteBindings,\n} from '../routing/validation';\nimport { AppContextProvider } from './AppContext';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\nimport {\n AppComponents,\n AppConfigLoader,\n AppContext,\n AppOptions,\n BackstageApp,\n} from './types';\nimport { AppThemeProvider } from './AppThemeProvider';\nimport { defaultConfigLoader } from './defaultConfigLoader';\nimport { ApiRegistry } from '../apis/system/ApiRegistry';\nimport { resolveRouteBindings } from './resolveRouteBindings';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { InternalAppContext } from './InternalAppContext';\nimport { AppRouter, getBasePath } from './AppRouter';\nimport { AppLanguageSelector } from '../apis/implementations/AppLanguageApi';\nimport { I18nextTranslationApi } from '../apis/implementations/TranslationApi';\nimport { overrideBaseUrlConfigs } from './overrideBaseUrlConfigs';\nimport { isProtectedApp } from './isProtectedApp';\n\ntype CompatiblePlugin =\n | BackstagePlugin\n | (Omit<BackstagePlugin, 'getFeatureFlags'> & {\n output(): Array<{ type: 'feature-flag'; name: string }>;\n });\n\nfunction useConfigLoader(\n configLoader: AppConfigLoader | undefined,\n components: AppComponents,\n appThemeApi: AppThemeApi,\n): { api: ConfigApi } | { node: JSX.Element } {\n // Keeping this synchronous when a config loader isn't set simplifies tests a lot\n const hasConfig = Boolean(configLoader);\n const config = useAsync(configLoader || (() => Promise.resolve([])));\n\n let noConfigNode = undefined;\n\n if (hasConfig && config.loading) {\n const { Progress } = components;\n noConfigNode = <Progress />;\n } else if (config.error) {\n const { BootErrorPage } = components;\n noConfigNode = <BootErrorPage step=\"load-config\" error={config.error} />;\n }\n\n const { ThemeProvider = AppThemeProvider } = components;\n\n // Before the config is loaded we can't use a router, so exit early\n if (noConfigNode) {\n return {\n node: (\n <ApiProvider apis={ApiRegistry.with(appThemeApiRef, appThemeApi)}>\n <ThemeProvider>{noConfigNode}</ThemeProvider>\n </ApiProvider>\n ),\n };\n }\n\n const configReader = ConfigReader.fromConfigs(\n config.value?.length ? overrideBaseUrlConfigs(config.value) : [],\n );\n\n return { api: configReader };\n}\n\nclass AppContextImpl implements AppContext {\n constructor(private readonly app: AppManager) {}\n\n getPlugins(): BackstagePlugin[] {\n return this.app.getPlugins();\n }\n\n getSystemIcon(key: string): IconComponent | undefined {\n return this.app.getSystemIcon(key);\n }\n\n getSystemIcons(): Record<string, IconComponent> {\n return this.app.getSystemIcons();\n }\n\n getComponents(): AppComponents {\n return this.app.getComponents();\n }\n}\n\nexport class AppManager implements BackstageApp {\n private apiHolder?: ApiHolder;\n private configApi?: ConfigApi;\n\n private readonly apis: Iterable<AnyApiFactory>;\n private readonly icons: NonNullable<AppOptions['icons']>;\n private readonly plugins: Set<CompatiblePlugin>;\n private readonly featureFlags: (FeatureFlag &\n Omit<FeatureFlag, 'pluginId'>)[];\n private readonly components: AppComponents;\n private readonly themes: AppTheme[];\n private readonly configLoader?: AppConfigLoader;\n private readonly defaultApis: Iterable<AnyApiFactory>;\n private readonly bindRoutes: AppOptions['bindRoutes'];\n private readonly appLanguageApi: AppLanguageApi;\n private readonly appThemeApi: AppThemeApi;\n private readonly translationResources: Array<\n TranslationResource | TranslationMessages\n >;\n\n private readonly appIdentityProxy = new AppIdentityProxy();\n private readonly apiFactoryRegistry: ApiFactoryRegistry;\n\n constructor(options: AppOptions) {\n this.apis = options.apis ?? [];\n this.icons = options.icons;\n this.plugins = new Set((options.plugins as CompatiblePlugin[]) ?? []);\n this.featureFlags = options.featureFlags ?? [];\n this.components = options.components;\n this.themes = options.themes as AppTheme[];\n this.configLoader = options.configLoader ?? defaultConfigLoader;\n this.defaultApis = options.defaultApis ?? [];\n this.bindRoutes = options.bindRoutes;\n this.apiFactoryRegistry = new ApiFactoryRegistry();\n this.appLanguageApi = AppLanguageSelector.createWithStorage({\n defaultLanguage: options.__experimentalTranslations?.defaultLanguage,\n availableLanguages:\n options.__experimentalTranslations?.availableLanguages,\n });\n // Create a single AppThemeSelector instance to be shared between\n // the loading phase and the main app, avoiding duplicate event listeners\n this.appThemeApi = AppThemeSelector.createWithStorage(this.themes);\n this.translationResources =\n options.__experimentalTranslations?.resources ?? [];\n }\n\n getPlugins(): BackstagePlugin[] {\n return Array.from(this.plugins) as BackstagePlugin[];\n }\n\n getSystemIcon(key: string): IconComponent | undefined {\n return this.icons[key];\n }\n\n getSystemIcons(): Record<string, IconComponent> {\n return this.icons;\n }\n\n getComponents(): AppComponents {\n return this.components;\n }\n\n createRoot(element: JSX.Element): ComponentType<PropsWithChildren<{}>> {\n const AppProvider = this.getProvider();\n const AppRoot = () => {\n return <AppProvider>{element}</AppProvider>;\n };\n return AppRoot;\n }\n\n #getProviderCalled = false;\n getProvider(): ComponentType<PropsWithChildren<{}>> {\n if (this.#getProviderCalled) {\n throw new Error(\n 'app.getProvider() or app.createRoot() has already been called, and can only be called once',\n );\n }\n this.#getProviderCalled = true;\n\n const appContext = new AppContextImpl(this);\n\n // We only bind and validate routes once\n let routeBindings: ReturnType<typeof resolveRouteBindings>;\n // Store and keep throwing the same error if we encounter one\n let routeValidationError: Error | undefined = undefined;\n\n const Provider = ({ children }: PropsWithChildren<{}>) => {\n const needsFeatureFlagRegistrationRef = useRef(true);\n // Use the shared AppThemeSelector instance created in the constructor\n // to avoid creating duplicate event listeners and subscriptions\n const appThemeApi = this.appThemeApi;\n\n const { routing, featureFlags } = useMemo(() => {\n const usesReactRouterBeta = isReactRouterBeta();\n if (usesReactRouterBeta) {\n // eslint-disable-next-line no-console\n console.warn(`\nDEPRECATION WARNING: React Router Beta is deprecated and support for it will be removed in a future release.\n Please migrate to use React Router v6 stable.\n See https://backstage.io/docs/tutorials/react-router-stable-migration\n`);\n }\n\n const result = traverseElementTree({\n root: children,\n discoverers: [childDiscoverer, routeElementDiscoverer],\n collectors: {\n routing: usesReactRouterBeta\n ? routingV1Collector\n : routingV2Collector,\n collectedPlugins: pluginCollector,\n featureFlags: featureFlagCollector,\n },\n });\n\n // TODO(Rugvip): Restructure the public API so that we can get an immediate view of\n // the app, rather than having to wait for the provider to render.\n // For now we need to push the additional plugins we find during\n // collection and then make sure we initialize things afterwards.\n result.collectedPlugins.forEach(plugin => this.plugins.add(plugin));\n this.verifyPlugins(this.plugins);\n\n // Initialize APIs once all plugins are available\n this.getApiHolder();\n return result;\n }, [children]);\n\n const loadedConfig = useConfigLoader(\n this.configLoader,\n this.components,\n appThemeApi,\n );\n\n const hasConfigApi = 'api' in loadedConfig;\n if (hasConfigApi) {\n const { api } = loadedConfig as { api: Config };\n this.configApi = api;\n }\n\n if ('node' in loadedConfig) {\n // Loading or error\n return loadedConfig.node;\n }\n\n if (routeValidationError) {\n throw routeValidationError;\n } else if (!routeBindings) {\n try {\n routeBindings = resolveRouteBindings(\n this.bindRoutes,\n loadedConfig.api,\n this.plugins,\n );\n\n validateRouteParameters(routing.paths, routing.parents);\n validateRouteBindings(routeBindings, this.plugins);\n } catch (error) {\n routeValidationError = error;\n throw error;\n }\n }\n\n // We can't register feature flags just after the element traversal, because the\n // config API isn't available yet and implementations frequently depend on it.\n // Instead we make it happen immediately, to make sure all flags are available\n // for the first render.\n if (hasConfigApi && needsFeatureFlagRegistrationRef.current) {\n needsFeatureFlagRegistrationRef.current = false;\n\n const featureFlagsApi = this.getApiHolder().get(featureFlagsApiRef)!;\n\n if (featureFlagsApi) {\n for (const flag of this.featureFlags) {\n featureFlagsApi.registerFlag({\n ...flag,\n pluginId: '',\n });\n }\n for (const plugin of this.plugins.values()) {\n if ('getFeatureFlags' in plugin) {\n for (const flag of plugin.getFeatureFlags()) {\n featureFlagsApi.registerFlag({\n name: flag.name,\n description: flag.description,\n pluginId: plugin.getId(),\n });\n }\n } else {\n for (const output of plugin.output()) {\n if (output.type === 'feature-flag') {\n featureFlagsApi.registerFlag({\n name: output.name,\n pluginId: plugin.getId(),\n });\n }\n }\n }\n }\n\n // Go through the featureFlags returned from the traversal and\n // register those now the configApi has been loaded\n const registeredFlags = featureFlagsApi.getRegisteredFlags();\n const flagNames = new Set(registeredFlags.map(f => f.name));\n for (const name of featureFlags) {\n // Prevents adding duplicate feature flags\n if (!flagNames.has(name)) {\n featureFlagsApi.registerFlag({ name, pluginId: '' });\n }\n }\n }\n }\n\n const { ThemeProvider = AppThemeProvider, Progress } = this.components;\n\n const apis = this.getApiHolder();\n\n if (isProtectedApp()) {\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n const discoveryApi = apis.get(discoveryApiRef);\n if (!errorApi || !fetchApi || !discoveryApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n this.appIdentityProxy.enableCookieAuth({\n errorApi,\n fetchApi,\n discoveryApi,\n });\n }\n\n return (\n <ApiProvider apis={apis}>\n <BUIProvider useAnalytics={useAnalytics}>\n <AppContextProvider appContext={appContext}>\n <ThemeProvider>\n <RoutingProvider\n routePaths={routing.paths}\n routeParents={routing.parents}\n routeObjects={routing.objects}\n routeBindings={routeBindings}\n basePath={getBasePath(loadedConfig.api)}\n >\n <InternalAppContext.Provider\n value={{\n routeObjects: routing.objects,\n appIdentityProxy: this.appIdentityProxy,\n }}\n >\n <Suspense fallback={<Progress />}>{children}</Suspense>\n </InternalAppContext.Provider>\n </RoutingProvider>\n </ThemeProvider>\n </AppContextProvider>\n </BUIProvider>\n </ApiProvider>\n );\n };\n return Provider;\n }\n\n getRouter(): ComponentType<PropsWithChildren<{}>> {\n return AppRouter;\n }\n\n private getApiHolder(): ApiHolder {\n if (this.apiHolder) {\n // Register additional plugins if they have been added.\n // Routes paths, objects and others are already updated in the provider when children of it change\n for (const plugin of this.plugins) {\n for (const factory of plugin.getApis()) {\n if (!this.apiFactoryRegistry.get(factory.api)) {\n this.apiFactoryRegistry.register('default', factory);\n }\n }\n }\n ApiResolver.validateFactories(\n this.apiFactoryRegistry,\n this.apiFactoryRegistry.getAllApis(),\n );\n return this.apiHolder;\n }\n this.apiFactoryRegistry.register('static', {\n api: appThemeApiRef,\n deps: {},\n // Use the shared AppThemeSelector instance to avoid duplicate event listeners\n factory: () => this.appThemeApi,\n });\n this.apiFactoryRegistry.register('static', {\n api: configApiRef,\n deps: {},\n factory: () => {\n if (!this.configApi) {\n throw new Error(\n 'Tried to access config API before config was loaded',\n );\n }\n return this.configApi;\n },\n });\n this.apiFactoryRegistry.register('static', {\n api: identityApiRef,\n deps: {},\n factory: () => this.appIdentityProxy,\n });\n this.apiFactoryRegistry.register('static', {\n api: appLanguageApiRef,\n deps: {},\n factory: () => this.appLanguageApi,\n });\n\n // The translation API is registered as a default API so that it can be overridden.\n // It will be up to the implementer of the new API to register translation resources.\n this.apiFactoryRegistry.register('default', {\n api: translationApiRef,\n deps: { languageApi: appLanguageApiRef },\n factory: ({ languageApi }) =>\n I18nextTranslationApi.create({\n languageApi,\n resources: this.translationResources,\n }),\n });\n\n // It's possible to replace the feature flag API, but since we must have at least\n // one implementation we add it here directly instead of through the defaultApis.\n this.apiFactoryRegistry.register('default', {\n api: featureFlagsApiRef,\n deps: {},\n factory: () => new LocalStorageFeatureFlags(),\n });\n for (const factory of this.defaultApis) {\n this.apiFactoryRegistry.register('default', factory);\n }\n\n for (const plugin of this.plugins) {\n for (const factory of plugin.getApis()) {\n if (!this.apiFactoryRegistry.register('default', factory)) {\n throw new Error(\n `Plugin ${plugin.getId()} tried to register duplicate or forbidden API factory for ${\n factory.api\n }`,\n );\n }\n }\n }\n\n for (const factory of this.apis) {\n if (!this.apiFactoryRegistry.register('app', factory)) {\n throw new Error(\n `Duplicate or forbidden API factory for ${factory.api} in app`,\n );\n }\n }\n\n ApiResolver.validateFactories(\n this.apiFactoryRegistry,\n this.apiFactoryRegistry.getAllApis(),\n );\n\n this.apiHolder = new ApiResolver(this.apiFactoryRegistry);\n return this.apiHolder;\n }\n\n private verifyPlugins(plugins: Iterable<CompatiblePlugin>) {\n const pluginIds = new Set<string>();\n\n for (const plugin of plugins) {\n const id = plugin.getId();\n if (pluginIds.has(id)) {\n throw new Error(`Duplicate plugin found '${id}'`);\n }\n pluginIds.add(id);\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqGA,SAAS,eAAA,CACP,YAAA,EACA,UAAA,EACA,WAAA,EAC4C;AAE5C,EAAA,MAAM,SAAA,GAAY,QAAQ,YAAY,CAAA;AACtC,EAAA,MAAM,MAAA,GAAS,SAAS,YAAA,KAAiB,MAAM,QAAQ,OAAA,CAAQ,EAAE,CAAA,CAAE,CAAA;AAEnE,EAAA,IAAI,YAAA,GAAe,MAAA;AAEnB,EAAA,IAAI,SAAA,IAAa,OAAO,OAAA,EAAS;AAC/B,IAAA,MAAM,EAAE,UAAS,GAAI,UAAA;AACrB,IAAA,YAAA,uBAAgB,QAAA,EAAA,EAAS,CAAA;AAAA,EAC3B,CAAA,MAAA,IAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,EAAE,eAAc,GAAI,UAAA;AAC1B,IAAA,YAAA,uBAAgB,aAAA,EAAA,EAAc,IAAA,EAAK,aAAA,EAAc,KAAA,EAAO,OAAO,KAAA,EAAO,CAAA;AAAA,EACxE;AAEA,EAAA,MAAM,EAAE,aAAA,GAAgB,gBAAA,EAAiB,GAAI,UAAA;AAG7C,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,OAAO;AAAA,MACL,IAAA,kBACE,GAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAM,WAAA,CAAY,IAAA,CAAK,cAAA,EAAgB,WAAW,CAAA,EAC7D,QAAA,kBAAA,GAAA,CAAC,aAAA,EAAA,EAAe,QAAA,EAAA,YAAA,EAAa,CAAA,EAC/B;AAAA,KAEJ;AAAA,EACF;AAEA,EAAA,MAAM,eAAe,YAAA,CAAa,WAAA;AAAA,IAChC,OAAO,KAAA,EAAO,MAAA,GAAS,uBAAuB,MAAA,CAAO,KAAK,IAAI;AAAC,GACjE;AAEA,EAAA,OAAO,EAAE,KAAK,YAAA,EAAa;AAC7B;AAEA,MAAM,cAAA,CAAqC;AAAA,EACzC,YAA6B,GAAA,EAAiB;AAAjB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAkB;AAAA,EAE/C,UAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,IAAI,UAAA,EAAW;AAAA,EAC7B;AAAA,EAEA,cAAc,GAAA,EAAwC;AACpD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,aAAA,CAAc,GAAG,CAAA;AAAA,EACnC;AAAA,EAEA,cAAA,GAAgD;AAC9C,IAAA,OAAO,IAAA,CAAK,IAAI,cAAA,EAAe;AAAA,EACjC;AAAA,EAEA,aAAA,GAA+B;AAC7B,IAAA,OAAO,IAAA,CAAK,IAAI,aAAA,EAAc;AAAA,EAChC;AACF;AAEO,MAAM,UAAA,CAAmC;AAAA,EACtC,SAAA;AAAA,EACA,SAAA;AAAA,EAES,IAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EAEA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA,WAAA;AAAA,EACA,oBAAA;AAAA,EAIA,gBAAA,GAAmB,IAAI,gBAAA,EAAiB;AAAA,EACxC,kBAAA;AAAA,EAEjB,YAAY,OAAA,EAAqB;AAC/B,IAAA,IAAA,CAAK,IAAA,GAAO,OAAA,CAAQ,IAAA,IAAQ,EAAC;AAC7B,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AACrB,IAAA,IAAA,CAAK,UAAU,IAAI,GAAA,CAAK,OAAA,CAAQ,OAAA,IAAkC,EAAE,CAAA;AACpE,IAAA,IAAA,CAAK,YAAA,GAAe,OAAA,CAAQ,YAAA,IAAgB,EAAC;AAC7C,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,YAAA,IAAgB,mBAAA;AAC5C,IAAA,IAAA,CAAK,WAAA,GAAc,OAAA,CAAQ,WAAA,IAAe,EAAC;AAC3C,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,kBAAA,GAAqB,IAAI,kBAAA,EAAmB;AACjD,IAAA,IAAA,CAAK,cAAA,GAAiB,oBAAoB,iBAAA,CAAkB;AAAA,MAC1D,eAAA,EAAiB,QAAQ,0BAAA,EAA4B,eAAA;AAAA,MACrD,kBAAA,EACE,QAAQ,0BAAA,EAA4B;AAAA,KACvC,CAAA;AAGD,IAAA,IAAA,CAAK,WAAA,GAAc,gBAAA,CAAiB,iBAAA,CAAkB,IAAA,CAAK,MAAM,CAAA;AACjE,IAAA,IAAA,CAAK,oBAAA,GACH,OAAA,CAAQ,0BAAA,EAA4B,SAAA,IAAa,EAAC;AAAA,EACtD;AAAA,EAEA,UAAA,GAAgC;AAC9B,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA;AAAA,EAChC;AAAA,EAEA,cAAc,GAAA,EAAwC;AACpD,IAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACvB;AAAA,EAEA,cAAA,GAAgD;AAC9C,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEA,aAAA,GAA+B;AAC7B,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,WAAW,OAAA,EAA4D;AACrE,IAAA,MAAM,WAAA,GAAc,KAAK,WAAA,EAAY;AACrC,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,uBAAO,GAAA,CAAC,eAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,IAC/B,CAAA;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,kBAAA,GAAqB,KAAA;AAAA,EACrB,WAAA,GAAoD;AAClD,IAAA,IAAI,KAAK,kBAAA,EAAoB;AAC3B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,kBAAA,GAAqB,IAAA;AAE1B,IAAA,MAAM,UAAA,GAAa,IAAI,cAAA,CAAe,IAAI,CAAA;AAG1C,IAAA,IAAI,aAAA;AAEJ,IAAA,IAAI,oBAAA,GAA0C,MAAA;AAE9C,IAAA,MAAM,QAAA,GAAW,CAAC,EAAE,QAAA,EAAS,KAA6B;AACxD,MAAA,MAAM,+BAAA,GAAkC,OAAO,IAAI,CAAA;AAGnD,MAAA,MAAM,cAAc,IAAA,CAAK,WAAA;AAEzB,MAAA,MAAM,EAAE,OAAA,EAAS,YAAA,EAAa,GAAI,QAAQ,MAAM;AAC9C,QAAA,MAAM,sBAAsB,iBAAA,EAAkB;AAC9C,QAAA,IAAI,mBAAA,EAAqB;AAEvB,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA;AAAA;AAAA;AAAA,CAItB,CAAA;AAAA,QACO;AAEA,QAAA,MAAM,SAAS,mBAAA,CAAoB;AAAA,UACjC,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa,CAAC,eAAA,EAAiB,sBAAsB,CAAA;AAAA,UACrD,UAAA,EAAY;AAAA,YACV,OAAA,EAAS,sBACL,kBAAA,GACA,kBAAA;AAAA,YACJ,gBAAA,EAAkB,eAAA;AAAA,YAClB,YAAA,EAAc;AAAA;AAChB,SACD,CAAA;AAMD,QAAA,MAAA,CAAO,iBAAiB,OAAA,CAAQ,CAAA,MAAA,KAAU,KAAK,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAC,CAAA;AAClE,QAAA,IAAA,CAAK,aAAA,CAAc,KAAK,OAAO,CAAA;AAG/B,QAAA,IAAA,CAAK,YAAA,EAAa;AAClB,QAAA,OAAO,MAAA;AAAA,MACT,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,MAAA,MAAM,YAAA,GAAe,eAAA;AAAA,QACnB,IAAA,CAAK,YAAA;AAAA,QACL,IAAA,CAAK,UAAA;AAAA,QACL;AAAA,OACF;AAEA,MAAA,MAAM,eAAe,KAAA,IAAS,YAAA;AAC9B,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAM,EAAE,KAAI,GAAI,YAAA;AAChB,QAAA,IAAA,CAAK,SAAA,GAAY,GAAA;AAAA,MACnB;AAEA,MAAA,IAAI,UAAU,YAAA,EAAc;AAE1B,QAAA,OAAO,YAAA,CAAa,IAAA;AAAA,MACtB;AAEA,MAAA,IAAI,oBAAA,EAAsB;AACxB,QAAA,MAAM,oBAAA;AAAA,MACR,CAAA,MAAA,IAAW,CAAC,aAAA,EAAe;AACzB,QAAA,IAAI;AACF,UAAA,aAAA,GAAgB,oBAAA;AAAA,YACd,IAAA,CAAK,UAAA;AAAA,YACL,YAAA,CAAa,GAAA;AAAA,YACb,IAAA,CAAK;AAAA,WACP;AAEA,UAAA,uBAAA,CAAwB,OAAA,CAAQ,KAAA,EAAO,OAAA,CAAQ,OAAO,CAAA;AACtD,UAAA,qBAAA,CAAsB,aAAA,EAAe,KAAK,OAAO,CAAA;AAAA,QACnD,SAAS,KAAA,EAAO;AACd,UAAA,oBAAA,GAAuB,KAAA;AACvB,UAAA,MAAM,KAAA;AAAA,QACR;AAAA,MACF;AAMA,MAAA,IAAI,YAAA,IAAgB,gCAAgC,OAAA,EAAS;AAC3D,QAAA,+BAAA,CAAgC,OAAA,GAAU,KAAA;AAE1C,QAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,YAAA,EAAa,CAAE,IAAI,kBAAkB,CAAA;AAElE,QAAA,IAAI,eAAA,EAAiB;AACnB,UAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,YAAA,EAAc;AACpC,YAAA,eAAA,CAAgB,YAAA,CAAa;AAAA,cAC3B,GAAG,IAAA;AAAA,cACH,QAAA,EAAU;AAAA,aACX,CAAA;AAAA,UACH;AACA,UAAA,KAAA,MAAW,MAAA,IAAU,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,EAAG;AAC1C,YAAA,IAAI,qBAAqB,MAAA,EAAQ;AAC/B,cAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,eAAA,EAAgB,EAAG;AAC3C,gBAAA,eAAA,CAAgB,YAAA,CAAa;AAAA,kBAC3B,MAAM,IAAA,CAAK,IAAA;AAAA,kBACX,aAAa,IAAA,CAAK,WAAA;AAAA,kBAClB,QAAA,EAAU,OAAO,KAAA;AAAM,iBACxB,CAAA;AAAA,cACH;AAAA,YACF,CAAA,MAAO;AACL,cAAA,KAAA,MAAW,MAAA,IAAU,MAAA,CAAO,MAAA,EAAO,EAAG;AACpC,gBAAA,IAAI,MAAA,CAAO,SAAS,cAAA,EAAgB;AAClC,kBAAA,eAAA,CAAgB,YAAA,CAAa;AAAA,oBAC3B,MAAM,MAAA,CAAO,IAAA;AAAA,oBACb,QAAA,EAAU,OAAO,KAAA;AAAM,mBACxB,CAAA;AAAA,gBACH;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAIA,UAAA,MAAM,eAAA,GAAkB,gBAAgB,kBAAA,EAAmB;AAC3D,UAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAC,CAAA;AAC1D,UAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAE/B,YAAA,IAAI,CAAC,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,cAAA,eAAA,CAAgB,YAAA,CAAa,EAAE,IAAA,EAAM,QAAA,EAAU,IAAI,CAAA;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,aAAA,GAAgB,gBAAA,EAAkB,QAAA,KAAa,IAAA,CAAK,UAAA;AAE5D,MAAA,MAAM,IAAA,GAAO,KAAK,YAAA,EAAa;AAE/B,MAAA,IAAI,gBAAe,EAAG;AACpB,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,QAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,eAAe,CAAA;AAC7C,QAAA,IAAI,CAAC,QAAA,IAAY,CAAC,QAAA,IAAY,CAAC,YAAA,EAAc;AAC3C,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA,QACF;AACA,QAAA,IAAA,CAAK,iBAAiB,gBAAA,CAAiB;AAAA,UACrC,QAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAEA,MAAA,uBACE,GAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EACX,QAAA,kBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,cACX,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,UAAA,EAClB,QAAA,kBAAA,GAAA,CAAC,aAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,QAAC,eAAA;AAAA,QAAA;AAAA,UACC,YAAY,OAAA,CAAQ,KAAA;AAAA,UACpB,cAAc,OAAA,CAAQ,OAAA;AAAA,UACtB,cAAc,OAAA,CAAQ,OAAA;AAAA,UACtB,aAAA;AAAA,UACA,QAAA,EAAU,WAAA,CAAY,YAAA,CAAa,GAAG,CAAA;AAAA,UAEtC,QAAA,kBAAA,GAAA;AAAA,YAAC,kBAAA,CAAmB,QAAA;AAAA,YAAnB;AAAA,cACC,KAAA,EAAO;AAAA,gBACL,cAAc,OAAA,CAAQ,OAAA;AAAA,gBACtB,kBAAkB,IAAA,CAAK;AAAA,eACzB;AAAA,cAEA,8BAAC,QAAA,EAAA,EAAS,QAAA,kBAAU,GAAA,CAAC,QAAA,EAAA,EAAS,GAAK,QAAA,EAAS;AAAA;AAAA;AAC9C;AAAA,OACF,EACF,CAAA,EACF,CAAA,EACF,CAAA,EACF,CAAA;AAAA,IAEJ,CAAA;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,SAAA,GAAkD;AAChD,IAAA,OAAO,SAAA;AAAA,EACT;AAAA,EAEQ,YAAA,GAA0B;AAChC,IAAA,IAAI,KAAK,SAAA,EAAW;AAGlB,MAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,QAAA,KAAA,MAAW,OAAA,IAAW,MAAA,CAAO,OAAA,EAAQ,EAAG;AACtC,UAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,CAAmB,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC7C,YAAA,IAAA,CAAK,kBAAA,CAAmB,QAAA,CAAS,SAAA,EAAW,OAAO,CAAA;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AACA,MAAA,WAAA,CAAY,iBAAA;AAAA,QACV,IAAA,CAAK,kBAAA;AAAA,QACL,IAAA,CAAK,mBAAmB,UAAA;AAAW,OACrC;AACA,MAAA,OAAO,IAAA,CAAK,SAAA;AAAA,IACd;AACA,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,QAAA,EAAU;AAAA,MACzC,GAAA,EAAK,cAAA;AAAA,MACL,MAAM,EAAC;AAAA;AAAA,MAEP,OAAA,EAAS,MAAM,IAAA,CAAK;AAAA,KACrB,CAAA;AACD,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,QAAA,EAAU;AAAA,MACzC,GAAA,EAAK,YAAA;AAAA,MACL,MAAM,EAAC;AAAA,MACP,SAAS,MAAM;AACb,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA,QACF;AACA,QAAA,OAAO,IAAA,CAAK,SAAA;AAAA,MACd;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,QAAA,EAAU;AAAA,MACzC,GAAA,EAAK,cAAA;AAAA,MACL,MAAM,EAAC;AAAA,MACP,OAAA,EAAS,MAAM,IAAA,CAAK;AAAA,KACrB,CAAA;AACD,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,QAAA,EAAU;AAAA,MACzC,GAAA,EAAK,iBAAA;AAAA,MACL,MAAM,EAAC;AAAA,MACP,OAAA,EAAS,MAAM,IAAA,CAAK;AAAA,KACrB,CAAA;AAID,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,SAAA,EAAW;AAAA,MAC1C,GAAA,EAAK,iBAAA;AAAA,MACL,IAAA,EAAM,EAAE,WAAA,EAAa,iBAAA,EAAkB;AAAA,MACvC,SAAS,CAAC,EAAE,WAAA,EAAY,KACtB,sBAAsB,MAAA,CAAO;AAAA,QAC3B,WAAA;AAAA,QACA,WAAW,IAAA,CAAK;AAAA,OACjB;AAAA,KACJ,CAAA;AAID,IAAA,IAAA,CAAK,kBAAA,CAAmB,SAAS,SAAA,EAAW;AAAA,MAC1C,GAAA,EAAK,kBAAA;AAAA,MACL,MAAM,EAAC;AAAA,MACP,OAAA,EAAS,MAAM,IAAI,wBAAA;AAAyB,KAC7C,CAAA;AACD,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,WAAA,EAAa;AACtC,MAAA,IAAA,CAAK,kBAAA,CAAmB,QAAA,CAAS,SAAA,EAAW,OAAO,CAAA;AAAA,IACrD;AAEA,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,MAAA,KAAA,MAAW,OAAA,IAAW,MAAA,CAAO,OAAA,EAAQ,EAAG;AACtC,QAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,CAAmB,QAAA,CAAS,SAAA,EAAW,OAAO,CAAA,EAAG;AACzD,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,UAAU,MAAA,CAAO,KAAA,EAAO,CAAA,0DAAA,EACtB,QAAQ,GACV,CAAA;AAAA,WACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,IAAA,EAAM;AAC/B,MAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,CAAmB,QAAA,CAAS,KAAA,EAAO,OAAO,CAAA,EAAG;AACrD,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,uCAAA,EAA0C,QAAQ,GAAG,CAAA,OAAA;AAAA,SACvD;AAAA,MACF;AAAA,IACF;AAEA,IAAA,WAAA,CAAY,iBAAA;AAAA,MACV,IAAA,CAAK,kBAAA;AAAA,MACL,IAAA,CAAK,mBAAmB,UAAA;AAAW,KACrC;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,WAAA,CAAY,IAAA,CAAK,kBAAkB,CAAA;AACxD,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEQ,cAAc,OAAA,EAAqC;AACzD,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAElC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,EAAA,GAAK,OAAO,KAAA,EAAM;AACxB,MAAA,IAAI,SAAA,CAAU,GAAA,CAAI,EAAE,CAAA,EAAG;AACrB,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,MAClD;AACA,MAAA,SAAA,CAAU,IAAI,EAAE,CAAA;AAAA,IAClB;AAAA,EACF;AACF;;;;"}
@@ -1,6 +1,7 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useContext, useState } from 'react';
3
- import { attachComponentData, useApp, useApi, configApiRef } from '@backstage/core-plugin-api';
3
+ import { attachComponentData, useApp, useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';
4
+ import { BUIProvider } from '@backstage/ui';
4
5
  import { InternalAppContext } from './InternalAppContext.esm.js';
5
6
  import { isReactRouterBeta } from './isReactRouterBeta.esm.js';
6
7
  import { RouteTracker } from '../routing/RouteTracker.esm.js';
@@ -72,18 +73,18 @@ function AppRouter(props) {
72
73
  { signOutTargetUrl: basePath || "/" }
73
74
  );
74
75
  if (isReactRouterBeta()) {
75
- return /* @__PURE__ */ jsxs(RouterComponent, { children: [
76
+ return /* @__PURE__ */ jsx(RouterComponent, { children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
76
77
  /* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
77
78
  /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: mountPath, element: /* @__PURE__ */ jsx(Fragment, { children: props.children }) }) })
78
- ] });
79
+ ] }) });
79
80
  }
80
- return /* @__PURE__ */ jsxs(RouterComponent, { basename: basePath, children: [
81
+ return /* @__PURE__ */ jsx(RouterComponent, { basename: basePath, children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
81
82
  /* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
82
83
  props.children
83
- ] });
84
+ ] }) });
84
85
  }
85
86
  if (isReactRouterBeta()) {
86
- return /* @__PURE__ */ jsxs(RouterComponent, { children: [
87
+ return /* @__PURE__ */ jsx(RouterComponent, { children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
87
88
  /* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
88
89
  /* @__PURE__ */ jsx(
89
90
  SignInPageWrapper,
@@ -93,9 +94,9 @@ function AppRouter(props) {
93
94
  children: /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: mountPath, element: /* @__PURE__ */ jsx(Fragment, { children: props.children }) }) })
94
95
  }
95
96
  )
96
- ] });
97
+ ] }) });
97
98
  }
98
- return /* @__PURE__ */ jsxs(RouterComponent, { basename: basePath, children: [
99
+ return /* @__PURE__ */ jsx(RouterComponent, { basename: basePath, children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
99
100
  /* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
100
101
  /* @__PURE__ */ jsx(
101
102
  SignInPageWrapper,
@@ -105,7 +106,7 @@ function AppRouter(props) {
105
106
  children: props.children
106
107
  }
107
108
  )
108
- ] });
109
+ ] }) });
109
110
  }
110
111
  attachComponentData(AppRouter, "core.type", "AppRouter");
111
112
 
@@ -1 +1 @@
1
- {"version":3,"file":"AppRouter.esm.js","sources":["../../src/app/AppRouter.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { useContext, ReactNode, ComponentType, useState } from 'react';\nimport {\n attachComponentData,\n ConfigApi,\n configApiRef,\n IdentityApi,\n SignInPageProps,\n useApi,\n useApp,\n} from '@backstage/core-plugin-api';\nimport { InternalAppContext } from './InternalAppContext';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { RouteTracker } from '../routing/RouteTracker';\nimport { Route, Routes } from 'react-router-dom';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\n\n/**\n * Get the app base path from the configured app baseUrl.\n *\n * The returned path does not have a trailing slash.\n */\nexport function getBasePath(configApi: ConfigApi) {\n if (!isReactRouterBeta()) {\n // When using rr v6 stable the base path is handled through the\n // basename prop on the router component instead.\n return '';\n }\n\n return readBasePath(configApi);\n}\n\n/**\n * Read the configured base path.\n *\n * The returned path does not have a trailing slash.\n */\nfunction readBasePath(configApi: ConfigApi) {\n let { pathname } = new URL(\n configApi.getOptionalString('app.baseUrl') ?? '/',\n 'http://sample.dev', // baseUrl can be specified as just a path\n );\n pathname = pathname.replace(/\\/*$/, '');\n return pathname;\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 = readBasePath(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}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @public\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 { Router: RouterComponent, SignInPage: SignInPageComponent } =\n useApp().getComponents();\n\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n const mountPath = `${basePath}/*`;\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 if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <RouteTracker routeObjects={routeObjects} />\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <RouteTracker routeObjects={routeObjects} />\n {props.children}\n </RouterComponent>\n );\n }\n\n if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </SignInPageWrapper>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {props.children}\n </SignInPageWrapper>\n </RouterComponent>\n );\n}\n\nattachComponentData(AppRouter, 'core.type', 'AppRouter');\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppRouter.esm.js","sources":["../../src/app/AppRouter.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { useContext, ReactNode, ComponentType, useState } from 'react';\nimport {\n attachComponentData,\n ConfigApi,\n configApiRef,\n IdentityApi,\n SignInPageProps,\n useApi,\n useApp,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport { BUIProvider } from '@backstage/ui';\nimport { InternalAppContext } from './InternalAppContext';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { RouteTracker } from '../routing/RouteTracker';\nimport { Route, Routes } from 'react-router-dom';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\n\n/**\n * Get the app base path from the configured app baseUrl.\n *\n * The returned path does not have a trailing slash.\n */\nexport function getBasePath(configApi: ConfigApi) {\n if (!isReactRouterBeta()) {\n // When using rr v6 stable the base path is handled through the\n // basename prop on the router component instead.\n return '';\n }\n\n return readBasePath(configApi);\n}\n\n/**\n * Read the configured base path.\n *\n * The returned path does not have a trailing slash.\n */\nfunction readBasePath(configApi: ConfigApi) {\n let { pathname } = new URL(\n configApi.getOptionalString('app.baseUrl') ?? '/',\n 'http://sample.dev', // baseUrl can be specified as just a path\n );\n pathname = pathname.replace(/\\/*$/, '');\n return pathname;\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 = readBasePath(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}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @public\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 { Router: RouterComponent, SignInPage: SignInPageComponent } =\n useApp().getComponents();\n\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n const mountPath = `${basePath}/*`;\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 if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n {props.children}\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </SignInPageWrapper>\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {props.children}\n </SignInPageWrapper>\n </BUIProvider>\n </RouterComponent>\n );\n}\n\nattachComponentData(AppRouter, 'core.type', 'AppRouter');\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -428,11 +428,13 @@ declare class OpenShiftAuth {
428
428
  * missing alerts that were posted before subscription.
429
429
  *
430
430
  * @public
431
+ * @deprecated Use ToastApi instead. AlertApi will be removed in a future release.
431
432
  */
432
433
  declare class AlertApiForwarder implements AlertApi {
433
434
  private readonly subject;
434
435
  private readonly recentAlerts;
435
436
  private readonly maxBufferSize;
437
+ private hasWarnedDeprecation;
436
438
  post(alert: AlertMessage): void;
437
439
  alert$(): Observable<AlertMessage>;
438
440
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AuthSessionStore.esm.js","sources":["../../../src/lib/AuthSessionManager/AuthSessionStore.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 { ZodSchema } from 'zod';\nimport {\n MutableSessionManager,\n SessionScopesFunc,\n SessionShouldRefreshFunc,\n GetSessionOptions,\n} from './types';\nimport { SessionScopeHelper } from './common';\n\ntype Options<T> = {\n /** The connector used for acting on the auth session */\n manager: MutableSessionManager<T>;\n /** Storage key to use to store sessions */\n storageKey: string;\n /** The schema used to validate the stored data */\n schema: ZodSchema<T>;\n /** Used to get the scope of the session */\n sessionScopes?: SessionScopesFunc<T>;\n /** Used to check if the session needs to be refreshed, defaults to never refresh */\n sessionShouldRefresh?: SessionShouldRefreshFunc<T>;\n};\n\n/**\n * AuthSessionStore decorates another SessionManager with a functionality\n * to store the session in local storage.\n *\n * Session is serialized to JSON with special support for following types: Set.\n */\nexport class AuthSessionStore<T> implements MutableSessionManager<T> {\n private readonly manager: MutableSessionManager<T>;\n private readonly storageKey: string;\n private readonly schema: ZodSchema<T>;\n private readonly sessionShouldRefreshFunc: SessionShouldRefreshFunc<T>;\n private readonly helper: SessionScopeHelper<T>;\n\n constructor(options: Options<T>) {\n const {\n manager,\n storageKey,\n schema,\n sessionScopes,\n sessionShouldRefresh = () => false,\n } = options;\n\n this.manager = manager;\n this.storageKey = storageKey;\n this.schema = schema;\n this.sessionShouldRefreshFunc = sessionShouldRefresh;\n this.helper = new SessionScopeHelper({\n sessionScopes,\n defaultScopes: new Set(),\n });\n }\n\n setSession(session: T | undefined): void {\n this.manager.setSession(session);\n this.saveSession(session);\n }\n\n async getSession(options: GetSessionOptions): Promise<T | undefined> {\n const { scopes } = options;\n const session = this.loadSession();\n\n if (this.helper.sessionExistsAndHasScope(session, scopes)) {\n const shouldRefresh = this.sessionShouldRefreshFunc(session!);\n\n if (!shouldRefresh) {\n this.manager.setSession(session!);\n return session!;\n }\n }\n\n const newSession = await this.manager.getSession(options);\n this.saveSession(newSession);\n return newSession;\n }\n\n async removeSession() {\n localStorage.removeItem(this.storageKey);\n await this.manager.removeSession();\n }\n\n sessionState$() {\n return this.manager.sessionState$();\n }\n\n private loadSession(): T | undefined {\n try {\n const sessionJson = localStorage.getItem(this.storageKey);\n if (sessionJson) {\n const session = JSON.parse(sessionJson, (_key, value) => {\n if (value?.__type === 'Set') {\n return new Set(value.__value);\n }\n return value;\n });\n\n try {\n return this.schema.parse(session);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to load session from local storage because it did not conform to the expected schema, ${e}`,\n );\n throw e;\n }\n }\n\n return undefined;\n } catch (error) {\n localStorage.removeItem(this.storageKey);\n return undefined;\n }\n }\n\n private saveSession(session: T | undefined) {\n if (session === undefined) {\n localStorage.removeItem(this.storageKey);\n return;\n }\n\n try {\n this.schema.parse(session);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to save session to local storage because it did not conform to the expected schema, ${e}`,\n );\n return;\n }\n\n localStorage.setItem(\n this.storageKey,\n JSON.stringify(session, (_key, value) => {\n if (value instanceof Set) {\n return {\n __type: 'Set',\n __value: Array.from(value),\n };\n }\n return value;\n }),\n );\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AuthSessionStore.esm.js","sources":["../../../src/lib/AuthSessionManager/AuthSessionStore.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 type { ZodSchema } from 'zod/v3';\nimport {\n MutableSessionManager,\n SessionScopesFunc,\n SessionShouldRefreshFunc,\n GetSessionOptions,\n} from './types';\nimport { SessionScopeHelper } from './common';\n\ntype Options<T> = {\n /** The connector used for acting on the auth session */\n manager: MutableSessionManager<T>;\n /** Storage key to use to store sessions */\n storageKey: string;\n /** The schema used to validate the stored data */\n schema: ZodSchema<T>;\n /** Used to get the scope of the session */\n sessionScopes?: SessionScopesFunc<T>;\n /** Used to check if the session needs to be refreshed, defaults to never refresh */\n sessionShouldRefresh?: SessionShouldRefreshFunc<T>;\n};\n\n/**\n * AuthSessionStore decorates another SessionManager with a functionality\n * to store the session in local storage.\n *\n * Session is serialized to JSON with special support for following types: Set.\n */\nexport class AuthSessionStore<T> implements MutableSessionManager<T> {\n private readonly manager: MutableSessionManager<T>;\n private readonly storageKey: string;\n private readonly schema: ZodSchema<T>;\n private readonly sessionShouldRefreshFunc: SessionShouldRefreshFunc<T>;\n private readonly helper: SessionScopeHelper<T>;\n\n constructor(options: Options<T>) {\n const {\n manager,\n storageKey,\n schema,\n sessionScopes,\n sessionShouldRefresh = () => false,\n } = options;\n\n this.manager = manager;\n this.storageKey = storageKey;\n this.schema = schema;\n this.sessionShouldRefreshFunc = sessionShouldRefresh;\n this.helper = new SessionScopeHelper({\n sessionScopes,\n defaultScopes: new Set(),\n });\n }\n\n setSession(session: T | undefined): void {\n this.manager.setSession(session);\n this.saveSession(session);\n }\n\n async getSession(options: GetSessionOptions): Promise<T | undefined> {\n const { scopes } = options;\n const session = this.loadSession();\n\n if (this.helper.sessionExistsAndHasScope(session, scopes)) {\n const shouldRefresh = this.sessionShouldRefreshFunc(session!);\n\n if (!shouldRefresh) {\n this.manager.setSession(session!);\n return session!;\n }\n }\n\n const newSession = await this.manager.getSession(options);\n this.saveSession(newSession);\n return newSession;\n }\n\n async removeSession() {\n localStorage.removeItem(this.storageKey);\n await this.manager.removeSession();\n }\n\n sessionState$() {\n return this.manager.sessionState$();\n }\n\n private loadSession(): T | undefined {\n try {\n const sessionJson = localStorage.getItem(this.storageKey);\n if (sessionJson) {\n const session = JSON.parse(sessionJson, (_key, value) => {\n if (value?.__type === 'Set') {\n return new Set(value.__value);\n }\n return value;\n });\n\n try {\n return this.schema.parse(session);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.log(\n `Failed to load session from local storage because it did not conform to the expected schema, ${e}`,\n );\n throw e;\n }\n }\n\n return undefined;\n } catch (error) {\n localStorage.removeItem(this.storageKey);\n return undefined;\n }\n }\n\n private saveSession(session: T | undefined) {\n if (session === undefined) {\n localStorage.removeItem(this.storageKey);\n return;\n }\n\n try {\n this.schema.parse(session);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to save session to local storage because it did not conform to the expected schema, ${e}`,\n );\n return;\n }\n\n localStorage.setItem(\n this.storageKey,\n JSON.stringify(session, (_key, value) => {\n if (value instanceof Set) {\n return {\n __type: 'Set',\n __value: Array.from(value),\n };\n }\n return value;\n }),\n );\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-app-api",
3
- "version": "1.19.6-next.0",
3
+ "version": "1.19.6",
4
4
  "description": "Core app API used by Backstage apps",
5
5
  "backstage": {
6
6
  "role": "web-library"
@@ -50,10 +50,11 @@
50
50
  "test": "backstage-cli package test"
51
51
  },
52
52
  "dependencies": {
53
- "@backstage/config": "1.3.6",
54
- "@backstage/core-plugin-api": "1.12.4-next.0",
55
- "@backstage/types": "1.2.2",
56
- "@backstage/version-bridge": "1.0.12",
53
+ "@backstage/config": "^1.3.6",
54
+ "@backstage/core-plugin-api": "^1.12.4",
55
+ "@backstage/types": "^1.2.2",
56
+ "@backstage/ui": "^0.13.0",
57
+ "@backstage/version-bridge": "^1.0.12",
57
58
  "@types/prop-types": "^15.7.3",
58
59
  "history": "^5.0.0",
59
60
  "i18next": "^22.4.15",
@@ -61,11 +62,11 @@
61
62
  "prop-types": "^15.7.2",
62
63
  "react-use": "^17.2.4",
63
64
  "zen-observable": "^0.10.0",
64
- "zod": "^3.25.76"
65
+ "zod": "^3.25.76 || ^4.0.0"
65
66
  },
66
67
  "devDependencies": {
67
- "@backstage/cli": "0.35.5-next.0",
68
- "@backstage/test-utils": "1.7.16-next.0",
68
+ "@backstage/cli": "^0.36.0",
69
+ "@backstage/test-utils": "^1.7.16",
69
70
  "@testing-library/dom": "^10.0.0",
70
71
  "@testing-library/jest-dom": "^6.0.0",
71
72
  "@testing-library/react": "^16.0.0",