Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@equinor/fusion-framework-module-app

Package Overview
Dependencies
Maintainers
0
Versions
187
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@equinor/fusion-framework-module-app - npm Package Compare versions

Comparing version 5.3.11 to 5.3.12-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db

dist/esm/ApplicationManifest.js

6

CHANGELOG.md
# Change Log
## 5.3.12-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db
### Patch Changes
- [#2178](https://github.com/equinor/fusion-framework/pull/2178) [`20bf065`](https://github.com/equinor/fusion-framework/commit/20bf0650f0d578683f2310b6d96c4ce0be96b7db) Thanks [@eikeland](https://github.com/eikeland)! - TODO: write a proper changeset
## 5.3.11

@@ -4,0 +10,0 @@

2

dist/esm/app/actions.js

@@ -15,3 +15,3 @@ import { createAction, createAsyncAction, } from '@equinor/fusion-observable';

setConfig: createAction('set_config', (config) => ({ payload: config })),
fetchConfig: createAsyncAction('fetch_config', (key) => ({ payload: key }), (config) => ({ payload: config }), (error) => ({ payload: error })),
fetchConfig: createAsyncAction('fetch_config', (manifest) => ({ payload: manifest }), (config) => ({ payload: config }), (error) => ({ payload: error })),
/** App loading */

@@ -18,0 +18,0 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any

@@ -23,3 +23,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

import { Observable } from '@equinor/fusion-observable';
import { combineLatest, filter, firstValueFrom, lastValueFrom, map, Subscription, } from 'rxjs';
import { combineLatest, filter, firstValueFrom, lastValueFrom, map, of, Subscription, } from 'rxjs';
import { createState } from './create-state';

@@ -135,3 +135,8 @@ import { actions } from './actions';

loadConfig() {
__classPrivateFieldGet(this, _App_state, "f").next(actions.fetchConfig(this.appKey));
// TODO - shit fix
(this.manifest ? of(this.manifest) : this.getManifest()).subscribe({
next: (manifest) => {
__classPrivateFieldGet(this, _App_state, "f").next(actions.fetchConfig(manifest));
},
});
}

@@ -147,3 +152,8 @@ loadManifest(update) {

const manifest = yield this.getManifestAsync(allow_cache);
__classPrivateFieldGet(this, _App_state, "f").next(actions.importApp(manifest.entry));
if (manifest.build.entryPoint) {
__classPrivateFieldGet(this, _App_state, "f").next(actions.importApp(manifest.build.entryPoint));
}
else {
console.log(`The ${manifest.key} is missing entryPoint, please upload a build for the app before continuing`);
}
});

@@ -270,4 +280,12 @@ }

this.getManifest().subscribe((manifest) => {
// dispatch import_app action to load the application script
__classPrivateFieldGet(this, _App_state, "f").next(actions.importApp(manifest.entry));
var _a;
if (manifest.build.entryPoint) {
// TODO - this should come from backend
const assetPath = (_a = manifest.build.assetPath) !== null && _a !== void 0 ? _a : [manifest.key, manifest.build.version].join('@');
// dispatch import_app action to load the application script
__classPrivateFieldGet(this, _App_state, "f").next(actions.importApp([assetPath, manifest.build.entryPoint].join('/')));
}
else {
console.error(`The ${manifest.key} app is missing a entry in the manifest, upload a build for your app before continuing`);
}
}));

@@ -274,0 +292,0 @@ });

@@ -8,4 +8,6 @@ import { getBaseType, createReducer as makeReducer, isCompleteAction, isRequestAction, } from '@equinor/fusion-observable';

