@backstage/plugin-app 0.3.2-next.0 → 0.3.3-next.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/plugin-app
2
2
 
3
+ ## 0.3.3-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - d02db50: Remove unnecessary use of `compatWrapper` and `convertLegacyRouteRef`(s) for the new frontend system.
8
+ - Updated dependencies
9
+ - @backstage/frontend-plugin-api@0.13.2-next.0
10
+ - @backstage/core-plugin-api@1.12.1-next.0
11
+ - @backstage/theme@0.7.1-next.0
12
+ - @backstage/integration-react@1.2.13-next.0
13
+ - @backstage/core-components@0.18.4-next.0
14
+ - @backstage/plugin-permission-react@0.4.39-next.0
15
+ - @backstage/types@1.2.2
16
+ - @backstage/version-bridge@1.0.11
17
+
18
+ ## 0.3.2
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+ - @backstage/frontend-plugin-api@0.13.0
24
+ - @backstage/core-components@0.18.3
25
+ - @backstage/core-plugin-api@1.12.0
26
+ - @backstage/plugin-permission-react@0.4.38
27
+ - @backstage/integration-react@1.2.12
28
+
3
29
  ## 0.3.2-next.0
4
30
 
5
31
  ### Patch Changes
@@ -2,6 +2,7 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { lazy } from 'react';
3
3
  import { OpaqueSwappableComponentRef } from '../../packages/frontend-internal/src/wiring/InternalSwappableComponentRef.esm.js';
4
4
  import '../../packages/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js';
5
+ import '../../packages/frontend-internal/src/wiring/InternalExtensionInput.esm.js';
5
6
  import '../../packages/frontend-internal/src/wiring/InternalFrontendPlugin.esm.js';
6
7
 
