@backstage/core-plugin-api 1.11.2-next.1 → 1.12.1-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.
Files changed (65) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/alpha.d.ts +1 -403
  3. package/dist/alpha.esm.js +1 -6
  4. package/dist/alpha.esm.js.map +1 -1
  5. package/dist/analytics/useAnalytics.esm.js +1 -12
  6. package/dist/analytics/useAnalytics.esm.js.map +1 -1
  7. package/dist/apis/definitions/AnalyticsApi.esm.js +1 -4
  8. package/dist/apis/definitions/AnalyticsApi.esm.js.map +1 -1
  9. package/dist/app/useApp.esm.js +104 -1
  10. package/dist/app/useApp.esm.js.map +1 -1
  11. package/dist/extensions/useElementFilter.esm.js +1 -12
  12. package/dist/extensions/useElementFilter.esm.js.map +1 -1
  13. package/dist/index.d.ts +75 -1122
  14. package/dist/index.esm.js +1 -14
  15. package/dist/index.esm.js.map +1 -1
  16. package/dist/routing/ExternalRouteRef.esm.js +28 -0
  17. package/dist/routing/ExternalRouteRef.esm.js.map +1 -1
  18. package/dist/routing/RouteRef.esm.js +29 -0
  19. package/dist/routing/RouteRef.esm.js.map +1 -1
  20. package/dist/routing/SubRouteRef.esm.js +13 -0
  21. package/dist/routing/SubRouteRef.esm.js.map +1 -1
  22. package/dist/routing/types.esm.js.map +1 -1
  23. package/dist/routing/useRouteRef.esm.js +33 -8
  24. package/dist/routing/useRouteRef.esm.js.map +1 -1
  25. package/package.json +8 -6
  26. package/dist/apis/definitions/AlertApi.esm.js +0 -11
  27. package/dist/apis/definitions/AlertApi.esm.js.map +0 -1
  28. package/dist/apis/definitions/AppLanguageApi.esm.js +0 -8
  29. package/dist/apis/definitions/AppLanguageApi.esm.js.map +0 -1
  30. package/dist/apis/definitions/AppThemeApi.esm.js +0 -11
  31. package/dist/apis/definitions/AppThemeApi.esm.js.map +0 -1
  32. package/dist/apis/definitions/ConfigApi.esm.js +0 -11
  33. package/dist/apis/definitions/ConfigApi.esm.js.map +0 -1
  34. package/dist/apis/definitions/DiscoveryApi.esm.js +0 -11
  35. package/dist/apis/definitions/DiscoveryApi.esm.js.map +0 -1
  36. package/dist/apis/definitions/ErrorApi.esm.js +0 -11
  37. package/dist/apis/definitions/ErrorApi.esm.js.map +0 -1
  38. package/dist/apis/definitions/FeatureFlagsApi.esm.js +0 -21
  39. package/dist/apis/definitions/FeatureFlagsApi.esm.js.map +0 -1
  40. package/dist/apis/definitions/FetchApi.esm.js +0 -11
  41. package/dist/apis/definitions/FetchApi.esm.js.map +0 -1
  42. package/dist/apis/definitions/IdentityApi.esm.js +0 -11
  43. package/dist/apis/definitions/IdentityApi.esm.js.map +0 -1
  44. package/dist/apis/definitions/OAuthRequestApi.esm.js +0 -11
  45. package/dist/apis/definitions/OAuthRequestApi.esm.js.map +0 -1
  46. package/dist/apis/definitions/StorageApi.esm.js +0 -11
  47. package/dist/apis/definitions/StorageApi.esm.js.map +0 -1
  48. package/dist/apis/definitions/TranslationApi.esm.js +0 -8
  49. package/dist/apis/definitions/TranslationApi.esm.js.map +0 -1
  50. package/dist/apis/definitions/auth.esm.js +0 -51
  51. package/dist/apis/definitions/auth.esm.js.map +0 -1
  52. package/dist/apis/system/ApiRef.esm.js +0 -27
  53. package/dist/apis/system/ApiRef.esm.js.map +0 -1
  54. package/dist/apis/system/helpers.esm.js +0 -13
  55. package/dist/apis/system/helpers.esm.js.map +0 -1
  56. package/dist/apis/system/useApi.esm.js +0 -50
  57. package/dist/apis/system/useApi.esm.js.map +0 -1
  58. package/dist/translation/TranslationMessages.esm.js +0 -11
  59. package/dist/translation/TranslationMessages.esm.js.map +0 -1
  60. package/dist/translation/TranslationRef.esm.js +0 -62
  61. package/dist/translation/TranslationRef.esm.js.map +0 -1
  62. package/dist/translation/TranslationResource.esm.js +0 -21
  63. package/dist/translation/TranslationResource.esm.js.map +0 -1
  64. package/dist/translation/useTranslationRef.esm.js +0 -84
  65. package/dist/translation/useTranslationRef.esm.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/core-plugin-api
2
2
 
3
+ ## 1.12.1-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 358c6f7: The `useApp` and `useRouteRef` functions are now forwards compatible with the new frontend system. Along with the previous route reference changes this means that there is no longer a need to use `compatWrapper` from `@backstage/core-compat-api` to make code based on `@backstage/core-plugin-api` compatible with `@backstage/frontend-plugin-api` APIs.
8
+ - 97cd16f: Reversed the relationship between the old `@backstage/core-plugin-api` and the new `@backstage/frontend-plugin-api`. Previously, the a lot of API definitions and utilities where defined in the old and re-exported from the old, but this change flips that around so that they now reside in the new package and are re-exported from the old. The external API of both packages remain the same, but this is a step towards being able to add further compatibility with the new frontend system built into the old.
9
+ - Updated dependencies
10
+ - @backstage/frontend-plugin-api@0.13.2-next.0
11
+ - @backstage/config@1.3.6
12
+ - @backstage/errors@1.2.7
13
+ - @backstage/types@1.2.2
14
+ - @backstage/version-bridge@1.0.11
15
+
16
+ ## 1.12.0
17
+
18
+ ### Minor Changes
19
+
20
+ - 83439b1: All route references are now forwards compatible with the new frontend system, i.e. `@backstage/frontend-plugin-api`. This means they no longer need to be converted with `convertLegacyRouteRef` or `convertLegacyRouteRefs` from `@backstage/core-compat-api`.
21
+
22
+ ### Patch Changes
23
+
24
+ - b2bef92: Convert all enums to erasable-syntax compliant patterns
25
+ - 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility.
26
+ - Updated dependencies
27
+ - @backstage/config@1.3.6
28
+
3
29
  ## 1.11.2-next.1
