@equinor/fusion-framework-module-app 8.1.0 → 8.1.1

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 (44) hide show
  1. package/dist/esm/version.js +1 -1
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/dist/types/version.d.ts +1 -1
  4. package/package.json +12 -9
  5. package/CHANGELOG.md +0 -1469
  6. package/src/AppClient.ts +0 -409
  7. package/src/AppConfig.ts +0 -99
  8. package/src/AppConfigSelector.ts +0 -25
  9. package/src/AppConfigurator.ts +0 -145
  10. package/src/AppModuleProvider.ts +0 -283
  11. package/src/__tests__/AppModuleProvider.test.ts +0 -47
  12. package/src/__tests__/MockAppClient.test.ts +0 -97
  13. package/src/app/App.ts +0 -984
  14. package/src/app/actions.ts +0 -112
  15. package/src/app/create-reducer.ts +0 -62
  16. package/src/app/create-state.ts +0 -52
  17. package/src/app/events.ts +0 -108
  18. package/src/app/filter-empty.ts +0 -11
  19. package/src/app/flows/handle-fetch-config.ts +0 -48
  20. package/src/app/flows/handle-fetch-manifest.ts +0 -53
  21. package/src/app/flows/handle-fetch-settings.ts +0 -50
  22. package/src/app/flows/handle-import-application.ts +0 -37
  23. package/src/app/flows/handle-update-settings.ts +0 -39
  24. package/src/app/flows/index.ts +0 -5
  25. package/src/app/index.ts +0 -10
  26. package/src/app/types.ts +0 -51
  27. package/src/enable-app-module.ts +0 -40
  28. package/src/errors/AppBuildError.ts +0 -47
  29. package/src/errors/AppConfigError.ts +0 -47
  30. package/src/errors/AppManifestError.ts +0 -47
  31. package/src/errors/AppScriptModuleError.ts +0 -20
  32. package/src/errors/AppSettingsError.ts +0 -47
  33. package/src/errors/app-error-type.ts +0 -9
  34. package/src/errors.ts +0 -6
  35. package/src/events.ts +0 -18
  36. package/src/index.ts +0 -40
  37. package/src/mock/MockAppClient.ts +0 -77
  38. package/src/mock/index.ts +0 -13
  39. package/src/module.ts +0 -59
  40. package/src/schemas.ts +0 -181
  41. package/src/types.ts +0 -263
  42. package/src/version.ts +0 -2
  43. package/tsconfig.json +0 -30
  44. package/vitest.config.ts +0 -11
