@equinor/fusion-framework-module-app 8.0.2 → 8.0.3
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 +13 -0
- package/dist/esm/AppClient.js +75 -8
- package/dist/esm/AppClient.js.map +1 -1
- package/dist/esm/AppConfig.js +9 -1
- package/dist/esm/AppConfig.js.map +1 -1
- package/dist/esm/{AppClient.Selectors.js → AppConfigSelector.js} +1 -1
- package/dist/esm/AppConfigSelector.js.map +1 -0
- package/dist/esm/AppConfigurator.js +28 -2
- package/dist/esm/AppConfigurator.js.map +1 -1
- package/dist/esm/AppModuleProvider.js +16 -0
- package/dist/esm/AppModuleProvider.js.map +1 -1
- package/dist/esm/app/App.js +82 -24
- package/dist/esm/app/App.js.map +1 -1
- package/dist/esm/app/actions.js +2 -2
- package/dist/esm/app/actions.js.map +1 -1
- package/dist/esm/app/create-reducer.js +2 -1
- package/dist/esm/app/create-reducer.js.map +1 -1
- package/dist/esm/app/filter-empty.js +11 -0
- package/dist/esm/app/filter-empty.js.map +1 -0
- package/dist/esm/app/flows/handle-fetch-config.js +30 -0
- package/dist/esm/app/flows/handle-fetch-config.js.map +1 -0
- package/dist/esm/app/flows/handle-fetch-manifest.js +30 -0
- package/dist/esm/app/flows/handle-fetch-manifest.js.map +1 -0
- package/dist/esm/app/flows/handle-fetch-settings.js +30 -0
- package/dist/esm/app/flows/handle-fetch-settings.js.map +1 -0
- package/dist/esm/app/flows/handle-import-application.js +23 -0
- package/dist/esm/app/flows/handle-import-application.js.map +1 -0
- package/dist/esm/app/flows/handle-update-settings.js +22 -0
- package/dist/esm/app/flows/handle-update-settings.js.map +1 -0
- package/dist/esm/app/flows/index.js +6 -0
- package/dist/esm/app/flows/index.js.map +1 -0
- package/dist/esm/enable-app-module.js +2 -1
- package/dist/esm/enable-app-module.js.map +1 -1
- package/dist/esm/errors/AppBuildError.js +35 -0
- package/dist/esm/errors/AppBuildError.js.map +1 -0
- package/dist/esm/errors/AppConfigError.js +35 -0
- package/dist/esm/errors/AppConfigError.js.map +1 -0
- package/dist/esm/errors/AppManifestError.js +35 -0
- package/dist/esm/errors/AppManifestError.js.map +1 -0
- package/dist/esm/errors/AppScriptModuleError.js +17 -0
- package/dist/esm/errors/AppScriptModuleError.js.map +1 -0
- package/dist/esm/errors/AppSettingsError.js +35 -0
- package/dist/esm/errors/AppSettingsError.js.map +1 -0
- package/dist/esm/errors/app-error-type.js +2 -0
- package/dist/esm/errors/app-error-type.js.map +1 -0
- package/dist/esm/errors.js +5 -148
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/module.js +2 -0
- package/dist/esm/module.js.map +1 -1
- package/dist/esm/schemas.js +4 -0
- package/dist/esm/schemas.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/AppClient.d.ts +42 -0
- package/dist/types/AppConfig.d.ts +7 -1
- package/dist/types/AppConfigurator.d.ts +25 -0
- package/dist/types/AppModuleProvider.d.ts +10 -0
- package/dist/types/app/App.d.ts +49 -8
- package/dist/types/app/create-reducer.d.ts +55 -55
- package/dist/types/app/filter-empty.d.ts +8 -0
- package/dist/types/app/flows/handle-fetch-config.d.ts +12 -0
- package/dist/types/app/flows/handle-fetch-manifest.d.ts +12 -0
- package/dist/types/app/flows/handle-fetch-settings.d.ts +12 -0
- package/dist/types/app/flows/handle-import-application.d.ts +10 -0
- package/dist/types/app/flows/handle-update-settings.d.ts +12 -0
- package/dist/types/app/flows/index.d.ts +5 -0
- package/dist/types/errors/AppBuildError.d.ts +21 -0
- package/dist/types/errors/AppConfigError.d.ts +21 -0
- package/dist/types/errors/AppManifestError.d.ts +21 -0
- package/dist/types/errors/AppScriptModuleError.d.ts +14 -0
- package/dist/types/errors/AppSettingsError.d.ts +21 -0
- package/dist/types/errors/app-error-type.d.ts +9 -0
- package/dist/types/errors.d.ts +6 -103
- package/dist/types/version.d.ts +1 -1
- package/package.json +9 -9
- package/src/AppClient.ts +65 -4
- package/src/AppConfig.ts +9 -1
- package/src/AppConfigurator.ts +28 -4
- package/src/AppModuleProvider.ts +16 -0
- package/src/app/App.ts +88 -31
- package/src/app/actions.ts +2 -2
- package/src/app/create-reducer.ts +2 -1
- package/src/app/filter-empty.ts +11 -0
- package/src/app/flows/handle-fetch-config.ts +48 -0
- package/src/app/flows/handle-fetch-manifest.ts +53 -0
- package/src/app/flows/handle-fetch-settings.ts +50 -0
- package/src/app/flows/handle-import-application.ts +37 -0
- package/src/app/flows/handle-update-settings.ts +39 -0
- package/src/app/flows/index.ts +5 -0
- package/src/app/types.ts +2 -2
- package/src/enable-app-module.ts +2 -1
- package/src/errors/AppBuildError.ts +47 -0
- package/src/errors/AppConfigError.ts +47 -0
- package/src/errors/AppManifestError.ts +47 -0
- package/src/errors/AppScriptModuleError.ts +20 -0
- package/src/errors/AppSettingsError.ts +47 -0
- package/src/errors/app-error-type.ts +9 -0
- package/src/errors.ts +6 -208
- package/src/module.ts +2 -0
- package/src/schemas.ts +4 -0
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
- package/dist/esm/AppClient.Selectors.js.map +0 -1
- package/dist/esm/app/flows.js +0 -120
- package/dist/esm/app/flows.js.map +0 -1
- package/dist/types/app/flows.d.ts +0 -41
- package/src/app/flows.ts +0 -189
- /package/dist/types/{AppClient.Selectors.d.ts → AppConfigSelector.d.ts} +0 -0
- /package/src/{AppClient.Selectors.ts → AppConfigSelector.ts} +0 -0
package/dist/types/errors.d.ts
CHANGED
|
@@ -1,103 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* - `'unknown'` – An unexpected failure occurred.
|
|
8
|
-
*/
|
|
9
|
-
type AppErrorType = 'not_found' | 'unauthorized' | 'unknown' | 'deleted';
|
|
10
|
-
/**
|
|
11
|
-
* Represents an error that occurs when loading an application manifest.
|
|
12
|
-
*/
|
|
13
|
-
export declare class AppManifestError extends Error {
|
|
14
|
-
readonly type: AppErrorType;
|
|
15
|
-
/**
|
|
16
|
-
* Creates an instance of AppManifestError based on the HTTP response status.
|
|
17
|
-
* @param response The HTTP response.
|
|
18
|
-
* @param options Optional error options.
|
|
19
|
-
* @returns An instance of AppManifestError.
|
|
20
|
-
*/
|
|
21
|
-
static fromHttpResponse(response: Response, options?: ErrorOptions): AppManifestError;
|
|
22
|
-
/**
|
|
23
|
-
* Creates an instance of AppManifestError.
|
|
24
|
-
* @param type The type of the error.
|
|
25
|
-
* @param message The error message.
|
|
26
|
-
* @param options Optional error options.
|
|
27
|
-
*/
|
|
28
|
-
constructor(type: AppErrorType, message?: string, options?: ErrorOptions);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Represents an error that occurs in the application configuration.
|
|
32
|
-
*/
|
|
33
|
-
export declare class AppConfigError extends Error {
|
|
34
|
-
readonly type: AppErrorType;
|
|
35
|
-
/**
|
|
36
|
-
* Creates an instance of `AppConfigError` based on the HTTP response status.
|
|
37
|
-
* @param response The HTTP response.
|
|
38
|
-
* @param options Additional error options.
|
|
39
|
-
* @returns An instance of `AppConfigError` based on the HTTP response status.
|
|
40
|
-
*/
|
|
41
|
-
static fromHttpResponse(response: Response, options?: ErrorOptions): AppConfigError;
|
|
42
|
-
/**
|
|
43
|
-
* Creates an instance of `AppConfigError`.
|
|
44
|
-
* @param type The type of the application error.
|
|
45
|
-
* @param message The error message.
|
|
46
|
-
* @param options Additional error options.
|
|
47
|
-
*/
|
|
48
|
-
constructor(type: AppErrorType, message?: string, options?: ErrorOptions);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Represents an error that occurs in the application build.
|
|
52
|
-
*/
|
|
53
|
-
export declare class AppBuildError extends Error {
|
|
54
|
-
readonly type: AppErrorType;
|
|
55
|
-
/**
|
|
56
|
-
* Creates an instance of `AppBuildError` based on the HTTP response status.
|
|
57
|
-
* @param response The HTTP response.
|
|
58
|
-
* @param options Additional error options.
|
|
59
|
-
* @returns An instance of `AppBuildError` based on the HTTP response status.
|
|
60
|
-
*/
|
|
61
|
-
static fromHttpResponse(response: Response, options?: ErrorOptions): AppBuildError;
|
|
62
|
-
/**
|
|
63
|
-
* Creates an instance of `AppBuildError`.
|
|
64
|
-
* @param type The type of the application error.
|
|
65
|
-
* @param message The error message.
|
|
66
|
-
* @param options Additional error options.
|
|
67
|
-
*/
|
|
68
|
-
constructor(type: AppErrorType, message?: string, options?: ErrorOptions);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Represents an error that occurs while fetching application settings.
|
|
72
|
-
*/
|
|
73
|
-
export declare class AppSettingsError extends Error {
|
|
74
|
-
readonly type: AppErrorType;
|
|
75
|
-
/**
|
|
76
|
-
* Creates an instance of `AppSettingsError` based on the HTTP response status.
|
|
77
|
-
* @param response The HTTP response.
|
|
78
|
-
* @param options Additional error options.
|
|
79
|
-
* @returns An instance of `AppSettingsError` based on the HTTP response status.
|
|
80
|
-
*/
|
|
81
|
-
static fromHttpResponse(response: Response, options?: ErrorOptions): AppSettingsError;
|
|
82
|
-
/**
|
|
83
|
-
* Creates an instance of `AppSettingsError`.
|
|
84
|
-
* @param type The type of the application error.
|
|
85
|
-
* @param message The error message.
|
|
86
|
-
* @param options Additional error options.
|
|
87
|
-
*/
|
|
88
|
-
constructor(type: AppErrorType, message?: string, options?: ErrorOptions);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Represents an error that occurs when loading the application script.
|
|
92
|
-
*/
|
|
93
|
-
export declare class AppScriptModuleError extends Error {
|
|
94
|
-
readonly type: AppErrorType;
|
|
95
|
-
/**
|
|
96
|
-
* Creates a new instance of the AppScriptModuleError class.
|
|
97
|
-
* @param type The type of the error.
|
|
98
|
-
* @param message The error message.
|
|
99
|
-
* @param options Additional options for the error.
|
|
100
|
-
*/
|
|
101
|
-
constructor(type: AppErrorType, message?: string, options?: ErrorOptions);
|
|
102
|
-
}
|
|
103
|
-
export {};
|
|
1
|
+
export { AppManifestError } from './errors/AppManifestError';
|
|
2
|
+
export { AppConfigError } from './errors/AppConfigError';
|
|
3
|
+
export { AppBuildError } from './errors/AppBuildError';
|
|
4
|
+
export { AppSettingsError } from './errors/AppSettingsError';
|
|
5
|
+
export { AppScriptModuleError } from './errors/AppScriptModuleError';
|
|
6
|
+
export type { AppErrorType } from './errors/app-error-type';
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "8.0.
|
|
1
|
+
export declare const version = "8.0.3";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-module-app",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -61,16 +61,16 @@
|
|
|
61
61
|
"rxjs": "^7.8.1",
|
|
62
62
|
"uuid": "^14.0.0",
|
|
63
63
|
"zod": "^4.4.3",
|
|
64
|
-
"@equinor/fusion-
|
|
65
|
-
"@equinor/fusion-
|
|
64
|
+
"@equinor/fusion-observable": "^9.1.1",
|
|
65
|
+
"@equinor/fusion-query": "^7.0.2"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"typescript": "^
|
|
69
|
-
"@equinor/fusion-framework-module": "^6.
|
|
70
|
-
"@equinor/fusion-framework-module-
|
|
71
|
-
"@equinor/fusion-framework-module-
|
|
72
|
-
"@equinor/fusion-framework-module-msal": "^
|
|
73
|
-
"@equinor/fusion-framework-module-
|
|
68
|
+
"typescript": "^7.0.2",
|
|
69
|
+
"@equinor/fusion-framework-module": "^6.1.1",
|
|
70
|
+
"@equinor/fusion-framework-module-event": "^6.0.1",
|
|
71
|
+
"@equinor/fusion-framework-module-http": "^8.0.4",
|
|
72
|
+
"@equinor/fusion-framework-module-msal": "^10.0.2",
|
|
73
|
+
"@equinor/fusion-framework-module-service-discovery": "^10.0.2"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"build": "tsc -b"
|
package/src/AppClient.ts
CHANGED
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
ConfigEnvironment,
|
|
21
21
|
} from './types';
|
|
22
22
|
import { AppBuildError, AppConfigError, AppManifestError, AppSettingsError } from './errors';
|
|
23
|
-
import { AppConfigSelector } from './
|
|
23
|
+
import { AppConfigSelector } from './AppConfigSelector';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Contract for an app service client that fetches application manifests,
|
|
@@ -102,11 +102,11 @@ const ApplicationSchema = ApiApplicationSchema.transform((x): AppManifest => {
|
|
|
102
102
|
const { category, ...props } = x;
|
|
103
103
|
return {
|
|
104
104
|
...props,
|
|
105
|
-
// TODO: remove deprecated appKey
|
|
105
|
+
// TODO(#5124): remove deprecated appKey
|
|
106
106
|
get key() {
|
|
107
107
|
return props.appKey;
|
|
108
108
|
},
|
|
109
|
-
// TODO: remove deprecated name
|
|
109
|
+
// TODO(#5124): remove deprecated name
|
|
110
110
|
get name() {
|
|
111
111
|
return props.displayName;
|
|
112
112
|
},
|
|
@@ -139,6 +139,10 @@ export class AppClient implements IAppClient {
|
|
|
139
139
|
#settings: Query<AppSettings, { appKey: string; settings?: AppSettings }>;
|
|
140
140
|
#client: IHttpClient;
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Creates a new {@link AppClient} backed by the given HTTP client.
|
|
144
|
+
* @param client - The HTTP client used to communicate with the Fusion app service API.
|
|
145
|
+
*/
|
|
142
146
|
constructor(client: IHttpClient) {
|
|
143
147
|
this.#client = client;
|
|
144
148
|
|
|
@@ -229,15 +233,26 @@ export class AppClient implements IAppClient {
|
|
|
229
233
|
});
|
|
230
234
|
}
|
|
231
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Fetches the build metadata for an application.
|
|
238
|
+
* @param args - Object containing the `appKey` and an optional version `tag`.
|
|
239
|
+
* @returns An observable that emits the resolved {@link AppBuildManifest}.
|
|
240
|
+
* @throws {AppBuildError} When the build metadata cannot be loaded.
|
|
241
|
+
*/
|
|
232
242
|
getAppBuild(args: { appKey: string; tag?: string }): Observable<AppBuildManifest> {
|
|
243
|
+
// unwrap the build manifest and map errors to a typed AppBuildError
|
|
233
244
|
return this.#build.query(args).pipe(
|
|
245
|
+
// unwrap the query result into the build manifest
|
|
234
246
|
map((res) => res.value as AppBuildManifest),
|
|
247
|
+
// map http/unknown errors into a typed AppBuildError
|
|
235
248
|
catchError((err) => {
|
|
236
249
|
const cause = err?.cause || err;
|
|
237
250
|
|
|
251
|
+
// rethrow already-typed errors as-is
|
|
238
252
|
if (cause instanceof AppBuildError) {
|
|
239
253
|
throw cause;
|
|
240
254
|
}
|
|
255
|
+
// map http errors to a typed AppBuildError
|
|
241
256
|
if (cause instanceof HttpJsonResponseError || cause instanceof HttpResponseError) {
|
|
242
257
|
throw AppBuildError.fromHttpResponse(cause.response, { cause });
|
|
243
258
|
}
|
|
@@ -246,16 +261,26 @@ export class AppClient implements IAppClient {
|
|
|
246
261
|
);
|
|
247
262
|
}
|
|
248
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Fetches the manifest for a single application.
|
|
266
|
+
* @param args - Object containing the `appKey` and an optional version `tag`.
|
|
267
|
+
* @returns An observable that emits the resolved {@link AppManifest}.
|
|
268
|
+
* @throws {AppManifestError} When the manifest cannot be loaded.
|
|
269
|
+
*/
|
|
249
270
|
getAppManifest(args: { appKey: string; tag?: string }): Observable<AppManifest> {
|
|
271
|
+
// unwrap the manifest and map errors to a typed AppManifestError
|
|
250
272
|
return this.#manifest.query(args).pipe(
|
|
251
273
|
queryValue,
|
|
274
|
+
// map http/unknown errors into a typed AppManifestError
|
|
252
275
|
catchError((err) => {
|
|
253
276
|
const cause = err?.cause || err;
|
|
254
277
|
|
|
278
|
+
// rethrow already-typed errors as-is
|
|
255
279
|
if (cause instanceof AppManifestError) {
|
|
256
280
|
throw cause;
|
|
257
281
|
}
|
|
258
282
|
|
|
283
|
+
// map http errors to a typed AppManifestError
|
|
259
284
|
if (cause instanceof HttpJsonResponseError || cause instanceof HttpResponseError) {
|
|
260
285
|
throw AppManifestError.fromHttpResponse(cause.response, { cause });
|
|
261
286
|
}
|
|
@@ -265,23 +290,41 @@ export class AppClient implements IAppClient {
|
|
|
265
290
|
);
|
|
266
291
|
}
|
|
267
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Fetches manifests for all registered applications.
|
|
295
|
+
* @param args - Optional filter; set `filterByCurrentUser` to `true` to return only apps the authenticated user has access to.
|
|
296
|
+
* @returns An observable that emits an array of {@link AppManifest} objects.
|
|
297
|
+
*/
|
|
268
298
|
getAppManifests(args: { filterByCurrentUser?: boolean } | undefined): Observable<AppManifest[]> {
|
|
299
|
+
// unwrap the query result into the manifest array
|
|
269
300
|
return this.#manifests.query(args).pipe(queryValue);
|
|
270
301
|
}
|
|
271
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Fetches the runtime configuration for an application.
|
|
305
|
+
* @template TType - Shape of the `environment` record in the returned config.
|
|
306
|
+
* @param args - Object containing the `appKey` and an optional version `tag`.
|
|
307
|
+
* @returns An observable that emits the resolved {@link AppConfig}.
|
|
308
|
+
* @throws {AppConfigError} When the configuration cannot be loaded.
|
|
309
|
+
*/
|
|
272
310
|
getAppConfig<TType extends ConfigEnvironment = ConfigEnvironment>(args: {
|
|
273
311
|
appKey: string;
|
|
274
312
|
tag?: string;
|
|
275
313
|
}): Observable<AppConfig<TType>> {
|
|
314
|
+
// unwrap the config and map errors to a typed AppConfigError
|
|
276
315
|
return this.#config.query(args).pipe(
|
|
316
|
+
// unwrap the query result into the config
|
|
277
317
|
map((res) => res.value as AppConfig<TType>),
|
|
318
|
+
// map http/unknown errors into a typed AppConfigError
|
|
278
319
|
catchError((err) => {
|
|
279
320
|
/** handle both direct errors and errors wrapped in a `cause` property */
|
|
280
321
|
const cause = err?.cause || err;
|
|
281
322
|
|
|
323
|
+
// rethrow already-typed errors as-is
|
|
282
324
|
if (cause instanceof AppConfigError) {
|
|
283
325
|
throw cause;
|
|
284
326
|
}
|
|
327
|
+
// map http errors to a typed AppConfigError
|
|
285
328
|
if (cause instanceof HttpJsonResponseError || cause instanceof HttpResponseError) {
|
|
286
329
|
throw AppConfigError.fromHttpResponse(cause.response, { cause });
|
|
287
330
|
}
|
|
@@ -290,16 +333,26 @@ export class AppClient implements IAppClient {
|
|
|
290
333
|
);
|
|
291
334
|
}
|
|
292
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Fetches per-user settings for an application.
|
|
338
|
+
* @param args - Object containing the `appKey`.
|
|
339
|
+
* @returns An observable that emits the {@link AppSettings} record.
|
|
340
|
+
* @throws {AppSettingsError} When settings cannot be loaded.
|
|
341
|
+
*/
|
|
293
342
|
getAppSettings(args: { appKey: string }): Observable<AppSettings> {
|
|
343
|
+
// unwrap the settings and map errors to a typed AppSettingsError
|
|
294
344
|
return this.#settings.query(args).pipe(
|
|
295
345
|
queryValue,
|
|
346
|
+
// map http/unknown errors into a typed AppSettingsError
|
|
296
347
|
catchError((err) => {
|
|
297
348
|
/** handle both direct errors and errors wrapped in a `cause` property */
|
|
298
349
|
const cause = err?.cause || err;
|
|
299
350
|
|
|
351
|
+
// rethrow already-typed errors as-is
|
|
300
352
|
if (cause instanceof AppSettingsError) {
|
|
301
353
|
throw cause;
|
|
302
354
|
}
|
|
355
|
+
// map http errors to a typed AppSettingsError
|
|
303
356
|
if (cause instanceof HttpJsonResponseError || cause instanceof HttpResponseError) {
|
|
304
357
|
throw AppSettingsError.fromHttpResponse(cause.response, { cause });
|
|
305
358
|
}
|
|
@@ -308,11 +361,15 @@ export class AppClient implements IAppClient {
|
|
|
308
361
|
);
|
|
309
362
|
}
|
|
310
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Persists updated per-user settings for an application via PUT.
|
|
366
|
+
* @param args - Object containing the `appKey` and the `settings` payload to save.
|
|
367
|
+
* @returns An observable that emits the persisted {@link AppSettings}.
|
|
368
|
+
*/
|
|
311
369
|
updateAppSettings(args: { appKey: string; settings: AppSettings }): Observable<AppSettings> {
|
|
312
370
|
const { appKey, settings } = args;
|
|
313
371
|
return (
|
|
314
372
|
this.#client
|
|
315
|
-
// execute PUT request to update settings
|
|
316
373
|
.json$<AppSettings>(`/persons/me/apps/${appKey}/settings`, {
|
|
317
374
|
method: 'PUT',
|
|
318
375
|
body: settings,
|
|
@@ -320,6 +377,7 @@ export class AppClient implements IAppClient {
|
|
|
320
377
|
'Api-Version': '1.0',
|
|
321
378
|
},
|
|
322
379
|
})
|
|
380
|
+
// update the settings cache with the persisted value
|
|
323
381
|
.pipe(
|
|
324
382
|
tap((value) => {
|
|
325
383
|
// update cache with new settings
|
|
@@ -335,6 +393,9 @@ export class AppClient implements IAppClient {
|
|
|
335
393
|
);
|
|
336
394
|
}
|
|
337
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Disposes of the client, completing all internal query streams.
|
|
398
|
+
*/
|
|
338
399
|
[Symbol.dispose]() {
|
|
339
400
|
console.warn('AppClient disposed');
|
|
340
401
|
this.#manifest.complete();
|
package/src/AppConfig.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* @returns The same object, deeply frozen.
|
|
7
7
|
*/
|
|
8
8
|
const deepFreeze = <T extends Record<string, unknown>>(obj: T): T => {
|
|
9
|
+
// recursively freeze any nested, unfrozen object properties
|
|
9
10
|
for (const property of Object.keys(obj)) {
|
|
11
|
+
// only descend into unfrozen object properties
|
|
10
12
|
if (
|
|
11
13
|
typeof obj[property] === 'object' &&
|
|
12
14
|
obj[property] !== null &&
|
|
@@ -59,18 +61,24 @@ export class AppConfig<TEnvironment extends ConfigEnvironment = ConfigEnvironmen
|
|
|
59
61
|
|
|
60
62
|
/**
|
|
61
63
|
* The environment configuration for the application.
|
|
64
|
+
* @returns The frozen environment configuration.
|
|
62
65
|
*/
|
|
63
66
|
get environment(): TEnvironment {
|
|
64
67
|
return this.#environment;
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
/**
|
|
68
|
-
* The configuration endpoints for the application
|
|
71
|
+
* The configuration endpoints for the application.
|
|
72
|
+
* @returns The frozen map of configuration endpoints.
|
|
69
73
|
*/
|
|
70
74
|
get endpoints(): Record<string, ConfigEndPoint> {
|
|
71
75
|
return this.#endpoints;
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Creates a new {@link AppConfig}, deep-freezing the provided environment and endpoints.
|
|
80
|
+
* @param config - The environment and endpoints to initialize the configuration with.
|
|
81
|
+
*/
|
|
74
82
|
constructor(config: {
|
|
75
83
|
environment?: TEnvironment | null;
|
|
76
84
|
endpoints?: Record<string, ConfigEndPoint>;
|
package/src/AppConfigurator.ts
CHANGED
|
@@ -6,8 +6,6 @@ import {
|
|
|
6
6
|
import type { HttpModule, IHttpClient } from '@equinor/fusion-framework-module-http';
|
|
7
7
|
import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
|
|
8
8
|
|
|
9
|
-
import { moduleKey } from './module';
|
|
10
|
-
|
|
11
9
|
import AppClient, { type IAppClient } from './AppClient';
|
|
12
10
|
|
|
13
11
|
/**
|
|
@@ -64,7 +62,13 @@ export class AppConfigurator
|
|
|
64
62
|
defaultExpireTime = 1 * 60 * 1000;
|
|
65
63
|
|
|
66
64
|
/**
|
|
65
|
+
* Creates the default HTTP client for the app service, preferring a pre-configured
|
|
66
|
+
* client from the http module and falling back to service discovery.
|
|
67
|
+
*
|
|
67
68
|
* WARNING: this function will be remove in future
|
|
69
|
+
*
|
|
70
|
+
* @param init - Module initializer args providing access to the http and service discovery modules.
|
|
71
|
+
* @returns A promise resolving to the {@link IHttpClient} used to communicate with the app service.
|
|
68
72
|
*/
|
|
69
73
|
protected async _createHttpClient(
|
|
70
74
|
init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>,
|
|
@@ -79,11 +83,16 @@ export class AppConfigurator
|
|
|
79
83
|
/** load service discovery module */
|
|
80
84
|
const serviceDiscovery = await init.requireInstance('serviceDiscovery');
|
|
81
85
|
|
|
82
|
-
// TODO - remove when refactor portal service!
|
|
86
|
+
// TODO(#5125) - remove when refactor portal service!
|
|
83
87
|
/** resolve and create a client from discovery */
|
|
84
88
|
return await serviceDiscovery.createClient(serviceName);
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Sets the app service client used to fetch manifests, configs, and settings.
|
|
93
|
+
* @param client_or_cb - A promise resolving to an {@link IAppClient}, or a callback
|
|
94
|
+
* that receives module initializer args and returns one.
|
|
95
|
+
*/
|
|
87
96
|
public setClient(
|
|
88
97
|
client_or_cb:
|
|
89
98
|
| Promise<AppModuleConfig['client']>
|
|
@@ -93,16 +102,30 @@ export class AppConfigurator
|
|
|
93
102
|
this._set('client', cb);
|
|
94
103
|
}
|
|
95
104
|
|
|
96
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Sets the base URI used to proxy-load application script bundles.
|
|
107
|
+
*
|
|
108
|
+
* TODO(#5132) - explain why, used in import of resources aka proxy url
|
|
109
|
+
*
|
|
110
|
+
* @param base_or_cb - A static URI string or a callback returning one.
|
|
111
|
+
*/
|
|
97
112
|
public setAssetUri(base_or_cb: string | ConfigBuilderCallback<string>) {
|
|
98
113
|
const cb = typeof base_or_cb === 'string' ? async () => base_or_cb : base_or_cb;
|
|
99
114
|
this._set('assetUri', cb);
|
|
100
115
|
}
|
|
101
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Builds the resolved {@link AppModuleConfig}, applying default client and asset URI
|
|
119
|
+
* when they haven't been explicitly configured.
|
|
120
|
+
* @param init - Module initializer args used to build the default client.
|
|
121
|
+
* @param initial - Optional initial partial configuration.
|
|
122
|
+
* @returns The resolved module config.
|
|
123
|
+
*/
|
|
102
124
|
protected _createConfig(
|
|
103
125
|
init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>,
|
|
104
126
|
initial?: Partial<AppModuleConfig>,
|
|
105
127
|
) {
|
|
128
|
+
// fall back to a default client created via the http/service discovery modules
|
|
106
129
|
if (!this._has('client')) {
|
|
107
130
|
this.setClient(async () => {
|
|
108
131
|
const httpClient = await this._createHttpClient(init);
|
|
@@ -111,6 +134,7 @@ export class AppConfigurator
|
|
|
111
134
|
});
|
|
112
135
|
}
|
|
113
136
|
|
|
137
|
+
// fall back to the default proxy asset uri
|
|
114
138
|
if (!this._has('assetUri')) {
|
|
115
139
|
this.setAssetUri('/apps-proxy');
|
|
116
140
|
}
|
package/src/AppModuleProvider.ts
CHANGED
|
@@ -45,6 +45,7 @@ export class AppModuleProvider {
|
|
|
45
45
|
/**
|
|
46
46
|
* Shallow-compares two app manifests by JSON serialization.
|
|
47
47
|
*
|
|
48
|
+
* @template T - The manifest type being compared.
|
|
48
49
|
* @param a - First manifest to compare.
|
|
49
50
|
* @param b - Second manifest to compare.
|
|
50
51
|
* @returns `true` if the serialized manifests are identical.
|
|
@@ -65,6 +66,7 @@ export class AppModuleProvider {
|
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Get module version
|
|
69
|
+
* @returns The module's semantic version.
|
|
68
70
|
*/
|
|
69
71
|
get version(): SemanticVersion {
|
|
70
72
|
return new SemanticVersion(version);
|
|
@@ -76,6 +78,8 @@ export class AppModuleProvider {
|
|
|
76
78
|
* - `undefined` – no application has been set yet.
|
|
77
79
|
* - `null` – the current application was explicitly cleared.
|
|
78
80
|
* - `App` – an active application instance.
|
|
81
|
+
*
|
|
82
|
+
* @returns The current active application, `null` if cleared, or `undefined` if never set.
|
|
79
83
|
*/
|
|
80
84
|
get current(): CurrentApp | null | undefined {
|
|
81
85
|
return this.#current$.value;
|
|
@@ -86,10 +90,14 @@ export class AppModuleProvider {
|
|
|
86
90
|
*
|
|
87
91
|
* Emits are deduplicated by `appKey`; re-setting the same app does not trigger
|
|
88
92
|
* a new emission.
|
|
93
|
+
*
|
|
94
|
+
* @returns An observable of the current active application.
|
|
89
95
|
*/
|
|
90
96
|
get current$(): Observable<CurrentApp | null> {
|
|
97
|
+
// dedupe emissions when the current app's key is unchanged
|
|
91
98
|
return this.#current$.pipe(
|
|
92
99
|
distinctUntilChanged((prev, next) => {
|
|
100
|
+
// compare by appKey when both are set, otherwise fall back to reference equality
|
|
93
101
|
if (prev && next) {
|
|
94
102
|
return prev.appKey === next.appKey;
|
|
95
103
|
}
|
|
@@ -116,6 +124,7 @@ export class AppModuleProvider {
|
|
|
116
124
|
|
|
117
125
|
this.#subscription.add(
|
|
118
126
|
this.current$
|
|
127
|
+
// dispatch a lifecycle event whenever the current app changes
|
|
119
128
|
.pipe(
|
|
120
129
|
pairwise(),
|
|
121
130
|
takeWhile(() => !!event),
|
|
@@ -130,6 +139,7 @@ export class AppModuleProvider {
|
|
|
130
139
|
|
|
131
140
|
this.#subscription.add(
|
|
132
141
|
this.#current$
|
|
142
|
+
// dispose the previous app once it has been replaced
|
|
133
143
|
.pipe(
|
|
134
144
|
pairwise(),
|
|
135
145
|
map(([previous]) => previous),
|
|
@@ -164,6 +174,7 @@ export class AppModuleProvider {
|
|
|
164
174
|
/**
|
|
165
175
|
* fetch all applications
|
|
166
176
|
* @deprecated use `getAppManifests` instead
|
|
177
|
+
* @returns An observable that emits an array of {@link AppManifest} objects.
|
|
167
178
|
*/
|
|
168
179
|
public getAllAppManifests(): Observable<AppManifest[]> {
|
|
169
180
|
return this.getAppManifests();
|
|
@@ -214,12 +225,14 @@ export class AppModuleProvider {
|
|
|
214
225
|
* @param appKeyOrApp - Application key, app reference, or an existing `IApp` instance.
|
|
215
226
|
*/
|
|
216
227
|
public setCurrentApp(appKeyOrApp: string | IApp | AppReference): void {
|
|
228
|
+
// a plain string is treated as an appKey to create a new App from
|
|
217
229
|
if (typeof appKeyOrApp === 'string') {
|
|
218
230
|
const newApp = new App({ appKey: appKeyOrApp }, { provider: this, event: this.#event });
|
|
219
231
|
this.#current$.next(newApp as CurrentApp);
|
|
220
232
|
return;
|
|
221
233
|
}
|
|
222
234
|
|
|
235
|
+
// an object with appKey and tag is treated as an AppReference to create a new App from
|
|
223
236
|
if (appKeyOrApp.appKey && 'tag' in appKeyOrApp) {
|
|
224
237
|
const newApp = new App(
|
|
225
238
|
{ appKey: appKeyOrApp.appKey, tag: appKeyOrApp.tag },
|
|
@@ -242,6 +255,7 @@ export class AppModuleProvider {
|
|
|
242
255
|
|
|
243
256
|
/**
|
|
244
257
|
* Base URI used for proxying application script imports.
|
|
258
|
+
* @returns The configured asset base URI.
|
|
245
259
|
*/
|
|
246
260
|
public get assetUri(): string {
|
|
247
261
|
return this.#appBaseUri;
|
|
@@ -250,6 +264,8 @@ export class AppModuleProvider {
|
|
|
250
264
|
/**
|
|
251
265
|
* This should not be used, only for legacy creation backdoor
|
|
252
266
|
* @deprecated
|
|
267
|
+
* @param value - The initial app bundle state to construct the app from.
|
|
268
|
+
* @returns The newly created {@link App} instance.
|
|
253
269
|
*/
|
|
254
270
|
public createApp(value: AppBundleStateInitial): App {
|
|
255
271
|
console.warn('AppModuleProvider.createApp is deprecated and should not be used.');
|