4
30
 
5
31
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -1,403 +1 @@
1
- import { TranslationRef as TranslationRef$1, TranslationMessages as TranslationMessages$1 } from '@backstage/core-plugin-api/alpha';
2
- import { ApiRef } from '@backstage/core-plugin-api';
3
- import { Expand, ExpandRecursive, Observable } from '@backstage/types';
4
- import { JSX } from 'react';
5
-
6
- /**
7
- * Represents a collection of messages to be provided for a given translation ref.
8
- *
9
- * @alpha
10
- * @remarks
11
- *
12
- * This collection of messages can either be used directly as an override for the
13
- * default messages, or it can be used to provide translations for a language by
14
- * by being referenced by a {@link TranslationResource}.
15
- */
16
- interface TranslationMessages<TId extends string = string, TMessages extends {
17
- [key in string]: string;
18
- } = {
19
- [key in string]: string;
20
- }, TFull extends boolean = boolean> {
21
- $$type: '@backstage/TranslationMessages';
22
- /** The ID of the translation ref that these messages are for */
23
- id: TId;
24
- /** Whether or not these messages override all known messages */
25
- full: TFull;
26
- /** The messages provided for the given translation ref */
27
- messages: TMessages;
28
- }
29
- /**
30
- * Options for {@link createTranslationMessages}.
31
- *
32
- * @alpha
33
- */
34
- interface TranslationMessagesOptions<TId extends string, TMessages extends {
35
- [key in string]: string;
36
- }, TFull extends boolean> {
37
- ref: TranslationRef$1<TId, TMessages>;
38
- full?: TFull;
39
- messages: false extends TFull ? {
40
- [key in keyof TMessages]?: string | null;
41
- } : {
42
- [key in keyof TMessages]: string | null;
43
- };
44
- }
45
- /**
46
- * Creates a collection of messages for a given translation ref.
47
- *
48
- * @alpha
49
- */
50
- declare function createTranslationMessages<TId extends string, TMessages extends {
51
- [key in string]: string;
52
- }, TFull extends boolean>(options: TranslationMessagesOptions<TId, TMessages, TFull>): TranslationMessages<TId, TMessages, TFull>;
53
-
54
- /** @alpha */
55
- interface TranslationResource<TId extends string = string> {
56
- $$type: '@backstage/TranslationResource';
57
- id: TId;
58
- }
59
- /** @alpha */
60
- interface TranslationResourceOptions<TId extends string, TMessages extends {
61
- [key in string]: string;
62
- }, TTranslations extends {
63
- [language in string]: () => Promise<{
64
- default: TranslationMessages$1<TId> | {
65
- [key in keyof TMessages]: string | null;
66
- };
67
- }>;
68
- }> {
69
- ref: TranslationRef$1<TId, TMessages>;
70
- translations: TTranslations;
71
- }
72
- /** @alpha */
73
- declare function createTranslationResource<TId extends string, TMessages extends {
74
- [key in string]: string;
75
- }, TTranslations extends {
76
- [language in string]: () => Promise<{
77
- default: TranslationMessages$1<TId> | {
78
- [key in keyof TMessages]: string | null;
79
- };
80
- }>;
81
- }>(options: TranslationResourceOptions<TId, TMessages, TTranslations>): TranslationResource<TId>;
82
-
83
- /** @alpha */
84
- interface TranslationRef<TId extends string = string, TMessages extends {
85
- [key in string]: string;
86
- } = {
87
- [key in string]: string;
88
- }> {
89
- $$type: '@backstage/TranslationRef';
90
- id: TId;
91
- T: TMessages;
92
- }
93
- /** @ignore */
94
- type AnyNestedMessages = {
95
- [key in string]: AnyNestedMessages | string;
96
- };
97
- /**
98
- * Flattens a nested message declaration into a flat object with dot-separated keys.
99
- *
100
- * @ignore
101
- */
102
- type FlattenedMessages<TMessages extends AnyNestedMessages> = {
103
- [TKey in keyof TMessages]: (_: TMessages[TKey] extends infer TValue ? TValue extends AnyNestedMessages ? FlattenedMessages<TValue> extends infer TNested ? {
104
- [TNestedKey in keyof TNested as `${TKey & string}.${TNestedKey & string}`]: TNested[TNestedKey];
105
- } : never : {
106
- [_ in TKey]: TValue;
107
- } : never) => void;
108
- }[keyof TMessages] extends (_: infer TIntersection) => void ? {
109
- readonly [TExpandKey in keyof TIntersection]: TIntersection[TExpandKey];
110
- } : never;
111
- /** @alpha */
112
- interface TranslationRefOptions<TId extends string, TNestedMessages extends AnyNestedMessages, TTranslations extends {
113
- [language in string]: () => Promise<{
114
- default: {
115
- [key in keyof FlattenedMessages<TNestedMessages>]: string | null;
116
- };
117
- }>;
118
- }> {
119
- id: TId;
120
- messages: TNestedMessages;
121
- translations?: TTranslations;
122
- }
123
- /** @alpha */
124
- declare function createTranslationRef<TId extends string, const TNestedMessages extends AnyNestedMessages, TTranslations extends {
125
- [language in string]: () => Promise<{
126
- default: {
127
- [key in keyof FlattenedMessages<TNestedMessages>]: string | null;
128
- };
129
- }>;
130
- }>(config: TranslationRefOptions<TId, TNestedMessages, TTranslations>): TranslationRef<TId, FlattenedMessages<TNestedMessages>>;
131
-
132
- /**
133
- * Base translation options.
134
- *
135
- * @alpha
136
- */
137
- interface BaseOptions {
138
- interpolation?: {
139
- /** Whether to HTML escape provided values, defaults to false */
140
- escapeValue?: boolean;
141
- };
142
- }
143
- /**
144
- * All pluralization suffixes supported by i18next
145
- *
146
- * @ignore
147
- */
148
- type TranslationPlural = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
149
- /**
150
- * A mapping of i18n formatting types to their corresponding types and options.
151
- * @ignore
152
- */
153
- type I18nextFormatMap = {
154
- number: {
155
- type: number;
156
- options: Intl.NumberFormatOptions;
157
- };
158
- currency: {
159
- type: number;
160
- options: Intl.NumberFormatOptions;
161
- };
162
- datetime: {
163
- type: Date;
164
- options: Intl.DateTimeFormatOptions;
165
- };
166
- relativetime: {
167
- type: number;
168
- options: {
169
- range?: Intl.RelativeTimeFormatUnit;
170
- } & Intl.RelativeTimeFormatOptions;
171
- };
172
- list: {
173
- type: string[];
174
- options: Intl.ListFormatOptions;
175
- };
176
- };
177
- /**
178
- * Extracts all pluralized keys from the message map.
179
- *
180
- * @example
181
- * ```
182
- * { foo: 'foo', bar_one: 'bar', bar_other: 'bars' } -> 'bar'
183
- * ```
184
- *
185
- * @ignore
186
- */
187
- type PluralKeys<TMessages extends {
188
- [key in string]: string;
189
- }> = {
190
- [Key in keyof TMessages]: Key extends `${infer K}_${TranslationPlural}` ? K : never;
191
- }[keyof TMessages];
192
- /**
193
- * Collapses a message map into normalized keys with union values.
194
- *
195
- * @example
196
- * ```
197
- * { foo_one: 'foo', foo_other: 'foos' } -> { foo: 'foo' | 'foos' }
198
- * ```
199
- *
200
- * @ignore
201
- */
202
- type CollapsedMessages<TMessages extends {
203
- [key in string]: string;
204
- }> = {
205
- [key in keyof TMessages as key extends `${infer K}_${TranslationPlural}` ? K : key]: TMessages[key];
206
- };
207
- /**
208
- * Trim away whitespace
209
- *
210
- * @ignore
211
- */
212
- type Trim<T> = T extends ` ${infer U}` ? Trim<U> : T extends `${infer U} ` ? Trim<U> : T;
213
- /**
214
- * Extracts the key and format from a replacement string.
215
- *
216
- * @example
217
- * ```
218
- * 'foo, number' -> { foo: number }, 'foo' -> { foo: undefined }
219
- * ```
220
- */
221
- type ExtractFormat<Replacement extends string> = Replacement extends `${infer Key},${infer FullFormat}` ? {
222
- [key in Trim<Key>]: Lowercase<Trim<FullFormat extends `${infer Format}(${string})${string}` ? Format : FullFormat>>;
223
- } : {
224
- [key in Trim<Replacement>]: undefined;
225
- };
226
- /**
227
- * Expand the keys in a flat map to nested objects.
228
- *
229
- * @example
230
- * ```
231
- * { 'a.b': 'foo', 'a.c': 'bar' } -> { a: { b: 'foo', c: 'bar' }
232
- * ```
233
- *
234
- * @ignore
235
- */
236
- type ExpandKeys<TMap extends {}> = {
237
- [Key in keyof TMap as Key extends `${infer Prefix}.${string}` ? Prefix : Key]: Key extends `${string}.${infer Rest}` ? ExpandKeys<{
238
- [key in Rest]: TMap[Key];
239
- }> : TMap[Key];
240
- };
241
- /**
242
- * Extracts all option keys and their format from a message string.
243
- *
244
- * @example
245
- * ```
246
- * 'foo {{bar}} {{baz, number}}' -> { 'bar': undefined, 'baz': 'number' }
247
- * ```
248
- *
249
- * @ignore
250
- */
251
- type ReplaceFormatsFromMessage<TMessage> = TMessage extends `${string}{{${infer Replacement}}}${infer Tail}` ? ExpandKeys<ExtractFormat<Replacement>> & ReplaceFormatsFromMessage<Tail> : {};
252
- /**
253
- * Generates the replace options structure
254
- *
255
- * @ignore
256
- */
257
- type ReplaceOptionsFromFormats<TFormats extends {}, TValueType> = {
258
- [Key in keyof TFormats]: TFormats[Key] extends keyof I18nextFormatMap ? I18nextFormatMap[TFormats[Key]]['type'] : TFormats[Key] extends {} ? Expand<ReplaceOptionsFromFormats<TFormats[Key], TValueType>> : TValueType;
259
- };
260
- /**
261
- * Generates the formatParams options structure
262
- *
263
- * @ignore
264
- */
265
- type ReplaceFormatParamsFromFormats<TFormats extends {}> = {
266
- [Key in keyof TFormats]?: TFormats[Key] extends keyof I18nextFormatMap ? I18nextFormatMap[TFormats[Key]]['options'] : TFormats[Key] extends {} ? Expand<ReplaceFormatParamsFromFormats<TFormats[Key]>> : undefined;
267
- };
268
- /**
269
- * Extracts all nesting keys from a message string.
270
- *
271
- * @example
272
- * ```
273
- * 'foo $t(bar) $t(baz)' -> 'bar' | 'baz'
274
- * ```
275
- *
276
- * @ignore
277
- */
278
- type NestingKeysFromMessage<TMessage extends string> = TMessage extends `${string}$t(${infer Key})${infer Tail}` ? Trim<Key> | NestingKeysFromMessage<Tail> : never;
279
- /**
280
- * Find all referenced keys, given a starting key and the full set of messages.
281
- *
282
- * This will only discover keys up to 3 levels deep.
283
- *
284
- * @example
285
- * ```
286
- * <'x', { x: '$t(y) $t(z)', y: 'y', z: '$t(w)', w: 'w', foo: 'foo' }> -> 'x' | 'y' | 'z' | 'w'
287
- * ```
288
- *
289
- * @ignore
290
- */
291
- type NestedMessageKeys<TKey extends keyof TMessages, TMessages extends {
292
- [key in string]: string;
293
- }> = TKey | NestedMessageKeys2<NestingKeysFromMessage<TMessages[TKey]>, TMessages>;
294
- type NestedMessageKeys2<TKey extends keyof TMessages, TMessages extends {
295
- [key in string]: string;
296
- }> = TKey | NestedMessageKeys3<NestingKeysFromMessage<TMessages[TKey]>, TMessages>;
297
- type NestedMessageKeys3<TKey extends keyof TMessages, TMessages extends {
298
- [key in string]: string;
299
- }> = TKey | NestingKeysFromMessage<TMessages[TKey]>;
300
- /**
301
- * Converts a union type to an intersection type.
302
- *
303
- * @example
304
- * ```
305
- * { foo: 'foo' } | { bar: 'bar' } -> { foo: 'foo' } & { bar: 'bar' }
306
- * ```
307
- *
308
- * @ignore
309
- */
310
- type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
311
- /**
312
- * Collects different types of options into a single object
313
- *
314
- * @ignore
315
- */
316
- type CollectOptions<TCount extends {
317
- count?: number;
318
- }, TFormats extends {}, TValueType> = TCount & (keyof Omit<TFormats, 'count'> extends never ? {} : (Expand<Omit<ReplaceOptionsFromFormats<TFormats, TValueType>, 'count'>> | {
319
- replace: Expand<Omit<ReplaceOptionsFromFormats<TFormats, TValueType>, 'count'>>;
320
- }) & {
321
- formatParams?: Expand<ReplaceFormatParamsFromFormats<TFormats>>;
322
- });
323
- /**
324
- * Helper type to only require options argument if needed
325
- *
326
- * @ignore
327
- */
328
- type OptionArgs<TOptions extends {}> = keyof TOptions extends never ? [options?: Expand<BaseOptions>] : [options: Expand<BaseOptions & TOptions>];
329
- /**
330
- * @ignore
331
- */
332
- type TranslationFunctionOptions<TKeys extends keyof TMessages, // All normalized message keys to be considered, i.e. included nested ones
333
- TPluralKeys extends keyof TMessages, // All keys in the message map that are pluralized
334
- TMessages extends {
335
- [key in string]: string;
336
- }, // Collapsed message map with normalized keys and union values
337
- TValueType> = OptionArgs<Expand<CollectOptions<TKeys & TPluralKeys extends never ? {} : {
338
- count: number;
339
- }, ExpandRecursive<UnionToIntersection<ReplaceFormatsFromMessage<TMessages[TKeys]>>>, TValueType>>>;
340
- /** @alpha */
341
- type TranslationFunction<TMessages extends {
342
- [key in string]: string;
343
- }> = CollapsedMessages<TMessages> extends infer IMessages extends {
344
- [key in string]: string;
345
- } ? {
346
- /**
347
- * A translation function that returns a string.
348
- */
349
- <TKey extends keyof IMessages>(key: TKey, ...[args]: TranslationFunctionOptions<NestedMessageKeys<TKey, IMessages>, PluralKeys<TMessages>, IMessages, string>): IMessages[TKey];
350
- /**
351
- * A translation function where at least one JSX.Element has been
352
- * provided as an interpolation value, and will therefore return a
353
- * JSX.Element.
354
- */
355
- <TKey extends keyof IMessages>(key: TKey, ...[args]: TranslationFunctionOptions<NestedMessageKeys<TKey, IMessages>, PluralKeys<TMessages>, IMessages, string | JSX.Element>): JSX.Element;
356
- } : never;
357
- /** @alpha */
358
- type TranslationSnapshot<TMessages extends {
359
- [key in string]: string;
360
- }> = {
361
- ready: false;
362
- } | {
363
- ready: true;
364
- t: TranslationFunction<TMessages>;
365
- };
366
- /** @alpha */
367
- type TranslationApi = {
368
- getTranslation<TMessages extends {
369
- [key in string]: string;
370
- }>(translationRef: TranslationRef<string, TMessages>): TranslationSnapshot<TMessages>;
371
- translation$<TMessages extends {
372
- [key in string]: string;
373
- }>(translationRef: TranslationRef<string, TMessages>): Observable<TranslationSnapshot<TMessages>>;
374
- };
375
- /**
376
- * @alpha
377
- */
378
- declare const translationApiRef: ApiRef<TranslationApi>;
379
-
380
- /** @alpha */
381
- type AppLanguageApi = {
382
- getAvailableLanguages(): {
383
- languages: string[];
384
- };
385
- setLanguage(language?: string): void;
386
- getLanguage(): {
387
- language: string;
388
- };
389
- language$(): Observable<{
390
- language: string;
391
- }>;
392
- };
393
- /**
394
- * @alpha
395
- */
396
- declare const appLanguageApiRef: ApiRef<AppLanguageApi>;
397
-
398
- /** @alpha */
399
- declare const useTranslationRef: <TMessages extends { [key in string]: string; }>(translationRef: TranslationRef<string, TMessages>) => {
400
- t: TranslationFunction<TMessages>;
401
- };
402
-
403
- export { type AppLanguageApi, type TranslationApi, type TranslationFunction, type TranslationMessages, type TranslationMessagesOptions, type TranslationRef, type TranslationRefOptions, type TranslationResource, type TranslationResourceOptions, type TranslationSnapshot, appLanguageApiRef, createTranslationMessages, createTranslationRef, createTranslationResource, translationApiRef, useTranslationRef };
1
+ export { AppLanguageApi, TranslationApi, TranslationFunction, TranslationMessages, TranslationMessagesOptions, TranslationRef, TranslationRefOptions, TranslationResource, TranslationResourceOptions, TranslationSnapshot, appLanguageApiRef, createTranslationMessages, createTranslationRef, createTranslationResource, translationApiRef, useTranslationRef } from '@backstage/frontend-plugin-api';
package/dist/alpha.esm.js CHANGED
@@ -1,7 +1,2 @@
1
- export { createTranslationMessages } from './translation/TranslationMessages.esm.js';
2
- export { createTranslationResource } from './translation/TranslationResource.esm.js';
3
- export { createTranslationRef } from './translation/TranslationRef.esm.js';
4
- export { useTranslationRef } from './translation/useTranslationRef.esm.js';
5
- export { translationApiRef } from './apis/definitions/TranslationApi.esm.js';
6
- export { appLanguageApiRef } from './apis/definitions/AppLanguageApi.esm.js';
1
+ export { appLanguageApiRef, createTranslationMessages, createTranslationRef, createTranslationResource, translationApiRef, useTranslationRef } from '@backstage/frontend-plugin-api';
7
2
  //# sourceMappingURL=alpha.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,17 +1,6 @@
1
1
  import { useAnalyticsContext } from './AnalyticsContext.esm.js';
2
- import { useApi } from '../apis/system/useApi.esm.js';
3
- import '../apis/definitions/auth.esm.js';
4
- import '../apis/definitions/AlertApi.esm.js';
2
+ import { useApi } from '@backstage/frontend-plugin-api';
5
3
  import { analyticsApiRef } from '../apis/definitions/AnalyticsApi.esm.js';
6
- import '../apis/definitions/AppThemeApi.esm.js';
7
- import '../apis/definitions/ConfigApi.esm.js';
8
- import '../apis/definitions/DiscoveryApi.esm.js';
9
- import '../apis/definitions/ErrorApi.esm.js';
10
- import '../apis/definitions/FeatureFlagsApi.esm.js';
11
- import '../apis/definitions/FetchApi.esm.js';
12
- import '../apis/definitions/IdentityApi.esm.js';
13
- import '../apis/definitions/OAuthRequestApi.esm.js';
14
- import '../apis/definitions/StorageApi.esm.js';
15
4
  import { useRef } from 'react';
16
5
  import { Tracker } from './Tracker.esm.js';
17
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"useAnalytics.esm.js","sources":["../../src/analytics/useAnalytics.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useAnalyticsContext } from './AnalyticsContext';\nimport {\n analyticsApiRef,\n AnalyticsTracker,\n AnalyticsApi,\n useApi,\n} from '../apis';\nimport { useRef } from 'react';\nimport { Tracker } from './Tracker';\n\nfunction useAnalyticsApi(): AnalyticsApi {\n try {\n return useApi(analyticsApiRef);\n } catch {\n return { captureEvent: () => {} };\n }\n}\n\n/**\n * Gets a pre-configured analytics tracker.\n *\n * @public\n */\nexport function useAnalytics(): AnalyticsTracker {\n const trackerRef = useRef<Tracker | null>(null);\n const context = useAnalyticsContext();\n // Our goal is to make this API truly optional for any/all consuming code\n // (including tests). This hook runs last to ensure hook order is, as much as\n // possible, maintained.\n const analyticsApi = useAnalyticsApi();\n\n function getTracker(): Tracker {\n if (trackerRef.current === null) {\n trackerRef.current = new Tracker(analyticsApi);\n }\n return trackerRef.current;\n }\n\n const tracker = getTracker();\n // this is not ideal, but it allows to memoize the tracker\n // without explicitly set the context as dependency.\n tracker.setContext(context);\n\n return tracker;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA0BA,SAAS,eAAA,GAAgC;AACvC,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,eAAe,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,cAAc,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAClC;AACF;AAOO,SAAS,YAAA,GAAiC;AAC/C,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,UAAU,mBAAA,EAAoB;AAIpC,EAAA,MAAM,eAAe,eAAA,EAAgB;AAErC,EAAA,SAAS,UAAA,GAAsB;AAC7B,IAAA,IAAI,UAAA,CAAW,YAAY,IAAA,EAAM;AAC/B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAI,OAAA,CAAQ,YAAY,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,UAAA,CAAW,OAAA;AAAA,EACpB;AAEA,EAAA,MAAM,UAAU,UAAA,EAAW;AAG3B,EAAA,OAAA,CAAQ,WAAW,OAAO,CAAA;AAE1B,EAAA,OAAO,OAAA;AACT;;;;"}
1
+ {"version":3,"file":"useAnalytics.esm.js","sources":["../../src/analytics/useAnalytics.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useAnalyticsContext } from './AnalyticsContext';\nimport { analyticsApiRef, AnalyticsTracker, AnalyticsApi } from '../apis';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport { useRef } from 'react';\nimport { Tracker } from './Tracker';\n\nfunction useAnalyticsApi(): AnalyticsApi {\n try {\n return useApi(analyticsApiRef);\n } catch {\n return { captureEvent: () => {} };\n }\n}\n\n/**\n * Gets a pre-configured analytics tracker.\n *\n * @public\n */\nexport function useAnalytics(): AnalyticsTracker {\n const trackerRef = useRef<Tracker | null>(null);\n const context = useAnalyticsContext();\n // Our goal is to make this API truly optional for any/all consuming code\n // (including tests). This hook runs last to ensure hook order is, as much as\n // possible, maintained.\n const analyticsApi = useAnalyticsApi();\n\n function getTracker(): Tracker {\n if (trackerRef.current === null) {\n trackerRef.current = new Tracker(analyticsApi);\n }\n return trackerRef.current;\n }\n\n const tracker = getTracker();\n // this is not ideal, but it allows to memoize the tracker\n // without explicitly set the context as dependency.\n tracker.setContext(context);\n\n return tracker;\n}\n"],"names":[],"mappings":";;;;;;AAsBA,SAAS,eAAA,GAAgC;AACvC,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,eAAe,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,cAAc,MAAM;AAAA,IAAC,CAAA,EAAE;AAAA,EAClC;AACF;AAOO,SAAS,YAAA,GAAiC;AAC/C,EAAA,MAAM,UAAA,GAAa,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,UAAU,mBAAA,EAAoB;AAIpC,EAAA,MAAM,eAAe,eAAA,EAAgB;AAErC,EAAA,SAAS,UAAA,GAAsB;AAC7B,IAAA,IAAI,UAAA,CAAW,YAAY,IAAA,EAAM;AAC/B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAI,OAAA,CAAQ,YAAY,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,UAAA,CAAW,OAAA;AAAA,EACpB;AAEA,EAAA,MAAM,UAAU,UAAA,EAAW;AAG3B,EAAA,OAAA,CAAQ,WAAW,OAAO,CAAA;AAE1B,EAAA,OAAO,OAAA;AACT;;;;"}
@@ -1,7 +1,4 @@
1
- import 'react/jsx-runtime';
2
- import '@backstage/version-bridge';
3
- import '@backstage/errors';
4
- import { createApiRef } from '../system/ApiRef.esm.js';
1
+ import { createApiRef } from '@backstage/frontend-plugin-api';
5
2
 