7
8
  class DefaultSwappableComponentsApi {
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSwappableComponentsApi.esm.js","sources":["../../../src/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.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 {\n SwappableComponentRef,\n SwappableComponentsApi,\n SwappableComponentBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { OpaqueSwappableComponentRef } from '@internal/frontend';\n\nimport { lazy } from 'react';\n\n/**\n * Implementation for the {@link SwappableComponentsApi}\n *\n * @internal\n */\nexport class DefaultSwappableComponentsApi implements SwappableComponentsApi {\n #components: Map<string, ((props: object) => JSX.Element | null) | undefined>;\n\n static fromComponents(\n components: Array<typeof SwappableComponentBlueprint.dataRefs.component.T>,\n ) {\n return new DefaultSwappableComponentsApi(\n new Map(\n components.map(entry => {\n return [\n entry.ref.id,\n entry.loader\n ? lazy(async () => ({\n default: await entry.loader!(),\n }))\n : undefined,\n ];\n }),\n ),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent(\n ref: SwappableComponentRef<any>,\n ): (props: object) => JSX.Element | null {\n const OverrideComponent = this.#components.get(ref.id);\n const { defaultComponent: DefaultComponent, transformProps } =\n OpaqueSwappableComponentRef.toInternal(ref);\n\n return (props: object) => {\n const innerProps = transformProps?.(props) ?? props;\n\n if (OverrideComponent) {\n return <OverrideComponent {...innerProps} />;\n }\n\n return <DefaultComponent {...innerProps} />;\n };\n }\n}\n"],"names":[],"mappings":";;;;;;AA8BO,MAAM,6BAAA,CAAgE;AAAA,EAC3E,WAAA;AAAA,EAEA,OAAO,eACL,UAAA,EACA;AACA,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAI,GAAA;AAAA,QACF,UAAA,CAAW,IAAI,CAAA,KAAA,KAAS;AACtB,UAAA,OAAO;AAAA,YACL,MAAM,GAAA,CAAI,EAAA;AAAA,YACV,KAAA,CAAM,MAAA,GACF,IAAA,CAAK,aAAa;AAAA,cAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA;AAAQ,cAC7B,CAAA,GACF;AAAA,WACN;AAAA,QACF,CAAC;AAAA;AACH,KACF;AAAA,EACF;AAAA,EAEA,YAAY,UAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AAAA,EACrB;AAAA,EAEA,aACE,GAAA,EACuC;AACvC,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,EAAE,CAAA;AACrD,IAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAA,EAAkB,gBAAe,GACzD,2BAAA,CAA4B,WAAW,GAAG,CAAA;AAE5C,IAAA,OAAO,CAAC,KAAA,KAAkB;AACxB,MAAA,MAAM,UAAA,GAAa,cAAA,GAAiB,KAAK,CAAA,IAAK,KAAA;AAE9C,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAmB,GAAG,UAAA,EAAY,CAAA;AAAA,MAC5C;AAEA,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,UAAA,EAAY,CAAA;AAAA,IAC3C,CAAA;AAAA,EACF;AACF;;;;"}
1
+ {"version":3,"file":"DefaultSwappableComponentsApi.esm.js","sources":["../../../src/apis/SwappableComponentsApi/DefaultSwappableComponentsApi.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 {\n SwappableComponentRef,\n SwappableComponentsApi,\n SwappableComponentBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { OpaqueSwappableComponentRef } from '@internal/frontend';\n\nimport { lazy } from 'react';\n\n/**\n * Implementation for the {@link SwappableComponentsApi}\n *\n * @internal\n */\nexport class DefaultSwappableComponentsApi implements SwappableComponentsApi {\n #components: Map<string, ((props: object) => JSX.Element | null) | undefined>;\n\n static fromComponents(\n components: Array<typeof SwappableComponentBlueprint.dataRefs.component.T>,\n ) {\n return new DefaultSwappableComponentsApi(\n new Map(\n components.map(entry => {\n return [\n entry.ref.id,\n entry.loader\n ? lazy(async () => ({\n default: await entry.loader!(),\n }))\n : undefined,\n ];\n }),\n ),\n );\n }\n\n constructor(components: Map<string, any>) {\n this.#components = components;\n }\n\n getComponent(\n ref: SwappableComponentRef<any>,\n ): (props: object) => JSX.Element | null {\n const OverrideComponent = this.#components.get(ref.id);\n const { defaultComponent: DefaultComponent, transformProps } =\n OpaqueSwappableComponentRef.toInternal(ref);\n\n return (props: object) => {\n const innerProps = transformProps?.(props) ?? props;\n\n if (OverrideComponent) {\n return <OverrideComponent {...innerProps} />;\n }\n\n return <DefaultComponent {...innerProps} />;\n };\n }\n}\n"],"names":[],"mappings":";;;;;;;AA8BO,MAAM,6BAAA,CAAgE;AAAA,EAC3E,WAAA;AAAA,EAEA,OAAO,eACL,UAAA,EACA;AACA,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAI,GAAA;AAAA,QACF,UAAA,CAAW,IAAI,CAAA,KAAA,KAAS;AACtB,UAAA,OAAO;AAAA,YACL,MAAM,GAAA,CAAI,EAAA;AAAA,YACV,KAAA,CAAM,MAAA,GACF,IAAA,CAAK,aAAa;AAAA,cAChB,OAAA,EAAS,MAAM,KAAA,CAAM,MAAA;AAAQ,cAC7B,CAAA,GACF;AAAA,WACN;AAAA,QACF,CAAC;AAAA;AACH,KACF;AAAA,EACF;AAAA,EAEA,YAAY,UAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AAAA,EACrB;AAAA,EAEA,aACE,GAAA,EACuC;AACvC,IAAA,MAAM,iBAAA,GAAoB,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAI,EAAE,CAAA;AACrD,IAAA,MAAM,EAAE,gBAAA,EAAkB,gBAAA,EAAkB,gBAAe,GACzD,2BAAA,CAA4B,WAAW,GAAG,CAAA;AAE5C,IAAA,OAAO,CAAC,KAAA,KAAkB;AACxB,MAAA,MAAM,UAAA,GAAa,cAAA,GAAiB,KAAK,CAAA,IAAK,KAAA;AAE9C,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAmB,GAAG,UAAA,EAAY,CAAA;AAAA,MAC5C;AAEA,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,UAAA,EAAY,CAAA;AAAA,IAC3C,CAAA;AAAA,EACF;AACF;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
- import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
2
1
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
3
2
  import * as react from 'react';
4
3
 
5
4
  /** @public */
6
5
  declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{}, {}, {
7
- app: _backstage_frontend_plugin_api.ExtensionDefinition<{
6
+ app: _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
8
7
  config: {};
9
8
  configInput: {};
10
9
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
@@ -18,7 +17,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
18
17
  kind: undefined;
19
18
  name: undefined;
20
19
  }>;
21
- "app/layout": _backstage_frontend_plugin_api.ExtensionDefinition<{
20
+ "app/layout": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
22
21
  config: {};
23
22
  configInput: {};
24
23
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
@@ -36,14 +35,14 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
36
35
  kind: undefined;
37
36
  name: "layout";
38
37
  }>;
39
- "app/nav": _backstage_frontend_plugin_api.ExtensionDefinition<{
38
+ "app/nav": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
40
39
  config: {};
41
40
  configInput: {};
42
41
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
43
42
  inputs: {
44
43
  items: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
45
44
  title: string;
46
- icon: _backstage_core_plugin_api.IconComponent;
45
+ icon: _backstage_frontend_plugin_api.IconComponent;
47
46
  routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
48
47
  }, "core.nav-item.target", {}>, {
49
48
  singleton: false;
@@ -58,7 +57,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
58
57
  kind: undefined;
59
58
  name: "nav";
60
59
  }>;
61
- "app/root": _backstage_frontend_plugin_api.ExtensionDefinition<{
60
+ "app/root": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
62
61
  config: {};
63
62
  configInput: {};
64
63
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
@@ -69,7 +68,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
69
68
  singleton: true;
70
69
  optional: true;
71
70
  }>;
72
- signInPage: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.ComponentType<_backstage_core_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>, {
71
+ signInPage: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>, {
73
72
  singleton: true;
74
73
  optional: true;
75
74
  }>;
@@ -92,7 +91,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
92
91
  kind: undefined;
93
92
  name: "root";
94
93
  }>;
95
- "app/routes": _backstage_frontend_plugin_api.ExtensionDefinition<{
94
+ "app/routes": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
96
95
  config: {};
97
96
  configInput: {};
98
97
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
@@ -108,7 +107,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
108
107
  kind: undefined;
109
108
  name: "routes";
110
109
  }>;
111
- "api:app/alert": _backstage_frontend_plugin_api.ExtensionDefinition<{
110
+ "api:app/alert": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
112
111
  kind: "api";
113
112
  name: "alert";
114
113
  config: {};
@@ -117,7 +116,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
117
116
  inputs: {};
118
117
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
119
118
  }>;
120
- "api:app/analytics": _backstage_frontend_plugin_api.ExtensionDefinition<{
119
+ "api:app/analytics": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
121
120
  config: {};
122
121
  configInput: {};
123
122
  output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
@@ -131,7 +130,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
131
130
  name: "analytics";
132
131
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
133
132
  }>;
134
- "api:app/app-language": _backstage_frontend_plugin_api.ExtensionDefinition<{
133
+ "api:app/app-language": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
135
134
  kind: "api";
136
135
  name: "app-language";
137
136
  config: {};
@@ -140,7 +139,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
140
139
  inputs: {};
141
140
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
142
141
  }>;
143
- "api:app/app-theme": _backstage_frontend_plugin_api.ExtensionDefinition<{
142
+ "api:app/app-theme": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
144
143
  config: {};
145
144
  configInput: {};
146
145
  output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
@@ -154,7 +153,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
154
153
  name: "app-theme";
155
154
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
156
155
  }>;
157
- "api:app/atlassian-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
156
+ "api:app/atlassian-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
158
157
  kind: "api";
159
158
  name: "atlassian-auth";
160
159
  config: {};
@@ -163,7 +162,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
163
162
  inputs: {};
164
163
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
165
164
  }>;
166
- "api:app/bitbucket-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
165
+ "api:app/bitbucket-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
167
166
  kind: "api";
168
167
  name: "bitbucket-auth";
169
168
  config: {};
@@ -172,7 +171,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
172
171
  inputs: {};
173
172
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
174
173
  }>;
175
- "api:app/bitbucket-server-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
174
+ "api:app/bitbucket-server-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
176
175
  kind: "api";
177
176
  name: "bitbucket-server-auth";
178
177
  config: {};
@@ -181,7 +180,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
181
180
  inputs: {};
182
181
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
183
182
  }>;
184
- "api:app/components": _backstage_frontend_plugin_api.ExtensionDefinition<{
183
+ "api:app/components": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
185
184
  kind: "api";
186
185
  name: "components";
187
186
  config: {};
@@ -190,7 +189,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
190
189
  inputs: {};
191
190
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
192
191
  }>;
193
- "api:app/dialog": _backstage_frontend_plugin_api.ExtensionDefinition<{
192
+ "api:app/dialog": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
194
193
  kind: "api";
195
194
  name: "dialog";
196
195
  config: {};
@@ -199,7 +198,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
199
198
  inputs: {};
200
199
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
201
200
  }>;
202
- "api:app/discovery": _backstage_frontend_plugin_api.ExtensionDefinition<{
201
+ "api:app/discovery": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
203
202
  kind: "api";
204
203
  name: "discovery";
205
204
  config: {};
@@ -208,7 +207,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
208
207
  inputs: {};
209
208
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
210
209
  }>;
211
- "api:app/error": _backstage_frontend_plugin_api.ExtensionDefinition<{
210
+ "api:app/error": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
212
211
  kind: "api";
213
212
  name: "error";
214
213
  config: {};
@@ -217,7 +216,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
217
216
  inputs: {};
218
217
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
219
218
  }>;
220
- "api:app/feature-flags": _backstage_frontend_plugin_api.ExtensionDefinition<{
219
+ "api:app/feature-flags": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
221
220
  kind: "api";
222
221
  name: "feature-flags";
223
222
  config: {};
@@ -226,7 +225,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
226
225
  inputs: {};
227
226
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
228
227
  }>;
229
- "api:app/fetch": _backstage_frontend_plugin_api.ExtensionDefinition<{
228
+ "api:app/fetch": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
230
229
  kind: "api";
231
230
  name: "fetch";
232
231
  config: {};
@@ -235,7 +234,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
235
234
  inputs: {};
236
235
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
237
236
  }>;
238
- "api:app/github-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
237
+ "api:app/github-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
239
238
  kind: "api";
240
239
  name: "github-auth";
241
240
  config: {};
@@ -244,7 +243,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
244
243
  inputs: {};
245
244
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
246
245
  }>;
247
- "api:app/gitlab-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
246
+ "api:app/gitlab-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
248
247
  kind: "api";
249
248
  name: "gitlab-auth";
250
249
  config: {};
@@ -253,7 +252,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
253
252
  inputs: {};
254
253
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
255
254
  }>;
256
- "api:app/google-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
255
+ "api:app/google-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
257
256
  kind: "api";
258
257
  name: "google-auth";
259
258
  config: {};
@@ -262,7 +261,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
262
261
  inputs: {};
263
262
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
264
263
  }>;
265
- "api:app/icons": _backstage_frontend_plugin_api.ExtensionDefinition<{
264
+ "api:app/icons": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
266
265
  config: {};
267
266
  configInput: {};
268
267
  output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
@@ -278,7 +277,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
278
277
  name: "icons";
279
278
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
280
279
  }>;
281
- "api:app/microsoft-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
280
+ "api:app/microsoft-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
282
281
  kind: "api";
283
282
  name: "microsoft-auth";
284
283
  config: {};
@@ -287,7 +286,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
287
286
  inputs: {};
288
287
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
289
288
  }>;
290
- "api:app/oauth-request": _backstage_frontend_plugin_api.ExtensionDefinition<{
289
+ "api:app/oauth-request": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
291
290
  kind: "api";
292
291
  name: "oauth-request";
293
292
  config: {};
@@ -296,7 +295,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
296
295
  inputs: {};
297
296
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
298
297
  }>;
299
- "api:app/okta-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
298
+ "api:app/okta-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
300
299
  kind: "api";
301
300
  name: "okta-auth";
302
301
  config: {};
@@ -305,7 +304,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
305
304
  inputs: {};
306
305
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
307
306
  }>;
308
- "api:app/onelogin-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
307
+ "api:app/onelogin-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
309
308
  kind: "api";
310
309
  name: "onelogin-auth";
311
310
  config: {};
@@ -314,7 +313,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
314
313
  inputs: {};
315
314
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
316
315
  }>;