@@ -1,40 +0,0 @@
1
- import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
2
- import { module } from './module';
3
- import type { AppConfigurator } from './AppConfigurator';
4
-
5
- /**
6
- * Registers the app module with a framework configurator.
7
- *
8
- * Call this during framework setup to enable application loading, manifest fetching,
9
- * configuration resolution, and per-user settings management.
10
- *
11
- * @param configurator - The framework modules configurator to register the app module with.
12
- * @param callback - Optional callback to customize the {@link AppConfigurator} before initialization
13
- * (e.g., override the HTTP client or set a custom asset URI).
14
- *
15
- * @example
16
- * ```ts
17
- * import { enableAppModule } from '@equinor/fusion-framework-module-app';
18
- *
19
- * export const configure = async (configurator: FrameworkConfigurator) => {
20
- * enableAppModule(configurator, (builder) => {
21
- * builder.setAssetUri('/custom-proxy');
22
- * });
23
- * };
24
- * ```
25
- */
26
- export const enableAppModule = (
27
- // biome-ignore lint/suspicious/noExplicitAny: `IModulesConfigurator<any, any>` widens to accept a configurator for any concrete module set — `unknown` would break assignability of a real configurator instance to this parameter
28
- configurator: IModulesConfigurator<any, any>,
29
- callback?: (builder: AppConfigurator) => void | Promise<void>,
30
- ): void => {
31
- configurator.addConfig({
32
- module,
33
- configure: async (configurator) => {
34
- // apply the caller's configuration overrides, if provided
35
- if (callback) {
36
- Promise.resolve(callback(configurator));
37
- }
38
- },
39
- });
40
- };
@@ -1,47 +0,0 @@
1
- import type { AppErrorType } from './app-error-type';
2
-
3
- /**
4
- * Represents an error that occurs in the application build.
5
- */
6
- export class AppBuildError extends Error {
7
- /**
8
- * Creates an instance of `AppBuildError` based on the HTTP response status.
9
- * @param response The HTTP response.
10
- * @param options Additional error options.
11
- * @returns An instance of `AppBuildError` based on the HTTP response status.
12
- */
13
- static fromHttpResponse(response: Response, options?: ErrorOptions): AppBuildError {
14
- // map well-known HTTP statuses to a specific error type
15
- switch (response.status) {
16
- case 401:
17
- return new AppBuildError(
18
- 'unauthorized',
19
- 'failed to load application build metadata, request not authorized',
20
- options,
21
- );
22
- case 404:
23
- return new AppBuildError('not_found', 'application build metadata not found', options);
24
- case 410:
25
- return new AppBuildError('deleted', 'application build deleted', options);
26
- }
27
- return new AppBuildError(
28
- 'unknown',
29
- `failed to load application build, status code ${response.status}`,
30
- options,
31
- );
32
- }
33
-
34
- /**
35
- * Creates an instance of `AppBuildError`.
36
- * @param type The type of the application error.
37
- * @param message The error message.
38
- * @param options Additional error options.
39
- */
40
- constructor(
41
- public readonly type: AppErrorType,
42
- message?: string,
43
- options?: ErrorOptions,
44
- ) {
45
- super(message, options);
46
- }
47
- }
@@ -1,47 +0,0 @@
1
- import type { AppErrorType } from './app-error-type';
2
-
3
- /**
4
- * Represents an error that occurs in the application configuration.
5
- */
6
- export class AppConfigError extends Error {
7
- /**
8
- * Creates an instance of `AppConfigError` based on the HTTP response status.
9
- * @param response The HTTP response.
10
- * @param options Additional error options.
11
- * @returns An instance of `AppConfigError` based on the HTTP response status.
12
- */
13
- static fromHttpResponse(response: Response, options?: ErrorOptions): AppConfigError {
14
- // map well-known HTTP statuses to a specific error type
15
- switch (response.status) {
16
- case 401:
17
- return new AppConfigError(
18
- 'unauthorized',
19
- 'failed to load application config, request not authorized',
20
- options,
21
- );
22
- case 404:
23
- return new AppConfigError('not_found', 'application config not found', options);
24
- case 410:
25
- return new AppConfigError('deleted', 'application config deleted', options);
26
- }
27
- return new AppConfigError(
28
- 'unknown',
29
- `failed to load application config, status code ${response.status}`,
30
- options,
31
- );
32
- }
33
-
34
- /**
35
- * Creates an instance of `AppConfigError`.
36
- * @param type The type of the application error.
37
- * @param message The error message.
38
- * @param options Additional error options.
39
- */
40
- constructor(
41
- public readonly type: AppErrorType,
42
- message?: string,
43
- options?: ErrorOptions,
44
- ) {
45
- super(message, options);
46
- }
47
- }
@@ -1,47 +0,0 @@
1
- import type { AppErrorType } from './app-error-type';
2
-
3
- /**
4
- * Represents an error that occurs when loading an application manifest.
5
- */
6
- export class AppManifestError extends Error {
7
- /**
8
- * Creates an instance of AppManifestError based on the HTTP response status.
9
- * @param response The HTTP response.
10
- * @param options Optional error options.
11
- * @returns An instance of AppManifestError.
12
- */
13
- static fromHttpResponse(response: Response, options?: ErrorOptions) {
14
- // map well-known HTTP statuses to a specific error type
15
- switch (response.status) {
16
- case 401:
17
- return new AppManifestError(
18
- 'unauthorized',
19
- 'failed to load application manifest, request not authorized',
20
- options,
21
- );
22
- case 404:
23
- return new AppManifestError('not_found', 'application manifest not found', options);
24
- case 410:
25
- return new AppManifestError('deleted', 'application manifest deleted', options);
26
- }
27
- return new AppManifestError(
28
- 'unknown',
29
- `failed to load application manifest, status code ${response.status}`,
30
- options,
31
- );
32
- }
33
-
34
- /**
35
- * Creates an instance of AppManifestError.
36
- * @param type The type of the error.
37
- * @param message The error message.
38
- * @param options Optional error options.
39
- */
40
- constructor(
41
- public readonly type: AppErrorType,
42
- message?: string,
43
- options?: ErrorOptions,
44
- ) {
45
- super(message, options);
46
- }
47
- }
@@ -1,20 +0,0 @@
1
- import type { AppErrorType } from './app-error-type';
2
-
3
- /**
4
- * Represents an error that occurs when loading the application script.
5
- */
6
- export class AppScriptModuleError extends Error {
7
- /**
8
- * Creates a new instance of the AppScriptModuleError class.
9
- * @param type The type of the error.
10
- * @param message The error message.
11
- * @param options Additional options for the error.
12
- */
13
- constructor(
14
- public readonly type: AppErrorType,
15
- message?: string,
16
- options?: ErrorOptions,
17
- ) {
18
- super(message, options);
19
- }
20
- }
@@ -1,47 +0,0 @@
1
- import type { AppErrorType } from './app-error-type';
2
-
3
- /**
4
- * Represents an error that occurs while fetching application settings.
5
- */
6
- export class AppSettingsError extends Error {
7
- /**
8
- * Creates an instance of `AppSettingsError` based on the HTTP response status.
9
- * @param response The HTTP response.
10
- * @param options Additional error options.
11
- * @returns An instance of `AppSettingsError` based on the HTTP response status.
12
- */
13
- static fromHttpResponse(response: Response, options?: ErrorOptions): AppSettingsError {
14
- // map well-known HTTP statuses to a specific error type
15
- switch (response.status) {
16
- case 401:
17
- return new AppSettingsError(
18
- 'unauthorized',
19
- 'failed to load application settings, request not authorized',
20
- options,
21
- );
22
- case 404:
23
- return new AppSettingsError('not_found', 'application not found', options);
24
- case 410:
25
- return new AppSettingsError('deleted', 'application settings deleted', options);
26
- }
27
- return new AppSettingsError(
28
- 'unknown',
29
- `failed to load application settings, status code ${response.status}`,
30
- options,
31
- );
32
- }
33
-
34
- /**
35
- * Creates an instance of `AppSettingsError`.
36
- * @param type The type of the application error.
37
- * @param message The error message.
38
- * @param options Additional error options.
39
- */
40
- constructor(
41
- public readonly type: AppErrorType,
42
- message?: string,
43
- options?: ErrorOptions,
44
- ) {
45
- super(message, options);
46
- }
47
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Discriminant for application-related errors.
3
- *
4
- * - `'not_found'` – The requested resource does not exist (HTTP 404).
5
- * - `'unauthorized'` – The request lacks valid credentials (HTTP 401).
6
- * - `'deleted'` – The resource has been removed (HTTP 410).
7
- * - `'unknown'` – An unexpected failure occurred.
8
- */
9
- export type AppErrorType = 'not_found' | 'unauthorized' | 'unknown' | 'deleted';
package/src/errors.ts DELETED
@@ -1,6 +0,0 @@
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/src/events.ts DELETED
@@ -1,18 +0,0 @@
1
- import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
2
- import type { App } from './app/App';
3
-
4
- import './app/events';
5
-
6
- declare module '@equinor/fusion-framework-module-event' {
7
- interface FrameworkEventMap {
8
- /** fired when the current selected application changes */
9
- onCurrentAppChanged: FrameworkEvent<
10
- FrameworkEventInit<{
11
- /** current application */
12
- next?: App;
13
- /** previous application */
14
- previous?: App;
15
- }>
16
- >;
17
- }
18
- }
package/src/index.ts DELETED
@@ -1,40 +0,0 @@
1
- /**
2
- * @packageDocumentation
3
- *
4
- * Framework module for loading, configuring, and managing Fusion applications at runtime.
5
- *
6
- * Use {@link enableAppModule} to register the module with a framework configurator.
7
- * Once initialized, {@link AppModuleProvider} exposes methods for fetching app manifests,
8
- * configurations, user settings, and for setting the current active application.
9
- *
10
- * @example
11
- * ```ts
12
- * import { enableAppModule } from '@equinor/fusion-framework-module-app';
13
- *
14
- * export const configure = async (configurator: FrameworkConfigurator) => {
15
- * enableAppModule(configurator);
16
- * };
17
- * ```
18
- */
19
-
20
- export {
21
- AppModuleConfig,
22
- AppConfigurator,
23
- IAppConfigurator,
24
- type AppModuleConfig as IAppModuleConfig,
25
- } from './AppConfigurator';
26
-
27
- export { AppClient, type IAppClient } from './AppClient';
28
-
29
- export { AppConfig } from './AppConfig';
30
-
31
- export { AppModuleProvider } from './AppModuleProvider';
32
-
33
- export { IApp } from './app/App';
34
-
35
- export * from './events';
36
- export * from './types';
37
-
38
- export { enableAppModule } from './enable-app-module';
39
-
40
- export { default, AppModule, module, moduleKey } from './module';
@@ -1,77 +0,0 @@
1
- import type { Observable } from 'rxjs';
2
- import { of } from 'rxjs';
3
-
4
- import type { IHttpClient } from '@equinor/fusion-framework-module-http';
5
-
6
- import { AppClient } from '../AppClient.js';
7
- import type { AppConfig, AppManifest, ConfigEnvironment } from '../types.js';
8
-
9
- /**
10
- * An {@link AppClient} that answers `getAppManifest` and `getAppConfig` for one
11
- * known app locally, delegating everything else — other app keys, tagged
12
- * requests, builds, settings — to the real client it wraps.
13
- *
14
- * @remarks
15
- * Whatever `client` was resolved to (a pre-configured http client, or one created
16
- * through service discovery) still backs every method this class doesn't
17
- * override, so pointing service discovery at a different registry or a real
18
- * local mock server keeps working unchanged.
19
- *
20
- * @example
21
- * ```ts
22
- * builder.setClient(async ({ requireInstance }) => {
23
- * const http = await requireInstance('http');
24
- * return new MockAppClient(http.createClient('apps'), manifest, config);
25
- * });
26
- * ```
27
- */
28
- export class MockAppClient extends AppClient {
29
- #manifest: AppManifest;
30
- #config?: AppConfig;
31
-
32
- /**
33
- * @param client - The real {@link IHttpClient} to delegate all other requests to.
34
- * @param manifest - The manifest to return for `getAppManifest({ appKey: manifest.appKey })`.
35
- * @param config - The config to return for `getAppConfig({ appKey: manifest.appKey })`, if any.
36
- */
37
- constructor(client: IHttpClient, manifest: AppManifest, config?: AppConfig) {
38
- super(client);
39
- this.#manifest = manifest;
40
- this.#config = config;
41
- }
42
-
43
- /**
44
- * Answers with the manifest passed to the constructor when `args` matches
45
- * this client's own app key and no tag; otherwise delegates to the real client.
46
- *
47
- * @param args - The app key and optional tag to resolve a manifest for.
48
- * @returns An observable of the resolved {@link AppManifest}.
49
- */
50
- override getAppManifest(args: { appKey: string; tag?: string }): Observable<AppManifest> {
51
- return args.appKey === this.#manifest.appKey && args.tag === undefined
52
- ? of(this.#manifest)
53
- : super.getAppManifest(args);
54
- }
55
-
56
- /**
57
- * Answers with the config passed to the constructor when `args` matches this
58
- * client's own app key and tag; otherwise delegates to the real client.
59
- *
60
- * @template TType - The shape of the config's `environment` data.
61
- * @param args - The app key and optional tag to resolve config for.
62
- * @returns An observable of the resolved {@link AppConfig}.
63
- */
64
- override getAppConfig<TType extends ConfigEnvironment = ConfigEnvironment>(args: {
65
- appKey: string;
66
- tag?: string;
67
- }): Observable<AppConfig<TType>> {
68
- // config is fetched against the manifest's own build version, not an explicit override tag,
69
- // so a matching tag is treated the same as an absent one -- an explicit empty string is not
70
- const isOwnTag = args.tag === undefined || args.tag === this.#manifest.build?.version;
71
- return args.appKey === this.#manifest.appKey && isOwnTag && this.#config
72
- ? of(this.#config as AppConfig<TType>)
73
- : super.getAppConfig(args);
74
- }
75
- }
76
-
77
- export default MockAppClient;
package/src/mock/index.ts DELETED
@@ -1,13 +0,0 @@
1
- /**
2
- * Test doubles for the app module.
3
- *
4
- * @remarks
5
- * Imported from `@equinor/fusion-framework-module-app/mock`, so the mock ships
6
- * and versions with the implementation it stands in for.
7
- *
8
- * This entry point has no dependency on any test runner.
9
- *
10
- * @packageDocumentation
11
- */
12
-
13
- export { MockAppClient } from './MockAppClient.js';
package/src/module.ts DELETED
@@ -1,59 +0,0 @@
1
- import type { Module } from '@equinor/fusion-framework-module';
2
- import type { ModuleDeps } from './types';
3
-
4
- import { AppConfigurator } from './AppConfigurator';
5
- import { AppModuleProvider } from './AppModuleProvider';
6
-
7
- /** Module key used to register and look up the app module in the framework. */
8
- export const moduleKey = 'app';
9
-
10
- /**
11
- * Type alias for the app module definition, binding the module key,
12
- * provider type ({@link AppModuleProvider}), configurator type
13
- * ({@link AppConfigurator}), and required module dependencies.
14
- */
15
- export type AppModule = Module<typeof moduleKey, AppModuleProvider, AppConfigurator, ModuleDeps>;
16
-
17
- /**
18
- * Represents a module for handling applications.
19
- * Responsible for loading applications, configurations and manifests.
20
- * @public
21
- */
22
- export const module: AppModule = {
23
- /**
24
- * The name of the module.
25
- */
26
- name: moduleKey,
27
- /**
28
- * Configures the module.
29
- * @returns An instance of AppConfigurator.
30
- */
31
- configure: () => new AppConfigurator(),
32
- /**
33
- * Initializes the module.
34
- * @param args - The initialization arguments.
35
- * @returns A new instance of AppModuleProvider.
36
- */
37
- initialize: async (args) => {
38
- const config = await args.config.createConfigAsync(args);
39
- const event = await args.requireInstance('event').catch(() => undefined);
40
- return new AppModuleProvider({ config, event });
41
- },
42
- /**
43
- * Disposes the module.
44
- * @param args - The disposal arguments.
45
- */
46
- dispose: (args) => {
47
- // `args.instance` is typed as the generic module instance, but the module descriptor
48
- // guarantees it was created as an `AppModuleProvider` — safe to cast for disposal.
49
- (args.instance as unknown as AppModuleProvider).dispose();
50
- },
51
- };
52
-
53
- export default module;
54
-
55
- declare module '@equinor/fusion-framework-module' {
56
- interface Modules {
57
- app: AppModule;
58
- }
59
- }
package/src/schemas.ts DELETED
@@ -1,181 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- /**
4
- * Schema for the API application configuration.
5
- *
6
- * This schema validates the structure of the configuration object used for the API application.
7
- *
8
- * Properties:
9
- * - `environment` (optional): A record of key-value pairs where the value can be of any type. Defaults to an empty object.
10
- * - `endpoints` (optional): A record where each key maps to an object containing:
11
- * - `url`: A string representing the endpoint URL.
12
- * - `scopes` (optional): An array of strings representing the scopes. Defaults to an empty array.
13
- */
14
- export const ApiAppConfigSchema = z.object({
15
- environment: z.record(z.string(), z.any()).optional().default({}),
16
- endpoints: z
17
- .record(
18
- z.string(),
19
- z.object({
20
- url: z.string(),
21
- scopes: z.array(z.string()).optional().default([]),
22
- }),
23
- )
24
- .optional(),
25
- });
26
-
27
- export type ApiAppConfig = z.infer<typeof ApiAppConfigSchema>;
28
-
29
- /**
30
- * Schema for validating an API application person object.
31
- *
32
- * Properties:
33
- * - `azureUniqueId` (string): The unique identifier for the person in Azure.
34
- * - `displayName` (string): The display name of the person.
35
- * - `mail` (string | nullish): The email address of the person, which can be null or undefined.
36
- * - `upn` (string | nullish): The User Principal Name (UPN) of the person, which can be null or undefined.
37
- * - `accountType` (string): The type of account the person has.
38
- * - `accountClassification` (string | nullish): The classification of the account, which can be null or undefined.
39
- * - `isExpired` (boolean | nullish): Indicates whether the account is expired, which can be null or undefined.
40
- */
41
- const ApiApplicationPersonSchema = z.object({
42
- azureUniqueId: z.string({ message: 'The unique identifier for the person in Azure.' }),
43
- displayName: z.string({ message: 'The display name of the person.' }),
44
- mail: z
45
- .string({ message: 'The email address of the person, which can be null or undefined.' })
46
- .nullish(),
47
- upn: z
48
- .string({
49
- message: 'The User Principal Name (UPN) of the person, which can be null or undefined.',
50
- })
51
- .nullish(),
52
- accountType: z.string({ message: 'The type of account the person has.' }),
53
- accountClassification: z
54
- .string({ message: 'The classification of the account, which can be null or undefined.' })
55
- .nullish(),
56
- isExpired: z
57
- .boolean({
58
- message: 'Indicates whether the account is expired, which can be null or undefined.',
59
- })
60
- .nullish(),
61
- });
62
-
63
- /**
64
- * Schema for validating the options object on application builds.
65
- *
66
- * Known properties:
67
- * - `contextRouting` (optional): Routing strategy for context — `'path'` or `'query'`.
68
- *
69
- * The schema uses `.catchall(z.unknown())` to permit additional properties
70
- * at runtime without requiring them to be declared here. Add known properties
71
- * to this schema as they are introduced.
72
- */
73
- // Deliberately co-located with ApiApplicationBuildSchema, which depends on it
74
- // fusion-lint-disable-next-line single-export-per-file
75
- export const FrameworkOptionsSchema = z
76
- .object({
77
- contextRouting: z
78
- .enum(['path', 'query'], {
79
- message: "The routing strategy for context, which can be either 'path' or 'query'.",
80
- })
81
- .nullish(),
82
- })
83
- .catchall(z.unknown());
84
-
85
- /**
86
- * Schema for validating the structure of an API application build.
87
- *
88
- * Properties:
89
- * - `version`: The version of the application build.
90
- * - `entryPoint`: The entry point of the application.
91
- * - `tags`: An optional array of tags associated with the build.
92
- * - `tag`: An optional tag indicating the build type (can be any string, commonly 'latest' or 'preview').
93
- * - `assetPath`: An optional path to the build assets.
94
- * - `configUrl`: An optional URL to the build configuration.
95
- * - `timestamp`: An optional timestamp of the build.
96
- * - `commitSha`: An optional commit SHA of the build.
97
- * - `githubRepo`: An optional GitHub repository associated with the build.
98
- * - `projectPage`: An optional project page URL.
99
- * - `allowedExtensions`: An optional array of allowed extensions for the build.
100
- * - `options`: An optional record of additional build options, where the key is a string and the value can be of any type.
101
- * - `uploadedBy`: An optional schema for the person who uploaded the build.
102
- */
103
- // Deliberately co-located with ApiApplicationPersonSchema, which it depends on
104
- // fusion-lint-disable-next-line single-export-per-file
105
- export const ApiApplicationBuildSchema = z.object({
106
- version: z.string(),
107
- entryPoint: z.string(),
108
- tags: z.array(z.string()).nullish(),
109
- tag: z.string().nullish(),
110
- assetPath: z.string().nullish(),
111
- configUrl: z.string().nullish(),
112
- timestamp: z.string().nullish(),
113
- commitSha: z.string().nullish(),
114
- githubRepo: z.string().nullish(),
115
- projectPage: z.string().nullish(),
116
- options: FrameworkOptionsSchema.nullish().default({
117
- contextRouting: 'path',
118
- }),
119
- allowedExtensions: z.array(z.string()).nullish(),
120
- uploadedBy: ApiApplicationPersonSchema.nullish(),
121
- });
122
-
123
- /**
124
- * Schema for validating API application data.
125
- *
126
- * Properties:
127
- * - `appKey` (string): Unique key for the application.
128
- * - `displayName` (string): Display name of the application.
129
- * - `description` (string): Description of the application.
130
- * - `type` (string): Type of the application.
131
- * - `isPinned` (boolean | nullish): Indicates if the application is pinned.
132
- * - `templateSource` (string | nullish): Source template of the application.
133
- * - `category` (object | nullish): Category details of the application.
134
- * - `id` (string): Unique identifier for the category.
135
- * - `name` (string): Name of the category.
136
- * - `displayName` (string): Display name of the category.
137
- * - `color` (string): Color associated with the category.
138
- * - `defaultIcon` (string): Default icon for the category.
139
- * - `sortOrder` (number): Sort order for the category.
140
- * - `visualization` (object | nullish): Visualization details of the application.
141
- * - `color` (string | nullish): Color for visualization.
142
- * - `icon` (string | nullish): Icon for visualization.
143
- * - `sortOrder` (number): Sort order for visualization.
144
- * - `keywords` (array of strings | nullish): Keywords associated with the application.
145
- * - `admins` (array of ApiApplicationPersonSchema | nullish): List of admin users for the application.
146
- * - `owners` (array of ApiApplicationPersonSchema | nullish): List of owner users for the application.
147
- * - `build` (ApiApplicationBuildSchema | nullish): Build details of the application.
148
- */
149
- // Deliberately co-located with ApiApplicationPersonSchema and ApiApplicationBuildSchema, which it depends on
150
- // fusion-lint-disable-next-line single-export-per-file
151
- export const ApiApplicationSchema = z.object({
152
- appKey: z.string(),
153
- displayName: z.string(),
154
- description: z.string(),
155
- type: z.string(),
156
- isPinned: z.boolean().nullish(),
157
- templateSource: z.string().nullish(),
158
- category: z
159
- .object({
160
- id: z.string(),
161
- name: z.string(),
162
- displayName: z.string(),
163
- color: z.string(),
164
- defaultIcon: z.string(),
165
- sortOrder: z.number(),
166
- })
167
- .nullish(),
168
- visualization: z
169
- .object({
170
- color: z.string().nullish(),
171
- icon: z.string().nullish(),
172
- sortOrder: z.number(),
173
- })
174
- .nullish(),
175
- keywords: z.array(z.string()).nullish(),
176
- admins: z.array(ApiApplicationPersonSchema).nullish(),
177
- owners: z.array(ApiApplicationPersonSchema).nullish(),
178
- build: ApiApplicationBuildSchema.nullish(),
179
- });
180
-
181
- export type ApiApplication = z.infer<typeof ApiApplicationSchema>;