6
3
  const analyticsApiRef = createApiRef({
7
4
  id: "core.analytics"
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsApi.esm.js","sources":["../../../src/apis/definitions/AnalyticsApi.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ApiRef, createApiRef } from '../system';\nimport { AnalyticsContextValue } from '../../analytics/types';\n\n/**\n * Represents an event worth tracking in an analytics system that could inform\n * how users of a Backstage instance are using its features.\n *\n * @public\n */\nexport type AnalyticsEvent = {\n /**\n * A string that identifies the event being tracked by the type of action the\n * event represents. Be careful not to encode extra metadata in this string\n * that should instead be placed in the Analytics Context or attributes.\n * Examples include:\n *\n * - view\n * - click\n * - filter\n * - search\n * - hover\n * - scroll\n */\n action: string;\n\n /**\n * A string that uniquely identifies the object that the action is being\n * taken on. Examples include:\n *\n * - The path of the page viewed\n * - The url of the link clicked\n * - The value that was filtered by\n * - The text that was searched for\n */\n subject: string;\n\n /**\n * An optional numeric value relevant to the event that could be aggregated\n * by analytics tools. Examples include:\n *\n * - The index or position of the clicked element in an ordered list\n * - The percentage of an element that has been scrolled through\n * - The amount of time that has elapsed since a fixed point\n * - A satisfaction score on a fixed scale\n */\n value?: number;\n\n /**\n * Optional, additional attributes (representing dimensions or metrics)\n * specific to the event that could be forwarded on to analytics systems.\n */\n attributes?: AnalyticsEventAttributes;\n\n /**\n * Contextual metadata relating to where the event was captured and by whom.\n * This could include information about the route, plugin, or extension in\n * which an event was captured.\n */\n context: AnalyticsContextValue;\n};\n\n/**\n * A structure allowing other arbitrary metadata to be provided by analytics\n * event emitters.\n *\n * @public\n */\nexport type AnalyticsEventAttributes = {\n [attribute in string]: string | boolean | number;\n};\n\n/**\n * Represents a tracker with methods that can be called to track events in a\n * configured analytics service.\n *\n * @public\n */\nexport type AnalyticsTracker = {\n captureEvent: (\n action: string,\n subject: string,\n options?: {\n value?: number;\n attributes?: AnalyticsEventAttributes;\n },\n ) => void;\n};\n\n/**\n * The Analytics API is used to track user behavior in a Backstage instance.\n *\n * @remarks\n *\n * To instrument your App or Plugin, retrieve an analytics tracker using the\n * useAnalytics() hook. This will return a pre-configured AnalyticsTracker\n * with relevant methods for instrumentation.\n *\n * @public\n */\nexport type AnalyticsApi = {\n /**\n * Primary event handler responsible for compiling and forwarding events to\n * an analytics system.\n */\n captureEvent(event: AnalyticsEvent): void;\n};\n\n/**\n * The {@link ApiRef} of {@link AnalyticsApi}.\n *\n * @public\n */\nexport const analyticsApiRef: ApiRef<AnalyticsApi> = createApiRef({\n id: 'core.analytics',\n});\n"],"names":[],"mappings":";;;;;AAgIO,MAAM,kBAAwC,YAAA,CAAa;AAAA,EAChE,EAAA,EAAI;AACN,CAAC;;;;"}
1
+ {"version":3,"file":"AnalyticsApi.esm.js","sources":["../../../src/apis/definitions/AnalyticsApi.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ApiRef, createApiRef } from '../system';\nimport { AnalyticsContextValue } from '../../analytics/types';\n\n/**\n * Represents an event worth tracking in an analytics system that could inform\n * how users of a Backstage instance are using its features.\n *\n * @public\n */\nexport type AnalyticsEvent = {\n /**\n * A string that identifies the event being tracked by the type of action the\n * event represents. Be careful not to encode extra metadata in this string\n * that should instead be placed in the Analytics Context or attributes.\n * Examples include:\n *\n * - view\n * - click\n * - filter\n * - search\n * - hover\n * - scroll\n */\n action: string;\n\n /**\n * A string that uniquely identifies the object that the action is being\n * taken on. Examples include:\n *\n * - The path of the page viewed\n * - The url of the link clicked\n * - The value that was filtered by\n * - The text that was searched for\n */\n subject: string;\n\n /**\n * An optional numeric value relevant to the event that could be aggregated\n * by analytics tools. Examples include:\n *\n * - The index or position of the clicked element in an ordered list\n * - The percentage of an element that has been scrolled through\n * - The amount of time that has elapsed since a fixed point\n * - A satisfaction score on a fixed scale\n */\n value?: number;\n\n /**\n * Optional, additional attributes (representing dimensions or metrics)\n * specific to the event that could be forwarded on to analytics systems.\n */\n attributes?: AnalyticsEventAttributes;\n\n /**\n * Contextual metadata relating to where the event was captured and by whom.\n * This could include information about the route, plugin, or extension in\n * which an event was captured.\n */\n context: AnalyticsContextValue;\n};\n\n/**\n * A structure allowing other arbitrary metadata to be provided by analytics\n * event emitters.\n *\n * @public\n */\nexport type AnalyticsEventAttributes = {\n [attribute in string]: string | boolean | number;\n};\n\n/**\n * Represents a tracker with methods that can be called to track events in a\n * configured analytics service.\n *\n * @public\n */\nexport type AnalyticsTracker = {\n captureEvent: (\n action: string,\n subject: string,\n options?: {\n value?: number;\n attributes?: AnalyticsEventAttributes;\n },\n ) => void;\n};\n\n/**\n * The Analytics API is used to track user behavior in a Backstage instance.\n *\n * @remarks\n *\n * To instrument your App or Plugin, retrieve an analytics tracker using the\n * useAnalytics() hook. This will return a pre-configured AnalyticsTracker\n * with relevant methods for instrumentation.\n *\n * @public\n */\nexport type AnalyticsApi = {\n /**\n * Primary event handler responsible for compiling and forwarding events to\n * an analytics system.\n */\n captureEvent(event: AnalyticsEvent): void;\n};\n\n/**\n * The `ApiRef` of {@link AnalyticsApi}.\n *\n * @public\n */\nexport const analyticsApiRef: ApiRef<AnalyticsApi> = createApiRef({\n id: 'core.analytics',\n});\n"],"names":[],"mappings":";;AAgIO,MAAM,kBAAwC,YAAA,CAAa;AAAA,EAChE,EAAA,EAAI;AACN,CAAC;;;;"}
@@ -1,9 +1,112 @@
1
- import { useVersionedContext } from '@backstage/version-bridge';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { getOrCreateGlobalSingleton, useVersionedContext } from '@backstage/version-bridge';
4
+ import { appTreeApiRef, iconsApiRef, Progress, NotFoundErrorPage, useApiHolder, ErrorDisplay, createFrontendPlugin } from '@backstage/frontend-plugin-api';
2
5
 
6
+ const legacyPluginStore = getOrCreateGlobalSingleton(
7
+ "legacy-plugin-compatibility-store",
8
+ () => /* @__PURE__ */ new WeakMap()
9
+ );
10
+ function toLegacyPlugin(plugin) {
11
+ let legacy = legacyPluginStore.get(plugin);
12
+ if (legacy) {
13
+ return legacy;
14
+ }
15
+ const errorMsg = "Not implemented in legacy plugin compatibility layer";
16
+ const notImplemented = () => {
17
+ throw new Error(errorMsg);
18
+ };
19
+ legacy = {
20
+ getId() {
21
+ return plugin.id;
22
+ },
23
+ get routes() {
24
+ return {};
25
+ },
26
+ get externalRoutes() {
27
+ return {};
28
+ },
29
+ getApis: notImplemented,
30
+ getFeatureFlags: notImplemented,
31
+ provide: notImplemented
32
+ };
33
+ legacyPluginStore.set(plugin, legacy);
34
+ return legacy;
35
+ }
36
+ function toNewPlugin(plugin) {
37
+ return createFrontendPlugin({
38
+ pluginId: plugin.getId()
39
+ });
40
+ }
41
+ function useOptionalApiHolder() {
42
+ try {
43
+ return useApiHolder();
44
+ } catch {
45
+ return void 0;
46
+ }
47
+ }
3
48
  const useApp = () => {
49
+ const apiHolder = useOptionalApiHolder();
50
+ const appTreeApi = apiHolder?.get(appTreeApiRef);
51
+ const iconsApi = apiHolder?.get(iconsApiRef);
4
52
  const versionedContext = useVersionedContext(
5
53
  "app-context"
6
54
  );
55
+ const newAppContext = useMemo(() => {
56
+ if (!appTreeApi) {
57
+ return void 0;
58
+ }
59
+ if (!iconsApi) {
60
+ return void 0;
61
+ }
62
+ const { tree } = appTreeApi.getTree();
63
+ let gatheredPlugins = void 0;
64
+ const ErrorBoundaryFallbackWrapper = ({ plugin, ...rest }) => /* @__PURE__ */ jsx(ErrorDisplay, { ...rest, plugin: plugin && toNewPlugin(plugin) });
65
+ return {
66
+ getPlugins() {
67
+ if (gatheredPlugins) {
68
+ return gatheredPlugins;
69
+ }
70
+ const pluginSet = /* @__PURE__ */ new Set();
71
+ for (const node of tree.nodes.values()) {
72
+ const plugin = node.spec.plugin;
73
+ if (plugin) {
74
+ pluginSet.add(toLegacyPlugin(plugin));
75
+ }
76
+ }
77
+ gatheredPlugins = Array.from(pluginSet);
78
+ return gatheredPlugins;
79
+ },
80
+ getSystemIcon(key) {
81
+ return iconsApi.getIcon(key);
82
+ },
83
+ getSystemIcons() {
84
+ return Object.fromEntries(
85
+ iconsApi.listIconKeys().map((key) => [key, iconsApi.getIcon(key)])
86
+ );
87
+ },
88
+ getComponents() {
89
+ return {
90
+ NotFoundErrorPage,
91
+ BootErrorPage() {
92
+ throw new Error(
93
+ "The BootErrorPage app component should not be accessed by plugins"
94
+ );
95
+ },
96
+ Progress,
97
+ Router() {
98
+ throw new Error(
99
+ "The Router app component should not be accessed by plugins"
100
+ );
101
+ },
102
+ ErrorBoundaryFallback: ErrorBoundaryFallbackWrapper
103
+ };
104
+ }
105
+ };
106
+ }, [appTreeApi, iconsApi]);
107
+ if (newAppContext) {
108
+ return newAppContext;
109
+ }
7
110
  if (!versionedContext) {
8
111
  throw new Error("App context is not available");
9
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useApp.esm.js","sources":["../../src/app/useApp.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useVersionedContext } from '@backstage/version-bridge';\nimport { AppContext as AppContextV1 } from './types';\n\n/**\n * React hook providing {@link AppContext}.\n *\n * @public\n */\nexport const useApp = (): AppContextV1 => {\n const versionedContext = useVersionedContext<{ 1: AppContextV1 }>(\n 'app-context',\n );\n if (!versionedContext) {\n throw new Error('App context is not available');\n }\n\n const appContext = versionedContext.atVersion(1);\n if (!appContext) {\n throw new Error('AppContext v1 not available');\n }\n return appContext;\n};\n"],"names":[],"mappings":";;AAwBO,MAAM,SAAS,MAAoB;AACxC,EAAA,MAAM,gBAAA,GAAmB,mBAAA;AAAA,IACvB;AAAA,GACF;AACA,EAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,IAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,EAChD;AAEA,EAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,SAAA,CAAU,CAAC,CAAA;AAC/C,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,UAAA;AACT;;;;"}
1
+ {"version":3,"file":"useApp.esm.js","sources":["../../src/app/useApp.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useMemo } from 'react';\nimport { useVersionedContext } from '@backstage/version-bridge';\nimport {\n appTreeApiRef,\n iconsApiRef,\n useApiHolder,\n ErrorDisplay,\n NotFoundErrorPage,\n Progress,\n createFrontendPlugin,\n FrontendPlugin,\n ApiHolder,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppComponents,\n IconComponent,\n BackstagePlugin,\n} from '@backstage/core-plugin-api';\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\nimport { AppContext as AppContextV1 } from './types';\n\nconst legacyPluginStore = getOrCreateGlobalSingleton(\n 'legacy-plugin-compatibility-store',\n () => new WeakMap<FrontendPlugin, BackstagePlugin>(),\n);\n\nfunction toLegacyPlugin(plugin: FrontendPlugin): BackstagePlugin {\n let legacy = legacyPluginStore.get(plugin);\n if (legacy) {\n return legacy;\n }\n\n const errorMsg = 'Not implemented in legacy plugin compatibility layer';\n const notImplemented = () => {\n throw new Error(errorMsg);\n };\n\n legacy = {\n getId(): string {\n return plugin.id;\n },\n get routes() {\n return {};\n },\n get externalRoutes() {\n return {};\n },\n getApis: notImplemented,\n getFeatureFlags: notImplemented,\n provide: notImplemented,\n };\n\n legacyPluginStore.set(plugin, legacy);\n return legacy;\n}\n\nfunction toNewPlugin(plugin: BackstagePlugin): FrontendPlugin {\n return createFrontendPlugin({\n pluginId: plugin.getId(),\n });\n}\n\nfunction useOptionalApiHolder(): ApiHolder | undefined {\n try {\n return useApiHolder();\n } catch {\n return undefined;\n }\n}\n\n/**\n * React hook providing {@link AppContext}.\n *\n * @public\n */\nexport const useApp = (): AppContextV1 => {\n const apiHolder = useOptionalApiHolder();\n const appTreeApi = apiHolder?.get(appTreeApiRef);\n const iconsApi = apiHolder?.get(iconsApiRef);\n const versionedContext = useVersionedContext<{ 1: AppContextV1 }>(\n 'app-context',\n );\n\n const newAppContext = useMemo<AppContextV1 | undefined>(() => {\n if (!appTreeApi) {\n return undefined;\n }\n\n if (!iconsApi) {\n return undefined;\n }\n\n const { tree } = appTreeApi.getTree();\n\n let gatheredPlugins: BackstagePlugin[] | undefined = undefined;\n\n const ErrorBoundaryFallbackWrapper: AppComponents['ErrorBoundaryFallback'] =\n ({ plugin, ...rest }) => (\n <ErrorDisplay {...rest} plugin={plugin && toNewPlugin(plugin)} />\n );\n\n return {\n getPlugins(): BackstagePlugin[] {\n if (gatheredPlugins) {\n return gatheredPlugins;\n }\n\n const pluginSet = new Set<BackstagePlugin>();\n for (const node of tree.nodes.values()) {\n const plugin = node.spec.plugin;\n if (plugin) {\n pluginSet.add(toLegacyPlugin(plugin));\n }\n }\n gatheredPlugins = Array.from(pluginSet);\n\n return gatheredPlugins;\n },\n\n getSystemIcon(key: string): IconComponent | undefined {\n return iconsApi.getIcon(key);\n },\n\n getSystemIcons(): Record<string, IconComponent> {\n return Object.fromEntries(\n iconsApi.listIconKeys().map(key => [key, iconsApi.getIcon(key)!]),\n );\n },\n\n getComponents(): AppComponents {\n return {\n NotFoundErrorPage: NotFoundErrorPage,\n BootErrorPage() {\n throw new Error(\n 'The BootErrorPage app component should not be accessed by plugins',\n );\n },\n Progress: Progress,\n Router() {\n throw new Error(\n 'The Router app component should not be accessed by plugins',\n );\n },\n ErrorBoundaryFallback: ErrorBoundaryFallbackWrapper,\n };\n },\n };\n }, [appTreeApi, iconsApi]);\n\n if (newAppContext) {\n return newAppContext;\n }\n\n if (!versionedContext) {\n throw new Error('App context is not available');\n }\n\n const appContext = versionedContext.atVersion(1);\n if (!appContext) {\n throw new Error('AppContext v1 not available');\n }\n return appContext;\n};\n"],"names":[],"mappings":"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"}