317
- "api:app/openshift-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
316
+ "api:app/openshift-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
318
317
  kind: "api";
319
318
  name: "openshift-auth";
320
319
  config: {};
@@ -323,7 +322,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
323
322
  inputs: {};
324
323
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
325
324
  }>;
326
- "api:app/permission": _backstage_frontend_plugin_api.ExtensionDefinition<{
325
+ "api:app/permission": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
327
326
  kind: "api";
328
327
  name: "permission";
329
328
  config: {};
@@ -332,7 +331,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
332
331
  inputs: {};
333
332
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
334
333
  }>;
335
- "api:app/scm-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
334
+ "api:app/scm-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
336
335
  kind: "api";
337
336
  name: "scm-auth";
338
337
  config: {};
@@ -341,7 +340,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
341
340
  inputs: {};
342
341
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
343
342
  }>;
344
- "api:app/scm-integrations": _backstage_frontend_plugin_api.ExtensionDefinition<{
343
+ "api:app/scm-integrations": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
345
344
  kind: "api";
346
345
  name: "scm-integrations";
347
346
  config: {};
@@ -350,7 +349,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
350
349
  inputs: {};
351
350
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
352
351
  }>;
353
- "api:app/storage": _backstage_frontend_plugin_api.ExtensionDefinition<{
352
+ "api:app/storage": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
354
353
  kind: "api";
355
354
  name: "storage";
356
355
  config: {};
@@ -359,7 +358,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
359
358
  inputs: {};
360
359
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
361
360
  }>;
362
- "api:app/swappable-components": _backstage_frontend_plugin_api.ExtensionDefinition<{
361
+ "api:app/swappable-components": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
363
362
  config: {};
364
363
  configInput: {};
365
364
  output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
@@ -376,7 +375,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
376
375
  name: "swappable-components";
377
376
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
378
377
  }>;
379
- "api:app/translations": _backstage_frontend_plugin_api.ExtensionDefinition<{
378
+ "api:app/translations": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
380
379
  config: {};
381
380
  configInput: {};
382
381
  output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
@@ -392,7 +391,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
392
391
  name: "translations";
393
392
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
394
393
  }>;
395
- "api:app/vmware-cloud-auth": _backstage_frontend_plugin_api.ExtensionDefinition<{
394
+ "api:app/vmware-cloud-auth": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
396
395
  kind: "api";
397
396
  name: "vmware-cloud-auth";
398
397
  config: {};
@@ -401,7 +400,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
401
400
  inputs: {};
402
401
  params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
403
402
  }>;
404
- "app-root-element:app/alert-display": _backstage_frontend_plugin_api.ExtensionDefinition<{
403
+ "app-root-element:app/alert-display": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
405
404
  config: {
406
405
  transientTimeoutMs: number;
407
406
  anchorOrigin: {
@@ -419,8 +418,8 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
419
418
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
420
419
  inputs: {
421
420
  [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ExtensionDataRef, {
422
- optional: boolean;
423
421
  singleton: boolean;
422
+ optional: boolean;
424
423
  }>;
425
424
  };
426
425
  kind: "app-root-element";
@@ -429,14 +428,14 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
429
428
  element: JSX.Element;
430
429
  };
431
430
  }>;
432
- "app-root-element:app/dialog-display": _backstage_frontend_plugin_api.ExtensionDefinition<{
431
+ "app-root-element:app/dialog-display": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
433
432
  config: {};
434
433
  configInput: {};
435
434
  output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}>;
436
435
  inputs: {
437
436
  [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ExtensionDataRef, {
438
- optional: boolean;
439
437
  singleton: boolean;
438
+ optional: boolean;
440
439
  }>;
441
440
  };
442
441
  kind: "app-root-element";
@@ -445,7 +444,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
445
444
  element: JSX.Element;
446
445
  };
447
446
  }>;
448
- "app-root-element:app/oauth-request-dialog": _backstage_frontend_plugin_api.ExtensionDefinition<{
447
+ "app-root-element:app/oauth-request-dialog": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
449
448
  kind: "app-root-element";
450
449
  name: "oauth-request-dialog";
451
450
  config: {};
@@ -456,7 +455,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
456
455
  element: JSX.Element;
457
456
  };
458
457
  }>;
459
- "component:app/core-error-display": _backstage_frontend_plugin_api.ExtensionDefinition<{
458
+ "component:app/core-error-display": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
460
459
  kind: "component";
461
460
  name: "core-error-display";
462
461
  config: {};
@@ -478,7 +477,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
478
477
  loader: Ref extends _backstage_frontend_plugin_api.SwappableComponentRef<infer IInnerComponentProps, any> ? (() => (props: IInnerComponentProps) => JSX.Element | null) | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) : never;
479
478
  }>;
480
479
  }>;
481
- "component:app/core-not-found-error-page": _backstage_frontend_plugin_api.ExtensionDefinition<{
480
+ "component:app/core-not-found-error-page": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
482
481
  kind: "component";
483
482
  name: "core-not-found-error-page";
484
483
  config: {};
@@ -500,7 +499,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
500
499
  loader: Ref extends _backstage_frontend_plugin_api.SwappableComponentRef<infer IInnerComponentProps, any> ? (() => (props: IInnerComponentProps) => JSX.Element | null) | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) : never;
501
500
  }>;
502
501
  }>;
503
- "component:app/core-progress": _backstage_frontend_plugin_api.ExtensionDefinition<{
502
+ "component:app/core-progress": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
504
503
  kind: "component";
505
504
  name: "core-progress";
506
505
  config: {};
@@ -522,18 +521,18 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
522
521
  loader: Ref extends _backstage_frontend_plugin_api.SwappableComponentRef<infer IInnerComponentProps, any> ? (() => (props: IInnerComponentProps) => JSX.Element | null) | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) : never;
523
522
  }>;
524
523
  }>;
525
- "sign-in-page:app": _backstage_frontend_plugin_api.ExtensionDefinition<{
524
+ "sign-in-page:app": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
526
525
  kind: "sign-in-page";
527
526
  name: undefined;
528
527
  config: {};
529
528
  configInput: {};
530
- output: _backstage_frontend_plugin_api.ExtensionDataRef<react.ComponentType<_backstage_core_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>;
529
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>, "core.sign-in-page.component", {}>;
531
530
  inputs: {};
532
531
  params: {
533
- loader: () => Promise<react.ComponentType<_backstage_core_plugin_api.SignInPageProps>>;
532
+ loader: () => Promise<react.ComponentType<_backstage_frontend_plugin_api.SignInPageProps>>;
534
533
  };
535
534
  }>;
536
- "theme:app/dark": _backstage_frontend_plugin_api.ExtensionDefinition<{
535
+ "theme:app/dark": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
537
536
  kind: "theme";
538
537
  name: "dark";
539
538
  config: {};
@@ -544,7 +543,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
544
543
  theme: _backstage_frontend_plugin_api.AppTheme;
545
544
  };
546
545
  }>;
547
- "theme:app/light": _backstage_frontend_plugin_api.ExtensionDefinition<{
546
+ "theme:app/light": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
548
547
  kind: "theme";
549
548
  name: "light";
550
549
  config: {};
@@ -1,7 +1,7 @@
1
1
  import { createInstance } from 'i18next';
2
2
  import ObservableImpl from 'zen-observable';
3
- import { toInternalTranslationResource } from '../../../../../core-plugin-api/src/translation/TranslationResource.esm.js';
4
- import { toInternalTranslationRef } from '../../../../../core-plugin-api/src/translation/TranslationRef.esm.js';
3
+ import { toInternalTranslationResource } from '../../../../../frontend-plugin-api/src/translation/TranslationResource.esm.js';
4
+ import { toInternalTranslationRef } from '../../../../../frontend-plugin-api/src/translation/TranslationRef.esm.js';
5
5
  import { DEFAULT_LANGUAGE } from '../AppLanguageApi/AppLanguageSelector.esm.js';
6
6
  import { isValidElement, createElement, Fragment } from 'react';
7
7
 
@@ -1 +1 @@
1
- {"version":3,"file":"I18nextTranslationApi.esm.js","sources":["../../../../../../../../../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.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 AppLanguageApi,\n TranslationApi,\n TranslationFunction,\n TranslationMessages,\n TranslationRef,\n TranslationResource,\n TranslationSnapshot,\n} from '@backstage/core-plugin-api/alpha';\nimport {\n createInstance as createI18n,\n FormatFunction,\n Interpolator,\n TFunction,\n type i18n as I18n,\n} from 'i18next';\nimport ObservableImpl from 'zen-observable';\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 {\n toInternalTranslationResource,\n InternalTranslationResourceLoader,\n} from '../../../../../core-plugin-api/src/translation/TranslationResource';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n toInternalTranslationRef,\n InternalTranslationRef,\n} from '../../../../../core-plugin-api/src/translation/TranslationRef';\nimport { Observable } from '@backstage/types';\nimport { DEFAULT_LANGUAGE } from '../AppLanguageApi/AppLanguageSelector';\nimport { createElement, Fragment, ReactNode, isValidElement } from 'react';\n\n/** @alpha */\nexport interface I18nextTranslationApiOptions {\n languageApi: AppLanguageApi;\n resources?: Array<TranslationMessages | TranslationResource>;\n}\n\nfunction removeNulls(\n messages: Record<string, string | null>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(messages).filter(\n (e): e is [string, string] => e[1] !== null,\n ),\n );\n}\n\n/**\n * The built-in i18next backend loading logic doesn't handle on the fly switches\n * of language very well. It gets a bit confused about whether resources are actually\n * loaded or not, so instead we implement our own resource loader.\n */\nclass ResourceLoader {\n /** Loaded resources by loader key */\n #loaded = new Set<string>();\n /** Resource loading promises by loader key */\n #loading = new Map<string, Promise<void>>();\n /** Loaders for each resource language */\n #loaders = new Map<string, InternalTranslationResourceLoader>();\n\n constructor(\n private readonly onLoad: (loaded: {\n language: string;\n namespace: string;\n messages: Record<string, string | null>;\n }) => void,\n ) {}\n\n addTranslationResource(resource: TranslationResource) {\n const internalResource = toInternalTranslationResource(resource);\n for (const entry of internalResource.resources) {\n const key = this.#getLoaderKey(entry.language, internalResource.id);\n\n // First loader to register wins, this means that resources registered in the app\n // have priority over default resource from translation refs\n if (!this.#loaders.has(key)) {\n this.#loaders.set(key, entry.loader);\n }\n }\n }\n\n #getLoaderKey(language: string, namespace: string) {\n return `${language}/${namespace}`;\n }\n\n needsLoading(language: string, namespace: string) {\n const key = this.#getLoaderKey(language, namespace);\n const loader = this.#loaders.get(key);\n if (!loader) {\n return false;\n }\n\n return !this.#loaded.has(key);\n }\n\n async load(language: string, namespace: string): Promise<void> {\n const key = this.#getLoaderKey(language, namespace);\n\n const loader = this.#loaders.get(key);\n if (!loader) {\n return;\n }\n\n if (this.#loaded.has(key)) {\n return;\n }\n\n const loading = this.#loading.get(key);\n if (loading) {\n await loading;\n return;\n }\n\n const load = loader().then(\n result => {\n this.onLoad({ language, namespace, messages: result.messages });\n this.#loaded.add(key);\n },\n error => {\n this.#loaded.add(key); // Do not try to load failed resources again\n throw error;\n },\n );\n this.#loading.set(key, load);\n await load;\n }\n}\n\n/**\n * A helper for implementing JSX interpolation\n */\nexport class JsxInterpolator {\n readonly #setFormatHook: (hook: FormatFunction) => void;\n readonly #marker: string;\n readonly #pattern: RegExp;\n\n static fromI18n(i18n: I18n) {\n const interpolator = i18n.services.interpolator as Interpolator & {\n format: FormatFunction;\n };\n const originalFormat = interpolator.format;\n\n let formatHook: FormatFunction | undefined;\n\n // This is the only way to override the format function of the interpolator\n // without overriding the default formatters. See the behavior here:\n // https://github.com/i18next/i18next/blob/c633121e57e2b6024080142d78027842bf2a6e5e/src/i18next.js#L120-L125\n interpolator.format = (value, format, lng, formatOpts) => {\n if (format) {\n return originalFormat(value, format, lng, formatOpts);\n }\n return formatHook?.(value, format, lng, formatOpts) ?? value;\n };\n\n return new JsxInterpolator(\n // Using a random marker to ensure it can't be misused\n Math.random().toString(36).substring(2, 8),\n hook => {\n formatHook = hook;\n },\n );\n }\n\n private constructor(\n marker: string,\n setFormatHook: (hook: FormatFunction) => void,\n ) {\n this.#setFormatHook = setFormatHook;\n this.#marker = marker;\n this.#pattern = new RegExp(`\\\\$${marker}\\\\(([^)]+)\\\\)`);\n }\n\n wrapT<TMessages extends { [key in string]: string }>(\n originalT: TFunction,\n ): TranslationFunction<TMessages> {\n return ((key, options) => {\n let elementsMap: Map<string, ReactNode> | undefined = undefined;\n\n // There's no way to override the format hook via the translation function\n // options, event though types indicate that it might be possible.\n // Instead, override the format function hook before every invocation and\n // rely on synchronous execution.\n this.#setFormatHook(value => {\n if (isValidElement(value)) {\n if (!elementsMap) {\n elementsMap = new Map();\n }\n const elementKey = elementsMap.size.toString();\n elementsMap.set(elementKey, value);\n\n return `$${this.#marker}(${elementKey})`;\n }\n return value;\n });\n\n // Overriding the return options is not allowed via TranslationFunction,\n // so this will always be a string\n const result = originalT(key, options as any) as unknown as string;\n if (!elementsMap) {\n return result;\n }\n\n const split = result.split(this.#pattern);\n\n return createElement(\n Fragment,\n null,\n ...split\n .map((part, index) => {\n if (index % 2 === 0) {\n return part;\n }\n return elementsMap?.get(part);\n })\n .filter(Boolean),\n );\n }) as TranslationFunction<TMessages>;\n }\n}\n\n/** @alpha */\nexport class I18nextTranslationApi implements TranslationApi {\n static create(options: I18nextTranslationApiOptions) {\n const { languages } = options.languageApi.getAvailableLanguages();\n\n const i18n = createI18n({\n fallbackLng: DEFAULT_LANGUAGE,\n supportedLngs: languages,\n interpolation: {\n escapeValue: false,\n // Used for the JsxInterpolator format hook\n alwaysFormat: true,\n },\n ns: [],\n defaultNS: false,\n fallbackNS: false,\n\n // Disable resource loading on init, meaning i18n will be ready to use immediately\n initImmediate: false,\n });\n\n i18n.init();\n if (!i18n.isInitialized) {\n throw new Error('i18next was unexpectedly not initialized');\n }\n\n const interpolator = JsxInterpolator.fromI18n(i18n);\n\n const { language: initialLanguage } = options.languageApi.getLanguage();\n if (initialLanguage !== DEFAULT_LANGUAGE) {\n i18n.changeLanguage(initialLanguage);\n }\n\n const loader = new ResourceLoader(loaded => {\n i18n.addResourceBundle(\n loaded.language,\n loaded.namespace,\n removeNulls(loaded.messages),\n false, // do not merge with existing translations\n true, // overwrite translations\n );\n });\n\n const resources = options?.resources || [];\n // Iterate in reverse, giving higher priority to resources registered later\n for (let i = resources.length - 1; i >= 0; i--) {\n const resource = resources[i];\n if (resource.$$type === '@backstage/TranslationResource') {\n loader.addTranslationResource(resource);\n } else if (resource.$$type === '@backstage/TranslationMessages') {\n // Overrides for default messages, created with createTranslationMessages and installed via app\n i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n resource.id,\n removeNulls(resource.messages),\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n }\n }\n\n const instance = new I18nextTranslationApi(\n i18n,\n loader,\n options.languageApi.getLanguage().language,\n interpolator,\n );\n\n options.languageApi.language$().subscribe(({ language }) => {\n instance.#changeLanguage(language);\n });\n\n return instance;\n }\n\n #i18n: I18n;\n #loader: ResourceLoader;\n #language: string;\n #jsxInterpolator: JsxInterpolator;\n\n /** Keep track of which refs we have registered default resources for */\n #registeredRefs = new Set<string>();\n /** Notify observers when language changes */\n #languageChangeListeners = new Set<() => void>();\n\n private constructor(\n i18n: I18n,\n loader: ResourceLoader,\n language: string,\n jsxInterpolator: JsxInterpolator,\n ) {\n this.#i18n = i18n;\n this.#loader = loader;\n this.#language = language;\n this.#jsxInterpolator = jsxInterpolator;\n }\n\n getTranslation<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return this.#createSnapshot(internalRef);\n }\n\n translation$<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): Observable<TranslationSnapshot<TMessages>> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return new ObservableImpl<TranslationSnapshot<TMessages>>(subscriber => {\n let loadTicket = {}; // To check for stale loads\n\n const loadResource = () => {\n loadTicket = {};\n const ticket = loadTicket;\n this.#loader.load(this.#language, internalRef.id).then(\n () => {\n if (ticket === loadTicket) {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n }\n }\n },\n error => {\n if (ticket === loadTicket) {\n subscriber.error(Array.isArray(error) ? error[0] : error);\n }\n },\n );\n };\n\n const onChange = () => {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n } else {\n loadResource();\n }\n };\n\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n loadResource();\n }\n\n this.#languageChangeListeners.add(onChange);\n return () => {\n this.#languageChangeListeners.delete(onChange);\n };\n });\n }\n\n #changeLanguage(language: string): void {\n if (this.#language !== language) {\n this.#language = language;\n this.#i18n.changeLanguage(language);\n this.#languageChangeListeners.forEach(listener => listener());\n }\n }\n\n #createSnapshot<TMessages extends { [key in string]: string }>(\n internalRef: InternalTranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n return { ready: false };\n }\n\n const unwrappedT = this.#i18n.getFixedT(null, internalRef.id);\n const t = this.#jsxInterpolator.wrapT<TMessages>(unwrappedT);\n\n return {\n ready: true,\n t,\n };\n }\n\n #registerDefaults(internalRef: InternalTranslationRef): void {\n if (this.#registeredRefs.has(internalRef.id)) {\n return;\n }\n this.#registeredRefs.add(internalRef.id);\n\n const defaultMessages = internalRef.getDefaultMessages();\n this.#i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n internalRef.id,\n defaultMessages,\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n\n const defaultResource = internalRef.getDefaultResource();\n if (defaultResource) {\n this.#loader.addTranslationResource(defaultResource);\n }\n }\n}\n"],"names":["createI18n"],"mappings":";;;;;;;AAuDA,SAAS,YACP,QAAA,EACwB;AACxB,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,CAAE,MAAA;AAAA,MACvB,CAAC,CAAA,KAA6B,CAAA,CAAE,CAAC,CAAA,KAAM;AAAA;AACzC,GACF;AACF;AAOA,MAAM,cAAA,CAAe;AAAA,EAQnB,YACmB,MAAA,EAKjB;AALiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAAA,EAKhB;AAAA;AAAA,EAZH,OAAA,uBAAc,GAAA,EAAY;AAAA;AAAA,EAE1B,QAAA,uBAAe,GAAA,EAA2B;AAAA;AAAA,EAE1C,QAAA,uBAAe,GAAA,EAA+C;AAAA,EAU9D,uBAAuB,QAAA,EAA+B;AACpD,IAAA,MAAM,gBAAA,GAAmB,8BAA8B,QAAQ,CAAA;AAC/D,IAAA,KAAA,MAAW,KAAA,IAAS,iBAAiB,SAAA,EAAW;AAC9C,MAAA,MAAM,MAAM,IAAA,CAAK,aAAA,CAAc,KAAA,CAAM,QAAA,EAAU,iBAAiB,EAAE,CAAA;AAIlE,MAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AAC3B,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,KAAA,CAAM,MAAM,CAAA;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAA,CAAc,UAAkB,SAAA,EAAmB;AACjD,IAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAAA,EACjC;AAAA,EAEA,YAAA,CAAa,UAAkB,SAAA,EAAmB;AAChD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,SAAS,CAAA;AAClD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,OAAO,CAAC,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAAA,EAC9B;AAAA,EAEA,MAAM,IAAA,CAAK,QAAA,EAAkB,SAAA,EAAkC;AAC7D,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,SAAS,CAAA;AAElD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AACpC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACzB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,OAAA;AACN,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAO,QAAO,CAAE,IAAA;AAAA,MACpB,CAAA,MAAA,KAAU;AACR,QAAA,IAAA,CAAK,OAAO,EAAE,QAAA,EAAU,WAAW,QAAA,EAAU,MAAA,CAAO,UAAU,CAAA;AAC9D,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,GAAG,CAAA;AAAA,MACtB,CAAA;AAAA,MACA,CAAA,KAAA,KAAS;AACP,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,GAAG,CAAA;AACpB,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,KACF;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAC3B,IAAA,MAAM,IAAA;AAAA,EACR;AACF;AAKO,MAAM,eAAA,CAAgB;AAAA,EAClB,cAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EAET,OAAO,SAAS,IAAA,EAAY;AAC1B,IAAA,MAAM,YAAA,GAAe,KAAK,QAAA,CAAS,YAAA;AAGnC,IAAA,MAAM,iBAAiB,YAAA,CAAa,MAAA;AAEpC,IAAA,IAAI,UAAA;AAKJ,IAAA,YAAA,CAAa,MAAA,GAAS,CAAC,KAAA,EAAO,MAAA,EAAQ,KAAK,UAAA,KAAe;AACxD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAO,cAAA,CAAe,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,UAAU,CAAA;AAAA,MACtD;AACA,MAAA,OAAO,UAAA,GAAa,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAK,UAAU,CAAA,IAAK,KAAA;AAAA,IACzD,CAAA;AAEA,IAAA,OAAO,IAAI,eAAA;AAAA;AAAA,MAET,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,MACzC,CAAA,IAAA,KAAQ;AACN,QAAA,UAAA,GAAa,IAAA;AAAA,MACf;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,WAAA,CACN,QACA,aAAA,EACA;AACA,IAAA,IAAA,CAAK,cAAA,GAAiB,aAAA;AACtB,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,MAAA,CAAO,CAAA,GAAA,EAAM,MAAM,CAAA,aAAA,CAAe,CAAA;AAAA,EACxD;AAAA,EAEA,MACE,SAAA,EACgC;AAChC,IAAA,OAAQ,CAAC,KAAK,OAAA,KAAY;AACxB,MAAA,IAAI,WAAA,GAAkD,MAAA;AAMtD,MAAA,IAAA,CAAK,eAAe,CAAA,KAAA,KAAS;AAC3B,QAAA,IAAI,cAAA,CAAe,KAAK,CAAA,EAAG;AACzB,UAAA,IAAI,CAAC,WAAA,EAAa;AAChB,YAAA,WAAA,uBAAkB,GAAA,EAAI;AAAA,UACxB;AACA,UAAA,MAAM,UAAA,GAAa,WAAA,CAAY,IAAA,CAAK,QAAA,EAAS;AAC7C,UAAA,WAAA,CAAY,GAAA,CAAI,YAAY,KAAK,CAAA;AAEjC,UAAA,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,OAAO,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,CAAA;AAAA,QACvC;AACA,QAAA,OAAO,KAAA;AAAA,MACT,CAAC,CAAA;AAID,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,EAAK,OAAc,CAAA;AAC5C,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,OAAO,MAAA;AAAA,MACT;AAEA,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAExC,MAAA,OAAO,aAAA;AAAA,QACL,QAAA;AAAA,QACA,IAAA;AAAA,QACA,GAAG,KAAA,CACA,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AACpB,UAAA,IAAI,KAAA,GAAQ,MAAM,CAAA,EAAG;AACnB,YAAA,OAAO,IAAA;AAAA,UACT;AACA,UAAA,OAAO,WAAA,EAAa,IAAI,IAAI,CAAA;AAAA,QAC9B,CAAC,CAAA,CACA,MAAA,CAAO,OAAO;AAAA,OACnB;AAAA,IACF,CAAA;AAAA,EACF;AACF;AAGO,MAAM,qBAAA,CAAgD;AAAA,EAC3D,OAAO,OAAO,OAAA,EAAuC;AACnD,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,YAAY,qBAAA,EAAsB;AAEhE,IAAA,MAAM,OAAOA,cAAA,CAAW;AAAA,MACtB,WAAA,EAAa,gBAAA;AAAA,MACb,aAAA,EAAe,SAAA;AAAA,MACf,aAAA,EAAe;AAAA,QACb,WAAA,EAAa,KAAA;AAAA;AAAA,QAEb,YAAA,EAAc;AAAA,OAChB;AAAA,MACA,IAAI,EAAC;AAAA,MACL,SAAA,EAAW,KAAA;AAAA,MACX,UAAA,EAAY,KAAA;AAAA;AAAA,MAGZ,aAAA,EAAe;AAAA,KAChB,CAAA;AAED,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,MAAA,MAAM,IAAI,MAAM,0CAA0C,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,QAAA,CAAS,IAAI,CAAA;AAElD,IAAA,MAAM,EAAE,QAAA,EAAU,eAAA,EAAgB,GAAI,OAAA,CAAQ,YAAY,WAAA,EAAY;AACtE,IAAA,IAAI,oBAAoB,gBAAA,EAAkB;AACxC,MAAA,IAAA,CAAK,eAAe,eAAe,CAAA;AAAA,IACrC;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,cAAA,CAAe,CAAA,MAAA,KAAU;AAC1C,MAAA,IAAA,CAAK,iBAAA;AAAA,QACH,MAAA,CAAO,QAAA;AAAA,QACP,MAAA,CAAO,SAAA;AAAA,QACP,WAAA,CAAY,OAAO,QAAQ,CAAA;AAAA,QAC3B,KAAA;AAAA;AAAA,QACA;AAAA;AAAA,OACF;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,OAAA,EAAS,SAAA,IAAa,EAAC;AAEzC,IAAA,KAAA,IAAS,IAAI,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC9C,MAAA,MAAM,QAAA,GAAW,UAAU,CAAC,CAAA;AAC5B,MAAA,IAAI,QAAA,CAAS,WAAW,gCAAA,EAAkC;AACxD,QAAA,MAAA,CAAO,uBAAuB,QAAQ,CAAA;AAAA,MACxC,CAAA,MAAA,IAAW,QAAA,CAAS,MAAA,KAAW,gCAAA,EAAkC;AAE/D,QAAA,IAAA,CAAK,iBAAA;AAAA,UACH,gBAAA;AAAA,UACA,QAAA,CAAS,EAAA;AAAA,UACT,WAAA,CAAY,SAAS,QAAQ,CAAA;AAAA,UAC7B,IAAA;AAAA;AAAA,UACA;AAAA;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,IAAI,qBAAA;AAAA,MACnB,IAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA,CAAQ,WAAA,CAAY,WAAA,EAAY,CAAE,QAAA;AAAA,MAClC;AAAA,KACF;AAEA,IAAA,OAAA,CAAQ,YAAY,SAAA,EAAU,CAAE,UAAU,CAAC,EAAE,UAAS,KAAM;AAC1D,MAAA,QAAA,CAAS,gBAAgB,QAAQ,CAAA;AAAA,IACnC,CAAC,CAAA;AAED,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA;AAAA,EAGA,eAAA,uBAAsB,GAAA,EAAY;AAAA;AAAA,EAElC,wBAAA,uBAA+B,GAAA,EAAgB;AAAA,EAEvC,WAAA,CACN,IAAA,EACA,MAAA,EACA,QAAA,EACA,eAAA,EACA;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AACf,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAA,CAAK,gBAAA,GAAmB,eAAA;AAAA,EAC1B;AAAA,EAEA,eACE,cAAA,EACgC;AAChC,IAAA,MAAM,WAAA,GAAc,yBAAyB,cAAc,CAAA;AAE3D,IAAA,IAAA,CAAK,kBAAkB,WAAW,CAAA;AAElC,IAAA,OAAO,IAAA,CAAK,gBAAgB,WAAW,CAAA;AAAA,EACzC;AAAA,EAEA,aACE,cAAA,EAC4C;AAC5C,IAAA,MAAM,WAAA,GAAc,yBAAyB,cAAc,CAAA;AAE3D,IAAA,IAAA,CAAK,kBAAkB,WAAW,CAAA;AAElC,IAAA,OAAO,IAAI,eAA+C,CAAA,UAAA,KAAc;AACtE,MAAA,IAAI,aAAa,EAAC;AAElB,MAAA,MAAM,eAAe,MAAM;AACzB,QAAA,UAAA,GAAa,EAAC;AACd,QAAA,MAAM,MAAA,GAAS,UAAA;AACf,QAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,WAAA,CAAY,EAAE,CAAA,CAAE,IAAA;AAAA,UAChD,MAAM;AACJ,YAAA,IAAI,WAAW,UAAA,EAAY;AACzB,cAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,WAAW,CAAA;AACjD,cAAA,IAAI,SAAS,KAAA,EAAO;AAClB,gBAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,cAC1B;AAAA,YACF;AAAA,UACF,CAAA;AAAA,UACA,CAAA,KAAA,KAAS;AACP,YAAA,IAAI,WAAW,UAAA,EAAY;AACzB,cAAA,UAAA,CAAW,KAAA,CAAM,MAAM,OAAA,CAAQ,KAAK,IAAI,KAAA,CAAM,CAAC,IAAI,KAAK,CAAA;AAAA,YAC1D;AAAA,UACF;AAAA,SACF;AAAA,MACF,CAAA;AAEA,MAAA,MAAM,WAAW,MAAM;AACrB,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,WAAW,CAAA;AACjD,QAAA,IAAI,SAAS,KAAA,EAAO;AAClB,UAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,QAC1B,CAAA,MAAO;AACL,UAAA,YAAA,EAAa;AAAA,QACf;AAAA,MACF,CAAA;AAEA,MAAA,IAAI,KAAK,OAAA,CAAQ,YAAA,CAAa,KAAK,SAAA,EAAW,WAAA,CAAY,EAAE,CAAA,EAAG;AAC7D,QAAA,YAAA,EAAa;AAAA,MACf;AAEA,MAAA,IAAA,CAAK,wBAAA,CAAyB,IAAI,QAAQ,CAAA;AAC1C,MAAA,OAAO,MAAM;AACX,QAAA,IAAA,CAAK,wBAAA,CAAyB,OAAO,QAAQ,CAAA;AAAA,MAC/C,CAAA;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,gBAAgB,QAAA,EAAwB;AACtC,IAAA,IAAI,IAAA,CAAK,cAAc,QAAA,EAAU;AAC/B,MAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,MAAA,IAAA,CAAK,KAAA,CAAM,eAAe,QAAQ,CAAA;AAClC,MAAA,IAAA,CAAK,wBAAA,CAAyB,OAAA,CAAQ,CAAA,QAAA,KAAY,QAAA,EAAU,CAAA;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,gBACE,WAAA,EACgC;AAChC,IAAA,IAAI,KAAK,OAAA,CAAQ,YAAA,CAAa,KAAK,SAAA,EAAW,WAAA,CAAY,EAAE,CAAA,EAAG;AAC7D,MAAA,OAAO,EAAE,OAAO,KAAA,EAAM;AAAA,IACxB;AAEA,IAAA,MAAM,aAAa,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,IAAA,EAAM,YAAY,EAAE,CAAA;AAC5D,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,gBAAA,CAAiB,KAAA,CAAiB,UAAU,CAAA;AAE3D,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA;AAAA,MACP;AAAA,KACF;AAAA,EACF;AAAA,EAEA,kBAAkB,WAAA,EAA2C;AAC3D,IAAA,IAAI,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,WAAA,CAAY,EAAE,CAAA,EAAG;AAC5C,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,WAAA,CAAY,EAAE,CAAA;AAEvC,IAAA,MAAM,eAAA,GAAkB,YAAY,kBAAA,EAAmB;AACvD,IAAA,IAAA,CAAK,KAAA,CAAM,iBAAA;AAAA,MACT,gBAAA;AAAA,MACA,WAAA,CAAY,EAAA;AAAA,MACZ,eAAA;AAAA,MACA,IAAA;AAAA;AAAA,MACA;AAAA;AAAA,KACF;AAEA,IAAA,MAAM,eAAA,GAAkB,YAAY,kBAAA,EAAmB;AACvD,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,IAAA,CAAK,OAAA,CAAQ,uBAAuB,eAAe,CAAA;AAAA,IACrD;AAAA,EACF;AACF;;;;"}
1
+ {"version":3,"file":"I18nextTranslationApi.esm.js","sources":["../../../../../../../../../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi.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 AppLanguageApi,\n TranslationApi,\n TranslationFunction,\n TranslationMessages,\n TranslationRef,\n TranslationResource,\n TranslationSnapshot,\n} from '@backstage/core-plugin-api/alpha';\nimport {\n createInstance as createI18n,\n FormatFunction,\n Interpolator,\n TFunction,\n type i18n as I18n,\n} from 'i18next';\nimport ObservableImpl from 'zen-observable';\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 {\n toInternalTranslationResource,\n InternalTranslationResourceLoader,\n} from '../../../../../frontend-plugin-api/src/translation/TranslationResource';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport {\n toInternalTranslationRef,\n InternalTranslationRef,\n} from '../../../../../frontend-plugin-api/src/translation/TranslationRef';\nimport { Observable } from '@backstage/types';\nimport { DEFAULT_LANGUAGE } from '../AppLanguageApi/AppLanguageSelector';\nimport { createElement, Fragment, ReactNode, isValidElement } from 'react';\n\n/** @alpha */\nexport interface I18nextTranslationApiOptions {\n languageApi: AppLanguageApi;\n resources?: Array<TranslationMessages | TranslationResource>;\n}\n\nfunction removeNulls(\n messages: Record<string, string | null>,\n): Record<string, string> {\n return Object.fromEntries(\n Object.entries(messages).filter(\n (e): e is [string, string] => e[1] !== null,\n ),\n );\n}\n\n/**\n * The built-in i18next backend loading logic doesn't handle on the fly switches\n * of language very well. It gets a bit confused about whether resources are actually\n * loaded or not, so instead we implement our own resource loader.\n */\nclass ResourceLoader {\n /** Loaded resources by loader key */\n #loaded = new Set<string>();\n /** Resource loading promises by loader key */\n #loading = new Map<string, Promise<void>>();\n /** Loaders for each resource language */\n #loaders = new Map<string, InternalTranslationResourceLoader>();\n\n constructor(\n private readonly onLoad: (loaded: {\n language: string;\n namespace: string;\n messages: Record<string, string | null>;\n }) => void,\n ) {}\n\n addTranslationResource(resource: TranslationResource) {\n const internalResource = toInternalTranslationResource(resource);\n for (const entry of internalResource.resources) {\n const key = this.#getLoaderKey(entry.language, internalResource.id);\n\n // First loader to register wins, this means that resources registered in the app\n // have priority over default resource from translation refs\n if (!this.#loaders.has(key)) {\n this.#loaders.set(key, entry.loader);\n }\n }\n }\n\n #getLoaderKey(language: string, namespace: string) {\n return `${language}/${namespace}`;\n }\n\n needsLoading(language: string, namespace: string) {\n const key = this.#getLoaderKey(language, namespace);\n const loader = this.#loaders.get(key);\n if (!loader) {\n return false;\n }\n\n return !this.#loaded.has(key);\n }\n\n async load(language: string, namespace: string): Promise<void> {\n const key = this.#getLoaderKey(language, namespace);\n\n const loader = this.#loaders.get(key);\n if (!loader) {\n return;\n }\n\n if (this.#loaded.has(key)) {\n return;\n }\n\n const loading = this.#loading.get(key);\n if (loading) {\n await loading;\n return;\n }\n\n const load = loader().then(\n result => {\n this.onLoad({ language, namespace, messages: result.messages });\n this.#loaded.add(key);\n },\n error => {\n this.#loaded.add(key); // Do not try to load failed resources again\n throw error;\n },\n );\n this.#loading.set(key, load);\n await load;\n }\n}\n\n/**\n * A helper for implementing JSX interpolation\n */\nexport class JsxInterpolator {\n readonly #setFormatHook: (hook: FormatFunction) => void;\n readonly #marker: string;\n readonly #pattern: RegExp;\n\n static fromI18n(i18n: I18n) {\n const interpolator = i18n.services.interpolator as Interpolator & {\n format: FormatFunction;\n };\n const originalFormat = interpolator.format;\n\n let formatHook: FormatFunction | undefined;\n\n // This is the only way to override the format function of the interpolator\n // without overriding the default formatters. See the behavior here:\n // https://github.com/i18next/i18next/blob/c633121e57e2b6024080142d78027842bf2a6e5e/src/i18next.js#L120-L125\n interpolator.format = (value, format, lng, formatOpts) => {\n if (format) {\n return originalFormat(value, format, lng, formatOpts);\n }\n return formatHook?.(value, format, lng, formatOpts) ?? value;\n };\n\n return new JsxInterpolator(\n // Using a random marker to ensure it can't be misused\n Math.random().toString(36).substring(2, 8),\n hook => {\n formatHook = hook;\n },\n );\n }\n\n private constructor(\n marker: string,\n setFormatHook: (hook: FormatFunction) => void,\n ) {\n this.#setFormatHook = setFormatHook;\n this.#marker = marker;\n this.#pattern = new RegExp(`\\\\$${marker}\\\\(([^)]+)\\\\)`);\n }\n\n wrapT<TMessages extends { [key in string]: string }>(\n originalT: TFunction,\n ): TranslationFunction<TMessages> {\n return ((key, options) => {\n let elementsMap: Map<string, ReactNode> | undefined = undefined;\n\n // There's no way to override the format hook via the translation function\n // options, event though types indicate that it might be possible.\n // Instead, override the format function hook before every invocation and\n // rely on synchronous execution.\n this.#setFormatHook(value => {\n if (isValidElement(value)) {\n if (!elementsMap) {\n elementsMap = new Map();\n }\n const elementKey = elementsMap.size.toString();\n elementsMap.set(elementKey, value);\n\n return `$${this.#marker}(${elementKey})`;\n }\n return value;\n });\n\n // Overriding the return options is not allowed via TranslationFunction,\n // so this will always be a string\n const result = originalT(key, options as any) as unknown as string;\n if (!elementsMap) {\n return result;\n }\n\n const split = result.split(this.#pattern);\n\n return createElement(\n Fragment,\n null,\n ...split\n .map((part, index) => {\n if (index % 2 === 0) {\n return part;\n }\n return elementsMap?.get(part);\n })\n .filter(Boolean),\n );\n }) as TranslationFunction<TMessages>;\n }\n}\n\n/** @alpha */\nexport class I18nextTranslationApi implements TranslationApi {\n static create(options: I18nextTranslationApiOptions) {\n const { languages } = options.languageApi.getAvailableLanguages();\n\n const i18n = createI18n({\n fallbackLng: DEFAULT_LANGUAGE,\n supportedLngs: languages,\n interpolation: {\n escapeValue: false,\n // Used for the JsxInterpolator format hook\n alwaysFormat: true,\n },\n ns: [],\n defaultNS: false,\n fallbackNS: false,\n\n // Disable resource loading on init, meaning i18n will be ready to use immediately\n initImmediate: false,\n });\n\n i18n.init();\n if (!i18n.isInitialized) {\n throw new Error('i18next was unexpectedly not initialized');\n }\n\n const interpolator = JsxInterpolator.fromI18n(i18n);\n\n const { language: initialLanguage } = options.languageApi.getLanguage();\n if (initialLanguage !== DEFAULT_LANGUAGE) {\n i18n.changeLanguage(initialLanguage);\n }\n\n const loader = new ResourceLoader(loaded => {\n i18n.addResourceBundle(\n loaded.language,\n loaded.namespace,\n removeNulls(loaded.messages),\n false, // do not merge with existing translations\n true, // overwrite translations\n );\n });\n\n const resources = options?.resources || [];\n // Iterate in reverse, giving higher priority to resources registered later\n for (let i = resources.length - 1; i >= 0; i--) {\n const resource = resources[i];\n if (resource.$$type === '@backstage/TranslationResource') {\n loader.addTranslationResource(resource);\n } else if (resource.$$type === '@backstage/TranslationMessages') {\n // Overrides for default messages, created with createTranslationMessages and installed via app\n i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n resource.id,\n removeNulls(resource.messages),\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n }\n }\n\n const instance = new I18nextTranslationApi(\n i18n,\n loader,\n options.languageApi.getLanguage().language,\n interpolator,\n );\n\n options.languageApi.language$().subscribe(({ language }) => {\n instance.#changeLanguage(language);\n });\n\n return instance;\n }\n\n #i18n: I18n;\n #loader: ResourceLoader;\n #language: string;\n #jsxInterpolator: JsxInterpolator;\n\n /** Keep track of which refs we have registered default resources for */\n #registeredRefs = new Set<string>();\n /** Notify observers when language changes */\n #languageChangeListeners = new Set<() => void>();\n\n private constructor(\n i18n: I18n,\n loader: ResourceLoader,\n language: string,\n jsxInterpolator: JsxInterpolator,\n ) {\n this.#i18n = i18n;\n this.#loader = loader;\n this.#language = language;\n this.#jsxInterpolator = jsxInterpolator;\n }\n\n getTranslation<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return this.#createSnapshot(internalRef);\n }\n\n translation$<TMessages extends { [key in string]: string }>(\n translationRef: TranslationRef<string, TMessages>,\n ): Observable<TranslationSnapshot<TMessages>> {\n const internalRef = toInternalTranslationRef(translationRef);\n\n this.#registerDefaults(internalRef);\n\n return new ObservableImpl<TranslationSnapshot<TMessages>>(subscriber => {\n let loadTicket = {}; // To check for stale loads\n\n const loadResource = () => {\n loadTicket = {};\n const ticket = loadTicket;\n this.#loader.load(this.#language, internalRef.id).then(\n () => {\n if (ticket === loadTicket) {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n }\n }\n },\n error => {\n if (ticket === loadTicket) {\n subscriber.error(Array.isArray(error) ? error[0] : error);\n }\n },\n );\n };\n\n const onChange = () => {\n const snapshot = this.#createSnapshot(internalRef);\n if (snapshot.ready) {\n subscriber.next(snapshot);\n } else {\n loadResource();\n }\n };\n\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n loadResource();\n }\n\n this.#languageChangeListeners.add(onChange);\n return () => {\n this.#languageChangeListeners.delete(onChange);\n };\n });\n }\n\n #changeLanguage(language: string): void {\n if (this.#language !== language) {\n this.#language = language;\n this.#i18n.changeLanguage(language);\n this.#languageChangeListeners.forEach(listener => listener());\n }\n }\n\n #createSnapshot<TMessages extends { [key in string]: string }>(\n internalRef: InternalTranslationRef<string, TMessages>,\n ): TranslationSnapshot<TMessages> {\n if (this.#loader.needsLoading(this.#language, internalRef.id)) {\n return { ready: false };\n }\n\n const unwrappedT = this.#i18n.getFixedT(null, internalRef.id);\n const t = this.#jsxInterpolator.wrapT<TMessages>(unwrappedT);\n\n return {\n ready: true,\n t,\n };\n }\n\n #registerDefaults(internalRef: InternalTranslationRef): void {\n if (this.#registeredRefs.has(internalRef.id)) {\n return;\n }\n this.#registeredRefs.add(internalRef.id);\n\n const defaultMessages = internalRef.getDefaultMessages();\n this.#i18n.addResourceBundle(\n DEFAULT_LANGUAGE,\n internalRef.id,\n defaultMessages,\n true, // merge with existing translations\n false, // do not overwrite translations\n );\n\n const defaultResource = internalRef.getDefaultResource();\n if (defaultResource) {\n this.#loader.addTranslationResource(defaultResource);\n }\n }\n}\n"],"names":["createI18n"],"mappings":"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"}
@@ -1 +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"}
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 ExtensionDefinitionAttachTo,\n ExtensionDataValue,\n ExtensionDataRef,\n OverridableExtensionDefinition,\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: OverridableExtensionDefinition<ExtensionDefinitionParameters>;\n versions:\n | {\n readonly version: 'v1';\n readonly kind?: string;\n readonly namespace?: string;\n readonly name?: string;\n readonly attachTo: ExtensionDefinitionAttachTo;\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: ExtensionDefinitionAttachTo;\n readonly disabled: boolean;\n readonly configSchema?: PortableSchema<any, any>;\n readonly inputs: { [inputName in string]: ExtensionInput };\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 }>;\n }): Iterable<ExtensionDataValue<any, any>>;\n };\n}>({\n type: '@backstage/ExtensionDefinition',\n versions: ['v1', 'v2'],\n});\n"],"names":[],"mappings":";;AA8ByC,WAAW,MAAA,CAqDjD;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/ExtensionInput",
5
+ versions: [void 0]
6
+ });
7
+ //# sourceMappingURL=InternalExtensionInput.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InternalExtensionInput.esm.js","sources":["../../../../../../../packages/frontend-internal/src/wiring/InternalExtensionInput.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 { ExtensionInput } from '@backstage/frontend-plugin-api';\nimport { OpaqueType } from '@internal/opaque';\n\nexport type ExtensionInputContext = {\n input: string;\n kind?: string;\n name?: string;\n};\n\nexport const OpaqueExtensionInput = OpaqueType.create<{\n public: ExtensionInput;\n versions: {\n readonly version: undefined;\n readonly context?: ExtensionInputContext;\n withContext?(context: ExtensionInputContext): ExtensionInput;\n };\n}>({\n type: '@backstage/ExtensionInput',\n versions: [undefined],\n});\n"],"names":[],"mappings":";;AAyBoC,WAAW,MAAA,CAO5C;AAAA,EACD,IAAA,EAAM,2BAAA;AAAA,EACN,QAAA,EAAU,CAAC,MAAS;AACtB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslationRef.esm.js","sources":["../../../../../../../packages/frontend-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/** @public */\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/** @public */\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/** @public */\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;;;;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslationResource.esm.js","sources":["../../../../../../../packages/frontend-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 { TranslationMessages } from './TranslationMessages';\nimport { TranslationRef } from './TranslationRef';\n\n/** @public */\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/** @public */\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/** @public */\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":"AAyCO,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,5 +1,5 @@
1
1
  var name = "@backstage/plugin-app";
