@backstage/core-app-api 1.12.4 → 1.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -4
- package/dist/apis/implementations/AlertApi/AlertApiForwarder.esm.js +22 -0
- package/dist/apis/implementations/AlertApi/AlertApiForwarder.esm.js.map +1 -0
- package/dist/apis/implementations/AnalyticsApi/MultipleAnalyticsApi.esm.js +35 -0
- package/dist/apis/implementations/AnalyticsApi/MultipleAnalyticsApi.esm.js.map +1 -0
- package/dist/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.esm.js +7 -0
- package/dist/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.esm.js.map +1 -0
- package/dist/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js +114 -0
- package/dist/apis/implementations/AppLanguageApi/AppLanguageSelector.esm.js.map +1 -0
- package/dist/apis/implementations/AppThemeApi/AppThemeSelector.esm.js +56 -0
- package/dist/apis/implementations/AppThemeApi/AppThemeSelector.esm.js.map +1 -0
- package/dist/apis/implementations/DiscoveryApi/FrontendHostDiscovery.esm.js +53 -0
- package/dist/apis/implementations/DiscoveryApi/FrontendHostDiscovery.esm.js.map +1 -0
- package/dist/apis/implementations/DiscoveryApi/UrlPatternDiscovery.esm.js +39 -0
- package/dist/apis/implementations/DiscoveryApi/UrlPatternDiscovery.esm.js.map +1 -0
- package/dist/apis/implementations/ErrorApi/ErrorAlerter.esm.js +18 -0
- package/dist/apis/implementations/ErrorApi/ErrorAlerter.esm.js.map +1 -0
- package/dist/apis/implementations/ErrorApi/ErrorApiForwarder.esm.js +22 -0
- package/dist/apis/implementations/ErrorApi/ErrorApiForwarder.esm.js.map +1 -0
- package/dist/apis/implementations/ErrorApi/UnhandledErrorForwarder.esm.js +16 -0
- package/dist/apis/implementations/ErrorApi/UnhandledErrorForwarder.esm.js.map +1 -0
- package/dist/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js +84 -0
- package/dist/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.esm.js.map +1 -0
- package/dist/apis/implementations/FetchApi/FetchMiddlewares.esm.js +45 -0
- package/dist/apis/implementations/FetchApi/FetchMiddlewares.esm.js.map +1 -0
- package/dist/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.esm.js +50 -0
- package/dist/apis/implementations/FetchApi/IdentityAuthInjectorFetchMiddleware.esm.js.map +1 -0
- package/dist/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.esm.js +40 -0
- package/dist/apis/implementations/FetchApi/PluginProtocolResolverFetchMiddleware.esm.js.map +1 -0
- package/dist/apis/implementations/FetchApi/createFetchApi.esm.js +14 -0
- package/dist/apis/implementations/FetchApi/createFetchApi.esm.js.map +1 -0
- package/dist/apis/implementations/IdentityApi/AppIdentityProxy.esm.js +128 -0
- package/dist/apis/implementations/IdentityApi/AppIdentityProxy.esm.js.map +1 -0
- package/dist/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js +105 -0
- package/dist/apis/implementations/IdentityApi/startCookieAuthRefresh.esm.js.map +1 -0
- package/dist/apis/implementations/OAuthRequestApi/OAuthPendingRequests.esm.js +79 -0
- package/dist/apis/implementations/OAuthRequestApi/OAuthPendingRequests.esm.js.map +1 -0
- package/dist/apis/implementations/OAuthRequestApi/OAuthRequestManager.esm.js +62 -0
- package/dist/apis/implementations/OAuthRequestApi/OAuthRequestManager.esm.js.map +1 -0
- package/dist/apis/implementations/StorageApi/WebStorage.esm.js +105 -0
- package/dist/apis/implementations/StorageApi/WebStorage.esm.js.map +1 -0
- package/dist/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js +275 -0
- package/dist/apis/implementations/TranslationApi/I18nextTranslationApi.esm.js.map +1 -0
- package/dist/apis/implementations/auth/atlassian/AtlassianAuth.esm.js +28 -0
- package/dist/apis/implementations/auth/atlassian/AtlassianAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/bitbucket/BitbucketAuth.esm.js +30 -0
- package/dist/apis/implementations/auth/bitbucket/BitbucketAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.esm.js +30 -0
- package/dist/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/github/GithubAuth.esm.js +30 -0
- package/dist/apis/implementations/auth/github/GithubAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/gitlab/GitlabAuth.esm.js +30 -0
- package/dist/apis/implementations/auth/gitlab/GitlabAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/google/GoogleAuth.esm.js +49 -0
- package/dist/apis/implementations/auth/google/GoogleAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/microsoft/MicrosoftAuth.esm.js +139 -0
- package/dist/apis/implementations/auth/microsoft/MicrosoftAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/oauth2/OAuth2.esm.js +136 -0
- package/dist/apis/implementations/auth/oauth2/OAuth2.esm.js.map +1 -0
- package/dist/apis/implementations/auth/okta/OktaAuth.esm.js +51 -0
- package/dist/apis/implementations/auth/okta/OktaAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/onelogin/OneLoginAuth.esm.js +50 -0
- package/dist/apis/implementations/auth/onelogin/OneLoginAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/saml/SamlAuth.esm.js +58 -0
- package/dist/apis/implementations/auth/saml/SamlAuth.esm.js.map +1 -0
- package/dist/apis/implementations/auth/saml/types.esm.js +20 -0
- package/dist/apis/implementations/auth/saml/types.esm.js.map +1 -0
- package/dist/apis/implementations/auth/vmwareCloud/VMwareCloudAuth.esm.js +30 -0
- package/dist/apis/implementations/auth/vmwareCloud/VMwareCloudAuth.esm.js.map +1 -0
- package/dist/apis/system/ApiAggregator.esm.js +24 -0
- package/dist/apis/system/ApiAggregator.esm.js.map +1 -0
- package/dist/apis/system/ApiFactoryRegistry.esm.js +50 -0
- package/dist/apis/system/ApiFactoryRegistry.esm.js.map +1 -0
- package/dist/apis/system/ApiProvider.esm.js +26 -0
- package/dist/apis/system/ApiProvider.esm.js.map +1 -0
- package/dist/apis/system/ApiRegistry.esm.js +58 -0
- package/dist/apis/system/ApiRegistry.esm.js.map +1 -0
- package/dist/apis/system/ApiResolver.esm.js +77 -0
- package/dist/apis/system/ApiResolver.esm.js.map +1 -0
- package/dist/app/AppContext.esm.js +14 -0
- package/dist/app/AppContext.esm.js.map +1 -0
- package/dist/app/AppManager.esm.js +391 -0
- package/dist/app/AppManager.esm.js.map +1 -0
- package/dist/app/AppRouter.esm.js +101 -0
- package/dist/app/AppRouter.esm.js.map +1 -0
- package/dist/app/AppThemeProvider.esm.js +60 -0
- package/dist/app/AppThemeProvider.esm.js.map +1 -0
- package/dist/app/InternalAppContext.esm.js +6 -0
- package/dist/app/InternalAppContext.esm.js.map +1 -0
- package/dist/app/createSpecializedApp.esm.js +8 -0
- package/dist/app/createSpecializedApp.esm.js.map +1 -0
- package/dist/app/defaultConfigLoader.esm.js +34 -0
- package/dist/app/defaultConfigLoader.esm.js.map +1 -0
- package/dist/app/isProtectedApp.esm.js +9 -0
- package/dist/app/isProtectedApp.esm.js.map +1 -0
- package/dist/app/isReactRouterBeta.esm.js +10 -0
- package/dist/app/isReactRouterBeta.esm.js.map +1 -0
- package/dist/app/overrideBaseUrlConfigs.esm.js +50 -0
- package/dist/app/overrideBaseUrlConfigs.esm.js.map +1 -0
- package/dist/app/resolveRouteBindings.esm.js +26 -0
- package/dist/app/resolveRouteBindings.esm.js.map +1 -0
- package/dist/core-plugin-api/src/translation/TranslationRef.esm.js +13 -0
- package/dist/core-plugin-api/src/translation/TranslationRef.esm.js.map +1 -0
- package/dist/core-plugin-api/src/translation/TranslationResource.esm.js +13 -0
- package/dist/core-plugin-api/src/translation/TranslationResource.esm.js.map +1 -0
- package/dist/extensions/traversal.esm.js +67 -0
- package/dist/extensions/traversal.esm.js.map +1 -0
- package/dist/index.esm.js +34 -4226
- package/dist/index.esm.js.map +1 -1
- package/dist/lib/AuthConnector/DefaultAuthConnector.esm.js +172 -0
- package/dist/lib/AuthConnector/DefaultAuthConnector.esm.js.map +1 -0
- package/dist/lib/AuthConnector/DirectAuthConnector.esm.js +58 -0
- package/dist/lib/AuthConnector/DirectAuthConnector.esm.js.map +1 -0
- package/dist/lib/AuthSessionManager/AuthSessionStore.esm.js +111 -0
- package/dist/lib/AuthSessionManager/AuthSessionStore.esm.js.map +1 -0
- package/dist/lib/AuthSessionManager/RefreshingAuthSessionManager.esm.js +97 -0
- package/dist/lib/AuthSessionManager/RefreshingAuthSessionManager.esm.js.map +1 -0
- package/dist/lib/AuthSessionManager/SessionStateTracker.esm.js +31 -0
- package/dist/lib/AuthSessionManager/SessionStateTracker.esm.js.map +1 -0
- package/dist/lib/AuthSessionManager/StaticAuthSessionManager.esm.js +54 -0
- package/dist/lib/AuthSessionManager/StaticAuthSessionManager.esm.js.map +1 -0
- package/dist/lib/AuthSessionManager/common.esm.js +44 -0
- package/dist/lib/AuthSessionManager/common.esm.js.map +1 -0
- package/dist/lib/loginPopup.esm.js +62 -0
- package/dist/lib/loginPopup.esm.js.map +1 -0
- package/dist/lib/subjects.esm.js +132 -0
- package/dist/lib/subjects.esm.js.map +1 -0
- package/dist/plugins/collectors.esm.js +15 -0
- package/dist/plugins/collectors.esm.js.map +1 -0
- package/dist/routing/FeatureFlagged.esm.js +13 -0
- package/dist/routing/FeatureFlagged.esm.js.map +1 -0
- package/dist/routing/FlatRoutes.esm.js +60 -0
- package/dist/routing/FlatRoutes.esm.js.map +1 -0
- package/dist/routing/RouteResolver.esm.js +136 -0
- package/dist/routing/RouteResolver.esm.js.map +1 -0
- package/dist/routing/RouteTracker.esm.js +80 -0
- package/dist/routing/RouteTracker.esm.js.map +1 -0
- package/dist/routing/RoutingProvider.esm.js +28 -0
- package/dist/routing/RoutingProvider.esm.js.map +1 -0
- package/dist/routing/collectors.esm.js +268 -0
- package/dist/routing/collectors.esm.js.map +1 -0
- package/dist/routing/helpers.esm.js +10 -0
- package/dist/routing/helpers.esm.js.map +1 -0
- package/dist/routing/types.esm.js +18 -0
- package/dist/routing/types.esm.js.map +1 -0
- package/dist/routing/validation.esm.js +55 -0
- package/dist/routing/validation.esm.js.map +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @backstage/core-app-api
|
|
2
2
|
|
|
3
|
+
## 1.12.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1bed9a3: The Backstage identity session expiration check will no longer fall back to using the provider expiration. This was introduced to smooth out the rollout of Backstage release 1.18, and is no longer needed.
|
|
8
|
+
|
|
3
9
|
## 1.12.4
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -539,8 +545,7 @@
|
|
|
539
545
|
|
|
540
546
|
This change makes the dependence explicit, and removes the burden on
|
|
541
547
|
OAuth2-based providers which require an ID token (e.g. this is done by various
|
|
542
|
-
default [auth
|
|
543
|
-
handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add
|
|
548
|
+
default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add
|
|
544
549
|
`openid` to their default scopes. _That_ could carry another indirect benefit:
|
|
545
550
|
by removing `openid` from the default scopes for a provider, grants for
|
|
546
551
|
resource-specific access tokens can avoid requesting excess ID token-related
|
|
@@ -568,8 +573,7 @@
|
|
|
568
573
|
|
|
569
574
|
This change makes the dependence explicit, and removes the burden on
|
|
570
575
|
OAuth2-based providers which require an ID token (e.g. this is done by various
|
|
571
|
-
default [auth
|
|
572
|
-
handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add
|
|
576
|
+
default [auth handlers](https://backstage.io/docs/auth/identity-resolver/#authhandler)) to add
|
|
573
577
|
`openid` to their default scopes. _That_ could carry another indirect benefit:
|
|
574
578
|
by removing `openid` from the default scopes for a provider, grants for
|
|
575
579
|
resource-specific access tokens can avoid requesting excess ID token-related
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PublishSubject } from '../../../lib/subjects.esm.js';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => {
|
|
6
|
+
__defNormalProp(obj, key + "" , value);
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
class AlertApiForwarder {
|
|
10
|
+
constructor() {
|
|
11
|
+
__publicField(this, "subject", new PublishSubject());
|
|
12
|
+
}
|
|
13
|
+
post(alert) {
|
|
14
|
+
this.subject.next(alert);
|
|
15
|
+
}
|
|
16
|
+
alert$() {
|
|
17
|
+
return this.subject;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { AlertApiForwarder };
|
|
22
|
+
//# sourceMappingURL=AlertApiForwarder.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlertApiForwarder.esm.js","sources":["../../../../src/apis/implementations/AlertApi/AlertApiForwarder.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AlertApi, AlertMessage } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\n\n/**\n * Base implementation for the AlertApi that simply forwards alerts to consumers.\n *\n * @public\n */\nexport class AlertApiForwarder implements AlertApi {\n private readonly subject = new PublishSubject<AlertMessage>();\n\n post(alert: AlertMessage) {\n this.subject.next(alert);\n }\n\n alert$(): Observable<AlertMessage> {\n return this.subject;\n }\n}\n"],"names":[],"mappings":";;;;;;;;AAyBO,MAAM,iBAAsC,CAAA;AAAA,EAA5C,WAAA,GAAA;AACL,IAAiB,aAAA,CAAA,IAAA,EAAA,SAAA,EAAU,IAAI,cAA6B,EAAA,CAAA,CAAA;AAAA,GAAA;AAAA,EAE5D,KAAK,KAAqB,EAAA;AACxB,IAAK,IAAA,CAAA,OAAA,CAAQ,KAAK,KAAK,CAAA,CAAA;AAAA,GACzB;AAAA,EAEA,MAAmC,GAAA;AACjC,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GACd;AACF;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class MultipleAnalyticsApi {
|
|
2
|
+
constructor(actualApis) {
|
|
3
|
+
this.actualApis = actualApis;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Create an AnalyticsApi implementation from an array of concrete
|
|
7
|
+
* implementations.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```jsx
|
|
12
|
+
* MultipleAnalyticsApi.fromApis([
|
|
13
|
+
* SomeAnalyticsApi.fromConfig(configApi),
|
|
14
|
+
* new CustomAnalyticsApi(),
|
|
15
|
+
* ]);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
static fromApis(actualApis) {
|
|
19
|
+
return new MultipleAnalyticsApi(actualApis);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Forward the event to all configured analytics API implementations.
|
|
23
|
+
*/
|
|
24
|
+
captureEvent(event) {
|
|
25
|
+
this.actualApis.forEach((analyticsApi) => {
|
|
26
|
+
try {
|
|
27
|
+
analyticsApi.captureEvent(event);
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { MultipleAnalyticsApi };
|
|
35
|
+
//# sourceMappingURL=MultipleAnalyticsApi.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultipleAnalyticsApi.esm.js","sources":["../../../../src/apis/implementations/AnalyticsApi/MultipleAnalyticsApi.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api';\n\n/**\n * An implementation of the AnalyticsApi that can be used to forward analytics\n * events to multiple concrete implementations.\n *\n * @public\n *\n * @example\n *\n * ```jsx\n * createApiFactory({\n * api: analyticsApiRef,\n * deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef },\n * factory: ({ configApi, identityApi, storageApi }) =>\n * MultipleAnalyticsApi.fromApis([\n * VendorAnalyticsApi.fromConfig(configApi, { identityApi }),\n * CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }),\n * ]),\n * });\n * ```\n */\nexport class MultipleAnalyticsApi implements AnalyticsApi {\n private constructor(private readonly actualApis: AnalyticsApi[]) {}\n\n /**\n * Create an AnalyticsApi implementation from an array of concrete\n * implementations.\n *\n * @example\n *\n * ```jsx\n * MultipleAnalyticsApi.fromApis([\n * SomeAnalyticsApi.fromConfig(configApi),\n * new CustomAnalyticsApi(),\n * ]);\n * ```\n */\n static fromApis(actualApis: AnalyticsApi[]) {\n return new MultipleAnalyticsApi(actualApis);\n }\n\n /**\n * Forward the event to all configured analytics API implementations.\n */\n captureEvent(event: AnalyticsEvent): void {\n this.actualApis.forEach(analyticsApi => {\n try {\n analyticsApi.captureEvent(event);\n } catch {\n /* ignored */\n }\n });\n }\n}\n"],"names":[],"mappings":"AAqCO,MAAM,oBAA6C,CAAA;AAAA,EAChD,YAA6B,UAA4B,EAAA;AAA5B,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA,CAAA;AAAA,GAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAelE,OAAO,SAAS,UAA4B,EAAA;AAC1C,IAAO,OAAA,IAAI,qBAAqB,UAAU,CAAA,CAAA;AAAA,GAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAA6B,EAAA;AACxC,IAAK,IAAA,CAAA,UAAA,CAAW,QAAQ,CAAgB,YAAA,KAAA;AACtC,MAAI,IAAA;AACF,QAAA,YAAA,CAAa,aAAa,KAAK,CAAA,CAAA;AAAA,OACzB,CAAA,MAAA;AAAA,OAER;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoOpAnalyticsApi.esm.js","sources":["../../../../src/apis/implementations/AnalyticsApi/NoOpAnalyticsApi.ts"],"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 */\nimport { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api';\n\n/**\n * Base implementation for the AnalyticsApi that does nothing.\n *\n * @public\n */\nexport class NoOpAnalyticsApi implements AnalyticsApi {\n captureEvent(_event: AnalyticsEvent): void {}\n}\n"],"names":[],"mappings":"AAsBO,MAAM,gBAAyC,CAAA;AAAA,EACpD,aAAa,MAA8B,EAAA;AAAA,GAAC;AAC9C;;;;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { BehaviorSubject } from '../../../lib/subjects.esm.js';
|
|
2
|
+
import '@backstage/core-plugin-api';
|
|
3
|
+
|
|
4
|
+
var __accessCheck = (obj, member, msg) => {
|
|
5
|
+
if (!member.has(obj))
|
|
6
|
+
throw TypeError("Cannot " + msg);
|
|
7
|
+
};
|
|
8
|
+
var __privateGet = (obj, member, getter) => {
|
|
9
|
+
__accessCheck(obj, member, "read from private field");
|
|
10
|
+
return member.get(obj);
|
|
11
|
+
};
|
|
12
|
+
var __privateAdd = (obj, member, value) => {
|
|
13
|
+
if (member.has(obj))
|
|
14
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
15
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
16
|
+
};
|
|
17
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
18
|
+
__accessCheck(obj, member, "write to private field");
|
|
19
|
+
member.set(obj, value);
|
|
20
|
+
return value;
|
|
21
|
+
};
|
|
22
|
+
var _languages, _language, _subject;
|
|
23
|
+
const STORAGE_KEY = "language";
|
|
24
|
+
const DEFAULT_LANGUAGE = "en";
|
|
25
|
+
const _AppLanguageSelector = class _AppLanguageSelector {
|
|
26
|
+
constructor(languages, initialLanguage) {
|
|
27
|
+
__privateAdd(this, _languages, void 0);
|
|
28
|
+
__privateAdd(this, _language, void 0);
|
|
29
|
+
__privateAdd(this, _subject, void 0);
|
|
30
|
+
__privateSet(this, _languages, languages);
|
|
31
|
+
__privateSet(this, _language, initialLanguage);
|
|
32
|
+
__privateSet(this, _subject, new BehaviorSubject({
|
|
33
|
+
language: __privateGet(this, _language)
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
static create(options) {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
const languages = (_a = options == null ? void 0 : options.availableLanguages) != null ? _a : [DEFAULT_LANGUAGE];
|
|
39
|
+
if (languages.length !== new Set(languages).size) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Supported languages may not contain duplicates, got '${languages.join(
|
|
42
|
+
"', '"
|
|
43
|
+
)}'`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (!languages.includes(DEFAULT_LANGUAGE)) {
|
|
47
|
+
throw new Error(`Supported languages must include '${DEFAULT_LANGUAGE}'`);
|
|
48
|
+
}
|
|
49
|
+
const initialLanguage = (_b = options == null ? void 0 : options.defaultLanguage) != null ? _b : DEFAULT_LANGUAGE;
|
|
50
|
+
if (!languages.includes(initialLanguage)) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Initial language must be one of the supported languages, got '${initialLanguage}'`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return new _AppLanguageSelector(languages, initialLanguage);
|
|
56
|
+
}
|
|
57
|
+
static createWithStorage(options) {
|
|
58
|
+
const selector = _AppLanguageSelector.create(options);
|
|
59
|
+
if (!window.localStorage) {
|
|
60
|
+
return selector;
|
|
61
|
+
}
|
|
62
|
+
const storedLanguage = window.localStorage.getItem(STORAGE_KEY);
|
|
63
|
+
const { languages } = selector.getAvailableLanguages();
|
|
64
|
+
if (storedLanguage && languages.includes(storedLanguage)) {
|
|
65
|
+
selector.setLanguage(storedLanguage);
|
|
66
|
+
}
|
|
67
|
+
selector.language$().subscribe(({ language }) => {
|
|
68
|
+
if (language !== window.localStorage.getItem(STORAGE_KEY)) {
|
|
69
|
+
window.localStorage.setItem(STORAGE_KEY, language);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
window.addEventListener("storage", (event) => {
|
|
73
|
+
var _a;
|
|
74
|
+
if (event.key === STORAGE_KEY) {
|
|
75
|
+
const language = (_a = localStorage.getItem(STORAGE_KEY)) != null ? _a : void 0;
|
|
76
|
+
if (language) {
|
|
77
|
+
selector.setLanguage(language);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return selector;
|
|
82
|
+
}
|
|
83
|
+
getAvailableLanguages() {
|
|
84
|
+
return { languages: __privateGet(this, _languages).slice() };
|
|
85
|
+
}
|
|
86
|
+
setLanguage(language) {
|
|
87
|
+
const lng = language != null ? language : DEFAULT_LANGUAGE;
|
|
88
|
+
if (lng === __privateGet(this, _language)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (lng && !__privateGet(this, _languages).includes(lng)) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Failed to change language to '${lng}', available languages are '${__privateGet(this, _languages).join(
|
|
94
|
+
"', '"
|
|
95
|
+
)}'`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
__privateSet(this, _language, lng);
|
|
99
|
+
__privateGet(this, _subject).next({ language: lng });
|
|
100
|
+
}
|
|
101
|
+
getLanguage() {
|
|
102
|
+
return { language: __privateGet(this, _language) };
|
|
103
|
+
}
|
|
104
|
+
language$() {
|
|
105
|
+
return __privateGet(this, _subject);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
_languages = new WeakMap();
|
|
109
|
+
_language = new WeakMap();
|
|
110
|
+
_subject = new WeakMap();
|
|
111
|
+
let AppLanguageSelector = _AppLanguageSelector;
|
|
112
|
+
|
|
113
|
+
export { AppLanguageSelector, DEFAULT_LANGUAGE };
|
|
114
|
+
//# sourceMappingURL=AppLanguageSelector.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppLanguageSelector.esm.js","sources":["../../../../src/apis/implementations/AppLanguageApi/AppLanguageSelector.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\n// Internal import to avoid code duplication, this will lead to duplication in build output\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppLanguageApi } from '@backstage/core-plugin-api/alpha';\nimport { Observable } from '@backstage/types';\nimport { BehaviorSubject } from '../../../lib';\n\nconst STORAGE_KEY = 'language';\nexport const DEFAULT_LANGUAGE = 'en';\n\n/** @alpha */\nexport interface AppLanguageSelectorOptions {\n defaultLanguage?: string;\n availableLanguages?: string[];\n}\n\n/**\n * Exposes the available languages in the app and allows for switching of the active language.\n *\n * @alpha\n */\nexport class AppLanguageSelector implements AppLanguageApi {\n static create(options?: AppLanguageSelectorOptions) {\n const languages = options?.availableLanguages ?? [DEFAULT_LANGUAGE];\n if (languages.length !== new Set(languages).size) {\n throw new Error(\n `Supported languages may not contain duplicates, got '${languages.join(\n \"', '\",\n )}'`,\n );\n }\n if (!languages.includes(DEFAULT_LANGUAGE)) {\n throw new Error(`Supported languages must include '${DEFAULT_LANGUAGE}'`);\n }\n\n const initialLanguage = options?.defaultLanguage ?? DEFAULT_LANGUAGE;\n if (!languages.includes(initialLanguage)) {\n throw new Error(\n `Initial language must be one of the supported languages, got '${initialLanguage}'`,\n );\n }\n\n return new AppLanguageSelector(languages, initialLanguage);\n }\n\n static createWithStorage(options?: AppLanguageSelectorOptions) {\n const selector = AppLanguageSelector.create(options);\n\n if (!window.localStorage) {\n return selector;\n }\n\n const storedLanguage = window.localStorage.getItem(STORAGE_KEY);\n const { languages } = selector.getAvailableLanguages();\n if (storedLanguage && languages.includes(storedLanguage)) {\n selector.setLanguage(storedLanguage);\n }\n\n selector.language$().subscribe(({ language }) => {\n if (language !== window.localStorage.getItem(STORAGE_KEY)) {\n window.localStorage.setItem(STORAGE_KEY, language);\n }\n });\n\n window.addEventListener('storage', event => {\n if (event.key === STORAGE_KEY) {\n const language = localStorage.getItem(STORAGE_KEY) ?? undefined;\n if (language) {\n selector.setLanguage(language);\n }\n }\n });\n\n return selector;\n }\n\n #languages: string[];\n #language: string;\n #subject: BehaviorSubject<{ language: string }>;\n\n private constructor(languages: string[], initialLanguage: string) {\n this.#languages = languages;\n this.#language = initialLanguage;\n this.#subject = new BehaviorSubject<{ language: string }>({\n language: this.#language,\n });\n }\n\n getAvailableLanguages(): { languages: string[] } {\n return { languages: this.#languages.slice() };\n }\n\n setLanguage(language?: string | undefined): void {\n const lng = language ?? DEFAULT_LANGUAGE;\n if (lng === this.#language) {\n return;\n }\n if (lng && !this.#languages.includes(lng)) {\n throw new Error(\n `Failed to change language to '${lng}', available languages are '${this.#languages.join(\n \"', '\",\n )}'`,\n );\n }\n this.#language = lng;\n this.#subject.next({ language: lng });\n }\n\n getLanguage(): { language: string } {\n return { language: this.#language };\n }\n\n language$(): Observable<{ language: string }> {\n return this.#subject;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BehaviorSubject } from '../../../lib/subjects.esm.js';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => {
|
|
6
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
const STORAGE_KEY = "theme";
|
|
10
|
+
class AppThemeSelector {
|
|
11
|
+
constructor(themes) {
|
|
12
|
+
this.themes = themes;
|
|
13
|
+
__publicField(this, "activeThemeId");
|
|
14
|
+
__publicField(this, "subject", new BehaviorSubject(void 0));
|
|
15
|
+
}
|
|
16
|
+
static createWithStorage(themes) {
|
|
17
|
+
var _a;
|
|
18
|
+
const selector = new AppThemeSelector(themes);
|
|
19
|
+
if (!window.localStorage) {
|
|
20
|
+
return selector;
|
|
21
|
+
}
|
|
22
|
+
const initialThemeId = (_a = window.localStorage.getItem(STORAGE_KEY)) != null ? _a : void 0;
|
|
23
|
+
selector.setActiveThemeId(initialThemeId);
|
|
24
|
+
selector.activeThemeId$().subscribe((themeId) => {
|
|
25
|
+
if (themeId) {
|
|
26
|
+
window.localStorage.setItem(STORAGE_KEY, themeId);
|
|
27
|
+
} else {
|
|
28
|
+
window.localStorage.removeItem(STORAGE_KEY);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
window.addEventListener("storage", (event) => {
|
|
32
|
+
var _a2;
|
|
33
|
+
if (event.key === STORAGE_KEY) {
|
|
34
|
+
const themeId = (_a2 = localStorage.getItem(STORAGE_KEY)) != null ? _a2 : void 0;
|
|
35
|
+
selector.setActiveThemeId(themeId);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return selector;
|
|
39
|
+
}
|
|
40
|
+
getInstalledThemes() {
|
|
41
|
+
return this.themes.slice();
|
|
42
|
+
}
|
|
43
|
+
activeThemeId$() {
|
|
44
|
+
return this.subject;
|
|
45
|
+
}
|
|
46
|
+
getActiveThemeId() {
|
|
47
|
+
return this.activeThemeId;
|
|
48
|
+
}
|
|
49
|
+
setActiveThemeId(themeId) {
|
|
50
|
+
this.activeThemeId = themeId;
|
|
51
|
+
this.subject.next(themeId);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { AppThemeSelector };
|
|
56
|
+
//# sourceMappingURL=AppThemeSelector.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppThemeSelector.esm.js","sources":["../../../../src/apis/implementations/AppThemeApi/AppThemeSelector.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 { AppThemeApi, AppTheme } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { BehaviorSubject } from '../../../lib/subjects';\n\nconst STORAGE_KEY = 'theme';\n\n/**\n * Exposes the themes installed in the app, and permits switching the currently\n * active theme.\n *\n * @public\n */\nexport class AppThemeSelector implements AppThemeApi {\n static createWithStorage(themes: AppTheme[]) {\n const selector = new AppThemeSelector(themes);\n\n if (!window.localStorage) {\n return selector;\n }\n\n const initialThemeId =\n window.localStorage.getItem(STORAGE_KEY) ?? undefined;\n\n selector.setActiveThemeId(initialThemeId);\n\n selector.activeThemeId$().subscribe(themeId => {\n if (themeId) {\n window.localStorage.setItem(STORAGE_KEY, themeId);\n } else {\n window.localStorage.removeItem(STORAGE_KEY);\n }\n });\n\n window.addEventListener('storage', event => {\n if (event.key === STORAGE_KEY) {\n const themeId = localStorage.getItem(STORAGE_KEY) ?? undefined;\n selector.setActiveThemeId(themeId);\n }\n });\n\n return selector;\n }\n\n private activeThemeId: string | undefined;\n private readonly subject = new BehaviorSubject<string | undefined>(undefined);\n\n constructor(private readonly themes: AppTheme[]) {}\n\n getInstalledThemes(): AppTheme[] {\n return this.themes.slice();\n }\n\n activeThemeId$(): Observable<string | undefined> {\n return this.subject;\n }\n\n getActiveThemeId(): string | undefined {\n return this.activeThemeId;\n }\n\n setActiveThemeId(themeId?: string): void {\n this.activeThemeId = themeId;\n this.subject.next(themeId);\n }\n}\n"],"names":["_a"],"mappings":";;;;;;;;AAoBA,MAAM,WAAc,GAAA,OAAA,CAAA;AAQb,MAAM,gBAAwC,CAAA;AAAA,EAkCnD,YAA6B,MAAoB,EAAA;AAApB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AAH7B,IAAQ,aAAA,CAAA,IAAA,EAAA,eAAA,CAAA,CAAA;AACR,IAAiB,aAAA,CAAA,IAAA,EAAA,SAAA,EAAU,IAAI,eAAA,CAAoC,KAAS,CAAA,CAAA,CAAA,CAAA;AAAA,GAE1B;AAAA,EAjClD,OAAO,kBAAkB,MAAoB,EAAA;AA7B/C,IAAA,IAAA,EAAA,CAAA;AA8BI,IAAM,MAAA,QAAA,GAAW,IAAI,gBAAA,CAAiB,MAAM,CAAA,CAAA;AAE5C,IAAI,IAAA,CAAC,OAAO,YAAc,EAAA;AACxB,MAAO,OAAA,QAAA,CAAA;AAAA,KACT;AAEA,IAAA,MAAM,kBACJ,EAAO,GAAA,MAAA,CAAA,YAAA,CAAa,OAAQ,CAAA,WAAW,MAAvC,IAA4C,GAAA,EAAA,GAAA,KAAA,CAAA,CAAA;AAE9C,IAAA,QAAA,CAAS,iBAAiB,cAAc,CAAA,CAAA;AAExC,IAAS,QAAA,CAAA,cAAA,EAAiB,CAAA,SAAA,CAAU,CAAW,OAAA,KAAA;AAC7C,MAAA,IAAI,OAAS,EAAA;AACX,QAAO,MAAA,CAAA,YAAA,CAAa,OAAQ,CAAA,WAAA,EAAa,OAAO,CAAA,CAAA;AAAA,OAC3C,MAAA;AACL,QAAO,MAAA,CAAA,YAAA,CAAa,WAAW,WAAW,CAAA,CAAA;AAAA,OAC5C;AAAA,KACD,CAAA,CAAA;AAED,IAAO,MAAA,CAAA,gBAAA,CAAiB,WAAW,CAAS,KAAA,KAAA;AAjDhD,MAAAA,IAAAA,GAAAA,CAAAA;AAkDM,MAAI,IAAA,KAAA,CAAM,QAAQ,WAAa,EAAA;AAC7B,QAAA,MAAM,WAAUA,GAAA,GAAA,YAAA,CAAa,QAAQ,WAAW,CAAA,KAAhC,OAAAA,GAAqC,GAAA,KAAA,CAAA,CAAA;AACrD,QAAA,QAAA,CAAS,iBAAiB,OAAO,CAAA,CAAA;AAAA,OACnC;AAAA,KACD,CAAA,CAAA;AAED,IAAO,OAAA,QAAA,CAAA;AAAA,GACT;AAAA,EAOA,kBAAiC,GAAA;AAC/B,IAAO,OAAA,IAAA,CAAK,OAAO,KAAM,EAAA,CAAA;AAAA,GAC3B;AAAA,EAEA,cAAiD,GAAA;AAC/C,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GACd;AAAA,EAEA,gBAAuC,GAAA;AACrC,IAAA,OAAO,IAAK,CAAA,aAAA,CAAA;AAAA,GACd;AAAA,EAEA,iBAAiB,OAAwB,EAAA;AACvC,IAAA,IAAA,CAAK,aAAgB,GAAA,OAAA,CAAA;AACrB,IAAK,IAAA,CAAA,OAAA,CAAQ,KAAK,OAAO,CAAA,CAAA;AAAA,GAC3B;AACF;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UrlPatternDiscovery } from './UrlPatternDiscovery.esm.js';
|
|
2
|
+
|
|
3
|
+
class FrontendHostDiscovery {
|
|
4
|
+
constructor(endpoints, defaultEndpoint) {
|
|
5
|
+
this.endpoints = endpoints;
|
|
6
|
+
this.defaultEndpoint = defaultEndpoint;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new FrontendHostDiscovery discovery instance by reading
|
|
10
|
+
* the external target URL from the `discovery.endpoints` config section.
|
|
11
|
+
*
|
|
12
|
+
* eg.
|
|
13
|
+
* ```yaml
|
|
14
|
+
* discovery:
|
|
15
|
+
* endpoints:
|
|
16
|
+
* - target: https://internal.example.com/internal-catalog
|
|
17
|
+
* plugins: [catalog]
|
|
18
|
+
* - target: https://internal.example.com/secure/api/{{pluginId}}
|
|
19
|
+
* plugins: [auth, permissions]
|
|
20
|
+
* - target:
|
|
21
|
+
* internal: https://internal.example.com/search
|
|
22
|
+
* external: https://example.com/search
|
|
23
|
+
* plugins: [search]
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* If a plugin is not declared in the config, the discovery will fall back to using the baseUrl with
|
|
27
|
+
* the provided `pathPattern` appended. The default path pattern is `"/api/{{ pluginId }}"`.
|
|
28
|
+
*/
|
|
29
|
+
static fromConfig(config, options) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const path = (_a = options == null ? void 0 : options.pathPattern) != null ? _a : "/api/{{ pluginId }}";
|
|
32
|
+
const baseUrl = config.getString("backend.baseUrl");
|
|
33
|
+
const endpoints = (_b = config.getOptionalConfigArray("discovery.endpoints")) == null ? void 0 : _b.flatMap((e) => {
|
|
34
|
+
const target = typeof e.get("target") === "object" ? e.getString("target.external") : e.getString("target");
|
|
35
|
+
const discovery = UrlPatternDiscovery.compile(target);
|
|
36
|
+
return e.getStringArray("plugins").map((pluginId) => [pluginId, discovery]);
|
|
37
|
+
});
|
|
38
|
+
return new FrontendHostDiscovery(
|
|
39
|
+
new Map(endpoints),
|
|
40
|
+
UrlPatternDiscovery.compile(`${baseUrl}${path}`)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
async getBaseUrl(pluginId) {
|
|
44
|
+
const endpoint = this.endpoints.get(pluginId);
|
|
45
|
+
if (endpoint) {
|
|
46
|
+
return endpoint.getBaseUrl(pluginId);
|
|
47
|
+
}
|
|
48
|
+
return this.defaultEndpoint.getBaseUrl(pluginId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { FrontendHostDiscovery };
|
|
53
|
+
//# sourceMappingURL=FrontendHostDiscovery.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FrontendHostDiscovery.esm.js","sources":["../../../../src/apis/implementations/DiscoveryApi/FrontendHostDiscovery.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 */\nimport { Config } from '@backstage/config';\nimport { DiscoveryApi } from '@backstage/core-plugin-api';\nimport { UrlPatternDiscovery } from './UrlPatternDiscovery';\n\n/**\n * FrontendHostDiscovery is a config driven DiscoveryApi implementation.\n * It uses the app-config to determine the url for a plugin.\n *\n * @public\n */\nexport class FrontendHostDiscovery implements DiscoveryApi {\n /**\n * Creates a new FrontendHostDiscovery discovery instance by reading\n * the external target URL from the `discovery.endpoints` config section.\n *\n * eg.\n * ```yaml\n * discovery:\n * endpoints:\n * - target: https://internal.example.com/internal-catalog\n * plugins: [catalog]\n * - target: https://internal.example.com/secure/api/{{pluginId}}\n * plugins: [auth, permissions]\n * - target:\n * internal: https://internal.example.com/search\n * external: https://example.com/search\n * plugins: [search]\n * ```\n *\n * If a plugin is not declared in the config, the discovery will fall back to using the baseUrl with\n * the provided `pathPattern` appended. The default path pattern is `\"/api/{{ pluginId }}\"`.\n */\n static fromConfig(config: Config, options?: { pathPattern?: string }) {\n const path = options?.pathPattern ?? '/api/{{ pluginId }}';\n const baseUrl = config.getString('backend.baseUrl');\n\n const endpoints = config\n .getOptionalConfigArray('discovery.endpoints')\n ?.flatMap(e => {\n const target =\n typeof e.get('target') === 'object'\n ? e.getString('target.external')\n : e.getString('target');\n const discovery = UrlPatternDiscovery.compile(target);\n return e\n .getStringArray('plugins')\n .map(pluginId => [pluginId, discovery] as const);\n });\n\n return new FrontendHostDiscovery(\n new Map(endpoints),\n UrlPatternDiscovery.compile(`${baseUrl}${path}`),\n );\n }\n\n private constructor(\n private readonly endpoints: Map<string, DiscoveryApi>,\n private readonly defaultEndpoint: DiscoveryApi,\n ) {}\n\n async getBaseUrl(pluginId: string): Promise<string> {\n const endpoint = this.endpoints.get(pluginId);\n if (endpoint) {\n return endpoint.getBaseUrl(pluginId);\n }\n return this.defaultEndpoint.getBaseUrl(pluginId);\n }\n}\n"],"names":[],"mappings":";;AAyBO,MAAM,qBAA8C,CAAA;AAAA,EA6CjD,WAAA,CACW,WACA,eACjB,EAAA;AAFiB,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA,CAAA;AACA,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA,CAAA;AAAA,GAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA1BH,OAAO,UAAW,CAAA,MAAA,EAAgB,OAAoC,EAAA;AA/CxE,IAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAgDI,IAAM,MAAA,IAAA,GAAA,CAAO,EAAS,GAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,WAAA,KAAT,IAAwB,GAAA,EAAA,GAAA,qBAAA,CAAA;AACrC,IAAM,MAAA,OAAA,GAAU,MAAO,CAAA,SAAA,CAAU,iBAAiB,CAAA,CAAA;AAElD,IAAA,MAAM,aAAY,EACf,GAAA,MAAA,CAAA,sBAAA,CAAuB,qBAAqB,CAD7B,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAEd,QAAQ,CAAK,CAAA,KAAA;AACb,MAAA,MAAM,MACJ,GAAA,OAAO,CAAE,CAAA,GAAA,CAAI,QAAQ,CAAA,KAAM,QACvB,GAAA,CAAA,CAAE,SAAU,CAAA,iBAAiB,CAC7B,GAAA,CAAA,CAAE,UAAU,QAAQ,CAAA,CAAA;AAC1B,MAAM,MAAA,SAAA,GAAY,mBAAoB,CAAA,OAAA,CAAQ,MAAM,CAAA,CAAA;AACpD,MAAO,OAAA,CAAA,CACJ,eAAe,SAAS,CAAA,CACxB,IAAI,CAAY,QAAA,KAAA,CAAC,QAAU,EAAA,SAAS,CAAU,CAAA,CAAA;AAAA,KACnD,CAAA,CAAA;AAEF,IAAA,OAAO,IAAI,qBAAA;AAAA,MACT,IAAI,IAAI,SAAS,CAAA;AAAA,MACjB,oBAAoB,OAAQ,CAAA,CAAA,EAAG,OAAO,CAAA,EAAG,IAAI,CAAE,CAAA,CAAA;AAAA,KACjD,CAAA;AAAA,GACF;AAAA,EAOA,MAAM,WAAW,QAAmC,EAAA;AAClD,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,SAAU,CAAA,GAAA,CAAI,QAAQ,CAAA,CAAA;AAC5C,IAAA,IAAI,QAAU,EAAA;AACZ,MAAO,OAAA,QAAA,CAAS,WAAW,QAAQ,CAAA,CAAA;AAAA,KACrC;AACA,IAAO,OAAA,IAAA,CAAK,eAAgB,CAAA,UAAA,CAAW,QAAQ,CAAA,CAAA;AAAA,GACjD;AACF;;;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const ERROR_PREFIX = "Invalid discovery URL pattern,";
|
|
2
|
+
class UrlPatternDiscovery {
|
|
3
|
+
constructor(parts) {
|
|
4
|
+
this.parts = parts;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new UrlPatternDiscovery given a template. The the only
|
|
8
|
+
* interpolation done for the template is to replace instances of `{{pluginId}}`
|
|
9
|
+
* with the ID of the plugin being requested.
|
|
10
|
+
*
|
|
11
|
+
* Example pattern: `http://localhost:7007/api/{{ pluginId }}`
|
|
12
|
+
*/
|
|
13
|
+
static compile(pattern) {
|
|
14
|
+
const parts = pattern.split(/\{\{\s*pluginId\s*\}\}/);
|
|
15
|
+
const urlStr = parts.join("pluginId");
|
|
16
|
+
let url;
|
|
17
|
+
try {
|
|
18
|
+
url = new URL(urlStr);
|
|
19
|
+
} catch {
|
|
20
|
+
throw new Error(`${ERROR_PREFIX} URL '${urlStr}' is invalid`);
|
|
21
|
+
}
|
|
22
|
+
if (url.hash) {
|
|
23
|
+
throw new Error(`${ERROR_PREFIX} URL must not have a hash`);
|
|
24
|
+
}
|
|
25
|
+
if (url.search) {
|
|
26
|
+
throw new Error(`${ERROR_PREFIX} URL must not have a query`);
|
|
27
|
+
}
|
|
28
|
+
if (urlStr.endsWith("/")) {
|
|
29
|
+
throw new Error(`${ERROR_PREFIX} URL must not end with a slash`);
|
|
30
|
+
}
|
|
31
|
+
return new UrlPatternDiscovery(parts);
|
|
32
|
+
}
|
|
33
|
+
async getBaseUrl(pluginId) {
|
|
34
|
+
return this.parts.join(encodeURIComponent(pluginId));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { UrlPatternDiscovery };
|
|
39
|
+
//# sourceMappingURL=UrlPatternDiscovery.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UrlPatternDiscovery.esm.js","sources":["../../../../src/apis/implementations/DiscoveryApi/UrlPatternDiscovery.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 { DiscoveryApi } from '@backstage/core-plugin-api';\n\nconst ERROR_PREFIX = 'Invalid discovery URL pattern,';\n\n/**\n * UrlPatternDiscovery is a lightweight DiscoveryApi implementation.\n * It uses a single template string to construct URLs for each plugin.\n *\n * @public\n */\nexport class UrlPatternDiscovery implements DiscoveryApi {\n /**\n * Creates a new UrlPatternDiscovery given a template. The the only\n * interpolation done for the template is to replace instances of `{{pluginId}}`\n * with the ID of the plugin being requested.\n *\n * Example pattern: `http://localhost:7007/api/{{ pluginId }}`\n */\n static compile(pattern: string): UrlPatternDiscovery {\n const parts = pattern.split(/\\{\\{\\s*pluginId\\s*\\}\\}/);\n const urlStr = parts.join('pluginId');\n\n let url;\n try {\n url = new URL(urlStr);\n } catch {\n throw new Error(`${ERROR_PREFIX} URL '${urlStr}' is invalid`);\n }\n if (url.hash) {\n throw new Error(`${ERROR_PREFIX} URL must not have a hash`);\n }\n if (url.search) {\n throw new Error(`${ERROR_PREFIX} URL must not have a query`);\n }\n if (urlStr.endsWith('/')) {\n throw new Error(`${ERROR_PREFIX} URL must not end with a slash`);\n }\n\n return new UrlPatternDiscovery(parts);\n }\n\n private constructor(private readonly parts: string[]) {}\n\n async getBaseUrl(pluginId: string): Promise<string> {\n return this.parts.join(encodeURIComponent(pluginId));\n }\n}\n"],"names":[],"mappings":"AAkBA,MAAM,YAAe,GAAA,gCAAA,CAAA;AAQd,MAAM,mBAA4C,CAAA;AAAA,EA+B/C,YAA6B,KAAiB,EAAA;AAAjB,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA,CAAA;AAAA,GAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAvBvD,OAAO,QAAQ,OAAsC,EAAA;AACnD,IAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,KAAA,CAAM,wBAAwB,CAAA,CAAA;AACpD,IAAM,MAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AAEpC,IAAI,IAAA,GAAA,CAAA;AACJ,IAAI,IAAA;AACF,MAAM,GAAA,GAAA,IAAI,IAAI,MAAM,CAAA,CAAA;AAAA,KACd,CAAA,MAAA;AACN,MAAA,MAAM,IAAI,KAAM,CAAA,CAAA,EAAG,YAAY,CAAA,MAAA,EAAS,MAAM,CAAc,YAAA,CAAA,CAAA,CAAA;AAAA,KAC9D;AACA,IAAA,IAAI,IAAI,IAAM,EAAA;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAA,YAAY,CAA2B,yBAAA,CAAA,CAAA,CAAA;AAAA,KAC5D;AACA,IAAA,IAAI,IAAI,MAAQ,EAAA;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAA,YAAY,CAA4B,0BAAA,CAAA,CAAA,CAAA;AAAA,KAC7D;AACA,IAAI,IAAA,MAAA,CAAO,QAAS,CAAA,GAAG,CAAG,EAAA;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAG,EAAA,YAAY,CAAgC,8BAAA,CAAA,CAAA,CAAA;AAAA,KACjE;AAEA,IAAO,OAAA,IAAI,oBAAoB,KAAK,CAAA,CAAA;AAAA,GACtC;AAAA,EAIA,MAAM,WAAW,QAAmC,EAAA;AAClD,IAAA,OAAO,IAAK,CAAA,KAAA,CAAM,IAAK,CAAA,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,GACrD;AACF;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class ErrorAlerter {
|
|
2
|
+
constructor(alertApi, errorApi) {
|
|
3
|
+
this.alertApi = alertApi;
|
|
4
|
+
this.errorApi = errorApi;
|
|
5
|
+
}
|
|
6
|
+
post(error, context) {
|
|
7
|
+
if (!(context == null ? void 0 : context.hidden)) {
|
|
8
|
+
this.alertApi.post({ message: error.message, severity: "error" });
|
|
9
|
+
}
|
|
10
|
+
return this.errorApi.post(error, context);
|
|
11
|
+
}
|
|
12
|
+
error$() {
|
|
13
|
+
return this.errorApi.error$();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { ErrorAlerter };
|
|
18
|
+
//# sourceMappingURL=ErrorAlerter.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorAlerter.esm.js","sources":["../../../../src/apis/implementations/ErrorApi/ErrorAlerter.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 */\nimport {\n ErrorApi,\n ErrorApiError,\n ErrorApiErrorContext,\n AlertApi,\n} from '@backstage/core-plugin-api';\n\n/**\n * Decorates an ErrorApi by also forwarding error messages\n * to the alertApi with an 'error' severity.\n *\n * @public\n */\nexport class ErrorAlerter implements ErrorApi {\n constructor(\n private readonly alertApi: AlertApi,\n private readonly errorApi: ErrorApi,\n ) {}\n\n post(error: ErrorApiError, context?: ErrorApiErrorContext) {\n if (!context?.hidden) {\n this.alertApi.post({ message: error.message, severity: 'error' });\n }\n\n return this.errorApi.post(error, context);\n }\n\n error$() {\n return this.errorApi.error$();\n }\n}\n"],"names":[],"mappings":"AA4BO,MAAM,YAAiC,CAAA;AAAA,EAC5C,WAAA,CACmB,UACA,QACjB,EAAA;AAFiB,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA,CAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA,CAAA;AAAA,GAChB;AAAA,EAEH,IAAA,CAAK,OAAsB,OAAgC,EAAA;AACzD,IAAI,IAAA,EAAC,mCAAS,MAAQ,CAAA,EAAA;AACpB,MAAK,IAAA,CAAA,QAAA,CAAS,KAAK,EAAE,OAAA,EAAS,MAAM,OAAS,EAAA,QAAA,EAAU,SAAS,CAAA,CAAA;AAAA,KAClE;AAEA,IAAA,OAAO,IAAK,CAAA,QAAA,CAAS,IAAK,CAAA,KAAA,EAAO,OAAO,CAAA,CAAA;AAAA,GAC1C;AAAA,EAEA,MAAS,GAAA;AACP,IAAO,OAAA,IAAA,CAAK,SAAS,MAAO,EAAA,CAAA;AAAA,GAC9B;AACF;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PublishSubject } from '../../../lib/subjects.esm.js';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => {
|
|
6
|
+
__defNormalProp(obj, key + "" , value);
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
class ErrorApiForwarder {
|
|
10
|
+
constructor() {
|
|
11
|
+
__publicField(this, "subject", new PublishSubject());
|
|
12
|
+
}
|
|
13
|
+
post(error, context) {
|
|
14
|
+
this.subject.next({ error, context });
|
|
15
|
+
}
|
|
16
|
+
error$() {
|
|
17
|
+
return this.subject;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { ErrorApiForwarder };
|
|
22
|
+
//# sourceMappingURL=ErrorApiForwarder.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorApiForwarder.esm.js","sources":["../../../../src/apis/implementations/ErrorApi/ErrorApiForwarder.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ErrorApi,\n ErrorApiError,\n ErrorApiErrorContext,\n} from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\n\n/**\n * Base implementation for the ErrorApi that simply forwards errors to consumers.\n *\n * @public\n */\nexport class ErrorApiForwarder implements ErrorApi {\n private readonly subject = new PublishSubject<{\n error: Error;\n context?: ErrorApiErrorContext;\n }>();\n\n post(error: ErrorApiError, context?: ErrorApiErrorContext) {\n this.subject.next({ error, context });\n }\n\n error$(): Observable<{ error: Error; context?: ErrorApiErrorContext }> {\n return this.subject;\n }\n}\n"],"names":[],"mappings":";;;;;;;;AA6BO,MAAM,iBAAsC,CAAA;AAAA,EAA5C,WAAA,GAAA;AACL,IAAiB,aAAA,CAAA,IAAA,EAAA,SAAA,EAAU,IAAI,cAG5B,EAAA,CAAA,CAAA;AAAA,GAAA;AAAA,EAEH,IAAA,CAAK,OAAsB,OAAgC,EAAA;AACzD,IAAA,IAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,EAAE,KAAA,EAAO,SAAS,CAAA,CAAA;AAAA,GACtC;AAAA,EAEA,MAAuE,GAAA;AACrE,IAAA,OAAO,IAAK,CAAA,OAAA,CAAA;AAAA,GACd;AACF;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class UnhandledErrorForwarder {
|
|
2
|
+
/**
|
|
3
|
+
* Add event listener, such that unhandled errors can be forwarded using an given `ErrorApi` instance
|
|
4
|
+
*/
|
|
5
|
+
static forward(errorApi, errorContext) {
|
|
6
|
+
window.addEventListener(
|
|
7
|
+
"unhandledrejection",
|
|
8
|
+
(e) => {
|
|
9
|
+
errorApi.post(e.reason, errorContext);
|
|
10
|
+
}
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { UnhandledErrorForwarder };
|
|
16
|
+
//# sourceMappingURL=UnhandledErrorForwarder.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnhandledErrorForwarder.esm.js","sources":["../../../../src/apis/implementations/ErrorApi/UnhandledErrorForwarder.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ErrorApi,\n ErrorApiError,\n ErrorApiErrorContext,\n} from '@backstage/core-plugin-api';\n\n/**\n * Utility class that helps with error forwarding.\n *\n * @public\n */\nexport class UnhandledErrorForwarder {\n /**\n * Add event listener, such that unhandled errors can be forwarded using an given `ErrorApi` instance\n */\n static forward(errorApi: ErrorApi, errorContext: ErrorApiErrorContext) {\n window.addEventListener(\n 'unhandledrejection',\n (e: PromiseRejectionEvent) => {\n errorApi.post(e.reason as ErrorApiError, errorContext);\n },\n );\n }\n}\n"],"names":[],"mappings":"AA2BO,MAAM,uBAAwB,CAAA;AAAA;AAAA;AAAA;AAAA,EAInC,OAAO,OAAQ,CAAA,QAAA,EAAoB,YAAoC,EAAA;AACrE,IAAO,MAAA,CAAA,gBAAA;AAAA,MACL,oBAAA;AAAA,MACA,CAAC,CAA6B,KAAA;AAC5B,QAAS,QAAA,CAAA,IAAA,CAAK,CAAE,CAAA,MAAA,EAAyB,YAAY,CAAA,CAAA;AAAA,OACvD;AAAA,KACF,CAAA;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { FeatureFlagState } from '@backstage/core-plugin-api';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => {
|
|
6
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
function validateFlagName(name) {
|
|
10
|
+
if (name.length < 3) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`The '${name}' feature flag must have a minimum length of three characters.`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
if (name.length > 150) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`The '${name}' feature flag must not exceed 150 characters.`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
if (!name.match(/^[a-z]+[a-z0-9-]+$/)) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`The '${name}' feature flag must start with a lowercase letter and only contain lowercase letters, numbers and hyphens. Examples: feature-flag-one, alpha, release-2020`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class LocalStorageFeatureFlags {
|
|
27
|
+
constructor() {
|
|
28
|
+
__publicField(this, "registeredFeatureFlags", []);
|
|
29
|
+
__publicField(this, "flags");
|
|
30
|
+
}
|
|
31
|
+
registerFlag(flag) {
|
|
32
|
+
validateFlagName(flag.name);
|
|
33
|
+
this.registeredFeatureFlags.push(flag);
|
|
34
|
+
}
|
|
35
|
+
getRegisteredFlags() {
|
|
36
|
+
return this.registeredFeatureFlags.slice();
|
|
37
|
+
}
|
|
38
|
+
isActive(name) {
|
|
39
|
+
if (!this.flags) {
|
|
40
|
+
this.flags = this.load();
|
|
41
|
+
}
|
|
42
|
+
return this.flags.get(name) === FeatureFlagState.Active;
|
|
43
|
+
}
|
|
44
|
+
save(options) {
|
|
45
|
+
if (!this.flags) {
|
|
46
|
+
this.flags = this.load();
|
|
47
|
+
}
|
|
48
|
+
if (!options.merge) {
|
|
49
|
+
this.flags.clear();
|
|
50
|
+
}
|
|
51
|
+
for (const [name, state] of Object.entries(options.states)) {
|
|
52
|
+
this.flags.set(name, state);
|
|
53
|
+
}
|
|
54
|
+
const enabled = Array.from(this.flags.entries()).filter(
|
|
55
|
+
([, state]) => state === FeatureFlagState.Active
|
|
56
|
+
);
|
|
57
|
+
window.localStorage.setItem(
|
|
58
|
+
"featureFlags",
|
|
59
|
+
JSON.stringify(Object.fromEntries(enabled))
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
load() {
|
|
63
|
+
try {
|
|
64
|
+
const jsonStr = window.localStorage.getItem("featureFlags");
|
|
65
|
+
if (!jsonStr) {
|
|
66
|
+
return /* @__PURE__ */ new Map();
|
|
67
|
+
}
|
|
68
|
+
const json = JSON.parse(jsonStr);
|
|
69
|
+
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
70
|
+
return /* @__PURE__ */ new Map();
|
|
71
|
+
}
|
|
72
|
+
const entries = Object.entries(json).filter(([name, value]) => {
|
|
73
|
+
validateFlagName(name);
|
|
74
|
+
return value === FeatureFlagState.Active;
|
|
75
|
+
});
|
|
76
|
+
return new Map(entries);
|
|
77
|
+
} catch {
|
|
78
|
+
return /* @__PURE__ */ new Map();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { LocalStorageFeatureFlags, validateFlagName };
|
|
84
|
+
//# sourceMappingURL=LocalStorageFeatureFlags.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalStorageFeatureFlags.esm.js","sources":["../../../../src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags.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 {\n FeatureFlagState,\n FeatureFlagsApi,\n FeatureFlag,\n FeatureFlagsSaveOptions,\n} from '@backstage/core-plugin-api';\n\nexport function validateFlagName(name: string): void {\n if (name.length < 3) {\n throw new Error(\n `The '${name}' feature flag must have a minimum length of three characters.`,\n );\n }\n\n if (name.length > 150) {\n throw new Error(\n `The '${name}' feature flag must not exceed 150 characters.`,\n );\n }\n\n if (!name.match(/^[a-z]+[a-z0-9-]+$/)) {\n throw new Error(\n `The '${name}' feature flag must start with a lowercase letter and only contain lowercase letters, numbers and hyphens. ` +\n 'Examples: feature-flag-one, alpha, release-2020',\n );\n }\n}\n\n/**\n * A feature flags implementation that stores the flags in the browser's local\n * storage.\n *\n * @public\n */\nexport class LocalStorageFeatureFlags implements FeatureFlagsApi {\n private registeredFeatureFlags: FeatureFlag[] = [];\n private flags?: Map<string, FeatureFlagState>;\n\n registerFlag(flag: FeatureFlag) {\n validateFlagName(flag.name);\n this.registeredFeatureFlags.push(flag);\n }\n\n getRegisteredFlags(): FeatureFlag[] {\n return this.registeredFeatureFlags.slice();\n }\n\n isActive(name: string): boolean {\n if (!this.flags) {\n this.flags = this.load();\n }\n return this.flags.get(name) === FeatureFlagState.Active;\n }\n\n save(options: FeatureFlagsSaveOptions): void {\n if (!this.flags) {\n this.flags = this.load();\n }\n if (!options.merge) {\n this.flags.clear();\n }\n for (const [name, state] of Object.entries(options.states)) {\n this.flags.set(name, state);\n }\n\n const enabled = Array.from(this.flags.entries()).filter(\n ([, state]) => state === FeatureFlagState.Active,\n );\n window.localStorage.setItem(\n 'featureFlags',\n JSON.stringify(Object.fromEntries(enabled)),\n );\n }\n\n private load(): Map<string, FeatureFlagState> {\n try {\n const jsonStr = window.localStorage.getItem('featureFlags');\n if (!jsonStr) {\n return new Map();\n }\n const json = JSON.parse(jsonStr) as unknown;\n if (typeof json !== 'object' || json === null || Array.isArray(json)) {\n return new Map();\n }\n\n const entries = Object.entries(json).filter(([name, value]) => {\n validateFlagName(name);\n return value === FeatureFlagState.Active;\n });\n\n return new Map(entries);\n } catch {\n return new Map();\n }\n }\n}\n"],"names":[],"mappings":"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"}
|