@backstage/plugin-app 0.2.0-next.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +1 -7
  3. package/dist/alpha/appModulePublicSignIn.esm.js.map +1 -1
  4. package/dist/apis/DefaultDialogApi.esm.js.map +1 -1
  5. package/dist/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.esm.js +40 -0
  6. package/dist/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.esm.js.map +1 -0
  7. package/dist/defaultApis.esm.js +3 -3
  8. package/dist/defaultApis.esm.js.map +1 -1
  9. package/dist/extensions/AnalyticsApi.esm.js.map +1 -1
  10. package/dist/extensions/App.esm.js +1 -1
  11. package/dist/extensions/App.esm.js.map +1 -1
  12. package/dist/extensions/AppLanguageApi.esm.js.map +1 -1
  13. package/dist/extensions/AppLayout.esm.js +1 -1
  14. package/dist/extensions/AppLayout.esm.js.map +1 -1
  15. package/dist/extensions/AppNav.esm.js +1 -1
  16. package/dist/extensions/AppNav.esm.js.map +1 -1
  17. package/dist/extensions/AppRoot.esm.js +1 -1
  18. package/dist/extensions/AppRoot.esm.js.map +1 -1
  19. package/dist/extensions/AppRoutes.esm.js +1 -4
  20. package/dist/extensions/AppRoutes.esm.js.map +1 -1
  21. package/dist/extensions/AppThemeApi.esm.js +1 -1
  22. package/dist/extensions/AppThemeApi.esm.js.map +1 -1
  23. package/dist/extensions/DefaultSignInPage.esm.js.map +1 -1
  24. package/dist/extensions/DialogDisplay.esm.js.map +1 -1
  25. package/dist/extensions/FeatureFlagsApi.esm.js.map +1 -1
  26. package/dist/extensions/IconsApi.esm.js +1 -1
  27. package/dist/extensions/IconsApi.esm.js.map +1 -1
  28. package/dist/extensions/LegacyComponentsApi.esm.js +26 -0
  29. package/dist/extensions/LegacyComponentsApi.esm.js.map +1 -0
  30. package/dist/extensions/SwappableComponentsApi.esm.js +40 -0
  31. package/dist/extensions/SwappableComponentsApi.esm.js.map +1 -0
  32. package/dist/extensions/TranslationsApi.esm.js +1 -1
  33. package/dist/extensions/TranslationsApi.esm.js.map +1 -1
  34. package/dist/extensions/components.esm.js +21 -43
  35. package/dist/extensions/components.esm.js.map +1 -1
  36. package/dist/extensions/elements.esm.js.map +1 -1
  37. package/dist/index.d.ts +87 -12
  38. package/dist/packages/app-defaults/src/defaults/apis.esm.js +2 -2
  39. package/dist/packages/app-defaults/src/defaults/apis.esm.js.map +1 -1
  40. package/dist/packages/app-defaults/src/defaults/icons.esm.js.map +1 -1
  41. package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js.map +1 -1
  42. package/dist/packages/core-app-api/src/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js.map +1 -1
  43. package/dist/packages/core-app-api/src/apis/implementations/AppThemeApi/AppThemeSelector.esm.js.map +1 -1
  44. package/dist/packages/core-app-api/src/apis/implementations/DiscoveryApi/UrlPatternDiscovery.esm.js.map +1 -1
  45. package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/ErrorAlerter.esm.js.map +1 -1
  46. package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/ErrorApiForwarder.esm.js.map +1 -1
  47. package/dist/packages/core-app-api/src/apis/implementations/ErrorApi/UnhandledErrorForwarder.esm.js.map +1 -1
  48. package/dist/packages/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js.map +1 -1
  49. package/dist/packages/core-app-api/src/apis/implementations/FetchApi/FetchMiddlewares.esm.js.map +1 -1
  50. package/dist/packages/core-app-api/src/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.esm.js.map +1 -1
  51. package/dist/packages/core-app-api/src/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.esm.js.map +1 -1
  52. package/dist/packages/core-app-api/src/apis/implementations/FetchApi/createFetchApi.esm.js.map +1 -1
  53. package/dist/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthPendingRequests.esm.js.map +1 -1
  54. package/dist/packages/core-app-api/src/apis/implementations/OAuthRequestApi/OAuthRequestManager.esm.js.map +1 -1
  55. package/dist/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.esm.js.map +1 -1
  56. package/dist/packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js.map +1 -1
  57. package/dist/packages/core-app-api/src/apis/implementations/auth/atlassian/AtlassianAuth.esm.js.map +1 -1
  58. package/dist/packages/core-app-api/src/apis/implementations/auth/bitbucket/BitbucketAuth.esm.js.map +1 -1
  59. package/dist/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.esm.js.map +1 -1
  60. package/dist/packages/core-app-api/src/apis/implementations/auth/github/GithubAuth.esm.js.map +1 -1
  61. package/dist/packages/core-app-api/src/apis/implementations/auth/gitlab/GitlabAuth.esm.js.map +1 -1
  62. package/dist/packages/core-app-api/src/apis/implementations/auth/google/GoogleAuth.esm.js.map +1 -1
  63. package/dist/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.esm.js.map +1 -1
  64. package/dist/packages/core-app-api/src/apis/implementations/auth/oauth2/OAuth2.esm.js.map +1 -1
  65. package/dist/packages/core-app-api/src/apis/implementations/auth/okta/OktaAuth.esm.js.map +1 -1
  66. package/dist/packages/core-app-api/src/apis/implementations/auth/onelogin/OneLoginAuth.esm.js.map +1 -1
  67. package/dist/packages/core-app-api/src/apis/implementations/auth/saml/types.esm.js.map +1 -1
  68. package/dist/packages/core-app-api/src/apis/implementations/auth/vmwareCloud/VMwareCloudAuth.esm.js.map +1 -1
  69. package/dist/packages/core-app-api/src/apis/system/ApiAggregator.esm.js.map +1 -1
  70. package/dist/packages/core-app-api/src/apis/system/ApiProvider.esm.js.map +1 -1
  71. package/dist/packages/core-app-api/src/app/AppRouter.esm.js.map +1 -1
  72. package/dist/packages/core-app-api/src/app/AppThemeProvider.esm.js.map +1 -1
  73. package/dist/packages/core-app-api/src/app/InternalAppContext.esm.js.map +1 -1
  74. package/dist/packages/core-app-api/src/app/isProtectedApp.esm.js.map +1 -1
  75. package/dist/packages/core-app-api/src/app/isReactRouterBeta.esm.js.map +1 -1
  76. package/dist/packages/core-app-api/src/lib/AuthConnector/DefaultAuthConnector.esm.js.map +1 -1
  77. package/dist/packages/core-app-api/src/lib/AuthSessionManager/RefreshingAuthSessionManager.esm.js.map +1 -1
  78. package/dist/packages/core-app-api/src/lib/AuthSessionManager/SessionStateTracker.esm.js.map +1 -1
  79. package/dist/packages/core-app-api/src/lib/AuthSessionManager/common.esm.js.map +1 -1
  80. package/dist/packages/core-app-api/src/lib/loginPopup.esm.js.map +1 -1
  81. package/dist/packages/core-app-api/src/lib/subjects.esm.js.map +1 -1
  82. package/dist/packages/core-app-api/src/routing/FeatureFlagged.esm.js.map +1 -1
  83. package/dist/packages/core-app-api/src/routing/FlatRoutes.esm.js.map +1 -1
  84. package/dist/packages/core-app-api/src/routing/RouteTracker.esm.js.map +1 -1
  85. package/dist/packages/core-plugin-api/src/translation/TranslationRef.esm.js.map +1 -1
  86. package/dist/packages/core-plugin-api/src/translation/TranslationResource.esm.js.map +1 -1
  87. package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map +1 -1
  88. package/dist/packages/frontend-app-api/src/routing/RouteTracker.esm.js.map +1 -1
  89. package/dist/packages/frontend-app-api/src/routing/getBasePath.esm.js.map +1 -1
  90. package/dist/packages/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js +7 -0
  91. package/dist/packages/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js.map +1 -0
  92. package/dist/packages/frontend-internal/src/wiring/InternalFrontendPlugin.esm.js +7 -0
  93. package/dist/packages/frontend-internal/src/wiring/InternalFrontendPlugin.esm.js.map +1 -0
  94. package/dist/packages/frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js +9 -0
  95. package/dist/packages/frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js.map +1 -0
  96. package/dist/packages/opaque-internal/src/OpaqueType.esm.js +103 -0
  97. package/dist/packages/opaque-internal/src/OpaqueType.esm.js.map +1 -0
  98. package/dist/plugin.esm.js +9 -7
  99. package/dist/plugin.esm.js.map +1 -1
  100. package/dist/plugins/app/package.json.esm.js +7 -5
  101. package/dist/plugins/app/package.json.esm.js.map +1 -1
  102. package/package.json +18 -16
  103. package/dist/extensions/ComponentsApi.esm.js +0 -28
  104. package/dist/extensions/ComponentsApi.esm.js.map +0 -1
  105. package/dist/packages/app-defaults/src/defaults/components.esm.js +0 -46
  106. package/dist/packages/app-defaults/src/defaults/components.esm.js.map +0 -1
  107. package/dist/packages/frontend-app-api/src/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js +0 -21
  108. package/dist/packages/frontend-app-api/src/apis/implementations/ComponentsApi/DefaultComponentsApi.esm.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"loginPopup.esm.js","sources":["../../../../../../../packages/core-app-api/src/lib/loginPopup.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\n/**\n * Options used to open a login popup.\n *\n * @public\n */\nexport type OpenLoginPopupOptions = {\n /**\n * The URL that the auth popup should point to\n */\n url: string;\n\n /**\n * The name of the popup, as in second argument to window.open\n */\n name: string;\n\n /**\n * The width of the popup in pixels, defaults to 500\n */\n width?: number;\n\n /**\n * The height of the popup in pixels, defaults to 700\n */\n height?: number;\n};\n\ntype AuthResult =\n | {\n type: 'authorization_response';\n response: unknown;\n }\n | {\n type: 'authorization_response';\n error: {\n name: string;\n message: string;\n };\n };\n\n/**\n * Show a popup pointing to a URL that starts an auth flow. Implementing the receiving\n * end of the postMessage mechanism outlined in https://tools.ietf.org/html/draft-sakimura-oauth-wmrm-00\n *\n * The redirect handler of the flow should use postMessage to communicate back\n * to the app window. The message posted to the app must match the AuthResult type.\n *\n * The returned promise resolves to the response of the message that was posted from the auth popup.\n *\n * @public\n */\nexport function openLoginPopup(\n options: OpenLoginPopupOptions,\n): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const width = options.width || 500;\n const height = options.height || 700;\n const left = window.screen.width / 2 - width / 2;\n const top = window.screen.height / 2 - height / 2;\n\n const origin = new URL(options.url).origin;\n\n const popup = window.open(\n options.url,\n options.name,\n `menubar=no,location=no,resizable=no,scrollbars=no,status=no,width=${width},height=${height},top=${top},left=${left}`,\n );\n\n let targetOrigin = '';\n\n if (!popup || typeof popup.closed === 'undefined' || popup.closed) {\n const error = new Error('Failed to open auth popup.');\n error.name = 'PopupRejectedError';\n reject(error);\n return;\n }\n\n const messageListener = (event: MessageEvent) => {\n if (event.source !== popup) {\n return;\n }\n if (event.origin !== origin) {\n return;\n }\n const { data } = event;\n\n if (data.type === 'config_info') {\n targetOrigin = data.targetOrigin;\n return;\n }\n\n if (data.type !== 'authorization_response') {\n return;\n }\n const authResult = data as AuthResult;\n\n if ('error' in authResult) {\n const error = new Error(authResult.error.message);\n error.name = authResult.error.name;\n // TODO: proper error type\n // error.extra = authResult.error.extra;\n reject(error);\n } else {\n resolve(authResult.response);\n }\n done();\n };\n\n const intervalId = setInterval(() => {\n if (popup.closed) {\n const errMessage = `Login failed, ${\n targetOrigin && targetOrigin !== window.location.origin\n ? `Incorrect app origin, expected ${targetOrigin}`\n : 'popup was closed'\n }`;\n const error = new Error(errMessage);\n error.name = 'PopupClosedError';\n reject(error);\n done();\n }\n }, 100);\n\n function done() {\n window.removeEventListener('message', messageListener);\n clearInterval(intervalId);\n }\n\n window.addEventListener('message', messageListener);\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loginPopup.esm.js","sources":["../../../../../../../packages/core-app-api/src/lib/loginPopup.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\n/**\n * Options used to open a login popup.\n *\n * @public\n */\nexport type OpenLoginPopupOptions = {\n /**\n * The URL that the auth popup should point to\n */\n url: string;\n\n /**\n * The name of the popup, as in second argument to window.open\n */\n name: string;\n\n /**\n * The width of the popup in pixels, defaults to 500\n */\n width?: number;\n\n /**\n * The height of the popup in pixels, defaults to 700\n */\n height?: number;\n};\n\ntype AuthResult =\n | {\n type: 'authorization_response';\n response: unknown;\n }\n | {\n type: 'authorization_response';\n error: {\n name: string;\n message: string;\n };\n };\n\n/**\n * Show a popup pointing to a URL that starts an auth flow. Implementing the receiving\n * end of the postMessage mechanism outlined in https://tools.ietf.org/html/draft-sakimura-oauth-wmrm-00\n *\n * The redirect handler of the flow should use postMessage to communicate back\n * to the app window. The message posted to the app must match the AuthResult type.\n *\n * The returned promise resolves to the response of the message that was posted from the auth popup.\n *\n * @public\n */\nexport function openLoginPopup(\n options: OpenLoginPopupOptions,\n): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const width = options.width || 500;\n const height = options.height || 700;\n const left = window.screen.width / 2 - width / 2;\n const top = window.screen.height / 2 - height / 2;\n\n const origin = new URL(options.url).origin;\n\n const popup = window.open(\n options.url,\n options.name,\n `menubar=no,location=no,resizable=no,scrollbars=no,status=no,width=${width},height=${height},top=${top},left=${left}`,\n );\n\n let targetOrigin = '';\n\n if (!popup || typeof popup.closed === 'undefined' || popup.closed) {\n const error = new Error('Failed to open auth popup.');\n error.name = 'PopupRejectedError';\n reject(error);\n return;\n }\n\n const messageListener = (event: MessageEvent) => {\n if (event.source !== popup) {\n return;\n }\n if (event.origin !== origin) {\n return;\n }\n const { data } = event;\n\n if (data.type === 'config_info') {\n targetOrigin = data.targetOrigin;\n return;\n }\n\n if (data.type !== 'authorization_response') {\n return;\n }\n const authResult = data as AuthResult;\n\n if ('error' in authResult) {\n const error = new Error(authResult.error.message);\n error.name = authResult.error.name;\n // TODO: proper error type\n // error.extra = authResult.error.extra;\n reject(error);\n } else {\n resolve(authResult.response);\n }\n done();\n };\n\n const intervalId = setInterval(() => {\n if (popup.closed) {\n const errMessage = `Login failed, ${\n targetOrigin && targetOrigin !== window.location.origin\n ? `Incorrect app origin, expected ${targetOrigin}`\n : 'popup was closed'\n }`;\n const error = new Error(errMessage);\n error.name = 'PopupClosedError';\n reject(error);\n done();\n }\n }, 100);\n\n function done() {\n window.removeEventListener('message', messageListener);\n clearInterval(intervalId);\n }\n\n window.addEventListener('message', messageListener);\n });\n}\n"],"names":[],"mappings":"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"}
@@ -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":"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"}
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,cAAA,CAEb;AAAA,EACU,QAAA,GAAW,KAAA;AAAA,EACX,gBAAA;AAAA,EAES,UAAA,GAAa,IAAI,cAAA,CAAkB,CAAA,UAAA,KAAc;AAChE,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,QAAA,UAAA,CAAW,KAAA,CAAM,KAAK,gBAAgB,CAAA;AAAA,MACxC,CAAA,MAAO;AACL,QAAA,UAAA,CAAW,QAAA,EAAS;AAAA,MACtB;AACA,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,IAAI,UAAU,CAAA;AAC/B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,WAAA,CAAY,OAAO,UAAU,CAAA;AAAA,IACpC,CAAA;AAAA,EACF,CAAC,CAAA;AAAA,EAEgB,WAAA,uBAAkB,GAAA,EAEjC;AAAA,EAEF,CAAC,MAAA,CAAO,UAAU,CAAA,GAAI;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAI,MAAA,GAAS;AACX,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,KAAK,KAAA,EAAU;AACb,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,IAC5C;AACA,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,EAC/D;AAAA,EAEA,MAAM,KAAA,EAAc;AAClB,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,IAC5C;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EAChE;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,IAC5C;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,UAAU,CAAA;AAAA,EAC9D;AAAA,EAQA,SAAA,CACE,MAAA,EACA,OAAA,EACA,UAAA,EAC4B;AAC5B,IAAA,MAAM,QAAA,GACJ,OAAO,MAAA,KAAW,UAAA,GACd;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,KAAA,EAAO,OAAA;AAAA,MACP,QAAA,EAAU;AAAA,KACZ,GACA,MAAA;AAEN,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AACF;AAcO,MAAM,eAAA,CAEb;AAAA,EACU,QAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACS,UAAA;AAAA,EAEjB,YAAY,KAAA,EAAU;AACpB,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAChB,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,IAAA,IAAA,CAAK,gBAAA,GAAmB,MAAA;AACxB,IAAA,IAAA,CAAK,UAAA,GAAa,IAAI,cAAA,CAAkB,CAAA,UAAA,KAAc;AACpD,MAAA,IAAI,KAAK,QAAA,EAAU;AACjB,QAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,UAAA,UAAA,CAAW,KAAA,CAAM,KAAK,gBAAgB,CAAA;AAAA,QACxC,CAAA,MAAO;AACL,UAAA,UAAA,CAAW,QAAA,EAAS;AAAA,QACtB;AACA,QAAA,OAAO,MAAM;AAAA,QAAC,CAAA;AAAA,MAChB;AAEA,MAAA,UAAA,CAAW,IAAA,CAAK,KAAK,YAAY,CAAA;AAEjC,MAAA,IAAA,CAAK,WAAA,CAAY,IAAI,UAAU,CAAA;AAC/B,MAAA,OAAO,MAAM;AACX,QAAA,IAAA,CAAK,WAAA,CAAY,OAAO,UAAU,CAAA;AAAA,MACpC,CAAA;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEiB,WAAA,uBAAkB,GAAA,EAEjC;AAAA,EAEF,CAAC,MAAA,CAAO,UAAU,CAAA,GAAI;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAI,MAAA,GAAS;AACX,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA,EAEA,KAAK,KAAA,EAAU;AACb,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AACA,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,EAC/D;AAAA,EAEA,MAAM,KAAA,EAAc;AAClB,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EAChE;AAAA,EAEA,QAAA,GAAW;AACT,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,CAAA,UAAA,KAAc,UAAA,CAAW,UAAU,CAAA;AAAA,EAC9D;AAAA,EAQA,SAAA,CACE,MAAA,EACA,OAAA,EACA,UAAA,EAC4B;AAC5B,IAAA,MAAM,QAAA,GACJ,OAAO,MAAA,KAAW,UAAA,GACd;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,KAAA,EAAO,OAAA;AAAA,MACP,QAAA,EAAU;AAAA,KACZ,GACA,MAAA;AAEN,IAAA,OAAO,IAAA,CAAK,UAAA,CAAW,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC3C;AACF;;;;"}
@@ -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 { 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,GAAA,CAAA,QAAA,EAAA,EAAG,QAAY,EAAA,SAAA,GAAA,QAAA,GAAW,IAAK,EAAA,CAAA;AACxC;AAEA,mBAAoB,CAAA,cAAA,EAAgB,uBAAuB,IAAI,CAAA;;;;"}
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 { 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":";;;AAuCO,MAAM,cAAA,GAAiB,CAAC,KAAA,KAA+B;AAC5D,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,MAAM,cAAA,GAAiB,OAAO,kBAAkB,CAAA;AAChD,EAAA,MAAM,SAAA,GACJ,MAAA,IAAU,KAAA,GACN,cAAA,CAAe,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,GAClC,CAAC,cAAA,CAAe,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA;AAC5C,EAAA,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,SAAA,GAAY,QAAA,GAAW,IAAA,EAAK,CAAA;AACxC;AAEA,mBAAA,CAAoB,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 { 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,sBAAU,iBAAkB,EAAA,EAAA;AAAA;AAC9B,GACF;AAEA,EAAA,OAAO,UAAU,YAAY,CAAA;AAC/B;AAEA,mBAAoB,CAAA,UAAA,EAAY,aAAa,YAAY,CAAA;;;;"}
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 { 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,MAAA,GAAS,KAAA;AA4BN,MAAM,UAAA,GAAa,CAAC,KAAA,KAA+C;AACxE,EAAA,MAAM,MAAM,MAAA,EAAO;AACnB,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,GAAA,CAAI,aAAA,EAAc;AAChD,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAM,iBAAA,EAAkB,EAAG,EAAE,CAAA;AACpD,EAAA,MAAM,MAAA,GAAS,gBAAA;AAAA,IAAiB,KAAA,CAAM,QAAA;AAAA,IAAU,CAAA,QAAA,KAC9C,QAAA,CACG,WAAA,EAIE,CACF,QAAqB,CAAA,KAAA,KAAS;AAC7B,MAAA,IAAI,IAAA,GAAO,MAAM,KAAA,CAAM,IAAA;AAGvB,MAAA,IAAI,SAAS,EAAA,EAAI;AACf,QAAA,OAAO,EAAC;AAAA,MACV;AACA,MAAA,IAAA,GAAO,IAAA,EAAM,OAAA,CAAQ,OAAA,EAAS,EAAE,CAAA,IAAK,GAAA;AAErC,MAAA,IAAI,OAAA,GAAU,MAAA,GAAS,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,OAAA;AAC3C,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AACvB,QAAA,OAAA,GAAU,KAAA;AACV,QAAA,IAAI,CAAC,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,aAAa,MAAA,EAAQ;AAE9C,UAAA,OAAA,CAAQ,IAAA;AAAA,YACN;AAAA,WAEF;AACA,UAAA,MAAA,GAAS,IAAA;AAAA,QACX;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL;AAAA;AAAA,UAEE,IAAA;AAAA,UACA,OAAA;AAAA,UACA,QAAA,EAAU,KAAA,CAAM,KAAA,CAAM,QAAA,GAClB;AAAA;AAAA;AAAA,YAGE;AAAA,cACE,IAAA,EAAM,IAAA,KAAS,GAAA,GAAM,GAAA,GAAM,GAAA;AAAA;AAAA,cAC3B,OAAA,EAAS,MAAM,KAAA,CAAM;AAAA;AACvB,WACF,GACA;AAAA;AACN,OACF;AAAA,IACF,CAAC,CAAA,CAGA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAC,CAAA,CAC3C,GAAA,CAAI,CAAA,GAAA,MAAQ,EAAE,GAAG,GAAA,EAAK,IAAA,EAAM,GAAA,CAAI,IAAA,KAAS,GAAA,GAAM,GAAA,GAAM,CAAA,EAAG,GAAA,CAAI,IAAI,CAAA,EAAA,CAAA,EAAK,CAAE;AAAA,GAC5E;AAGA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,GAAG,MAAA;AAAA,IACH;AAAA,MACE,IAAA,EAAM,GAAA;AAAA,MACN,OAAA,sBAAU,iBAAA,EAAA,EAAkB;AAAA;AAC9B,GACF;AAEA,EAAA,OAAO,UAAU,YAAY,CAAA;AAC/B;AAEA,mBAAA,CAAoB,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 { 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,GAAA,CAAC,oBAAiB,UAChB,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAY,EAAA;AAAA;AAAA,GAEhB,EAAA,CAAA;AAEJ;;;;"}
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 { 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":"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"}
@@ -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;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
+ {"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,GAAA,EAA6E;AAC7E,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,IAAI,CAAA,CAAE,WAAW,2BAAA,EAA6B;AAC5C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,CAAA,CAAE,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,CAAA,CAAE,YAAY,IAAA,EAAM;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sCAAA,EAAyC,CAAA,CAAE,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,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;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
+ {"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,QAAA,EACkC;AAClC,EAAA,MAAM,CAAA,GAAI,QAAA;AACV,EAAA,IAAI,CAAA,CAAE,WAAW,gCAAA,EAAkC;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2C,CAAA,CAAE,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EACxE;AACA,EAAA,IAAI,CAAA,CAAE,YAAY,IAAA,EAAM;AACtB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2CAAA,EAA8C,CAAA,CAAE,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAO,CAAA;AACT;;;;"}
@@ -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;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
+ {"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,eAAA,CAAoC;AAAA,EAC/C,MAAA;AAAA,EAEA,YAAY,KAAA,EAA2C;AACrD,IAAA,IAAA,CAAK,SAAS,IAAI,GAAA,CAAI,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAC7C;AAAA,EAEA,QAAQ,GAAA,EAAwC;AAC9C,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAAA,EAC5B;AAAA,EAEA,YAAA,GAAyB;AACvB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,EACtC;AACF;;;;"}
@@ -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 { 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.plugin;\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,GAAA,CAAC,oBAAiB,UAChB,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAY,EAAA;AAAA;AAAA,GAEhB,EAAA,CAAA;AAEJ;;;;"}
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 { 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.plugin;\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,MAAA,KACG;AACH,EAAA,IAAI;AAEF,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,MAAA,EAAQ,EAAE,UAAU,CAAA;AAKhD,IAAA,MAAM,UAAA,GAAa,OAAA,EACf,MAAA,CAAO,CAAA,KAAA,KAAS,KAAA,EAAO,MAAM,SAAA,EAAW,IAAA,GAAO,CAAC,CAAA,CACjD,GAAA,EAAI;AACP,IAAA,MAAM,cAAc,UAAA,EAAY,KAAA;AAGhC,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAIA,IAAA,IAAI,WAAA,CAAY,IAAA,KAAS,EAAA,IAAM,QAAA,KAAa,GAAA,EAAK;AAC/C,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAEA,IAAA,MAAM,SAAS,MAAA,CAAO,OAAA;AAAA,MACpB,UAAA,EAAY,UAAU;AAAC,MACvB,MAAA,CAAiC,CAAC,KAAK,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AACxD,MAAA,IAAI,KAAA,KAAU,KAAA,CAAA,IAAa,GAAA,KAAQ,GAAA,EAAK;AACtC,QAAA,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA;AAAA,MACb;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA,EAAG,EAAE,CAAA;AAEL,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,MAAA;AACzC,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,SAAA;AAE5C,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,QAAA,EAAU,QAAQ,EAAA,IAAM,MAAA;AAAA,MACxB,WAAA,EAAa,WAAW,EAAA,IAAM;AAAA,KAChC;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;AAKA,MAAM,kBAAkB,CAAC;AAAA,EACvB,QAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,KAKM;AACJ,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,YAAA,CAAa,YAAY,CAAA,EAAG,QAAQ,GAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,MAChE;AAAA,KACD,CAAA;AAAA,EACH,GAAG,CAAC,SAAA,EAAW,UAAU,MAAA,EAAQ,IAAA,EAAM,UAAU,CAAC,CAAA;AAElD,EAAA,OAAO,IAAA;AACT,CAAA;AAMO,MAAM,eAAe,CAAC;AAAA,EAC3B;AACF,CAAA,KAEM;AACJ,EAAA,MAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,IAAA,KAAS,WAAA,EAAY;AAE/C,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,UAAA,EAAW,GAAI,mBAAA;AAAA,IAChC,QAAA;AAAA,IACA;AAAA,GACF,IAAK,EAAE,MAAA,EAAQ,EAAC,EAAE;AAElB,EAAA,uBACE,GAAA,CAAC,oBAAiB,UAAA,EAChB,QAAA,kBAAA,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,QAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAA,EAAY;AAAA;AAAA,GACd,EACF,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;AAAA;AAAA,GACF;AACA,EAAW,QAAA,GAAA,QAAA,CAAS,OAAQ,CAAA,MAAA,EAAQ,EAAE,CAAA;AACtC,EAAO,OAAA,QAAA;AACT;;;;"}
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,SAAA,EAAsB;AAChD,EAAA,IAAI,EAAE,QAAA,EAAS,GAAI,IAAI,GAAA;AAAA,IACrB,SAAA,CAAU,iBAAA,CAAkB,aAAa,CAAA,IAAK,GAAA;AAAA,IAC9C;AAAA;AAAA,GACF;AACA,EAAA,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACtC,EAAA,OAAO,QAAA;AACT;;;;"}
@@ -0,0 +1,7 @@
1
+ import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
2
+
3
+ OpaqueType.create({
4
+ type: "@backstage/ExtensionDefinition",
5
+ versions: ["v1", "v2"]
6
+ });
7
+ //# sourceMappingURL=InternalExtensionDefinition.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InternalExtensionDefinition.esm.js","sources":["../../../../../../../packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiHolder,\n AppNode,\n ExtensionAttachToSpec,\n ExtensionDataValue,\n ExtensionDataRef,\n ExtensionDefinition,\n ExtensionDefinitionParameters,\n ExtensionInput,\n PortableSchema,\n ResolvedExtensionInputs,\n} from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueExtensionDefinition = OpaqueType.create<{\n public: ExtensionDefinition<ExtensionDefinitionParameters>;\n versions:\n | {\n readonly version: 'v1';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: ExtensionAttachToSpec;\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<any, any>;\n readonly inputs: {\n [inputName in string]: {\n $$type: '@backstage/ExtensionInput';\n extensionData: {\n [name in string]: ExtensionDataRef;\n };\n config: { optional: boolean; singleton: boolean };\n };\n };\n readonly output: {\n [name in string]: ExtensionDataRef;\n };\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: object;\n inputs: {\n [inputName in string]: unknown;\n };\n }): {\n [inputName in string]: unknown;\n };\n }\n | {\n readonly version: 'v2';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: ExtensionAttachToSpec;\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<any, any>;\n readonly inputs: {\n [inputName in string]: ExtensionInput<\n ExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n };\n readonly output: Array<ExtensionDataRef>;\n factory(context: {\n node: AppNode;\n apis: ApiHolder;\n config: object;\n inputs: ResolvedExtensionInputs<{\n [inputName in string]: ExtensionInput<\n ExtensionDataRef,\n { optional: boolean; singleton: boolean }\n >;\n }>;\n }): Iterable<ExtensionDataValue<any, any>>;\n };\n}>({\n type: '@backstage/ExtensionDefinition',\n versions: ['v1', 'v2'],\n});\n"],"names":[],"mappings":";;AA8ByC,WAAW,MAAA,CA6DjD;AAAA,EACD,IAAA,EAAM,gCAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAA,EAAM,IAAI;AACvB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
2
+
3
+ OpaqueType.create({
4
+ type: "@backstage/FrontendPlugin",
5
+ versions: ["v1"]
6
+ });
7
+ //# sourceMappingURL=InternalFrontendPlugin.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InternalFrontendPlugin.esm.js","sources":["../../../../../../../packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Extension,\n FeatureFlagConfig,\n OverridableFrontendPlugin,\n} from '@backstage/frontend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueFrontendPlugin = OpaqueType.create<{\n public: OverridableFrontendPlugin;\n versions: {\n readonly version: 'v1';\n readonly extensions: Extension<unknown>[];\n readonly featureFlags: FeatureFlagConfig[];\n readonly infoOptions?: {\n packageJson?: () => Promise<JsonObject>;\n manifest?: () => Promise<JsonObject>;\n };\n };\n}>({\n type: '@backstage/FrontendPlugin',\n versions: ['v1'],\n});\n"],"names":[],"mappings":";;AAwBoC,WAAW,MAAA,CAW5C;AAAA,EACD,IAAA,EAAM,2BAAA;AAAA,EACN,QAAA,EAAU,CAAC,IAAI;AACjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { OpaqueType } from '../../../opaque-internal/src/OpaqueType.esm.js';
2
+
3
+ const OpaqueSwappableComponentRef = OpaqueType.create({
4
+ versions: ["v1"],
5
+ type: "@backstage/SwappableComponentRef"
6
+ });
7
+
8
+ export { OpaqueSwappableComponentRef };
9
+ //# sourceMappingURL=InternalSwappableComponentRef.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InternalSwappableComponentRef.esm.js","sources":["../../../../../../../packages/frontend-internal/src/wiring/InternalSwappableComponentRef.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SwappableComponentRef } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport const OpaqueSwappableComponentRef = OpaqueType.create<{\n public: SwappableComponentRef;\n versions: {\n readonly version: 'v1';\n readonly transformProps?: (props: object) => object;\n readonly defaultComponent: (props: object) => JSX.Element | null;\n };\n}>({\n versions: ['v1'],\n type: '@backstage/SwappableComponentRef',\n});\n"],"names":[],"mappings":";;AAmBO,MAAM,2BAAA,GAA8B,WAAW,MAAA,CAOnD;AAAA,EACD,QAAA,EAAU,CAAC,IAAI,CAAA;AAAA,EACf,IAAA,EAAM;AACR,CAAC;;;;"}
@@ -0,0 +1,103 @@
1
+ class OpaqueType {
2
+ /**
3
+ * Creates a new opaque type.
4
+ *
5
+ * @param options.type The type identifier of the opaque type
6
+ * @param options.versions The available versions of the opaque type
7
+ * @returns A new opaque type helper
8
+ */
9
+ static create(options) {
10
+ return new OpaqueType(options.type, new Set(options.versions));
11
+ }
12
+ #type;
13
+ #versions;
14
+ constructor(type, versions) {
15
+ this.#type = type;
16
+ this.#versions = versions;
17
+ }
18
+ /**
19
+ * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`
20
+ *
21
+ * @remarks
22
+ *
23
+ * This property is only useful for type checking, its runtime value is `undefined`.
24
+ */
25
+ TPublic = void 0;
26
+ /**
27
+ * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`
28
+ *
29
+ * @remarks
30
+ *
31
+ * This property is only useful for type checking, its runtime value is `undefined`.
32
+ */
33
+ TInternal = void 0;
34
+ /**
35
+ * @param value Input value expected to be an instance of this opaque type
36
+ * @returns True if the value matches this opaque type
37
+ */
38
+ isType = (value) => {
39
+ return this.#isThisInternalType(value);
40
+ };
41
+ /**
42
+ * @param value Input value expected to be an instance of this opaque type
43
+ * @throws If the value is not an instance of this opaque type or is of an unsupported version
44
+ * @returns The internal version of the opaque type
45
+ */
46
+ toInternal = (value) => {
47
+ if (!this.#isThisInternalType(value)) {
48
+ throw new TypeError(
49
+ `Invalid opaque type, expected '${this.#type}', but got '${this.#stringifyUnknown(value)}'`
50
+ );
51
+ }
52
+ if (!this.#versions.has(value.version)) {
53
+ const versions = Array.from(this.#versions).map(this.#stringifyVersion);
54
+ if (versions.length > 1) {
55
+ versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;
56
+ }
57
+ const expected = versions.length > 2 ? versions.join(", ") : versions.join(" ");
58
+ throw new TypeError(
59
+ `Invalid opaque type instance, got version ${this.#stringifyVersion(
60
+ value.version
61
+ )}, expected ${expected}`
62
+ );
63
+ }
64
+ return value;
65
+ };
66
+ /**
67
+ * Creates an instance of the opaque type, returning the public type.
68
+ *
69
+ * @param version The version of the instance to create
70
+ * @param value The remaining public and internal properties of the instance
71
+ * @returns An instance of the opaque type
72
+ */
73
+ createInstance(version, props) {
74
+ return Object.assign(props, {
75
+ $$type: this.#type,
76
+ ...version && { version }
77
+ });
78
+ }
79
+ #isThisInternalType(value) {
80
+ if (value === null || typeof value !== "object") {
81
+ return false;
82
+ }
83
+ return value.$$type === this.#type;
84
+ }
85
+ #stringifyUnknown(value) {
86
+ if (typeof value !== "object") {
87
+ return `<${typeof value}>`;
88
+ }
89
+ if (value === null) {
90
+ return "<null>";
91
+ }
92
+ if ("$$type" in value) {
93
+ return String(value.$$type);
94
+ }
95
+ return String(value);
96
+ }
97
+ #stringifyVersion = (version) => {
98
+ return version ? `'${version}'` : "undefined";
99
+ };
100
+ }
101
+
102
+ export { OpaqueType };
103
+ //# sourceMappingURL=OpaqueType.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpaqueType.esm.js","sources":["../../../../../../packages/opaque-internal/src/OpaqueType.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\n// TODO(Rugvip): This lives here temporarily, but should be moved to a more\n// central location. It's useful for backend packages too so we'll need to have\n// it in a common package, but it might also be that we want to make it\n// available publicly too in which case it would make sense to have this be part\n// of @backstage/version-bridge. The problem with exporting it from there is\n// that it would need to be very stable at that point, so it might be a bit\n// early to put it there already.\n\n/**\n * A helper for working with opaque types.\n */\nexport class OpaqueType<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n> {\n /**\n * Creates a new opaque type.\n *\n * @param options.type The type identifier of the opaque type\n * @param options.versions The available versions of the opaque type\n * @returns A new opaque type helper\n */\n static create<\n T extends {\n public: { $$type: string };\n versions: { version: string | undefined };\n },\n >(options: {\n type: T['public']['$$type'];\n versions: Array<T['versions']['version']>;\n }) {\n return new OpaqueType<T>(options.type, new Set(options.versions));\n }\n\n #type: string;\n #versions: Set<string | undefined>;\n\n private constructor(type: string, versions: Set<string | undefined>) {\n this.#type = type;\n this.#versions = versions;\n }\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TPublic`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TPublic: T['public'] = undefined as any;\n\n /**\n * The internal version of the opaque type, used like this: `typeof MyOpaqueType.TInternal`\n *\n * @remarks\n *\n * This property is only useful for type checking, its runtime value is `undefined`.\n */\n TInternal: T['public'] & T['versions'] = undefined as any;\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @returns True if the value matches this opaque type\n */\n isType = (value: unknown): value is T['public'] => {\n return this.#isThisInternalType(value);\n };\n\n /**\n * @param value Input value expected to be an instance of this opaque type\n * @throws If the value is not an instance of this opaque type or is of an unsupported version\n * @returns The internal version of the opaque type\n */\n toInternal = (value: unknown): T['public'] & T['versions'] => {\n if (!this.#isThisInternalType(value)) {\n throw new TypeError(\n `Invalid opaque type, expected '${\n this.#type\n }', but got '${this.#stringifyUnknown(value)}'`,\n );\n }\n\n if (!this.#versions.has(value.version)) {\n const versions = Array.from(this.#versions).map(this.#stringifyVersion);\n if (versions.length > 1) {\n versions[versions.length - 1] = `or ${versions[versions.length - 1]}`;\n }\n const expected =\n versions.length > 2 ? versions.join(', ') : versions.join(' ');\n throw new TypeError(\n `Invalid opaque type instance, got version ${this.#stringifyVersion(\n value.version,\n )}, expected ${expected}`,\n );\n }\n\n return value;\n };\n\n /**\n * Creates an instance of the opaque type, returning the public type.\n *\n * @param version The version of the instance to create\n * @param value The remaining public and internal properties of the instance\n * @returns An instance of the opaque type\n */\n createInstance<\n TVersion extends T['versions']['version'],\n TPublic extends T['public'],\n >(\n version: TVersion,\n props: Omit<T['public'], '$$type'> &\n (T['versions'] extends infer UVersion\n ? UVersion extends { version: TVersion }\n ? Omit<UVersion, 'version'>\n : never\n : never) &\n Object, // & Object to allow for object properties too, e.g. toString()\n ): TPublic {\n return Object.assign(props as object, {\n $$type: this.#type,\n ...(version && { version }),\n }) as unknown as TPublic;\n }\n\n #isThisInternalType(value: unknown): value is T['public'] & T['versions'] {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n return (value as T['public']).$$type === this.#type;\n }\n\n #stringifyUnknown(value: unknown) {\n if (typeof value !== 'object') {\n return `<${typeof value}>`;\n }\n if (value === null) {\n return '<null>';\n }\n if ('$$type' in value) {\n return String(value.$$type);\n }\n return String(value);\n }\n\n #stringifyVersion = (version: string | undefined) => {\n return version ? `'${version}'` : 'undefined';\n };\n}\n"],"names":[],"mappings":"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"}
@@ -6,14 +6,15 @@ import { AppNav } from './extensions/AppNav.esm.js';
6
6
  import { AppRoot } from './extensions/AppRoot.esm.js';
7
7
  import { AppRoutes } from './extensions/AppRoutes.esm.js';
8
8
  import { AppThemeApi, DarkTheme, LightTheme } from './extensions/AppThemeApi.esm.js';
9
- import { ComponentsApi } from './extensions/ComponentsApi.esm.js';
9
+ import { SwappableComponentsApi } from './extensions/SwappableComponentsApi.esm.js';
10
+ import { LegacyComponentsApi } from './extensions/LegacyComponentsApi.esm.js';
10
11
  import { IconsApi } from './extensions/IconsApi.esm.js';
11
12
  import { FeatureFlagsApi } from './extensions/FeatureFlagsApi.esm.js';
12
13
  import { TranslationsApi } from './extensions/TranslationsApi.esm.js';
13
14
  import { DefaultSignInPage } from './extensions/DefaultSignInPage.esm.js';
14
15
  import { dialogDisplayAppRootElement } from './extensions/DialogDisplay.esm.js';
15
- import { DefaultProgressComponent, DefaultNotFoundErrorPageComponent, DefaultErrorBoundaryComponent } from './extensions/components.esm.js';
16
16
  import { oauthRequestDialogAppRootElement, alertDisplayAppRootElement } from './extensions/elements.esm.js';
17
+ import { Progress, NotFoundErrorPage, ErrorDisplay } from './extensions/components.esm.js';
17
18
  import { apis } from './defaultApis.esm.js';
18
19
 
19
20
  const appPlugin = createFrontendPlugin({
@@ -30,17 +31,18 @@ const appPlugin = createFrontendPlugin({
30
31
  AppThemeApi,
31
32
  DarkTheme,
32
33
  LightTheme,
33
- ComponentsApi,
34
+ SwappableComponentsApi,
34
35
  IconsApi,
35
36
  FeatureFlagsApi,
36
37
  TranslationsApi,
37
- DefaultProgressComponent,
38
- DefaultNotFoundErrorPageComponent,
39
- DefaultErrorBoundaryComponent,
40
38
  DefaultSignInPage,
41
39
  oauthRequestDialogAppRootElement,
42
40
  alertDisplayAppRootElement,
43
- dialogDisplayAppRootElement
41
+ dialogDisplayAppRootElement,
42
+ Progress,
43
+ NotFoundErrorPage,
44
+ ErrorDisplay,
45
+ LegacyComponentsApi
44
46
  ]
45
47
  });
46
48
 
@@ -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 dialogDisplayAppRootElement,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n pluginId: 'app',\n info: { packageJson: () => import('../package.json') },\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n ComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultProgressComponent,\n DefaultNotFoundErrorPageComponent,\n DefaultErrorBoundaryComponent,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n dialogDisplayAppRootElement,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA0CO,MAAM,YAAY,oBAAqB,CAAA;AAAA,EAC5C,QAAU,EAAA,KAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,mCAAiB,CAAE,EAAA;AAAA,EACrD,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,0BAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport {\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n DefaultSignInPage,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n} from './extensions';\nimport { apis } from './defaultApis';\n\n/** @public */\nexport const appPlugin = createFrontendPlugin({\n pluginId: 'app',\n info: { packageJson: () => import('../package.json') },\n extensions: [\n ...apis,\n App,\n AppLanguageApi,\n AppLayout,\n AppNav,\n AppRoot,\n AppRoutes,\n AppThemeApi,\n DarkTheme,\n LightTheme,\n SwappableComponentsApi,\n IconsApi,\n FeatureFlagsApi,\n TranslationsApi,\n DefaultSignInPage,\n oauthRequestDialogAppRootElement,\n alertDisplayAppRootElement,\n dialogDisplayAppRootElement,\n Progress,\n NotFoundErrorPage,\n ErrorDisplay,\n LegacyComponentsApi,\n ],\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA2CO,MAAM,YAAY,oBAAA,CAAqB;AAAA,EAC5C,QAAA,EAAU,KAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,mCAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY;AAAA,IACV,GAAG,IAAA;AAAA,IACH,GAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA,sBAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAA;AAAA,IACA,gCAAA;AAAA,IACA,0BAAA;AAAA,IACA,2BAAA;AAAA,IACA,QAAA;AAAA,IACA,iBAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}