2
- var version = "0.3.2-next.0";
2
+ var version = "0.3.3-next.0";
3
3
  var backstage = {
4
4
  role: "frontend-plugin",
5
5
  pluginId: "app",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-app",
3
- "version": "0.3.2-next.0",
3
+ "version": "0.3.3-next.0",
4
4
  "backstage": {
5
5
  "role": "frontend-plugin",
6
6
  "pluginId": "app",
@@ -62,12 +62,12 @@
62
62
  "test": "backstage-cli package test"
63
63
  },
64
64
  "dependencies": {
65
- "@backstage/core-components": "0.18.3-next.0",
66
- "@backstage/core-plugin-api": "1.11.2-next.0",
67
- "@backstage/frontend-plugin-api": "0.12.2-next.0",
68
- "@backstage/integration-react": "1.2.12-next.0",
69
- "@backstage/plugin-permission-react": "0.4.38-next.0",
70
- "@backstage/theme": "0.7.0",
65
+ "@backstage/core-components": "0.18.4-next.0",
66
+ "@backstage/core-plugin-api": "1.12.1-next.0",
67
+ "@backstage/frontend-plugin-api": "0.13.2-next.0",
68
+ "@backstage/integration-react": "1.2.13-next.0",
69
+ "@backstage/plugin-permission-react": "0.4.39-next.0",
70
+ "@backstage/theme": "0.7.1-next.0",
71
71
  "@backstage/types": "1.2.2",
72
72
  "@backstage/version-bridge": "1.0.11",
73
73
  "@material-ui/core": "^4.9.13",
@@ -78,11 +78,11 @@
78
78
  "zod": "^3.22.4"
79
79
  },
80
80
  "devDependencies": {
81
- "@backstage/cli": "0.34.5-next.0",
82
- "@backstage/dev-utils": "1.1.17-next.0",
83
- "@backstage/frontend-defaults": "0.3.3-next.0",
84
- "@backstage/frontend-test-utils": "0.4.1-next.0",
85
- "@backstage/test-utils": "1.7.13-next.0",
81
+ "@backstage/cli": "0.34.6-next.0",
82
+ "@backstage/dev-utils": "1.1.18-next.0",
83
+ "@backstage/frontend-defaults": "0.3.4-next.0",
84
+ "@backstage/frontend-test-utils": "0.4.2-next.0",
85
+ "@backstage/test-utils": "1.7.14-next.0",
86
86
  "@testing-library/jest-dom": "^6.0.0",
87
87
  "@testing-library/react": "^16.0.0",
88
88
  "@testing-library/user-event": "^14.0.0",
@@ -1 +0,0 @@
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 +0,0 @@
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;;;;"}