@backstage/plugin-app 0.1.2-next.1 → 0.1.2-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/defaultApis.esm.js.map +1 -1
- package/dist/extensions/App.esm.js.map +1 -1
- package/dist/extensions/AppLanguageApi.esm.js.map +1 -1
- package/dist/extensions/AppLayout.esm.js.map +1 -1
- package/dist/extensions/AppNav.esm.js.map +1 -1
- package/dist/extensions/AppRoot.esm.js.map +1 -1
- package/dist/extensions/AppRoutes.esm.js.map +1 -1
- package/dist/extensions/AppThemeApi.esm.js.map +1 -1
- package/dist/extensions/ComponentsApi.esm.js.map +1 -1
- package/dist/extensions/DefaultSignInPage.esm.js.map +1 -1
- package/dist/extensions/FeatureFlagsApi.esm.js.map +1 -1
- package/dist/extensions/IconsApi.esm.js.map +1 -1
- package/dist/extensions/TranslationsApi.esm.js.map +1 -1
- package/dist/extensions/components.esm.js.map +1 -1
- package/dist/extensions/elements.esm.js.map +1 -1
- package/dist/packages/app/src/components/Root/LogoFull.esm.js.map +1 -1
- package/dist/packages/app/src/components/Root/LogoIcon.esm.js.map +1 -1
- package/dist/packages/app-defaults/src/defaults/apis.esm.js.map +1 -1
- package/dist/packages/app-defaults/src/defaults/components.esm.js.map +1 -1
- package/dist/packages/app-defaults/src/defaults/icons.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/AppThemeApi/AppThemeSelector.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/DiscoveryApi/UrlPatternDiscovery.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/ErrorAlerter.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/ErrorApiForwarder.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/UnhandledErrorForwarder.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/FetchApi/createFetchApi.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthPendingRequests.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/atlassian/AtlassianAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/bitbucket/BitbucketAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/github/GithubAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/gitlab/GitlabAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/google/GoogleAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/oauth2/OAuth2.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/okta/OktaAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/saml/types.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/vmwareCloud/VMwareCloudAuth.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/system/ApiAggregator.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/system/ApiProvider.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/app/AppRouter.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/app/AppThemeProvider.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/app/isProtectedApp.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/app/isReactRouterBeta.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/AuthSessionManager/RefreshingAuthSessionManager.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/AuthSessionManager/SessionStateTracker.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/AuthSessionManager/common.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/loginPopup.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/lib/subjects.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/routing/FeatureFlagged.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/routing/FlatRoutes.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/routing/RouteTracker.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/routing/RoutingProvider.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/routing/types.esm.js.map +1 -1
- package/dist/packages/core-plugin-api/src/translation/TranslationRef.esm.js.map +1 -1
- package/dist/packages/core-plugin-api/src/translation/TranslationResource.esm.js.map +1 -1
- package/dist/packages/frontend-app-api/src/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js.map +1 -1
- package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map +1 -1
- package/dist/packages/frontend-app-api/src/routing/RouteTracker.esm.js.map +1 -1
- package/dist/packages/frontend-app-api/src/routing/getBasePath.esm.js.map +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/package.json +13 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subjects.esm.js","sources":["../../../../../../../packages/core-app-api/src/lib/subjects.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 { Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\n\n// TODO(Rugvip): These are stopgap and probably incomplete implementations of subjects.\n// If we add a more complete Observables library they should be replaced.\n\n/**\n * A basic implementation of ReactiveX publish subjects.\n *\n * A subject is a convenient way to create an observable when you want\n * to fan out a single value to all subscribers.\n *\n * See http://reactivex.io/documentation/subject.html\n */\nexport class PublishSubject<T>\n implements Observable<T>, ZenObservable.SubscriptionObserver<T>\n{\n private isClosed = false;\n private terminatingError?: Error;\n\n private readonly observable = new ObservableImpl<T>(subscriber => {\n if (this.isClosed) {\n if (this.terminatingError) {\n subscriber.error(this.terminatingError);\n } else {\n subscriber.complete();\n }\n return () => {};\n }\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<T>\n >();\n\n [Symbol.observable]() {\n return this;\n }\n\n get closed() {\n return this.isClosed;\n }\n\n next(value: T) {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.subscribers.forEach(subscriber => subscriber.next(value));\n }\n\n error(error: Error) {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.isClosed = true;\n this.terminatingError = error;\n this.subscribers.forEach(subscriber => subscriber.error(error));\n }\n\n complete() {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.isClosed = true;\n this.subscribers.forEach(subscriber => subscriber.complete());\n }\n\n subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;\n subscribe(\n onNext: (value: T) => void,\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription;\n subscribe(\n onNext: ZenObservable.Observer<T> | ((value: T) => void),\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription {\n const observer =\n typeof onNext === 'function'\n ? {\n next: onNext,\n error: onError,\n complete: onComplete,\n }\n : onNext;\n\n return this.observable.subscribe(observer);\n }\n}\n\n/**\n * A basic implementation of ReactiveX behavior subjects.\n *\n * A subject is a convenient way to create an observable when you want\n * to fan out a single value to all subscribers.\n *\n * The BehaviorSubject will emit the most recently emitted value or error\n * whenever a new observer subscribes to the subject.\n *\n * See http://reactivex.io/documentation/subject.html\n */\n\nexport class BehaviorSubject<T>\n implements Observable<T>, ZenObservable.SubscriptionObserver<T>\n{\n private isClosed: boolean;\n private currentValue: T;\n private terminatingError: Error | undefined;\n private readonly observable: Observable<T>;\n\n constructor(value: T) {\n this.isClosed = false;\n this.currentValue = value;\n this.terminatingError = undefined;\n this.observable = new ObservableImpl<T>(subscriber => {\n if (this.isClosed) {\n if (this.terminatingError) {\n subscriber.error(this.terminatingError);\n } else {\n subscriber.complete();\n }\n return () => {};\n }\n\n subscriber.next(this.currentValue);\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n }\n\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<T>\n >();\n\n [Symbol.observable]() {\n return this;\n }\n\n get closed() {\n return this.isClosed;\n }\n\n next(value: T) {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.currentValue = value;\n this.subscribers.forEach(subscriber => subscriber.next(value));\n }\n\n error(error: Error) {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.isClosed = true;\n this.terminatingError = error;\n this.subscribers.forEach(subscriber => subscriber.error(error));\n }\n\n complete() {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.isClosed = true;\n this.subscribers.forEach(subscriber => subscriber.complete());\n }\n\n subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;\n subscribe(\n onNext: (value: T) => void,\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription;\n subscribe(\n onNext: ZenObservable.Observer<T> | ((value: T) => void),\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription {\n const observer =\n typeof onNext === 'function'\n ? {\n next: onNext,\n error: onError,\n complete: onComplete,\n }\n : onNext;\n\n return this.observable.subscribe(observer);\n }\n}\n"],"names":[],"mappings":";;AA8BO,MAAM,cAEb,CAAA;AAAA,EACU,QAAW,GAAA,KAAA
|
|
1
|
+
{"version":3,"file":"subjects.esm.js","sources":["../../../../../../../packages/core-app-api/src/lib/subjects.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 { Observable } from '@backstage/types';\nimport ObservableImpl from 'zen-observable';\n\n// TODO(Rugvip): These are stopgap and probably incomplete implementations of subjects.\n// If we add a more complete Observables library they should be replaced.\n\n/**\n * A basic implementation of ReactiveX publish subjects.\n *\n * A subject is a convenient way to create an observable when you want\n * to fan out a single value to all subscribers.\n *\n * See http://reactivex.io/documentation/subject.html\n */\nexport class PublishSubject<T>\n implements Observable<T>, ZenObservable.SubscriptionObserver<T>\n{\n private isClosed = false;\n private terminatingError?: Error;\n\n private readonly observable = new ObservableImpl<T>(subscriber => {\n if (this.isClosed) {\n if (this.terminatingError) {\n subscriber.error(this.terminatingError);\n } else {\n subscriber.complete();\n }\n return () => {};\n }\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<T>\n >();\n\n [Symbol.observable]() {\n return this;\n }\n\n get closed() {\n return this.isClosed;\n }\n\n next(value: T) {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.subscribers.forEach(subscriber => subscriber.next(value));\n }\n\n error(error: Error) {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.isClosed = true;\n this.terminatingError = error;\n this.subscribers.forEach(subscriber => subscriber.error(error));\n }\n\n complete() {\n if (this.isClosed) {\n throw new Error('PublishSubject is closed');\n }\n this.isClosed = true;\n this.subscribers.forEach(subscriber => subscriber.complete());\n }\n\n subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;\n subscribe(\n onNext: (value: T) => void,\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription;\n subscribe(\n onNext: ZenObservable.Observer<T> | ((value: T) => void),\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription {\n const observer =\n typeof onNext === 'function'\n ? {\n next: onNext,\n error: onError,\n complete: onComplete,\n }\n : onNext;\n\n return this.observable.subscribe(observer);\n }\n}\n\n/**\n * A basic implementation of ReactiveX behavior subjects.\n *\n * A subject is a convenient way to create an observable when you want\n * to fan out a single value to all subscribers.\n *\n * The BehaviorSubject will emit the most recently emitted value or error\n * whenever a new observer subscribes to the subject.\n *\n * See http://reactivex.io/documentation/subject.html\n */\n\nexport class BehaviorSubject<T>\n implements Observable<T>, ZenObservable.SubscriptionObserver<T>\n{\n private isClosed: boolean;\n private currentValue: T;\n private terminatingError: Error | undefined;\n private readonly observable: Observable<T>;\n\n constructor(value: T) {\n this.isClosed = false;\n this.currentValue = value;\n this.terminatingError = undefined;\n this.observable = new ObservableImpl<T>(subscriber => {\n if (this.isClosed) {\n if (this.terminatingError) {\n subscriber.error(this.terminatingError);\n } else {\n subscriber.complete();\n }\n return () => {};\n }\n\n subscriber.next(this.currentValue);\n\n this.subscribers.add(subscriber);\n return () => {\n this.subscribers.delete(subscriber);\n };\n });\n }\n\n private readonly subscribers = new Set<\n ZenObservable.SubscriptionObserver<T>\n >();\n\n [Symbol.observable]() {\n return this;\n }\n\n get closed() {\n return this.isClosed;\n }\n\n next(value: T) {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.currentValue = value;\n this.subscribers.forEach(subscriber => subscriber.next(value));\n }\n\n error(error: Error) {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.isClosed = true;\n this.terminatingError = error;\n this.subscribers.forEach(subscriber => subscriber.error(error));\n }\n\n complete() {\n if (this.isClosed) {\n throw new Error('BehaviorSubject is closed');\n }\n this.isClosed = true;\n this.subscribers.forEach(subscriber => subscriber.complete());\n }\n\n subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;\n subscribe(\n onNext: (value: T) => void,\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription;\n subscribe(\n onNext: ZenObservable.Observer<T> | ((value: T) => void),\n onError?: (error: any) => void,\n onComplete?: () => void,\n ): ZenObservable.Subscription {\n const observer =\n typeof onNext === 'function'\n ? {\n next: onNext,\n error: onError,\n complete: onComplete,\n }\n : onNext;\n\n return this.observable.subscribe(observer);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureFlagged.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/FeatureFlagged.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 featureFlagsApiRef,\n useApi,\n attachComponentData,\n} from '@backstage/core-plugin-api';\nimport React, { ReactNode } from 'react';\n\n/**\n * Props for the {@link FeatureFlagged} component.\n *\n * @public\n */\nexport type FeatureFlaggedProps = { children: ReactNode } & (\n | { with: string }\n | { without: string }\n);\n\n/**\n * Enables or disables rendering of its children based on the state of a given\n * feature flag.\n *\n * @public\n */\nexport const FeatureFlagged = (props: FeatureFlaggedProps) => {\n const { children } = props;\n const featureFlagApi = useApi(featureFlagsApiRef);\n const isEnabled =\n 'with' in props\n ? featureFlagApi.isActive(props.with)\n : !featureFlagApi.isActive(props.without);\n return <>{isEnabled ? children : null}</>;\n};\n\nattachComponentData(FeatureFlagged, 'core.featureFlagged', true);\n"],"names":[],"mappings":";;;AAuCa,MAAA,cAAA,GAAiB,CAAC,KAA+B,KAAA;AAC5D,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA
|
|
1
|
+
{"version":3,"file":"FeatureFlagged.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/FeatureFlagged.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 featureFlagsApiRef,\n useApi,\n attachComponentData,\n} from '@backstage/core-plugin-api';\nimport React, { ReactNode } from 'react';\n\n/**\n * Props for the {@link FeatureFlagged} component.\n *\n * @public\n */\nexport type FeatureFlaggedProps = { children: ReactNode } & (\n | { with: string }\n | { without: string }\n);\n\n/**\n * Enables or disables rendering of its children based on the state of a given\n * feature flag.\n *\n * @public\n */\nexport const FeatureFlagged = (props: FeatureFlaggedProps) => {\n const { children } = props;\n const featureFlagApi = useApi(featureFlagsApiRef);\n const isEnabled =\n 'with' in props\n ? featureFlagApi.isActive(props.with)\n : !featureFlagApi.isActive(props.without);\n return <>{isEnabled ? children : null}</>;\n};\n\nattachComponentData(FeatureFlagged, 'core.featureFlagged', true);\n"],"names":[],"mappings":";;;AAuCa,MAAA,cAAA,GAAiB,CAAC,KAA+B,KAAA;AAC5D,EAAM,MAAA,EAAE,UAAa,GAAA,KAAA;AACrB,EAAM,MAAA,cAAA,GAAiB,OAAO,kBAAkB,CAAA;AAChD,EAAA,MAAM,SACJ,GAAA,MAAA,IAAU,KACN,GAAA,cAAA,CAAe,QAAS,CAAA,KAAA,CAAM,IAAI,CAAA,GAClC,CAAC,cAAA,CAAe,QAAS,CAAA,KAAA,CAAM,OAAO,CAAA;AAC5C,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAG,SAAY,GAAA,QAAA,GAAW,IAAK,CAAA;AACxC;AAEA,mBAAoB,CAAA,cAAA,EAAgB,uBAAuB,IAAI,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlatRoutes.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/FlatRoutes.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 React, { ReactNode, useMemo } from 'react';\nimport { useRoutes } from 'react-router-dom';\nimport {\n attachComponentData,\n useApp,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport { isReactRouterBeta } from '../app/isReactRouterBeta';\n\nlet warned = false;\n\ntype RouteObject = {\n path: string;\n element: ReactNode;\n children?: RouteObject[];\n};\n\n/**\n * Props for the {@link FlatRoutes} component.\n *\n * @public\n */\nexport type FlatRoutesProps = {\n children: ReactNode;\n};\n\n/**\n * A wrapper around a set of routes.\n *\n * @remarks\n *\n * The root of the routing hierarchy in your app should use this component,\n * instead of the one from `react-router-dom`. This ensures that all of the\n * plugin route and utility API wiring happens under the hood.\n *\n * @public\n */\nexport const FlatRoutes = (props: FlatRoutesProps): JSX.Element | null => {\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\n const isBeta = useMemo(() => isReactRouterBeta(), []);\n const routes = useElementFilter(props.children, elements =>\n elements\n .getElements<{\n path?: string;\n element?: ReactNode;\n children?: ReactNode;\n }>()\n .flatMap<RouteObject>(child => {\n let path = child.props.path;\n\n // TODO(Rugvip): Work around plugins registering empty paths, remove once deprecated routes are gone\n if (path === '') {\n return [];\n }\n path = path?.replace(/\\/\\*$/, '') ?? '/';\n\n let element = isBeta ? child : child.props.element;\n if (!isBeta && !element) {\n element = child;\n if (!warned && process.env.NODE_ENV !== 'test') {\n // eslint-disable-next-line no-console\n console.warn(\n 'DEPRECATION WARNING: All elements within <FlatRoutes> must be of type <Route> with an element prop. ' +\n 'Existing usages of <Navigate key=[path] to=[to] /> should be replaced with <Route path=[path] element={<Navigate to=[to] />} />.',\n );\n warned = true;\n }\n }\n\n return [\n {\n // Each route matches any sub route, except for the explicit root path\n path,\n element,\n children: child.props.children\n ? [\n // These are the children of each route, which we all add in under a catch-all\n // subroute in order to make them available to `useOutlet`\n {\n path: path === '/' ? '/' : '*', // The root path must require an exact match\n element: child.props.children,\n },\n ]\n : undefined,\n },\n ];\n })\n // Routes are sorted to work around a bug where prefixes are unexpectedly matched\n // TODO(Rugvip): This can be removed once react-router v6 beta is no longer supported\n .sort((a, b) => b.path.localeCompare(a.path))\n .map(obj => ({ ...obj, path: obj.path === '/' ? '/' : `${obj.path}/*` })),\n );\n\n // TODO(Rugvip): Possibly add a way to skip this, like a noNotFoundPage prop\n const withNotFound = [\n ...routes,\n {\n path: '*',\n element: <NotFoundErrorPage />,\n },\n ];\n\n return useRoutes(withNotFound);\n};\n\nattachComponentData(FlatRoutes, 'core.type', 'FlatRoutes');\n"],"names":[],"mappings":";;;;;AAyBA,IAAI,MAAS,GAAA,KAAA
|
|
1
|
+
{"version":3,"file":"FlatRoutes.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/FlatRoutes.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 React, { ReactNode, useMemo } from 'react';\nimport { useRoutes } from 'react-router-dom';\nimport {\n attachComponentData,\n useApp,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport { isReactRouterBeta } from '../app/isReactRouterBeta';\n\nlet warned = false;\n\ntype RouteObject = {\n path: string;\n element: ReactNode;\n children?: RouteObject[];\n};\n\n/**\n * Props for the {@link FlatRoutes} component.\n *\n * @public\n */\nexport type FlatRoutesProps = {\n children: ReactNode;\n};\n\n/**\n * A wrapper around a set of routes.\n *\n * @remarks\n *\n * The root of the routing hierarchy in your app should use this component,\n * instead of the one from `react-router-dom`. This ensures that all of the\n * plugin route and utility API wiring happens under the hood.\n *\n * @public\n */\nexport const FlatRoutes = (props: FlatRoutesProps): JSX.Element | null => {\n const app = useApp();\n const { NotFoundErrorPage } = app.getComponents();\n const isBeta = useMemo(() => isReactRouterBeta(), []);\n const routes = useElementFilter(props.children, elements =>\n elements\n .getElements<{\n path?: string;\n element?: ReactNode;\n children?: ReactNode;\n }>()\n .flatMap<RouteObject>(child => {\n let path = child.props.path;\n\n // TODO(Rugvip): Work around plugins registering empty paths, remove once deprecated routes are gone\n if (path === '') {\n return [];\n }\n path = path?.replace(/\\/\\*$/, '') ?? '/';\n\n let element = isBeta ? child : child.props.element;\n if (!isBeta && !element) {\n element = child;\n if (!warned && process.env.NODE_ENV !== 'test') {\n // eslint-disable-next-line no-console\n console.warn(\n 'DEPRECATION WARNING: All elements within <FlatRoutes> must be of type <Route> with an element prop. ' +\n 'Existing usages of <Navigate key=[path] to=[to] /> should be replaced with <Route path=[path] element={<Navigate to=[to] />} />.',\n );\n warned = true;\n }\n }\n\n return [\n {\n // Each route matches any sub route, except for the explicit root path\n path,\n element,\n children: child.props.children\n ? [\n // These are the children of each route, which we all add in under a catch-all\n // subroute in order to make them available to `useOutlet`\n {\n path: path === '/' ? '/' : '*', // The root path must require an exact match\n element: child.props.children,\n },\n ]\n : undefined,\n },\n ];\n })\n // Routes are sorted to work around a bug where prefixes are unexpectedly matched\n // TODO(Rugvip): This can be removed once react-router v6 beta is no longer supported\n .sort((a, b) => b.path.localeCompare(a.path))\n .map(obj => ({ ...obj, path: obj.path === '/' ? '/' : `${obj.path}/*` })),\n );\n\n // TODO(Rugvip): Possibly add a way to skip this, like a noNotFoundPage prop\n const withNotFound = [\n ...routes,\n {\n path: '*',\n element: <NotFoundErrorPage />,\n },\n ];\n\n return useRoutes(withNotFound);\n};\n\nattachComponentData(FlatRoutes, 'core.type', 'FlatRoutes');\n"],"names":[],"mappings":";;;;;AAyBA,IAAI,MAAS,GAAA,KAAA;AA4BA,MAAA,UAAA,GAAa,CAAC,KAA+C,KAAA;AACxE,EAAA,MAAM,MAAM,MAAO,EAAA;AACnB,EAAA,MAAM,EAAE,iBAAA,EAAsB,GAAA,GAAA,CAAI,aAAc,EAAA;AAChD,EAAA,MAAM,SAAS,OAAQ,CAAA,MAAM,iBAAkB,EAAA,EAAG,EAAE,CAAA;AACpD,EAAA,MAAM,MAAS,GAAA,gBAAA;AAAA,IAAiB,KAAM,CAAA,QAAA;AAAA,IAAU,CAC9C,QAAA,KAAA,QAAA,CACG,WAIE,EAAA,CACF,QAAqB,CAAS,KAAA,KAAA;AAC7B,MAAI,IAAA,IAAA,GAAO,MAAM,KAAM,CAAA,IAAA;AAGvB,MAAA,IAAI,SAAS,EAAI,EAAA;AACf,QAAA,OAAO,EAAC;AAAA;AAEV,MAAA,IAAA,GAAO,IAAM,EAAA,OAAA,CAAQ,OAAS,EAAA,EAAE,CAAK,IAAA,GAAA;AAErC,MAAA,IAAI,OAAU,GAAA,MAAA,GAAS,KAAQ,GAAA,KAAA,CAAM,KAAM,CAAA,OAAA;AAC3C,MAAI,IAAA,CAAC,MAAU,IAAA,CAAC,OAAS,EAAA;AACvB,QAAU,OAAA,GAAA,KAAA;AACV,QAAA,IAAI,CAAC,MAAA,IAAU,OAAQ,CAAA,GAAA,CAAI,aAAa,MAAQ,EAAA;AAE9C,UAAQ,OAAA,CAAA,IAAA;AAAA,YACN;AAAA,WAEF;AACA,UAAS,MAAA,GAAA,IAAA;AAAA;AACX;AAGF,MAAO,OAAA;AAAA,QACL;AAAA;AAAA,UAEE,IAAA;AAAA,UACA,OAAA;AAAA,UACA,QAAA,EAAU,KAAM,CAAA,KAAA,CAAM,QAClB,GAAA;AAAA;AAAA;AAAA,YAGE;AAAA,cACE,IAAA,EAAM,IAAS,KAAA,GAAA,GAAM,GAAM,GAAA,GAAA;AAAA;AAAA,cAC3B,OAAA,EAAS,MAAM,KAAM,CAAA;AAAA;AACvB,WAEF,GAAA,KAAA;AAAA;AACN,OACF;AAAA,KACD,CAGA,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAM,KAAA,CAAA,CAAE,IAAK,CAAA,aAAA,CAAc,CAAE,CAAA,IAAI,CAAC,CAAA,CAC3C,GAAI,CAAA,CAAA,GAAA,MAAQ,EAAE,GAAG,GAAK,EAAA,IAAA,EAAM,GAAI,CAAA,IAAA,KAAS,GAAM,GAAA,GAAA,GAAM,CAAG,EAAA,GAAA,CAAI,IAAI,CAAA,EAAA,CAAA,EAAO,CAAA;AAAA,GAC5E;AAGA,EAAA,MAAM,YAAe,GAAA;AAAA,IACnB,GAAG,MAAA;AAAA,IACH;AAAA,MACE,IAAM,EAAA,GAAA;AAAA,MACN,OAAA,sCAAU,iBAAkB,EAAA,IAAA;AAAA;AAC9B,GACF;AAEA,EAAA,OAAO,UAAU,YAAY,CAAA;AAC/B;AAEA,mBAAoB,CAAA,UAAA,EAAY,aAAa,YAAY,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteTracker.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/RouteTracker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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, { useEffect } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport {\n useAnalytics,\n AnalyticsContext,\n RouteRef,\n AnalyticsEventAttributes,\n BackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { BackstageRouteObject } from './types';\n\n/**\n * Returns an extension context given the current pathname and a list of\n * Backstage route objects.\n */\nconst getExtensionContext = (\n pathname: string,\n routes: BackstageRouteObject[],\n) => {\n try {\n // Find matching routes for the given path name.\n const matches = matchRoutes(routes, { pathname });\n\n // Of the matching routes, get the last (e.g. most specific) instance of\n // the BackstageRouteObject that contains a routeRef. Filtering by routeRef\n // ensures subRouteRefs are aligned to their parent routes' context.\n const routeMatch = matches\n ?.filter(match => match?.route.routeRefs?.size > 0)\n .pop();\n const routeObject = routeMatch?.route;\n\n // If there is no route object, then allow inheritance of default context.\n if (!routeObject) {\n return undefined;\n }\n\n // If the matched route is the root route (no path), and the pathname is\n // not the path of the homepage, then inherit from the default context.\n if (routeObject.path === '' && pathname !== '/') {\n return undefined;\n }\n\n // If there is a single route ref, use it.\n let routeRef: RouteRef | undefined;\n if (routeObject.routeRefs.size === 1) {\n routeRef = routeObject.routeRefs.values().next().value;\n }\n\n // If there is a single plugin, use it.\n let plugin: BackstagePlugin | undefined;\n if (routeObject.plugins.size === 1) {\n plugin = routeObject.plugins.values().next().value;\n }\n\n const params = Object.entries(\n routeMatch?.params || {},\n ).reduce<AnalyticsEventAttributes>((acc, [key, value]) => {\n if (value !== undefined && key !== '*') {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n return {\n extension: 'App',\n pluginId: plugin?.getId() || 'root',\n ...(routeRef ? { routeRef: (routeRef as { id?: string }).id } : {}),\n _routeNodeType: routeObject.element as string,\n params,\n };\n } catch {\n return undefined;\n }\n};\n\n/**\n * Performs the actual event capture on render.\n */\nconst TrackNavigation = ({\n pathname,\n search,\n hash,\n attributes,\n}: {\n pathname: string;\n search: string;\n hash: string;\n attributes?: AnalyticsEventAttributes;\n}) => {\n const analytics = useAnalytics();\n useEffect(() => {\n analytics.captureEvent('navigate', `${pathname}${search}${hash}`, {\n attributes,\n });\n }, [analytics, pathname, search, hash, attributes]);\n\n return null;\n};\n\n/**\n * Logs a \"navigate\" event with appropriate plugin-level analytics context\n * attributes each time the user navigates to a page.\n */\nexport const RouteTracker = ({\n routeObjects,\n}: {\n routeObjects: BackstageRouteObject[];\n}) => {\n const { pathname, search, hash } = useLocation();\n\n const { params, ...attributes } = getExtensionContext(\n pathname,\n routeObjects,\n ) || { params: {} };\n\n return (\n <AnalyticsContext attributes={attributes}>\n <TrackNavigation\n pathname={pathname}\n search={search}\n hash={hash}\n attributes={params}\n />\n </AnalyticsContext>\n );\n};\n"],"names":[],"mappings":";;;;AA+BA,MAAM,mBAAA,GAAsB,CAC1B,QAAA,EACA,MACG,KAAA;AACH,EAAI,IAAA;AAEF,IAAA,MAAM,OAAU,GAAA,WAAA,CAAY,MAAQ,EAAA,EAAE,UAAU,CAAA
|
|
1
|
+
{"version":3,"file":"RouteTracker.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/RouteTracker.tsx"],"sourcesContent":["/*\n * Copyright 2021 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, { useEffect } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport {\n useAnalytics,\n AnalyticsContext,\n RouteRef,\n AnalyticsEventAttributes,\n BackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { BackstageRouteObject } from './types';\n\n/**\n * Returns an extension context given the current pathname and a list of\n * Backstage route objects.\n */\nconst getExtensionContext = (\n pathname: string,\n routes: BackstageRouteObject[],\n) => {\n try {\n // Find matching routes for the given path name.\n const matches = matchRoutes(routes, { pathname });\n\n // Of the matching routes, get the last (e.g. most specific) instance of\n // the BackstageRouteObject that contains a routeRef. Filtering by routeRef\n // ensures subRouteRefs are aligned to their parent routes' context.\n const routeMatch = matches\n ?.filter(match => match?.route.routeRefs?.size > 0)\n .pop();\n const routeObject = routeMatch?.route;\n\n // If there is no route object, then allow inheritance of default context.\n if (!routeObject) {\n return undefined;\n }\n\n // If the matched route is the root route (no path), and the pathname is\n // not the path of the homepage, then inherit from the default context.\n if (routeObject.path === '' && pathname !== '/') {\n return undefined;\n }\n\n // If there is a single route ref, use it.\n let routeRef: RouteRef | undefined;\n if (routeObject.routeRefs.size === 1) {\n routeRef = routeObject.routeRefs.values().next().value;\n }\n\n // If there is a single plugin, use it.\n let plugin: BackstagePlugin | undefined;\n if (routeObject.plugins.size === 1) {\n plugin = routeObject.plugins.values().next().value;\n }\n\n const params = Object.entries(\n routeMatch?.params || {},\n ).reduce<AnalyticsEventAttributes>((acc, [key, value]) => {\n if (value !== undefined && key !== '*') {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n return {\n extension: 'App',\n pluginId: plugin?.getId() || 'root',\n ...(routeRef ? { routeRef: (routeRef as { id?: string }).id } : {}),\n _routeNodeType: routeObject.element as string,\n params,\n };\n } catch {\n return undefined;\n }\n};\n\n/**\n * Performs the actual event capture on render.\n */\nconst TrackNavigation = ({\n pathname,\n search,\n hash,\n attributes,\n}: {\n pathname: string;\n search: string;\n hash: string;\n attributes?: AnalyticsEventAttributes;\n}) => {\n const analytics = useAnalytics();\n useEffect(() => {\n analytics.captureEvent('navigate', `${pathname}${search}${hash}`, {\n attributes,\n });\n }, [analytics, pathname, search, hash, attributes]);\n\n return null;\n};\n\n/**\n * Logs a \"navigate\" event with appropriate plugin-level analytics context\n * attributes each time the user navigates to a page.\n */\nexport const RouteTracker = ({\n routeObjects,\n}: {\n routeObjects: BackstageRouteObject[];\n}) => {\n const { pathname, search, hash } = useLocation();\n\n const { params, ...attributes } = getExtensionContext(\n pathname,\n routeObjects,\n ) || { params: {} };\n\n return (\n <AnalyticsContext attributes={attributes}>\n <TrackNavigation\n pathname={pathname}\n search={search}\n hash={hash}\n attributes={params}\n />\n </AnalyticsContext>\n );\n};\n"],"names":[],"mappings":";;;;AA+BA,MAAM,mBAAA,GAAsB,CAC1B,QAAA,EACA,MACG,KAAA;AACH,EAAI,IAAA;AAEF,IAAA,MAAM,OAAU,GAAA,WAAA,CAAY,MAAQ,EAAA,EAAE,UAAU,CAAA;AAKhD,IAAM,MAAA,UAAA,GAAa,OACf,EAAA,MAAA,CAAO,CAAS,KAAA,KAAA,KAAA,EAAO,MAAM,SAAW,EAAA,IAAA,GAAO,CAAC,CAAA,CACjD,GAAI,EAAA;AACP,IAAA,MAAM,cAAc,UAAY,EAAA,KAAA;AAGhC,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAO,OAAA,KAAA,CAAA;AAAA;AAKT,IAAA,IAAI,WAAY,CAAA,IAAA,KAAS,EAAM,IAAA,QAAA,KAAa,GAAK,EAAA;AAC/C,MAAO,OAAA,KAAA,CAAA;AAAA;AAIT,IAAI,IAAA,QAAA;AACJ,IAAI,IAAA,WAAA,CAAY,SAAU,CAAA,IAAA,KAAS,CAAG,EAAA;AACpC,MAAA,QAAA,GAAW,WAAY,CAAA,SAAA,CAAU,MAAO,EAAA,CAAE,MAAO,CAAA,KAAA;AAAA;AAInD,IAAI,IAAA,MAAA;AACJ,IAAI,IAAA,WAAA,CAAY,OAAQ,CAAA,IAAA,KAAS,CAAG,EAAA;AAClC,MAAA,MAAA,GAAS,WAAY,CAAA,OAAA,CAAQ,MAAO,EAAA,CAAE,MAAO,CAAA,KAAA;AAAA;AAG/C,IAAA,MAAM,SAAS,MAAO,CAAA,OAAA;AAAA,MACpB,UAAA,EAAY,UAAU;AAAC,MACvB,MAAiC,CAAA,CAAC,KAAK,CAAC,GAAA,EAAK,KAAK,CAAM,KAAA;AACxD,MAAI,IAAA,KAAA,KAAU,KAAa,CAAA,IAAA,GAAA,KAAQ,GAAK,EAAA;AACtC,QAAA,GAAA,CAAI,GAAG,CAAI,GAAA,KAAA;AAAA;AAEb,MAAO,OAAA,GAAA;AAAA,KACT,EAAG,EAAE,CAAA;AAEL,IAAO,OAAA;AAAA,MACL,SAAW,EAAA,KAAA;AAAA,MACX,QAAA,EAAU,MAAQ,EAAA,KAAA,EAAW,IAAA,MAAA;AAAA,MAC7B,GAAI,QAAW,GAAA,EAAE,UAAW,QAA6B,CAAA,EAAA,KAAO,EAAC;AAAA,MACjE,gBAAgB,WAAY,CAAA,OAAA;AAAA,MAC5B;AAAA,KACF;AAAA,GACM,CAAA,MAAA;AACN,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAKA,MAAM,kBAAkB,CAAC;AAAA,EACvB,QAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAKM,KAAA;AACJ,EAAA,MAAM,YAAY,YAAa,EAAA;AAC/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAU,SAAA,CAAA,YAAA,CAAa,YAAY,CAAG,EAAA,QAAQ,GAAG,MAAM,CAAA,EAAG,IAAI,CAAI,CAAA,EAAA;AAAA,MAChE;AAAA,KACD,CAAA;AAAA,KACA,CAAC,SAAA,EAAW,UAAU,MAAQ,EAAA,IAAA,EAAM,UAAU,CAAC,CAAA;AAElD,EAAO,OAAA,IAAA;AACT,CAAA;AAMO,MAAM,eAAe,CAAC;AAAA,EAC3B;AACF,CAEM,KAAA;AACJ,EAAA,MAAM,EAAE,QAAA,EAAU,MAAQ,EAAA,IAAA,KAAS,WAAY,EAAA;AAE/C,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,UAAA,EAAe,GAAA,mBAAA;AAAA,IAChC,QAAA;AAAA,IACA;AAAA,GACG,IAAA,EAAE,MAAQ,EAAA,EAAG,EAAA;AAElB,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,oBAAiB,UAChB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAY,EAAA;AAAA;AAAA,GAEhB,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoutingProvider.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/RoutingProvider.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 React, { ReactNode } from 'react';\nimport {\n ExternalRouteRef,\n RouteRef,\n SubRouteRef,\n} from '@backstage/core-plugin-api';\nimport {\n createVersionedValueMap,\n createVersionedContext,\n} from '@backstage/version-bridge';\nimport { RouteResolver } from './RouteResolver';\nimport { BackstageRouteObject } from './types';\n\nconst RoutingContext = createVersionedContext<{ 1: RouteResolver }>(\n 'routing-context',\n);\n\ntype ProviderProps = {\n routePaths: Map<RouteRef, string>;\n routeParents: Map<RouteRef, RouteRef | undefined>;\n routeObjects: BackstageRouteObject[];\n routeBindings: Map<ExternalRouteRef, RouteRef | SubRouteRef>;\n basePath?: string;\n children: ReactNode;\n};\n\nexport const RoutingProvider = ({\n routePaths,\n routeParents,\n routeObjects,\n routeBindings,\n basePath = '',\n children,\n}: ProviderProps) => {\n const resolver = new RouteResolver(\n routePaths,\n routeParents,\n routeObjects,\n routeBindings,\n basePath,\n );\n\n const versionedValue = createVersionedValueMap({ 1: resolver });\n return (\n <RoutingContext.Provider value={versionedValue}>\n {children}\n </RoutingContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;;;AA6BuB,sBAAA;AAAA,EACrB
|
|
1
|
+
{"version":3,"file":"RoutingProvider.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/RoutingProvider.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 React, { ReactNode } from 'react';\nimport {\n ExternalRouteRef,\n RouteRef,\n SubRouteRef,\n} from '@backstage/core-plugin-api';\nimport {\n createVersionedValueMap,\n createVersionedContext,\n} from '@backstage/version-bridge';\nimport { RouteResolver } from './RouteResolver';\nimport { BackstageRouteObject } from './types';\n\nconst RoutingContext = createVersionedContext<{ 1: RouteResolver }>(\n 'routing-context',\n);\n\ntype ProviderProps = {\n routePaths: Map<RouteRef, string>;\n routeParents: Map<RouteRef, RouteRef | undefined>;\n routeObjects: BackstageRouteObject[];\n routeBindings: Map<ExternalRouteRef, RouteRef | SubRouteRef>;\n basePath?: string;\n children: ReactNode;\n};\n\nexport const RoutingProvider = ({\n routePaths,\n routeParents,\n routeObjects,\n routeBindings,\n basePath = '',\n children,\n}: ProviderProps) => {\n const resolver = new RouteResolver(\n routePaths,\n routeParents,\n routeObjects,\n routeBindings,\n basePath,\n );\n\n const versionedValue = createVersionedValueMap({ 1: resolver });\n return (\n <RoutingContext.Provider value={versionedValue}>\n {children}\n </RoutingContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;;;AA6BuB,sBAAA;AAAA,EACrB;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/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 RouteRef,\n SubRouteRef,\n ExternalRouteRef,\n BackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\n\ntype RouteRefType = Exclude<\n keyof RouteRef,\n 'params' | 'path' | 'title' | 'icon'\n>;\nexport const routeRefType: RouteRefType = getOrCreateGlobalSingleton<any>(\n 'route-ref-type',\n () => Symbol('route-ref-type'),\n);\n\nexport type AnyParams = { [param in string]: string } | undefined;\n\nexport type AnyRouteRef =\n | RouteRef<any>\n | SubRouteRef<any>\n | ExternalRouteRef<any, any>;\n\n// The extra TS magic here is to require a single params argument if the RouteRef\n// had at least one param defined, but require 0 arguments if there are no params defined.\n// Without this we'd have to pass in empty object to all parameter-less RouteRefs\n// just to make TypeScript happy, or we would have to make the argument optional in\n// which case you might forget to pass it in when it is actually required.\nexport type RouteFunc<Params extends AnyParams> = (\n ...[params]: Params extends undefined ? readonly [] : readonly [Params]\n) => string;\n\n// A duplicate of the react-router RouteObject, but with routeRef added\nexport interface BackstageRouteObject {\n caseSensitive: boolean;\n children?: BackstageRouteObject[];\n element: React.ReactNode;\n path: string;\n routeRefs: Set<RouteRef>;\n plugins: Set<BackstagePlugin>;\n}\n\nexport function isRouteRef<Params extends AnyParams>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, any>,\n): routeRef is RouteRef<Params> {\n return routeRef[routeRefType] === 'absolute';\n}\n\nexport function isSubRouteRef<Params extends AnyParams>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, any>,\n): routeRef is SubRouteRef<Params> {\n return routeRef[routeRefType] === 'sub';\n}\n\nexport function isExternalRouteRef<\n Params extends AnyParams,\n Optional extends boolean,\n>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, Optional>,\n): routeRef is ExternalRouteRef<Params, Optional> {\n return routeRef[routeRefType] === 'external';\n}\n"],"names":[],"mappings":";;AA4B0C,0BAAA;AAAA,EACxC,gBAAA;AAAA,EACA,MAAM,OAAO,gBAAgB
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../../../../../../../packages/core-app-api/src/routing/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 RouteRef,\n SubRouteRef,\n ExternalRouteRef,\n BackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\n\ntype RouteRefType = Exclude<\n keyof RouteRef,\n 'params' | 'path' | 'title' | 'icon'\n>;\nexport const routeRefType: RouteRefType = getOrCreateGlobalSingleton<any>(\n 'route-ref-type',\n () => Symbol('route-ref-type'),\n);\n\nexport type AnyParams = { [param in string]: string } | undefined;\n\nexport type AnyRouteRef =\n | RouteRef<any>\n | SubRouteRef<any>\n | ExternalRouteRef<any, any>;\n\n// The extra TS magic here is to require a single params argument if the RouteRef\n// had at least one param defined, but require 0 arguments if there are no params defined.\n// Without this we'd have to pass in empty object to all parameter-less RouteRefs\n// just to make TypeScript happy, or we would have to make the argument optional in\n// which case you might forget to pass it in when it is actually required.\nexport type RouteFunc<Params extends AnyParams> = (\n ...[params]: Params extends undefined ? readonly [] : readonly [Params]\n) => string;\n\n// A duplicate of the react-router RouteObject, but with routeRef added\nexport interface BackstageRouteObject {\n caseSensitive: boolean;\n children?: BackstageRouteObject[];\n element: React.ReactNode;\n path: string;\n routeRefs: Set<RouteRef>;\n plugins: Set<BackstagePlugin>;\n}\n\nexport function isRouteRef<Params extends AnyParams>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, any>,\n): routeRef is RouteRef<Params> {\n return routeRef[routeRefType] === 'absolute';\n}\n\nexport function isSubRouteRef<Params extends AnyParams>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, any>,\n): routeRef is SubRouteRef<Params> {\n return routeRef[routeRefType] === 'sub';\n}\n\nexport function isExternalRouteRef<\n Params extends AnyParams,\n Optional extends boolean,\n>(\n routeRef:\n | RouteRef<Params>\n | SubRouteRef<Params>\n | ExternalRouteRef<Params, Optional>,\n): routeRef is ExternalRouteRef<Params, Optional> {\n return routeRef[routeRefType] === 'external';\n}\n"],"names":[],"mappings":";;AA4B0C,0BAAA;AAAA,EACxC,gBAAA;AAAA,EACA,MAAM,OAAO,gBAAgB;AAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranslationRef.esm.js","sources":["../../../../../../../packages/core-plugin-api/src/translation/TranslationRef.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 createTranslationResource,\n TranslationResource,\n} from './TranslationResource';\n\n/** @alpha */\nexport interface TranslationRef<\n TId extends string = string,\n TMessages extends { [key in string]: string } = { [key in string]: string },\n> {\n $$type: '@backstage/TranslationRef';\n\n id: TId;\n\n T: TMessages;\n}\n\n/** @internal */\ntype AnyMessages = { [key in string]: string };\n\n/** @ignore */\ntype AnyNestedMessages = { [key in string]: AnyNestedMessages | string };\n\n/**\n * Flattens a nested message declaration into a flat object with dot-separated keys.\n *\n * @ignore\n */\ntype FlattenedMessages<TMessages extends AnyNestedMessages> =\n // Flatten out object keys into a union structure of objects, e.g. { a: 'a', b: 'b' } -> { a: 'a' } | { b: 'b' }\n // Any nested object will be flattened into the individual unions, e.g. { a: 'a', b: { x: 'x', y: 'y' } } -> { a: 'a' } | { 'b.x': 'x', 'b.y': 'y' }\n // We create this structure by first nesting the desired union types into the original object, and\n // then extract them by indexing with `keyof TMessages` to form the union.\n // Throughout this the objects are wrapped up in a function parameter, which allows us to have the\n // final step of flipping this unions around to an intersection by inferring the function parameter.\n {\n [TKey in keyof TMessages]: (\n _: TMessages[TKey] extends infer TValue // \"local variable\" for the value\n ? TValue extends AnyNestedMessages\n ? FlattenedMessages<TValue> extends infer TNested // Recurse into nested messages, \"local variable\" for the result\n ? {\n [TNestedKey in keyof TNested as `${TKey & string}.${TNestedKey &\n string}`]: TNested[TNestedKey];\n }\n : never\n : { [_ in TKey]: TValue } // Primitive object values are passed through with the same key\n : never,\n ) => void;\n // The `[keyof TMessages]` extracts the object values union from our flattened structure, still wrapped up in function parameters.\n // The `extends (_: infer TIntersection) => void` flips the union to an intersection, at which point we have the correct type.\n }[keyof TMessages] extends (_: infer TIntersection) => void\n ? // This object mapping just expands similar to the Expand<> utility type, providing nicer type hints\n {\n readonly [TExpandKey in keyof TIntersection]: TIntersection[TExpandKey];\n }\n : never;\n\n/** @internal */\nexport interface InternalTranslationRef<\n TId extends string = string,\n TMessages extends { [key in string]: string } = { [key in string]: string },\n> extends TranslationRef<TId, TMessages> {\n version: 'v1';\n\n getDefaultMessages(): AnyMessages;\n\n getDefaultResource(): TranslationResource | undefined;\n}\n\n/** @alpha */\nexport interface TranslationRefOptions<\n TId extends string,\n TNestedMessages extends AnyNestedMessages,\n TTranslations extends {\n [language in string]: () => Promise<{\n default: {\n [key in keyof FlattenedMessages<TNestedMessages>]: string | null;\n };\n }>;\n },\n> {\n id: TId;\n messages: TNestedMessages;\n translations?: TTranslations;\n}\n\nfunction flattenMessages(nested: AnyNestedMessages): AnyMessages {\n const entries = new Array<[string, string]>();\n\n function visit(obj: AnyNestedMessages, prefix: string): void {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string') {\n entries.push([prefix + key, value]);\n } else {\n visit(value, `${prefix}${key}.`);\n }\n }\n }\n\n visit(nested, '');\n\n return Object.fromEntries(entries);\n}\n\n/** @internal */\nclass TranslationRefImpl<\n TId extends string,\n TNestedMessages extends AnyNestedMessages,\n> implements InternalTranslationRef<TId, FlattenedMessages<TNestedMessages>>\n{\n #id: TId;\n #messages: FlattenedMessages<TNestedMessages>;\n #resources: TranslationResource | undefined;\n\n constructor(options: TranslationRefOptions<TId, TNestedMessages, any>) {\n this.#id = options.id;\n this.#messages = flattenMessages(\n options.messages,\n ) as FlattenedMessages<TNestedMessages>;\n }\n\n $$type = '@backstage/TranslationRef' as const;\n\n version = 'v1' as const;\n\n get id(): TId {\n return this.#id;\n }\n\n get T(): never {\n throw new Error('Not implemented');\n }\n\n getDefaultMessages(): AnyMessages {\n return this.#messages;\n }\n\n setDefaultResource(resources: TranslationResource): void {\n this.#resources = resources;\n }\n\n getDefaultResource(): TranslationResource | undefined {\n return this.#resources;\n }\n\n toString() {\n return `TranslationRef{id=${this.id}}`;\n }\n}\n\n/** @alpha */\nexport function createTranslationRef<\n TId extends string,\n const TNestedMessages extends AnyNestedMessages,\n TTranslations extends {\n [language in string]: () => Promise<{\n default: {\n [key in keyof FlattenedMessages<TNestedMessages>]: string | null;\n };\n }>;\n },\n>(\n config: TranslationRefOptions<TId, TNestedMessages, TTranslations>,\n): TranslationRef<TId, FlattenedMessages<TNestedMessages>> {\n const ref = new TranslationRefImpl(config);\n if (config.translations) {\n ref.setDefaultResource(\n createTranslationResource({\n ref,\n translations: config.translations as any,\n }),\n );\n }\n return ref;\n}\n\n/** @internal */\nexport function toInternalTranslationRef<\n TId extends string,\n TMessages extends AnyMessages,\n>(ref: TranslationRef<TId, TMessages>): InternalTranslationRef<TId, TMessages> {\n const r = ref as InternalTranslationRef<TId, TMessages>;\n if (r.$$type !== '@backstage/TranslationRef') {\n throw new Error(`Invalid translation ref, bad type '${r.$$type}'`);\n }\n if (r.version !== 'v1') {\n throw new Error(`Invalid translation ref, bad version '${r.version}'`);\n }\n return r;\n}\n"],"names":[],"mappings":"AAiMO,SAAS,yBAGd,GAA6E,EAAA;AAC7E,EAAA,MAAM,CAAI,GAAA,GAAA
|
|
1
|
+
{"version":3,"file":"TranslationRef.esm.js","sources":["../../../../../../../packages/core-plugin-api/src/translation/TranslationRef.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 createTranslationResource,\n TranslationResource,\n} from './TranslationResource';\n\n/** @alpha */\nexport interface TranslationRef<\n TId extends string = string,\n TMessages extends { [key in string]: string } = { [key in string]: string },\n> {\n $$type: '@backstage/TranslationRef';\n\n id: TId;\n\n T: TMessages;\n}\n\n/** @internal */\ntype AnyMessages = { [key in string]: string };\n\n/** @ignore */\ntype AnyNestedMessages = { [key in string]: AnyNestedMessages | string };\n\n/**\n * Flattens a nested message declaration into a flat object with dot-separated keys.\n *\n * @ignore\n */\ntype FlattenedMessages<TMessages extends AnyNestedMessages> =\n // Flatten out object keys into a union structure of objects, e.g. { a: 'a', b: 'b' } -> { a: 'a' } | { b: 'b' }\n // Any nested object will be flattened into the individual unions, e.g. { a: 'a', b: { x: 'x', y: 'y' } } -> { a: 'a' } | { 'b.x': 'x', 'b.y': 'y' }\n // We create this structure by first nesting the desired union types into the original object, and\n // then extract them by indexing with `keyof TMessages` to form the union.\n // Throughout this the objects are wrapped up in a function parameter, which allows us to have the\n // final step of flipping this unions around to an intersection by inferring the function parameter.\n {\n [TKey in keyof TMessages]: (\n _: TMessages[TKey] extends infer TValue // \"local variable\" for the value\n ? TValue extends AnyNestedMessages\n ? FlattenedMessages<TValue> extends infer TNested // Recurse into nested messages, \"local variable\" for the result\n ? {\n [TNestedKey in keyof TNested as `${TKey & string}.${TNestedKey &\n string}`]: TNested[TNestedKey];\n }\n : never\n : { [_ in TKey]: TValue } // Primitive object values are passed through with the same key\n : never,\n ) => void;\n // The `[keyof TMessages]` extracts the object values union from our flattened structure, still wrapped up in function parameters.\n // The `extends (_: infer TIntersection) => void` flips the union to an intersection, at which point we have the correct type.\n }[keyof TMessages] extends (_: infer TIntersection) => void\n ? // This object mapping just expands similar to the Expand<> utility type, providing nicer type hints\n {\n readonly [TExpandKey in keyof TIntersection]: TIntersection[TExpandKey];\n }\n : never;\n\n/** @internal */\nexport interface InternalTranslationRef<\n TId extends string = string,\n TMessages extends { [key in string]: string } = { [key in string]: string },\n> extends TranslationRef<TId, TMessages> {\n version: 'v1';\n\n getDefaultMessages(): AnyMessages;\n\n getDefaultResource(): TranslationResource | undefined;\n}\n\n/** @alpha */\nexport interface TranslationRefOptions<\n TId extends string,\n TNestedMessages extends AnyNestedMessages,\n TTranslations extends {\n [language in string]: () => Promise<{\n default: {\n [key in keyof FlattenedMessages<TNestedMessages>]: string | null;\n };\n }>;\n },\n> {\n id: TId;\n messages: TNestedMessages;\n translations?: TTranslations;\n}\n\nfunction flattenMessages(nested: AnyNestedMessages): AnyMessages {\n const entries = new Array<[string, string]>();\n\n function visit(obj: AnyNestedMessages, prefix: string): void {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'string') {\n entries.push([prefix + key, value]);\n } else {\n visit(value, `${prefix}${key}.`);\n }\n }\n }\n\n visit(nested, '');\n\n return Object.fromEntries(entries);\n}\n\n/** @internal */\nclass TranslationRefImpl<\n TId extends string,\n TNestedMessages extends AnyNestedMessages,\n> implements InternalTranslationRef<TId, FlattenedMessages<TNestedMessages>>\n{\n #id: TId;\n #messages: FlattenedMessages<TNestedMessages>;\n #resources: TranslationResource | undefined;\n\n constructor(options: TranslationRefOptions<TId, TNestedMessages, any>) {\n this.#id = options.id;\n this.#messages = flattenMessages(\n options.messages,\n ) as FlattenedMessages<TNestedMessages>;\n }\n\n $$type = '@backstage/TranslationRef' as const;\n\n version = 'v1' as const;\n\n get id(): TId {\n return this.#id;\n }\n\n get T(): never {\n throw new Error('Not implemented');\n }\n\n getDefaultMessages(): AnyMessages {\n return this.#messages;\n }\n\n setDefaultResource(resources: TranslationResource): void {\n this.#resources = resources;\n }\n\n getDefaultResource(): TranslationResource | undefined {\n return this.#resources;\n }\n\n toString() {\n return `TranslationRef{id=${this.id}}`;\n }\n}\n\n/** @alpha */\nexport function createTranslationRef<\n TId extends string,\n const TNestedMessages extends AnyNestedMessages,\n TTranslations extends {\n [language in string]: () => Promise<{\n default: {\n [key in keyof FlattenedMessages<TNestedMessages>]: string | null;\n };\n }>;\n },\n>(\n config: TranslationRefOptions<TId, TNestedMessages, TTranslations>,\n): TranslationRef<TId, FlattenedMessages<TNestedMessages>> {\n const ref = new TranslationRefImpl(config);\n if (config.translations) {\n ref.setDefaultResource(\n createTranslationResource({\n ref,\n translations: config.translations as any,\n }),\n );\n }\n return ref;\n}\n\n/** @internal */\nexport function toInternalTranslationRef<\n TId extends string,\n TMessages extends AnyMessages,\n>(ref: TranslationRef<TId, TMessages>): InternalTranslationRef<TId, TMessages> {\n const r = ref as InternalTranslationRef<TId, TMessages>;\n if (r.$$type !== '@backstage/TranslationRef') {\n throw new Error(`Invalid translation ref, bad type '${r.$$type}'`);\n }\n if (r.version !== 'v1') {\n throw new Error(`Invalid translation ref, bad version '${r.version}'`);\n }\n return r;\n}\n"],"names":[],"mappings":"AAiMO,SAAS,yBAGd,GAA6E,EAAA;AAC7E,EAAA,MAAM,CAAI,GAAA,GAAA;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,2BAA6B,EAAA;AAC5C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAsC,mCAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA;AAAA;AAEnE,EAAI,IAAA,CAAA,CAAE,YAAY,IAAM,EAAA;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAyC,sCAAA,EAAA,CAAA,CAAE,OAAO,CAAG,CAAA,CAAA,CAAA;AAAA;AAEvE,EAAO,OAAA,CAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranslationResource.esm.js","sources":["../../../../../../../packages/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
|
|
1
|
+
{"version":3,"file":"TranslationResource.esm.js","sources":["../../../../../../../packages/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;AACV,EAAI,IAAA,CAAA,CAAE,WAAW,gCAAkC,EAAA;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAA2C,wCAAA,EAAA,CAAA,CAAE,MAAM,CAAG,CAAA,CAAA,CAAA;AAAA;AAExE,EAAI,IAAA,CAAA,CAAE,YAAY,IAAM,EAAA;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAA8C,2CAAA,EAAA,CAAA,CAAE,OAAO,CAAG,CAAA,CAAA,CAAA;AAAA;AAG5E,EAAO,OAAA,CAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultComponentsApi.esm.js","sources":["../../../../../../../../../packages/frontend-app-api/src/apis/implementations/ComponentsApi/DefaultComponentsApi.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 { ComponentType } from 'react';\nimport {\n ComponentRef,\n ComponentsApi,\n createComponentExtension,\n} from '@backstage/frontend-plugin-api';\n\n/**\n * Implementation for the {@linkComponentApi}\n *\n * @internal\n */\nexport class DefaultComponentsApi implements ComponentsApi {\n #components: Map<string, ComponentType<any>>;\n\n static fromComponents(\n components: Array<typeof createComponentExtension.componentDataRef.T>,\n ) {\n return new DefaultComponentsApi(\n new Map(components.map(entry => [entry.ref.id, entry.impl])),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent<T extends {}>(ref: ComponentRef<T>): ComponentType<T> {\n const impl = this.#components.get(ref.id);\n if (!impl) {\n throw new Error(`No implementation found for component ref ${ref}`);\n }\n return impl;\n }\n}\n"],"names":[],"mappings":"AA4BO,MAAM,oBAA8C,CAAA;AAAA,EACzD,WAAA
|
|
1
|
+
{"version":3,"file":"DefaultComponentsApi.esm.js","sources":["../../../../../../../../../packages/frontend-app-api/src/apis/implementations/ComponentsApi/DefaultComponentsApi.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 { ComponentType } from 'react';\nimport {\n ComponentRef,\n ComponentsApi,\n createComponentExtension,\n} from '@backstage/frontend-plugin-api';\n\n/**\n * Implementation for the {@linkComponentApi}\n *\n * @internal\n */\nexport class DefaultComponentsApi implements ComponentsApi {\n #components: Map<string, ComponentType<any>>;\n\n static fromComponents(\n components: Array<typeof createComponentExtension.componentDataRef.T>,\n ) {\n return new DefaultComponentsApi(\n new Map(components.map(entry => [entry.ref.id, entry.impl])),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent<T extends {}>(ref: ComponentRef<T>): ComponentType<T> {\n const impl = this.#components.get(ref.id);\n if (!impl) {\n throw new Error(`No implementation found for component ref ${ref}`);\n }\n return impl;\n }\n}\n"],"names":[],"mappings":"AA4BO,MAAM,oBAA8C,CAAA;AAAA,EACzD,WAAA;AAAA,EAEA,OAAO,eACL,UACA,EAAA;AACA,IAAA,OAAO,IAAI,oBAAA;AAAA,MACT,IAAI,GAAA,CAAI,UAAW,CAAA,GAAA,CAAI,CAAS,KAAA,KAAA,CAAC,KAAM,CAAA,GAAA,CAAI,EAAI,EAAA,KAAA,CAAM,IAAI,CAAC,CAAC;AAAA,KAC7D;AAAA;AACF,EAEA,YAAY,UAA8B,EAAA;AACxC,IAAA,IAAA,CAAK,WAAc,GAAA,UAAA;AAAA;AACrB,EAEA,aAA2B,GAAwC,EAAA;AACjE,IAAA,MAAM,IAAO,GAAA,IAAA,CAAK,WAAY,CAAA,GAAA,CAAI,IAAI,EAAE,CAAA;AACxC,IAAA,IAAI,CAAC,IAAM,EAAA;AACT,MAAA,MAAM,IAAI,KAAA,CAAM,CAA6C,0CAAA,EAAA,GAAG,CAAE,CAAA,CAAA;AAAA;AAEpE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
|
package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultIconsApi.esm.js","sources":["../../../../../../../../../packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.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 { IconComponent, IconsApi } from '@backstage/frontend-plugin-api';\n\n/**\n * Implementation for the {@link IconsApi}\n *\n * @internal\n */\nexport class DefaultIconsApi implements IconsApi {\n #icons: Map<string, IconComponent>;\n\n constructor(icons: { [key in string]: IconComponent }) {\n this.#icons = new Map(Object.entries(icons));\n }\n\n getIcon(key: string): IconComponent | undefined {\n return this.#icons.get(key);\n }\n\n listIconKeys(): string[] {\n return Array.from(this.#icons.keys());\n }\n}\n"],"names":[],"mappings":"AAuBO,MAAM,eAAoC,CAAA;AAAA,EAC/C,MAAA
|
|
1
|
+
{"version":3,"file":"DefaultIconsApi.esm.js","sources":["../../../../../../../../../packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.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 { IconComponent, IconsApi } from '@backstage/frontend-plugin-api';\n\n/**\n * Implementation for the {@link IconsApi}\n *\n * @internal\n */\nexport class DefaultIconsApi implements IconsApi {\n #icons: Map<string, IconComponent>;\n\n constructor(icons: { [key in string]: IconComponent }) {\n this.#icons = new Map(Object.entries(icons));\n }\n\n getIcon(key: string): IconComponent | undefined {\n return this.#icons.get(key);\n }\n\n listIconKeys(): string[] {\n return Array.from(this.#icons.keys());\n }\n}\n"],"names":[],"mappings":"AAuBO,MAAM,eAAoC,CAAA;AAAA,EAC/C,MAAA;AAAA,EAEA,YAAY,KAA2C,EAAA;AACrD,IAAA,IAAA,CAAK,SAAS,IAAI,GAAA,CAAI,MAAO,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA;AAC7C,EAEA,QAAQ,GAAwC,EAAA;AAC9C,IAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAA,CAAI,GAAG,CAAA;AAAA;AAC5B,EAEA,YAAyB,GAAA;AACvB,IAAA,OAAO,KAAM,CAAA,IAAA,CAAK,IAAK,CAAA,MAAA,CAAO,MAAM,CAAA;AAAA;AAExC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteTracker.esm.js","sources":["../../../../../../../packages/frontend-app-api/src/routing/RouteTracker.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, { useEffect } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport {\n useAnalytics,\n AnalyticsContext,\n AnalyticsEventAttributes,\n} from '@backstage/frontend-plugin-api';\nimport { BackstageRouteObject } from './types';\n\n/**\n * Returns an extension context given the current pathname and a list of\n * Backstage route objects.\n */\nconst getExtensionContext = (\n pathname: string,\n routes: BackstageRouteObject[],\n) => {\n try {\n // Find matching routes for the given path name.\n const matches = matchRoutes(routes, { pathname });\n\n // Of the matching routes, get the last (e.g. most specific) instance of\n // the BackstageRouteObject that contains a routeRef. Filtering by routeRef\n // ensures subRouteRefs are aligned to their parent routes' context.\n const routeMatch = matches\n ?.filter(match => match?.route.routeRefs?.size > 0)\n .pop();\n const routeObject = routeMatch?.route;\n\n // If there is no route object, then allow inheritance of default context.\n if (!routeObject) {\n return undefined;\n }\n\n // If the matched route is the root route (no path), and the pathname is\n // not the path of the homepage, then inherit from the default context.\n if (routeObject.path === '' && pathname !== '/') {\n return undefined;\n }\n\n const params = Object.entries(\n routeMatch?.params || {},\n ).reduce<AnalyticsEventAttributes>((acc, [key, value]) => {\n if (value !== undefined && key !== '*') {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n const plugin = routeObject.appNode?.spec.source;\n const extension = routeObject.appNode?.spec.extension;\n\n return {\n params,\n pluginId: plugin?.id || 'root',\n extensionId: extension?.id || 'App',\n };\n } catch {\n return undefined;\n }\n};\n\n/**\n * Performs the actual event capture on render.\n */\nconst TrackNavigation = ({\n pathname,\n search,\n hash,\n attributes,\n}: {\n pathname: string;\n search: string;\n hash: string;\n attributes?: AnalyticsEventAttributes;\n}) => {\n const analytics = useAnalytics();\n useEffect(() => {\n analytics.captureEvent('navigate', `${pathname}${search}${hash}`, {\n attributes,\n });\n }, [analytics, pathname, search, hash, attributes]);\n\n return null;\n};\n\n/**\n * Logs a \"navigate\" event with appropriate plugin-level analytics context\n * attributes each time the user navigates to a page.\n */\nexport const RouteTracker = ({\n routeObjects,\n}: {\n routeObjects: BackstageRouteObject[];\n}) => {\n const { pathname, search, hash } = useLocation();\n\n const { params, ...attributes } = getExtensionContext(\n pathname,\n routeObjects,\n ) || { params: {} };\n\n return (\n <AnalyticsContext attributes={attributes}>\n <TrackNavigation\n pathname={pathname}\n search={search}\n hash={hash}\n attributes={params}\n />\n </AnalyticsContext>\n );\n};\n"],"names":[],"mappings":";;;;AA6BA,MAAM,mBAAA,GAAsB,CAC1B,QAAA,EACA,MACG,KAAA;AACH,EAAI,IAAA;AAEF,IAAA,MAAM,OAAU,GAAA,WAAA,CAAY,MAAQ,EAAA,EAAE,UAAU,CAAA
|
|
1
|
+
{"version":3,"file":"RouteTracker.esm.js","sources":["../../../../../../../packages/frontend-app-api/src/routing/RouteTracker.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, { useEffect } from 'react';\nimport { matchRoutes, useLocation } from 'react-router-dom';\nimport {\n useAnalytics,\n AnalyticsContext,\n AnalyticsEventAttributes,\n} from '@backstage/frontend-plugin-api';\nimport { BackstageRouteObject } from './types';\n\n/**\n * Returns an extension context given the current pathname and a list of\n * Backstage route objects.\n */\nconst getExtensionContext = (\n pathname: string,\n routes: BackstageRouteObject[],\n) => {\n try {\n // Find matching routes for the given path name.\n const matches = matchRoutes(routes, { pathname });\n\n // Of the matching routes, get the last (e.g. most specific) instance of\n // the BackstageRouteObject that contains a routeRef. Filtering by routeRef\n // ensures subRouteRefs are aligned to their parent routes' context.\n const routeMatch = matches\n ?.filter(match => match?.route.routeRefs?.size > 0)\n .pop();\n const routeObject = routeMatch?.route;\n\n // If there is no route object, then allow inheritance of default context.\n if (!routeObject) {\n return undefined;\n }\n\n // If the matched route is the root route (no path), and the pathname is\n // not the path of the homepage, then inherit from the default context.\n if (routeObject.path === '' && pathname !== '/') {\n return undefined;\n }\n\n const params = Object.entries(\n routeMatch?.params || {},\n ).reduce<AnalyticsEventAttributes>((acc, [key, value]) => {\n if (value !== undefined && key !== '*') {\n acc[key] = value;\n }\n return acc;\n }, {});\n\n const plugin = routeObject.appNode?.spec.source;\n const extension = routeObject.appNode?.spec.extension;\n\n return {\n params,\n pluginId: plugin?.id || 'root',\n extensionId: extension?.id || 'App',\n };\n } catch {\n return undefined;\n }\n};\n\n/**\n * Performs the actual event capture on render.\n */\nconst TrackNavigation = ({\n pathname,\n search,\n hash,\n attributes,\n}: {\n pathname: string;\n search: string;\n hash: string;\n attributes?: AnalyticsEventAttributes;\n}) => {\n const analytics = useAnalytics();\n useEffect(() => {\n analytics.captureEvent('navigate', `${pathname}${search}${hash}`, {\n attributes,\n });\n }, [analytics, pathname, search, hash, attributes]);\n\n return null;\n};\n\n/**\n * Logs a \"navigate\" event with appropriate plugin-level analytics context\n * attributes each time the user navigates to a page.\n */\nexport const RouteTracker = ({\n routeObjects,\n}: {\n routeObjects: BackstageRouteObject[];\n}) => {\n const { pathname, search, hash } = useLocation();\n\n const { params, ...attributes } = getExtensionContext(\n pathname,\n routeObjects,\n ) || { params: {} };\n\n return (\n <AnalyticsContext attributes={attributes}>\n <TrackNavigation\n pathname={pathname}\n search={search}\n hash={hash}\n attributes={params}\n />\n </AnalyticsContext>\n );\n};\n"],"names":[],"mappings":";;;;AA6BA,MAAM,mBAAA,GAAsB,CAC1B,QAAA,EACA,MACG,KAAA;AACH,EAAI,IAAA;AAEF,IAAA,MAAM,OAAU,GAAA,WAAA,CAAY,MAAQ,EAAA,EAAE,UAAU,CAAA;AAKhD,IAAM,MAAA,UAAA,GAAa,OACf,EAAA,MAAA,CAAO,CAAS,KAAA,KAAA,KAAA,EAAO,MAAM,SAAW,EAAA,IAAA,GAAO,CAAC,CAAA,CACjD,GAAI,EAAA;AACP,IAAA,MAAM,cAAc,UAAY,EAAA,KAAA;AAGhC,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAO,OAAA,KAAA,CAAA;AAAA;AAKT,IAAA,IAAI,WAAY,CAAA,IAAA,KAAS,EAAM,IAAA,QAAA,KAAa,GAAK,EAAA;AAC/C,MAAO,OAAA,KAAA,CAAA;AAAA;AAGT,IAAA,MAAM,SAAS,MAAO,CAAA,OAAA;AAAA,MACpB,UAAA,EAAY,UAAU;AAAC,MACvB,MAAiC,CAAA,CAAC,KAAK,CAAC,GAAA,EAAK,KAAK,CAAM,KAAA;AACxD,MAAI,IAAA,KAAA,KAAU,KAAa,CAAA,IAAA,GAAA,KAAQ,GAAK,EAAA;AACtC,QAAA,GAAA,CAAI,GAAG,CAAI,GAAA,KAAA;AAAA;AAEb,MAAO,OAAA,GAAA;AAAA,KACT,EAAG,EAAE,CAAA;AAEL,IAAM,MAAA,MAAA,GAAS,WAAY,CAAA,OAAA,EAAS,IAAK,CAAA,MAAA;AACzC,IAAM,MAAA,SAAA,GAAY,WAAY,CAAA,OAAA,EAAS,IAAK,CAAA,SAAA;AAE5C,IAAO,OAAA;AAAA,MACL,MAAA;AAAA,MACA,QAAA,EAAU,QAAQ,EAAM,IAAA,MAAA;AAAA,MACxB,WAAA,EAAa,WAAW,EAAM,IAAA;AAAA,KAChC;AAAA,GACM,CAAA,MAAA;AACN,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAKA,MAAM,kBAAkB,CAAC;AAAA,EACvB,QAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAKM,KAAA;AACJ,EAAA,MAAM,YAAY,YAAa,EAAA;AAC/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAU,SAAA,CAAA,YAAA,CAAa,YAAY,CAAG,EAAA,QAAQ,GAAG,MAAM,CAAA,EAAG,IAAI,CAAI,CAAA,EAAA;AAAA,MAChE;AAAA,KACD,CAAA;AAAA,KACA,CAAC,SAAA,EAAW,UAAU,MAAQ,EAAA,IAAA,EAAM,UAAU,CAAC,CAAA;AAElD,EAAO,OAAA,IAAA;AACT,CAAA;AAMO,MAAM,eAAe,CAAC;AAAA,EAC3B;AACF,CAEM,KAAA;AACJ,EAAA,MAAM,EAAE,QAAA,EAAU,MAAQ,EAAA,IAAA,KAAS,WAAY,EAAA;AAE/C,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,UAAA,EAAe,GAAA,mBAAA;AAAA,IAChC,QAAA;AAAA,IACA;AAAA,GACG,IAAA,EAAE,MAAQ,EAAA,EAAG,EAAA;AAElB,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,oBAAiB,UAChB,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAY,EAAA;AAAA;AAAA,GAEhB,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getBasePath.esm.js","sources":["../../../../../../../packages/frontend-app-api/src/routing/getBasePath.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ConfigApi } from '@backstage/frontend-plugin-api';\n\n/** @internal */\nexport function getBasePath(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"],"names":[],"mappings":"AAmBO,SAAS,YAAY,SAAsB,EAAA;AAChD,EAAI,IAAA,EAAE,QAAS,EAAA,GAAI,IAAI,GAAA;AAAA,IACrB,SAAA,CAAU,iBAAkB,CAAA,aAAa,CAAK,IAAA,GAAA;AAAA,IAC9C
|
|
1
|
+
{"version":3,"file":"getBasePath.esm.js","sources":["../../../../../../../packages/frontend-app-api/src/routing/getBasePath.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ConfigApi } from '@backstage/frontend-plugin-api';\n\n/** @internal */\nexport function getBasePath(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"],"names":[],"mappings":"AAmBO,SAAS,YAAY,SAAsB,EAAA;AAChD,EAAI,IAAA,EAAE,QAAS,EAAA,GAAI,IAAI,GAAA;AAAA,IACrB,SAAA,CAAU,iBAAkB,CAAA,aAAa,CAAK,IAAA,GAAA;AAAA,IAC9C;AAAA;AAAA,GACF;AACA,EAAW,QAAA,GAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,EAAQ,EAAE,CAAA;AACtC,EAAO,OAAA,QAAA;AACT;;;;"}
|
package/dist/plugin.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n ComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultProgressComponent,\n DefaultNotFoundErrorPageComponent,\n DefaultErrorBoundaryComponent,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n DefaultSignInPage,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n id: 'app',\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n ComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultProgressComponent,\n DefaultNotFoundErrorPageComponent,\n DefaultErrorBoundaryComponent,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAyCO,MAAM,YAAY,oBAAqB,CAAA;AAAA,EAC5C,EAAI,EAAA,KAAA;AAAA,EACJ,UAAY,EAAA;AAAA,IACV,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,wBAAA;AAAA,IACA,iCAAA;AAAA,IACA,6BAAA;AAAA,IACA,iBAAA;AAAA,IACA,gCAAA;AAAA,IACA
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n ComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultProgressComponent,\n DefaultNotFoundErrorPageComponent,\n DefaultErrorBoundaryComponent,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n DefaultSignInPage,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n id: 'app',\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n ComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultProgressComponent,\n DefaultNotFoundErrorPageComponent,\n DefaultErrorBoundaryComponent,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAyCO,MAAM,YAAY,oBAAqB,CAAA;AAAA,EAC5C,EAAI,EAAA,KAAA;AAAA,EACJ,UAAY,EAAA;AAAA,IACV,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,wBAAA;AAAA,IACA,iCAAA;AAAA,IACA,6BAAA;AAAA,IACA,iBAAA;AAAA,IACA,gCAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-app",
|
|
3
|
-
"version": "0.1.2-next.
|
|
3
|
+
"version": "0.1.2-next.2",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "frontend-plugin",
|
|
6
6
|
"pluginId": "app",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"test": "backstage-cli package test"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@backstage/core-components": "0.16.0-next.
|
|
40
|
+
"@backstage/core-components": "0.16.0-next.2",
|
|
41
41
|
"@backstage/core-plugin-api": "1.10.0",
|
|
42
|
-
"@backstage/frontend-plugin-api": "0.9.1-next.
|
|
42
|
+
"@backstage/frontend-plugin-api": "0.9.1-next.2",
|
|
43
43
|
"@backstage/integration-react": "1.2.0",
|
|
44
44
|
"@backstage/plugin-permission-react": "0.4.27",
|
|
45
45
|
"@backstage/theme": "0.6.1-next.0",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"react-use": "^17.2.4"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@backstage/cli": "0.29.0-next.
|
|
53
|
-
"@backstage/dev-utils": "1.1.3-next.
|
|
54
|
-
"@backstage/frontend-test-utils": "0.2.2-next.
|
|
52
|
+
"@backstage/cli": "0.29.0-next.3",
|
|
53
|
+
"@backstage/dev-utils": "1.1.3-next.3",
|
|
54
|
+
"@backstage/frontend-test-utils": "0.2.2-next.2",
|
|
55
55
|
"@testing-library/jest-dom": "^6.0.0",
|
|
56
56
|
"@testing-library/react": "^16.0.0",
|
|
57
57
|
"@testing-library/user-event": "^14.0.0",
|
|
@@ -72,5 +72,12 @@
|
|
|
72
72
|
"optional": true
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
+
"typesVersions": {
|
|
76
|
+
"*": {
|
|
77
|
+
"index": [
|
|
78
|
+
"dist/index.d.ts"
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
},
|
|
75
82
|
"module": "./dist/index.esm.js"
|
|
76
83
|
}
|