.addCase(actions.setManifest, (state, action) => {
var _a;
// TODO: after legacy is removed, remove the update flag
if (action.meta.update) {
state.manifest = Object.assign(Object.assign({}, state.manifest), action.payload);
state.manifest = Object.assign((_a = state.manifest) !== null && _a !== void 0 ? _a : {}, action.payload);
}

@@ -12,0 +14,0 @@ else {

@@ -13,5 +13,5 @@ import { FlowSubject } from '@equinor/fusion-observable';

// add handler for loading application script
state.addFlow(handleImportApplication());
state.addFlow(handleImportApplication(provider));
return state;
};
//# sourceMappingURL=create-state.js.map

@@ -41,5 +41,6 @@ import { from, of, concat } from 'rxjs';

// when request is received, abort any ongoing request and start new
switchMap(({ payload: appKey }) => {
// fetch manifest from provider
const subject = from(provider.getAppConfig(appKey)).pipe(
switchMap(({ payload }) => {
// TODO - use the configUrl directly from the manifest
// fetch config from provider
const subject = from(provider.getAppConfig(payload.key, payload.version)).pipe(
// filter out null values

@@ -49,4 +50,4 @@ filter((x) => !!x),

share());
// first load manifest and then dispatch success action
return concat(subject.pipe(map((manifest) => actions.setConfig(manifest))), subject.pipe(last(), map((manifest) => actions.fetchConfig.success(manifest)))).pipe(
// first load config and then dispatch success action
return concat(subject.pipe(map((config) => actions.setConfig(config))), subject.pipe(last(), map((config) => actions.fetchConfig.success(config)))).pipe(
// catch any error and dispatch failure action

@@ -61,3 +62,3 @@ catchError((err) => {

*/
export const handleImportApplication = () => (action$) => action$.pipe(
export const handleImportApplication = (provider) => (action$) => action$.pipe(
// only handle import script request actions

@@ -67,4 +68,5 @@ filter(actions.importApp.match),

switchMap(({ payload }) => {
const endpoint = [provider.getBaseUri(), payload].join('/').replace(/\/{2,}/g, '/');
// dynamically import the application script
return from(import(payload)).pipe(
return from(import(/* @vite-ignore */ endpoint)).pipe(
// dispatch success action

@@ -71,0 +73,0 @@ map(actions.importApp.success),

@@ -10,23 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _AppConfigurator_configBuilders;
import { AppConfigBuilder } from './AppConfigBuilder';
import { BaseConfigBuilder, } from '@equinor/fusion-framework-module';
import { moduleKey } from './module';
export class AppConfigurator {
import { ApplicationManifest } from './ApplicationManifest';
import { map } from 'rxjs/operators';
export class AppConfigurator extends BaseConfigBuilder {
constructor() {
super(...arguments);
this.defaultExpireTime = 1 * 60 * 1000;
_AppConfigurator_configBuilders.set(this, []);
}
addConfigBuilder(init) {
__classPrivateFieldGet(this, _AppConfigurator_configBuilders, "f").push(init);
}
setProxyPath(path) {
this.addConfigBuilder((builder) => {
builder.config.proxy = { path };
});
}
/**

@@ -47,22 +35,18 @@ * WARNING: this function will be remove in future

/** resolve and create a client from discovery */
try {
return yield serviceDiscovery.createClient('app');
}
catch (_a) {
return yield serviceDiscovery.createClient('portal');
}
return yield serviceDiscovery.createClient('apps');
}
});
}
createConfig(init) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const config = yield __classPrivateFieldGet(this, _AppConfigurator_configBuilders, "f").reduce((cur, cb) => __awaiter(this, void 0, void 0, function* () {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const builder = new AppConfigBuilder(init, yield cur);
yield Promise.resolve(cb(builder));
return Object.assign(cur, builder.config);
}), Promise.resolve({}));
// TODO - make less lazy
(_a = config.client) !== null && _a !== void 0 ? _a : (config.client = yield (() => __awaiter(this, void 0, void 0, function* () {
setClient(client_or_cb) {
const cb = typeof client_or_cb === 'object' ? () => client_or_cb : client_or_cb;
this._set('client', cb);
}
// TODO - explain why, used in import of resources aka proxy url
setBaseUri(base_or_cb) {
const cb = typeof base_or_cb === 'string' ? () => __awaiter(this, void 0, void 0, function* () { return base_or_cb; }) : base_or_cb;
this._set('baseUri', cb);
}
_createConfig(init, initial) {
if (!this._has('client')) {
this.setClient(() => __awaiter(this, void 0, void 0, function* () {
const httpClient = yield this._createHttpClient(init);

@@ -72,3 +56,9 @@ return {

client: {
fn: ({ appKey }) => httpClient.json$(`/api/apps/${appKey}`),
fn: ({ appKey }) => httpClient
.json$(`/apps/${appKey}`, {
headers: {
'Api-Version': '1.0',
},
})
.pipe(map((apiApp) => new ApplicationManifest(apiApp))),
},

@@ -80,6 +70,21 @@ key: ({ appKey }) => appKey,

client: {
fn: () => httpClient.json$(`/api/apps`),
// TODO: add to config if use me or not
fn: (filter) => {
const path = (filter === null || filter === void 0 ? void 0 : filter.filterByCurrentUser)
? '/persons/me/apps'
: '/apps';
return httpClient
.json$(path, {
headers: {
'Api-Version': '1.0',
},
})
.pipe(map((x) => {
const apps = x.value.map((apiApp) => new ApplicationManifest(apiApp));
return apps;
}));
},
},
// TODO - might cast to checksum
key: () => 'manifests',
key: (filter) => (filter ? JSON.stringify(filter) : 'all'),
expire: this.defaultExpireTime,

@@ -89,3 +94,7 @@ },

client: {
fn: ({ appKey, tag }) => httpClient.json$(`/api/apps/${appKey}/config${tag ? `?tag=${tag}` : ''}`),
fn: ({ appKey, tag = 'latest' }) => httpClient.json$(`/apps/${appKey}/builds/${tag}/config`, {
headers: {
'Api-Version': '1.0',
},
}),
},

@@ -96,8 +105,10 @@ key: (args) => JSON.stringify(args),

};
}))());
return config;
});
}));
}
if (!this._has('baseUri')) {
this.setBaseUri('/apps-proxy');
}
return super._createConfig(init, initial);
}
}
_AppConfigurator_configBuilders = new WeakMap();
//# sourceMappingURL=AppConfigurator.js.map

@@ -12,3 +12,3 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {

};
var _AppModuleProvider_appsClient, _AppModuleProvider_configClient, _AppModuleProvider_current$, _AppModuleProvider_subscription, _AppModuleProvider_event;
var _AppModuleProvider_appsClient, _AppModuleProvider_configClient, _AppModuleProvider_appBaseUri, _AppModuleProvider_current$, _AppModuleProvider_subscription, _AppModuleProvider_event;
import { BehaviorSubject, catchError, distinctUntilChanged, map, pairwise, Subscription, takeWhile, } from 'rxjs';

@@ -42,5 +42,7 @@ import { HttpResponseError } from '@equinor/fusion-framework-module-http';

constructor(args) {
var _a;
_AppModuleProvider_appsClient.set(this, void 0);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_AppModuleProvider_configClient.set(this, void 0);
_AppModuleProvider_appBaseUri.set(this, void 0);
_AppModuleProvider_current$.set(this, void 0);

@@ -55,2 +57,3 @@ _AppModuleProvider_subscription.set(this, new Subscription());

__classPrivateFieldSet(this, _AppModuleProvider_configClient, new Query(config.client.getAppConfig), "f");
__classPrivateFieldSet(this, _AppModuleProvider_appBaseUri, (_a = config.baseUri) !== null && _a !== void 0 ? _a : '', "f");
__classPrivateFieldGet(this, _AppModuleProvider_subscription, "f").add(() => this.appClient.complete());

@@ -88,7 +91,11 @@ __classPrivateFieldGet(this, _AppModuleProvider_subscription, "f").add(() => __classPrivateFieldGet(this, _AppModuleProvider_appsClient, "f").complete());

}
getAppManifests(filter) {
return Query.extractQueryValue(__classPrivateFieldGet(this, _AppModuleProvider_appsClient, "f").query(filter));
}
/**
* fetch all applications
* @deprecated use `getAppManifests` instead
*/
getAllAppManifests() {
return Query.extractQueryValue(__classPrivateFieldGet(this, _AppModuleProvider_appsClient, "f").query());
return this.getAppManifests();
}

@@ -123,2 +130,5 @@ /**

}
getBaseUri() {
return __classPrivateFieldGet(this, _AppModuleProvider_appBaseUri, "f");
}
/**

@@ -136,4 +146,4 @@ * This should not be used, only for legacy creation backdoor

}
_AppModuleProvider_appsClient = new WeakMap(), _AppModuleProvider_configClient = new WeakMap(), _AppModuleProvider_current$ = new WeakMap(), _AppModuleProvider_subscription = new WeakMap(), _AppModuleProvider_event = new WeakMap();
_AppModuleProvider_appsClient = new WeakMap(), _AppModuleProvider_configClient = new WeakMap(), _AppModuleProvider_appBaseUri = new WeakMap(), _AppModuleProvider_current$ = new WeakMap(), _AppModuleProvider_subscription = new WeakMap(), _AppModuleProvider_event = new WeakMap();
export default AppModuleProvider;
//# sourceMappingURL=AppModuleProvider.js.map

@@ -0,1 +1,10 @@

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { module } from './module';

@@ -8,10 +17,12 @@ /**

// eslint-disable-next-line @typescript-eslint/no-explicit-any
configurator, builder) => {
configurator, callback) => {
configurator.addConfig({
module,
configure: (appConfigurator) => {
builder && appConfigurator.addConfigBuilder(builder);
},
configure: (configurator) => __awaiter(void 0, void 0, void 0, function* () {
if (callback) {
Promise.resolve(callback(configurator));
}
}),
});
};
//# sourceMappingURL=enable-app-module.js.map
export { AppConfigurator, } from './AppConfigurator';
export { AppModuleProvider } from './AppModuleProvider';
export { ApplicationManifest } from './ApplicationManifest';
export * from './events';

@@ -4,0 +5,0 @@ export * from './types';

@@ -34,3 +34,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

initialize: (args) => __awaiter(void 0, void 0, void 0, function* () {
const config = yield args.config.createConfig(args);
const config = yield args.config.createConfigAsync(args);
const event = yield args.requireInstance('event').catch(() => undefined);

@@ -37,0 +37,0 @@ return new AppModuleProvider({ config, event });

import { ActionInstanceMap, ActionTypes } from '@equinor/fusion-observable';
import { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import { ApplicationManifest } from '../ApplicationManifest';
declare const createActions: () => {
/** Manifest loading */
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest, update?: boolean | undefined], AppManifest, "set_manifest", never, {
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: ApplicationManifest, update?: boolean | undefined], ApplicationManifest, "set_manifest", never, {
created: number;

@@ -12,3 +13,3 @@ update: boolean | undefined;

}> & {
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest], AppManifest, "fetch_manifest::success", never, never>;
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: ApplicationManifest], ApplicationManifest, "fetch_manifest::success", never, never>;
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_manifest::failure", never, never>;

@@ -18,3 +19,3 @@ };

setConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: AppConfig], AppConfig, "set_config", never, never>;
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[key: string], string, "fetch_config::request", never, never> & {
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest], AppManifest, "fetch_config::request", never, never> & {
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: AppConfig], AppConfig, "fetch_config::success", never, never>;

@@ -37,3 +38,3 @@ failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_config::failure", never, never>;

/** Manifest loading */
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest, update?: boolean | undefined], AppManifest, "set_manifest", never, {
setManifest: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: ApplicationManifest, update?: boolean | undefined], ApplicationManifest, "set_manifest", never, {
created: number;

@@ -45,3 +46,3 @@ update: boolean | undefined;

}> & {
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest], AppManifest, "fetch_manifest::success", never, never>;
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: ApplicationManifest], ApplicationManifest, "fetch_manifest::success", never, never>;
failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_manifest::failure", never, never>;

@@ -51,3 +52,3 @@ };

setConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: AppConfig], AppConfig, "set_config", never, never>;
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[key: string], string, "fetch_config::request", never, never> & {
fetchConfig: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[manifest: AppManifest], AppManifest, "fetch_config::request", never, never> & {
success: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[config: AppConfig], AppConfig, "fetch_config::success", never, never>;

@@ -54,0 +55,0 @@ failure: import("@equinor/fusion-observable").ActionCreatorWithPreparedPayload<[error: unknown], unknown, "fetch_config::failure", never, never>;

@@ -1,2 +0,2 @@

import { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppModulesInstance, AppScriptModule } from '../types';
import { Observable } from '@equinor/fusion-observable';

@@ -9,2 +9,3 @@ import type { AppModuleProvider } from '../AppModuleProvider';

import './events';
import { ApplicationManifest } from '../ApplicationManifest';
export declare function filterEmpty<T>(): OperatorFunction<T | null | undefined, T>;

@@ -21,3 +22,3 @@ /**

*/
get manifest$(): Observable<AppManifest>;
get manifest$(): Observable<ApplicationManifest>;
/**

@@ -52,3 +53,3 @@ * Observable that emits the configuration of the app.

*/
get manifest(): AppManifest | undefined;
get manifest(): Readonly<ApplicationManifest> | undefined;
/**

@@ -58,3 +59,3 @@ * Retrieves the manifest asynchronously.

*/
get manifestAsync(): Promise<AppManifest>;
get manifestAsync(): Promise<Readonly<ApplicationManifest>>;
/**

@@ -86,3 +87,3 @@ * Gets the configuration of the app.

initialize(): Observable<{
manifest: AppManifest;
manifest: ApplicationManifest;
script: AppScriptModule;

@@ -121,3 +122,3 @@ config: AppConfig;

*/
getManifest(force_refresh?: boolean): Observable<AppManifest>;
getManifest(force_refresh?: boolean): Observable<ApplicationManifest>;
/**

@@ -128,3 +129,3 @@ * Retrieves the app manifest asynchronously.

*/
getManifestAsync(allow_cache?: boolean): Promise<AppManifest>;
getManifestAsync(allow_cache?: boolean): Promise<ApplicationManifest>;
/**

@@ -145,3 +146,3 @@ * Gets the app module.

#private;
get manifest$(): Observable<AppManifest>;
get manifest$(): Observable<ApplicationManifest>;
get config$(): Observable<AppConfig<TEnv>>;

@@ -152,4 +153,4 @@ get modules$(): Observable<AppScriptModule>;

get appKey(): string;
get manifest(): Readonly<AppManifest> | undefined;
get manifestAsync(): Promise<Readonly<AppManifest>>;
get manifest(): Readonly<ApplicationManifest> | undefined;
get manifestAsync(): Promise<Readonly<ApplicationManifest>>;
get config(): Readonly<AppConfig<TEnv>> | undefined;

@@ -163,3 +164,3 @@ get configAsync(): Promise<Readonly<AppConfig<TEnv>>>;

initialize(): Observable<{
manifest: AppManifest;
manifest: ApplicationManifest;
script: AppScriptModule;

@@ -170,8 +171,8 @@ config: AppConfig;

loadManifest(update?: boolean): void;
updateManifest(manifest: AppManifest, replace?: false): void;
updateManifest(manifest: ApplicationManifest, replace?: false): void;
loadAppModule(allow_cache?: boolean): Promise<void>;
getConfig(force_refresh?: boolean): Observable<AppConfig>;
getConfigAsync(allow_cache?: boolean): Promise<AppConfig>;
getManifest(force_refresh?: boolean): Observable<AppManifest>;
getManifestAsync(allow_cache?: boolean): Promise<AppManifest>;
getManifest(force_refresh?: boolean): Observable<ApplicationManifest>;
getManifestAsync(allow_cache?: boolean): Promise<ApplicationManifest>;
getAppModule(force_refresh?: boolean): Observable<AppScriptModule>;

@@ -178,0 +179,0 @@ getAppModuleAsync(allow_cache?: boolean): Promise<AppScriptModule>;

import { AppBundleState, AppBundleStateInitial } from './types';
export declare const createReducer: (value: AppBundleStateInitial) => import("@equinor/fusion-observable").ReducerWithInitialState<AppBundleState, import("@equinor/fusion-observable").PayloadAction<import("..").AppManifest, "set_manifest", {
export declare const createReducer: (value: AppBundleStateInitial) => import("@equinor/fusion-observable").ReducerWithInitialState<AppBundleState, import("@equinor/fusion-observable").PayloadAction<import("..").ApplicationManifest, "set_manifest", {
created: number;

@@ -11,3 +11,3 @@ update: boolean | undefined;

} | {
payload: string;
payload: import("..").AppManifest;
type: "fetch_config::request";

@@ -27,3 +27,3 @@ } | {

} | {
payload: import("..").AppManifest;
payload: import("..").ApplicationManifest;
type: "fetch_manifest::success";

@@ -30,0 +30,0 @@ } | {

@@ -25,2 +25,2 @@ import type { Flow } from '@equinor/fusion-observable';

*/
export declare const handleImportApplication: () => Flow<Actions, AppBundleState>;
export declare const handleImportApplication: (provider: AppModuleProvider) => Flow<Actions, AppBundleState>;

@@ -1,6 +0,7 @@

import type { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppModulesInstance, AppScriptModule } from '../types';
import { ApplicationManifest } from '../ApplicationManifest';
export type AppBundleState<TConfig = any, TModules = any> = {
appKey: string;
status: Set<string>;
manifest?: AppManifest;
manifest?: ApplicationManifest;
config?: AppConfig<TConfig>;

@@ -7,0 +8,0 @@ modules?: AppScriptModule;

@@ -1,16 +0,15 @@

import type { ModuleInitializerArgs } from '@equinor/fusion-framework-module';
import { BaseConfigBuilder, ConfigBuilderCallback, type ModuleInitializerArgs } from '@equinor/fusion-framework-module';
import type { HttpModule, IHttpClient } from '@equinor/fusion-framework-module-http';
import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';
import type { QueryCtorOptions } from '@equinor/fusion-query';
import { AppConfigBuilderCallback } from './AppConfigBuilder';
import type { AppConfig, AppManifest } from './types';
import type { AppConfig } from './types';
import { ApplicationManifest } from './ApplicationManifest';
export interface AppModuleConfig {
proxy: {
path: string;
};
client: {
getAppManifest: QueryCtorOptions<AppManifest, {
getAppManifest: QueryCtorOptions<ApplicationManifest, {
appKey: string;
}>;
getAppManifests: QueryCtorOptions<AppManifest[], void>;
getAppManifests: QueryCtorOptions<ApplicationManifest[], {
filterByCurrentUser?: boolean;
} | undefined>;
getAppConfig: QueryCtorOptions<AppConfig, {

@@ -21,11 +20,10 @@ appKey: string;

};
baseUri?: string;
}
export interface IAppConfigurator {
addConfigBuilder: (init: AppConfigBuilderCallback) => void;
setClient: (client_or_cb: Promise<AppModuleConfig['client']> | ConfigBuilderCallback<AppModuleConfig['client']>) => void;
setBaseUri: (base_or_cb: string | ConfigBuilderCallback<string>) => void;
}
export declare class AppConfigurator implements IAppConfigurator {
#private;
export declare class AppConfigurator extends BaseConfigBuilder<AppModuleConfig> implements IAppConfigurator {
defaultExpireTime: number;
addConfigBuilder(init: AppConfigBuilderCallback): void;
setProxyPath(path: string): void;
/**

@@ -35,3 +33,5 @@ * WARNING: this function will be remove in future

protected _createHttpClient(init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>): Promise<IHttpClient>;
createConfig(init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>): Promise<AppModuleConfig>;
setClient(client_or_cb: Promise<AppModuleConfig['client']> | ConfigBuilderCallback<AppModuleConfig['client']>): void;
setBaseUri(base_or_cb: string | ConfigBuilderCallback<string>): void;
protected _createConfig(init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>, initial?: Partial<AppModuleConfig>): import("rxjs").ObservableInput<AppModuleConfig>;
}

@@ -5,3 +5,4 @@ import { Observable } from 'rxjs';

import { Query } from '@equinor/fusion-query';
import type { AppConfig, AppManifest, CurrentApp } from './types';
import type { AppConfig, CurrentApp } from './types';
import { ApplicationManifest } from './ApplicationManifest';
import { App, IApp } from './app/App';

@@ -12,4 +13,4 @@ import { AppModuleConfig } from './AppConfigurator';

#private;
static compareAppManifest<T extends AppManifest>(a?: T, b?: T): boolean;
appClient: Query<AppManifest, {
static compareAppManifest<T extends ApplicationManifest>(a?: T, b?: T): boolean;
appClient: Query<ApplicationManifest, {
appKey: string;

@@ -34,7 +35,11 @@ }>;

*/
getAppManifest(appKey: string): Observable<AppManifest>;
getAppManifest(appKey: string): Observable<ApplicationManifest>;
getAppManifests(filter?: {
filterByCurrentUser: boolean;
}): Observable<ApplicationManifest[]>;
/**
* fetch all applications
* @deprecated use `getAppManifests` instead
*/
getAllAppManifests(): Observable<AppManifest[]>;
getAllAppManifests(): Observable<ApplicationManifest[]>;
/**

@@ -51,2 +56,3 @@ * fetch configuration for an application

clearCurrentApp(): void;
getBaseUri(): string;
/**

@@ -53,0 +59,0 @@ * This should not be used, only for legacy creation backdoor

import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
import type { AppConfigBuilderCallback } from './AppConfigBuilder';
import { AppConfigurator } from './AppConfigurator';
/**

@@ -7,2 +7,2 @@ * Method for enabling the Service module

*/
export declare const enableAppModule: (configurator: IModulesConfigurator<any, any>, builder?: AppConfigBuilderCallback) => void;
export declare const enableAppModule: (configurator: IModulesConfigurator<any, any>, callback?: (builder: AppConfigurator) => void | Promise<void>) => void;
export { AppModuleConfig, AppConfigurator, IAppConfigurator, AppModuleConfig as IAppModuleConfig, } from './AppConfigurator';
export { AppModuleProvider } from './AppModuleProvider';
export { IApp } from './app/App';
export { ApplicationManifest } from './ApplicationManifest';
export * from './events';

@@ -5,0 +6,0 @@ export * from './types';

import { Module } from '@equinor/fusion-framework-module';
import { ModuleDeps } from './types';
import { IAppConfigurator } from './AppConfigurator';
import { AppConfigurator } from './AppConfigurator';
import { AppModuleProvider } from './AppModuleProvider';
export declare const moduleKey = "app";
export type AppModule = Module<typeof moduleKey, AppModuleProvider, IAppConfigurator, ModuleDeps>;
export type AppModule = Module<typeof moduleKey, AppModuleProvider, AppConfigurator, ModuleDeps>;
/**

@@ -8,0 +8,0 @@ * Represents a module for handling applications.

@@ -7,6 +7,7 @@ import { AnyModule, CombinedModules, ModulesInstance } from '@equinor/fusion-framework-module';

import IApp from './app';
import { ApplicationManifest } from './ApplicationManifest';
type Fusion = any;
export type AppEnv<TConfig = unknown, TProps = unknown> = {
basename?: string;
manifest?: AppManifest;
manifest?: ApplicationManifest;
config?: AppConfig<TConfig>;

@@ -16,3 +17,3 @@ props?: TProps;

export type ModuleDeps = [HttpModule, ServiceDiscoveryModule, EventModule];
export type AppType = 'standalone' | 'report' | 'launcher';
export type AppType = 'standalone' | 'report' | 'launcher' | 'template';
export type CurrentApp<TModules extends Array<AnyModule> = [], TEnv = any> = IApp<TEnv, TModules> | null | undefined;

@@ -24,20 +25,65 @@ export type AppAuth = {

type AppCategory = {
id?: string;
name: string | null;
color: string | null;
defaultIcon: string | null;
id: string;
name?: string | null;
displayName?: string | null;
color?: string | null;
defaultIcon?: string | null;
sortOrder: number;
};
export type AppManifest = {
type AppVisualization = {
color?: string | null;
icon?: string | null;
sortOrder: number;
};
export type AzureId = {
azureId: string;
};
export type AzureUniqueId = {
azureUniqueId: string;
};
export type AppBuild<TUploaderId = AzureId | AzureUniqueId> = {
version?: string;
entryPoint?: string;
tags?: string[];
tag?: string;
assetPath?: string;
configUrl?: string;
timestamp?: string;
commitSha?: string;
githubRepo?: string;
projectPage?: string;
uploadedBy?: {
displayName?: string;
mail?: string;
upn?: string;
accountType?: string;
accountClassification?: string;
} & TUploaderId;
};
export type AppOwnerOrAdmin = {
id: string;
azureId?: string;
azureUniqueId?: string;
displayName?: string;
mail?: string;
upn?: string;
accountType?: string;
accountClassification?: string;
};
export interface AppManifest {
key: string;
name: string;
entry: string;
version: string;
name?: string;
entry?: string;
version?: string;
shortName?: string;
description?: string;
keywords?: string[];
type?: AppType;
isPinned?: boolean;
tags?: string[];
auth?: AppAuth[];
tag?: string;
auth?: AppOwnerOrAdmin[];
icon?: string;
order?: number;
publishedDate?: Date;
publishedDate?: string;
accentColor?: string;

@@ -47,11 +93,14 @@ categoryId?: string;

hide?: boolean;
};
visualization?: AppVisualization;
admins?: AppOwnerOrAdmin[];
owners?: AppOwnerOrAdmin[];
build?: AppBuild<AzureId>;
}
export type Endpoint = {
name: string;
uri: string;
url: string;
scopes?: string[];
};
export type AppConfig<TEnvironment = unknown> = {
environment: TEnvironment;
endpoints: Record<string, string | Endpoint>;
environment?: TEnvironment;
endpoints?: Record<string, Endpoint>;
};

@@ -63,3 +112,3 @@ /**

export type AppBundle<TEnvironment = unknown, TModule = unknown> = {
manifest: AppManifest;
manifest: ApplicationManifest;
config: AppConfig<TEnvironment>;

@@ -82,2 +131,27 @@ module: TModule;

export type AppModulesInstance<TModules extends Array<AnyModule> | unknown = unknown> = ModulesInstance<AppModules<TModules>>;
export type ApiAppVersionConfig = {
environment: string;
endpoints: Record<string, {
url: string;
scopes: string[];
}>;
};
export type ApiApp = {
appKey: string;
displayName?: string;
description?: string;
type?: AppType;
isPinned?: boolean;
templateSource?: string;
category?: AppCategory;
visualization: {
color: string;
icon: string;
sortOrder: number;
};
keywords: string[];
admins: AppOwnerOrAdmin[];
owners: AppOwnerOrAdmin[];
build: AppBuild<AzureUniqueId>;
};
export {};
{
"name": "@equinor/fusion-framework-module-app",
"version": "5.3.11",
"version": "5.3.12-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db",
"description": "",

@@ -56,7 +56,7 @@ "main": "dist/esm/index.js",

"typescript": "^5.5.4",
"@equinor/fusion-framework-module": "^4.3.4",
"@equinor/fusion-framework-module-event": "^4.2.3",
"@equinor/fusion-framework-module-http": "^6.0.3",
"@equinor/fusion-framework-module-msal": "^3.1.4",
"@equinor/fusion-framework-module-service-discovery": "^7.1.13"
"@equinor/fusion-framework-module": "^4.3.5-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db",
"@equinor/fusion-framework-module-event": "^4.2.4-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db",
"@equinor/fusion-framework-module-http": "^6.1.0-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db",
"@equinor/fusion-framework-module-msal": "^3.1.5-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db",
"@equinor/fusion-framework-module-service-discovery": "^8.0.0-alpha-20bf0650f0d578683f2310b6d96c4ce0be96b7db"
},

@@ -63,0 +63,0 @@ "scripts": {

@@ -7,14 +7,18 @@ import {

} from '@equinor/fusion-observable';
import { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import { ApplicationManifest } from '../ApplicationManifest';
const createActions = () => ({
/** Manifest loading */
setManifest: createAction('set_manifest', (manifest: AppManifest, update?: boolean) => ({
payload: manifest,
meta: {
// TODO when updating
created: Date.now(),
update,
},
})),
setManifest: createAction(
'set_manifest',
(manifest: ApplicationManifest, update?: boolean) => ({
payload: manifest,
meta: {
// TODO when updating
created: Date.now(),
update,
},
}),
),

@@ -24,3 +28,3 @@ fetchManifest: createAsyncAction(

(key: string, update?: boolean) => ({ payload: key, meta: { update } }),
(manifest: AppManifest) => ({ payload: manifest }),
(manifest: ApplicationManifest) => ({ payload: manifest }),
(error: unknown) => ({ payload: error }),

@@ -32,3 +36,3 @@ ),

'fetch_config',
(key: string) => ({ payload: key }),
(manifest: AppManifest) => ({ payload: manifest }),
(config: AppConfig) => ({ payload: config }),

@@ -35,0 +39,0 @@ (error: unknown) => ({ payload: error }),

@@ -1,2 +0,2 @@

import { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppModulesInstance, AppScriptModule } from '../types';
import { FlowSubject, Observable } from '@equinor/fusion-observable';

@@ -11,2 +11,3 @@

map,
of,
OperatorFunction,

@@ -22,2 +23,3 @@ Subscription,

import './events';
import { ApplicationManifest } from '../ApplicationManifest';

@@ -40,3 +42,3 @@ // TODO - move globally

*/
get manifest$(): Observable<AppManifest>;
get manifest$(): Observable<ApplicationManifest>;

@@ -77,3 +79,3 @@ /**

*/
get manifest(): AppManifest | undefined;
get manifest(): Readonly<ApplicationManifest> | undefined;

@@ -84,3 +86,3 @@ /**

*/
get manifestAsync(): Promise<AppManifest>;
get manifestAsync(): Promise<Readonly<ApplicationManifest>>;

@@ -115,3 +117,3 @@ /**

initialize(): Observable<{
manifest: AppManifest;
manifest: ApplicationManifest;
script: AppScriptModule;

@@ -156,3 +158,3 @@ config: AppConfig;

*/
getManifest(force_refresh?: boolean): Observable<AppManifest>;
getManifest(force_refresh?: boolean): Observable<ApplicationManifest>;

@@ -164,3 +166,3 @@ /**

*/
getManifestAsync(allow_cache?: boolean): Promise<AppManifest>;
getManifestAsync(allow_cache?: boolean): Promise<ApplicationManifest>;

@@ -191,3 +193,3 @@ /**

get manifest$(): Observable<AppManifest> {
get manifest$(): Observable<ApplicationManifest> {
return this.#state.pipe(

@@ -231,7 +233,7 @@ map(({ manifest }) => manifest),

get manifest(): Readonly<AppManifest> | undefined {
get manifest(): Readonly<ApplicationManifest> | undefined {
return this.state.manifest;
}
get manifestAsync(): Promise<Readonly<AppManifest>> {
get manifestAsync(): Promise<Readonly<ApplicationManifest>> {
return firstValueFrom(this.manifest$);

@@ -415,3 +417,3 @@ }

public initialize(): Observable<{
manifest: AppManifest;
manifest: ApplicationManifest;
script: AppScriptModule;

@@ -452,3 +454,8 @@ config: AppConfig;

public loadConfig() {
this.#state.next(actions.fetchConfig(this.appKey));
// TODO - shit fix
(this.manifest ? of(this.manifest) : this.getManifest()).subscribe({
next: (manifest) => {
this.#state.next(actions.fetchConfig(manifest));
},
});
}

@@ -460,3 +467,3 @@

public updateManifest(manifest: AppManifest, replace?: false) {
public updateManifest(manifest: ApplicationManifest, replace?: false) {
this.#state.next(actions.setManifest(manifest, !replace));

@@ -467,3 +474,9 @@ }

const manifest = await this.getManifestAsync(allow_cache);
this.#state.next(actions.importApp(manifest.entry));
if (manifest.build.entryPoint) {
this.#state.next(actions.importApp(manifest.build.entryPoint));
} else {
console.log(
`The ${manifest.key} is missing entryPoint, please upload a build for the app before continuing`,
);
}
}

@@ -523,3 +536,3 @@

public getManifest(force_refresh = false): Observable<AppManifest> {
public getManifest(force_refresh = false): Observable<ApplicationManifest> {
return new Observable((subscriber) => {

@@ -568,3 +581,3 @@ if (this.#state.value.manifest) {

public getManifestAsync(allow_cache = true): Promise<AppManifest> {
public getManifestAsync(allow_cache = true): Promise<ApplicationManifest> {
// when allow_cache is true, use first emitted value, otherwise use last emitted value

@@ -621,4 +634,16 @@ const operator = allow_cache ? firstValueFrom : lastValueFrom;

this.getManifest().subscribe((manifest) => {
// dispatch import_app action to load the application script
this.#state.next(actions.importApp(manifest.entry));
if (manifest.build.entryPoint) {
// TODO - this should come from backend
const assetPath =
manifest.build.assetPath ??
[manifest.key, manifest.build.version].join('@');
// dispatch import_app action to load the application script
this.#state.next(
actions.importApp([assetPath, manifest.build.entryPoint].join('/')),
);
} else {
console.error(
`The ${manifest.key} app is missing a entry in the manifest, upload a build for your app before continuing`,
);
}
}),

@@ -625,0 +650,0 @@ );

@@ -23,4 +23,5 @@ import {

.addCase(actions.setManifest, (state, action) => {
// TODO: after legacy is removed, remove the update flag
if (action.meta.update) {
state.manifest = { ...state.manifest, ...action.payload };
state.manifest = Object.assign(state.manifest ?? {}, action.payload);
} else {

@@ -27,0 +28,0 @@ state.manifest = action.payload;

@@ -27,5 +27,5 @@ import { FlowSubject } from '@equinor/fusion-observable';

// add handler for loading application script
state.addFlow(handleImportApplication());
state.addFlow(handleImportApplication(provider));
return state;
};

@@ -69,5 +69,6 @@ import { from, of, concat } from 'rxjs';

// when request is received, abort any ongoing request and start new
switchMap(({ payload: appKey }) => {
// fetch manifest from provider
const subject = from(provider.getAppConfig(appKey)).pipe(
switchMap(({ payload }) => {
// TODO - use the configUrl directly from the manifest
// fetch config from provider
const subject = from(provider.getAppConfig(payload.key, payload.version)).pipe(
// filter out null values

@@ -78,8 +79,8 @@ filter((x) => !!x),

);
// first load manifest and then dispatch success action
// first load config and then dispatch success action
return concat(
subject.pipe(map((manifest) => actions.setConfig(manifest))),
subject.pipe(map((config) => actions.setConfig(config))),
subject.pipe(
last(),
map((manifest) => actions.fetchConfig.success(manifest)),
map((config) => actions.fetchConfig.success(config)),
),

@@ -99,16 +100,19 @@ ).pipe(

*/
export const handleImportApplication = (): Flow<Actions, AppBundleState> => (action$) =>
action$.pipe(
// only handle import script request actions
filter(actions.importApp.match),
// when request is received, abort any ongoing request and start new
switchMap(({ payload }) => {
// dynamically import the application script
return from(import(payload)).pipe(
// dispatch success action
map(actions.importApp.success),
// catch any error and dispatch failure action
catchError((err) => of(actions.importApp.failure(err))),
);
}),
);
export const handleImportApplication =
(provider: AppModuleProvider): Flow<Actions, AppBundleState> =>
(action$) =>
action$.pipe(
// only handle import script request actions
filter(actions.importApp.match),
// when request is received, abort any ongoing request and start new
switchMap(({ payload }) => {
const endpoint = [provider.getBaseUri(), payload].join('/').replace(/\/{2,}/g, '/');
// dynamically import the application script
return from(import(/* @vite-ignore */ endpoint)).pipe(
// dispatch success action
map(actions.importApp.success),
// catch any error and dispatch failure action
catchError((err) => of(actions.importApp.failure(err))),
);
}),
);

@@ -1,2 +0,3 @@

import type { AppConfig, AppManifest, AppModulesInstance, AppScriptModule } from '../types';
import type { AppConfig, AppModulesInstance, AppScriptModule } from '../types';
import { ApplicationManifest } from '../ApplicationManifest';

@@ -7,3 +8,3 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any

status: Set<string>;
manifest?: AppManifest;
manifest?: ApplicationManifest;
config?: AppConfig<TConfig>;

@@ -10,0 +11,0 @@ modules?: AppScriptModule;

@@ -1,2 +0,6 @@

import type { ModuleInitializerArgs } from '@equinor/fusion-framework-module';
import {
BaseConfigBuilder,
ConfigBuilderCallback,
type ModuleInitializerArgs,
} from '@equinor/fusion-framework-module';
import type { HttpModule, IHttpClient } from '@equinor/fusion-framework-module-http';

@@ -6,38 +10,35 @@ import type { ServiceDiscoveryModule } from '@equinor/fusion-framework-module-service-discovery';

import { AppConfigBuilder, AppConfigBuilderCallback } from './AppConfigBuilder';
import { moduleKey } from './module';
import type { AppConfig, AppManifest } from './types';
import type { AppConfig, ApiApp, ApiAppVersionConfig } from './types';
import { ApplicationManifest } from './ApplicationManifest';
import { map } from 'rxjs/operators';
export interface AppModuleConfig {
proxy: {
path: string;
};
client: {
getAppManifest: QueryCtorOptions<AppManifest, { appKey: string }>;
getAppManifests: QueryCtorOptions<AppManifest[], void>;
getAppManifest: QueryCtorOptions<ApplicationManifest, { appKey: string }>;
getAppManifests: QueryCtorOptions<
ApplicationManifest[],
{ filterByCurrentUser?: boolean } | undefined
>;
getAppConfig: QueryCtorOptions<AppConfig, { appKey: string; tag?: string }>;
};
baseUri?: string;
}
export interface IAppConfigurator {
addConfigBuilder: (init: AppConfigBuilderCallback) => void;
setClient: (
client_or_cb:
| Promise<AppModuleConfig['client']>
| ConfigBuilderCallback<AppModuleConfig['client']>,
) => void;
setBaseUri: (base_or_cb: string | ConfigBuilderCallback<string>) => void;
}
export class AppConfigurator implements IAppConfigurator {
export class AppConfigurator
extends BaseConfigBuilder<AppModuleConfig>
implements IAppConfigurator
{
defaultExpireTime = 1 * 60 * 1000;
#configBuilders: Array<AppConfigBuilderCallback> = [];
addConfigBuilder(init: AppConfigBuilderCallback): void {
this.#configBuilders.push(init);
}
setProxyPath(path: string) {
this.addConfigBuilder((builder) => {
builder.config.proxy = { path };
});
}
/**

@@ -59,57 +60,95 @@ * WARNING: this function will be remove in future

/** resolve and create a client from discovery */
try {
return await serviceDiscovery.createClient('app');
} catch {
return await serviceDiscovery.createClient('portal');
}
return await serviceDiscovery.createClient('apps');
}
}
public async createConfig(
public setClient(
client_or_cb:
| Promise<AppModuleConfig['client']>
| ConfigBuilderCallback<AppModuleConfig['client']>,
) {
const cb = typeof client_or_cb === 'object' ? () => client_or_cb : client_or_cb;
this._set('client', cb);
}
// TODO - explain why, used in import of resources aka proxy url
public setBaseUri(base_or_cb: string | ConfigBuilderCallback<string>) {
const cb = typeof base_or_cb === 'string' ? async () => base_or_cb : base_or_cb;
this._set('baseUri', cb);
}
protected _createConfig(
init: ModuleInitializerArgs<IAppConfigurator, [HttpModule, ServiceDiscoveryModule]>,
): Promise<AppModuleConfig> {
const config = await this.#configBuilders.reduce(
async (cur, cb) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const builder = new AppConfigBuilder(init, await cur);
await Promise.resolve(cb(builder));
return Object.assign(cur, builder.config);
},
Promise.resolve({} as Partial<AppModuleConfig>),
);
// TODO - make less lazy
config.client ??= await (async (): Promise<AppModuleConfig['client']> => {
const httpClient = await this._createHttpClient(init);
return {
getAppManifest: {
client: {
fn: ({ appKey }) => httpClient.json$<AppManifest>(`/api/apps/${appKey}`),
initial?: Partial<AppModuleConfig>,
) {
if (!this._has('client')) {
this.setClient(async () => {
const httpClient = await this._createHttpClient(init);
return {
getAppManifest: {
client: {
fn: ({ appKey }) =>
httpClient
.json$<ApiApp>(`/apps/${appKey}`, {
headers: {
'Api-Version': '1.0',
},
})
.pipe(map((apiApp) => new ApplicationManifest(apiApp))),
},
key: ({ appKey }) => appKey,
expire: this.defaultExpireTime,
},
key: ({ appKey }) => appKey,
expire: this.defaultExpireTime,
},
getAppManifests: {
client: {
fn: () => httpClient.json$(`/api/apps`),
getAppManifests: {
client: {
// TODO: add to config if use me or not
fn: (filter) => {
const path = filter?.filterByCurrentUser
? '/persons/me/apps'
: '/apps';
return httpClient
.json$<{ value: ApiApp[] }>(path, {
headers: {
'Api-Version': '1.0',
},
})
.pipe(
map((x) => {
const apps = x.value.map(
(apiApp) => new ApplicationManifest(apiApp),
);
return apps;
}),
);
},
},
// TODO - might cast to checksum
key: (filter) => (filter ? JSON.stringify(filter) : 'all'),
expire: this.defaultExpireTime,
},
// TODO - might cast to checksum
key: () => 'manifests',
expire: this.defaultExpireTime,
},
getAppConfig: {
client: {
fn: ({ appKey, tag }) =>
httpClient.json$(
`/api/apps/${appKey}/config${tag ? `?tag=${tag}` : ''}`,
),
getAppConfig: {
client: {
fn: ({ appKey, tag = 'latest' }) =>
httpClient.json$<ApiAppVersionConfig>(
`/apps/${appKey}/builds/${tag}/config`,
{
headers: {
'Api-Version': '1.0',
},
},
),
},
key: (args) => JSON.stringify(args),
expire: this.defaultExpireTime,
},
key: (args) => JSON.stringify(args),
expire: this.defaultExpireTime,
},
};
})();
};
});
}
return config as AppModuleConfig;
if (!this._has('baseUri')) {
this.setBaseUri('/apps-proxy');
}
return super._createConfig(init, initial);
}
}

@@ -18,3 +18,4 @@ import {

import type { AppConfig, AppManifest, CurrentApp } from './types';
import type { AppConfig, CurrentApp } from './types';
import { ApplicationManifest } from './ApplicationManifest';

@@ -27,11 +28,13 @@ import { App, filterEmpty, IApp } from './app/App';

export class AppModuleProvider {
static compareAppManifest<T extends AppManifest>(a?: T, b?: T): boolean {
static compareAppManifest<T extends ApplicationManifest>(a?: T, b?: T): boolean {
return JSON.stringify(a) === JSON.stringify(b);
}
public appClient: Query<AppManifest, { appKey: string }>;
#appsClient: Query<AppManifest[], void>;
public appClient: Query<ApplicationManifest, { appKey: string }>;
#appsClient: Query<ApplicationManifest[], { filterByCurrentUser?: boolean } | undefined>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
#configClient: Query<AppConfig<any>, { appKey: string; tag?: string }>;
#appBaseUri: string;
#current$: BehaviorSubject<CurrentApp | null>;

@@ -76,2 +79,4 @@

this.#appBaseUri = config.baseUri ?? '';
this.#subscription.add(() => this.appClient.complete());

@@ -109,3 +114,3 @@ this.#subscription.add(() => this.#appsClient.complete());

*/
public getAppManifest(appKey: string): Observable<AppManifest> {
public getAppManifest(appKey: string): Observable<ApplicationManifest> {
return Query.extractQueryValue(

@@ -128,7 +133,14 @@ this.appClient.query({ appKey }).pipe(

public getAppManifests(filter?: {
filterByCurrentUser: boolean;
}): Observable<ApplicationManifest[]> {
return Query.extractQueryValue(this.#appsClient.query(filter));
}
/**
* fetch all applications
* @deprecated use `getAppManifests` instead
*/
public getAllAppManifests(): Observable<AppManifest[]> {
return Query.extractQueryValue(this.#appsClient.query());
public getAllAppManifests(): Observable<ApplicationManifest[]> {
return this.getAppManifests();
}

@@ -175,2 +187,6 @@

public getBaseUri(): string {
return this.#appBaseUri;
}
/**

@@ -177,0 +193,0 @@ * This should not be used, only for legacy creation backdoor

import type { IModulesConfigurator } from '@equinor/fusion-framework-module';
import type { AppConfigBuilderCallback } from './AppConfigBuilder';
import { module } from './module';
import { AppConfigurator } from './AppConfigurator';

@@ -13,10 +12,12 @@ /**

configurator: IModulesConfigurator<any, any>,
builder?: AppConfigBuilderCallback,
callback?: (builder: AppConfigurator) => void | Promise<void>,
): void => {
configurator.addConfig({
module,
configure: (appConfigurator) => {
builder && appConfigurator.addConfigBuilder(builder);
configure: async (configurator) => {
if (callback) {
Promise.resolve(callback(configurator));
}
},
});
};

@@ -11,2 +11,4 @@ export {

export { ApplicationManifest } from './ApplicationManifest';
export * from './events';

@@ -13,0 +15,0 @@ export * from './types';

import { Module } from '@equinor/fusion-framework-module';
import { ModuleDeps } from './types';
import { IAppConfigurator, AppConfigurator } from './AppConfigurator';
import { AppConfigurator } from './AppConfigurator';
import { AppModuleProvider } from './AppModuleProvider';

@@ -9,3 +9,3 @@

export type AppModule = Module<typeof moduleKey, AppModuleProvider, IAppConfigurator, ModuleDeps>;
export type AppModule = Module<typeof moduleKey, AppModuleProvider, AppConfigurator, ModuleDeps>;

@@ -33,3 +33,3 @@ /**

initialize: async (args) => {
const config = await (args.config as AppConfigurator).createConfig(args);
const config = await args.config.createConfigAsync(args);
const event = await args.requireInstance('event').catch(() => undefined);

@@ -36,0 +36,0 @@ return new AppModuleProvider({ config, event });

@@ -7,2 +7,3 @@ import { AnyModule, CombinedModules, ModulesInstance } from '@equinor/fusion-framework-module';

import IApp from './app';
import { ApplicationManifest } from './ApplicationManifest';

@@ -15,3 +16,3 @@ // TODO

basename?: string;
manifest?: AppManifest;
manifest?: ApplicationManifest;
config?: AppConfig<TConfig>;

@@ -24,3 +25,3 @@ props?: TProps;

export type AppType = 'standalone' | 'report' | 'launcher';
export type AppType = 'standalone' | 'report' | 'launcher' | 'template';

@@ -39,22 +40,69 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any

type AppCategory = {
id?: string;
name: string | null;
color: string | null;
defaultIcon: string | null;
id: string;
name?: string | null;
displayName?: string | null;
color?: string | null;
defaultIcon?: string | null;
sortOrder: number;
};
export type AppManifest = {
type AppVisualization = {
color?: string | null;
icon?: string | null;
sortOrder: number;
};
export type AzureId = {
azureId: string;
};
export type AzureUniqueId = {
azureUniqueId: string;
};
export type AppBuild<TUploaderId = AzureId | AzureUniqueId> = {
version?: string;
entryPoint?: string;
tags?: string[];
tag?: string;
assetPath?: string;
configUrl?: string;
timestamp?: string;
commitSha?: string;
githubRepo?: string;
projectPage?: string;
uploadedBy?: {
displayName?: string;
mail?: string;
upn?: string;
accountType?: string;
accountClassification?: string;
} & TUploaderId;
};
export type AppOwnerOrAdmin = {
id: string;
azureId?: string;
azureUniqueId?: string;
displayName?: string;
mail?: string;
upn?: string;
accountType?: string;
accountClassification?: string;
};
export interface AppManifest {
key: string;
name: string;
entry: string;
version: string;
name?: string;
entry?: string;
version?: string;
shortName?: string;
description?: string;
keywords?: string[];
type?: AppType;
isPinned?: boolean;
tags?: string[];
// context?: ContextManifest;
auth?: AppAuth[];
tag?: string;
auth?: AppOwnerOrAdmin[];
icon?: string;
order?: number;
publishedDate?: Date;
publishedDate?: string;
accentColor?: string;

@@ -64,9 +112,13 @@ categoryId?: string;

hide?: boolean;
};
visualization?: AppVisualization;
admins?: AppOwnerOrAdmin[];
owners?: AppOwnerOrAdmin[];
build?: AppBuild<AzureId>;
}
export type Endpoint = { name: string; uri: string; scopes?: string[] };
export type Endpoint = { url: string; scopes?: string[] };
export type AppConfig<TEnvironment = unknown> = {
environment: TEnvironment;
endpoints: Record<string, string | Endpoint>;
environment?: TEnvironment;
endpoints?: Record<string, Endpoint>;
};

@@ -79,3 +131,3 @@

export type AppBundle<TEnvironment = unknown, TModule = unknown> = {
manifest: AppManifest;
manifest: ApplicationManifest;
config: AppConfig<TEnvironment>;

@@ -102,1 +154,31 @@ module: TModule;

ModulesInstance<AppModules<TModules>>;
export type ApiAppVersionConfig = {
environment: string;
endpoints: Record<
string,
{
url: string;
scopes: string[];
}
>;
};
export type ApiApp = {
appKey: string;
displayName?: string;
description?: string;
type?: AppType;
isPinned?: boolean;
templateSource?: string;
category?: AppCategory;
visualization: {
color: string;
icon: string;
sortOrder: number;
};
keywords: string[];
admins: AppOwnerOrAdmin[];
owners: AppOwnerOrAdmin[];
build: AppBuild<AzureUniqueId>;
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc