diff --git a/application/apps/rustcore/ts-bindings/src/api/jobs.ts b/application/apps/rustcore/ts-bindings/src/api/jobs.ts index a883ed9799..6f78aa9d47 100644 --- a/application/apps/rustcore/ts-bindings/src/api/jobs.ts +++ b/application/apps/rustcore/ts-bindings/src/api/jobs.ts @@ -2,10 +2,14 @@ import { CancelablePromise } from 'platform/env/promise'; import { Base, Cancelled, decode } from '../native/native.jobs'; import { error } from 'platform/log/utils'; import { IFilter } from 'platform/types/filter'; -import { ShellProfile } from 'platform/types/shells'; import { SomeipStatistic } from 'platform/types/observe/parser/someip'; -import { StatisticInfo } from 'platform/types/observe/parser/dlt'; -import { FoldersScanningResult } from 'platform/types/bindings'; +import { + FoldersScanningResult, + DltStatisticInfo, + Profile, + ProfileList, + MapKeyValue, +} from 'platform/types/bindings'; import * as protocol from 'protocol'; import * as types from 'platform/types'; @@ -109,20 +113,18 @@ export class Jobs extends Base { return job; } - public getDltStats(paths: string[]): CancelablePromise { + public getDltStats(paths: string[]): CancelablePromise { const sequence = this.sequence(); - const job: CancelablePromise = this.execute( + const job: CancelablePromise = this.execute( (buf: Uint8Array): any | Error => { - const decoded = decode(buf, protocol.decodeCommandOutcomeWithString); + const decoded = decode( + buf, + protocol.decodeCommandOutcomeWithDltStatisticInfo, + ); if (decoded instanceof Error) { return decoded; } - console.log(decoded); - try { - return JSON.parse(decoded) as StatisticInfo; - } catch (e) { - return new Error(error(e)); - } + return decoded; }, this.native.getDltStats(sequence, paths), sequence, @@ -152,27 +154,12 @@ export class Jobs extends Base { return job; } - public getShellProfiles(): CancelablePromise { + public getShellProfiles(): CancelablePromise { const sequence = this.sequence(); - const job: CancelablePromise = this.execute( + const job: CancelablePromise = this.execute( (buf: Uint8Array): any | Error => { - const decoded = decode(buf, protocol.decodeCommandOutcomeWithString); - if (decoded instanceof Error) { - return decoded; - } - try { - const unparsed: unknown[] = JSON.parse(decoded); - const profiles: ShellProfile[] = []; - unparsed.forEach((unparsed: unknown) => { - const profile = ShellProfile.fromObj(unparsed); - if (!(profile instanceof Error)) { - profiles.push(profile); - } - }); - return profiles; - } catch (e) { - return new Error(error(e)); - } + const decoded = decode(buf, protocol.decodeCommandOutcomeWithString); + return decoded; }, this.native.getShellProfiles(sequence), sequence, @@ -185,27 +172,11 @@ export class Jobs extends Base { const sequence = this.sequence(); const job: CancelablePromise> = this.execute( (buf: Uint8Array): Map | Error => { - const decoded = decode(buf, protocol.decodeCommandOutcomeWithString); - if (decoded instanceof Error) { - return decoded; - } - try { - const unparsed: { [key: string]: string } = JSON.parse(decoded); - const envvars: Map = new Map(); - if ( - unparsed === undefined || - unparsed === null || - typeof unparsed !== 'object' - ) { - return new Error(`Fail to parse envvars string: ${unparsed}`); - } - Object.keys(unparsed).forEach((key) => { - envvars.set(key, unparsed[key]); - }); - return envvars; - } catch (e) { - return new Error(error(e)); - } + const decoded = decode( + buf, + protocol.decodeCommandOutcomeWithMapKeyValue, + ); + return decoded; }, this.native.getContextEnvvars(sequence), sequence, diff --git a/application/client/src/app/service/bridge.ts b/application/client/src/app/service/bridge.ts index 7e1d77d4f8..5b4fb1ada2 100644 --- a/application/client/src/app/service/bridge.ts +++ b/application/client/src/app/service/bridge.ts @@ -3,8 +3,7 @@ import { services } from '@register/services'; import { File, Entity } from '@platform/types/files'; import { FolderEntity } from '@platform/types/bindings'; import { FileType } from '@platform/types/observe/types/file'; -import { ShellProfile } from '@platform/types/shells'; -import { StatisticInfo } from '@platform/types/observe/parser/dlt'; +import { DltStatisticInfo, Profile } from '@platform/types/bindings'; import { Entry } from '@platform/types/storage/entry'; import { error } from '@platform/log/utils'; @@ -13,7 +12,7 @@ import * as Requests from '@platform/ipc/request/index'; @SetupService(services['bridge']) export class Service extends Implementation { protected cache: { - shells: ShellProfile[] | undefined; + shells: Profile[] | undefined; files: Map; checksums: Map; } = { @@ -23,7 +22,7 @@ export class Service extends Implementation { }; protected queue: { shells: Array<{ - resolve: (profiles: ShellProfile[]) => void; + resolve: (profiles: Profile[]) => void; reject: (err: Error) => void; }>; } = { @@ -400,10 +399,10 @@ export class Service extends Implementation { } public dlt(): { - stat(files: string[]): Promise; + stat(files: string[]): Promise; } { return { - stat: (files: string[]): Promise => { + stat: (files: string[]): Promise => { return new Promise((resolve, reject) => { Requests.IpcRequest.send( Requests.Dlt.Stat.Response, @@ -537,7 +536,7 @@ export class Service extends Implementation { public os(): { homedir(): Promise; - shells(): Promise; + shells(): Promise; envvars(): Promise>; } { return { @@ -553,7 +552,7 @@ export class Service extends Implementation { .catch(reject); }); }, - shells: (): Promise => { + shells: (): Promise => { return new Promise((resolve, reject) => { if (this.cache.shells !== undefined) { resolve(this.cache.shells); @@ -565,12 +564,10 @@ export class Service extends Implementation { new Requests.Os.Shells.Request(), ) .then((response) => { - this.cache.shells = response.profiles - .map((p) => ShellProfile.fromObj(p)) - .filter((p) => p instanceof ShellProfile) as ShellProfile[]; + this.cache.shells = response.profiles; this.queue.shells .map((h) => h.resolve) - .forEach((r) => r(this.cache.shells as ShellProfile[])); + .forEach((r) => r(this.cache.shells as Profile[])); }) .catch((err: Error) => { this.queue.shells.map((h) => h.reject).forEach((r) => r(err)); diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/bases/process/component.ts b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/bases/process/component.ts index ac8ba32e4f..7360e39cc8 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/bases/process/component.ts +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/bases/process/component.ts @@ -16,7 +16,7 @@ import { import { Ilc, IlcInterface } from '@env/decorators/component'; import { State } from '../../states/process'; import { components } from '@env/decorators/initial'; -import { ShellProfile } from '@platform/types/shells'; +import { Profile } from '@platform/types/bindings'; import { Action } from '@ui/tabs/observe/action'; import { Session } from '@service/session'; @@ -196,7 +196,7 @@ export class SetupBase }); } - public importEnvVars(profile: ShellProfile | undefined) { + public importEnvVars(profile: Profile | undefined) { this.state.importEnvvarsFromShell(profile).catch((err: Error) => { this.log().error(`Fail to save selected profile: ${err.message}`); }); diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/component.ts b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/component.ts index eed0bde450..d35ed8ea55 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/component.ts +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/component.ts @@ -13,6 +13,7 @@ import { Options as FoldersOptions } from '@elements/folderinput/component'; import { Subject } from '@platform/env/subscription'; import { CmdErrorState } from '../../bases/process/error'; import { SetupBase } from '../../bases/process/component'; +import { Profile } from '@platform/types/bindings'; @Component({ selector: 'app-transport-process', @@ -60,5 +61,9 @@ export class Setup extends SetupBase implements AfterContentInit, AfterViewInit, ); super.ngAfterContentInit(); } + + public getEnvvarsCount(profile: Profile) { + return profile.envvars ? profile.envvars.size : 0; + } } export interface Setup extends IlcInterface {} diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/template.html b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/template.html index f284601251..1c2757cde8 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/template.html +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/complete/process/template.html @@ -1,8 +1,11 @@
- + (panel)="panel()" + >
- + (panel)="panel()" +>

Import variables from:

- @@ -37,4 +50,4 @@
-
\ No newline at end of file + diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/component.ts b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/component.ts index 3570507b63..386a892af2 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/component.ts +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/component.ts @@ -11,6 +11,7 @@ import { Options as FoldersOptions } from '@elements/folderinput/component'; import { Subject } from '@platform/env/subscription'; import { CmdErrorState } from '../../bases/process/error'; import { SetupBase } from '../../bases/process/component'; +import { Profile } from '@platform/types/bindings'; @Component({ selector: 'app-process-quicksetup', @@ -46,6 +47,10 @@ export class QuickSetup extends SetupBase implements AfterContentInit, OnDestroy this.setInputs(this.inputs); } + public getEnvvarsCount(profile: Profile) { + return profile.envvars ? profile.envvars.size : 0; + } + public destroy(): Promise { return Promise.resolve(); } diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/template.html b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/template.html index f284601251..1c2757cde8 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/template.html +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/quick/process/template.html @@ -1,8 +1,11 @@
- + (panel)="panel()" + >
- + (panel)="panel()" +>

Import variables from:

- @@ -37,4 +50,4 @@
-
\ No newline at end of file + diff --git a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/states/process.ts b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/states/process.ts index 16c9ca27b8..c7380b1d99 100644 --- a/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/states/process.ts +++ b/application/client/src/app/ui/tabs/observe/origin/stream/transport/setup/states/process.ts @@ -1,4 +1,4 @@ -import { ShellProfile } from '@platform/types/shells'; +import { Profile } from '@platform/types/bindings'; import { bridge } from '@service/bridge'; import { Destroy } from '@platform/types/env/types'; import { Action } from '../../../../../action'; @@ -11,15 +11,15 @@ const ENTRY_KEY = 'selected_profile_path'; export class State implements Destroy { public profiles: { - all: ShellProfile[] | undefined; - valid: ShellProfile[] | undefined; + all: Profile[] | undefined; + valid: Profile[] | undefined; } = { all: undefined, valid: undefined, }; // No context envvars public envvars: Map = new Map(); - public current: ShellProfile | undefined; + public current: Profile | undefined; constructor( public readonly action: Action, @@ -30,8 +30,8 @@ export class State implements Destroy { // Having method "destroy()" is requirement of session's storage } - public setProfiles(profiles: ShellProfile[]): Promise { - const valid: ShellProfile[] = []; + public setProfiles(profiles: Profile[]): Promise { + const valid: Profile[] = []; profiles.forEach((profile) => { valid.find((p) => p.path === profile.path) === undefined && profile.envvars !== undefined && @@ -53,7 +53,7 @@ export class State implements Destroy { return this.profiles.all !== undefined; } - public importEnvvarsFromShell(profile: ShellProfile | undefined): Promise { + public importEnvvarsFromShell(profile: Profile | undefined): Promise { if (profile === undefined) { this.current = undefined; this.configuration.configuration.envs = obj.mapToObj(this.envvars); @@ -72,7 +72,7 @@ export class State implements Destroy { return obj.objToStringMap(this.configuration.configuration.envs); } - public isShellSelected(profile: ShellProfile): boolean { + public isShellSelected(profile: Profile): boolean { return this.current ? profile.path === this.current.path : false; } diff --git a/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/state.ts b/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/state.ts index c5f467566a..142485a7e0 100644 --- a/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/state.ts +++ b/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/state.ts @@ -3,6 +3,7 @@ import { Section } from './structure/section'; import { Summary } from './summary'; import { StatEntity } from './structure/statentity'; import { getTypedProp } from '@platform/env/obj'; +import { DltStatisticInfo, DltLevelDistribution } from '@platform/types/bindings'; import * as Dlt from '@platform/types/observe/parser/dlt'; @@ -19,7 +20,7 @@ export const NAMES: { [key: string]: string } = { }; export class State extends Base { public structure: Section[] = []; - public stat: Dlt.StatisticInfo | undefined; + public stat: DltStatisticInfo | undefined; public summary: { total: Summary; selected: Summary; @@ -101,9 +102,9 @@ export class State extends Base { const stat = this.stat; const structure: Section[] = []; ['app_ids', 'context_ids', 'ecu_ids'].forEach((key: string) => { - const content: Array<[string, Dlt.LevelDistribution]> = getTypedProp< - Dlt.StatisticInfo, - Array<[string, Dlt.LevelDistribution]> + const content: Array<[string, DltLevelDistribution]> = getTypedProp< + DltStatisticInfo, + Array<[string, DltLevelDistribution]> >(stat, key); const entities: StatEntity[] = content.map((record) => { const entity = new StatEntity(record[0], key, record[1], this.matcher); diff --git a/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/structure/statentity.ts b/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/structure/statentity.ts index f7a375ef0c..fb2961ffc2 100644 --- a/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/structure/statentity.ts +++ b/application/client/src/app/ui/tabs/observe/parsers/extra/dlt/structure/statentity.ts @@ -1,4 +1,4 @@ -import { LevelDistribution } from '@platform/types/observe/parser/dlt'; +import { DltLevelDistribution } from '@platform/types/bindings'; import { Matchee } from '@module/matcher'; import * as wasm from '@loader/wasm'; @@ -16,7 +16,7 @@ export class StatEntity extends Matchee { public log_verbose: number; public log_invalid: number; - constructor(id: string, parent: string, from: LevelDistribution, matcher: wasm.Matcher) { + constructor(id: string, parent: string, from: DltLevelDistribution, matcher: wasm.Matcher) { super(matcher, { id: id }); this.id = id; this.parent = parent; diff --git a/application/holder/src/service/unbound/dlt/stat.ts b/application/holder/src/service/unbound/dlt/stat.ts index 22b82371a4..a87d7b20fe 100644 --- a/application/holder/src/service/unbound/dlt/stat.ts +++ b/application/holder/src/service/unbound/dlt/stat.ts @@ -2,7 +2,7 @@ import { CancelablePromise } from 'platform/env/promise'; import { Logger } from 'platform/log'; import { jobs } from '@service/jobs'; import { unbound } from '@service/unbound'; -import { StatisticInfo } from 'platform/types/observe/parser/dlt'; +import { DltStatisticInfo } from 'platform/types/bindings'; import * as Requests from 'platform/ipc/request'; @@ -26,7 +26,7 @@ export const handler = Requests.InjectLogger< .start(); unbound.jobs .getDltStats(request.files) - .then((stat: StatisticInfo) => { + .then((stat: DltStatisticInfo) => { resolve( new Requests.Dlt.Stat.Response({ stat, diff --git a/application/holder/src/service/unbound/os/shells.ts b/application/holder/src/service/unbound/os/shells.ts index f3e3432075..7964494efe 100644 --- a/application/holder/src/service/unbound/os/shells.ts +++ b/application/holder/src/service/unbound/os/shells.ts @@ -1,11 +1,11 @@ import { CancelablePromise } from 'platform/env/promise'; import { Logger } from 'platform/log'; -import { ShellProfile } from 'platform/types/shells'; +import { Profile } from 'platform/types/bindings'; import { unbound } from '@service/unbound'; import * as Requests from 'platform/ipc/request'; -let cached: ShellProfile[] | undefined = undefined; +let cached: Profile[] | undefined = undefined; export const handler = Requests.InjectLogger< Requests.Os.Shells.Request, diff --git a/application/platform/ipc/request/dlt/stat.ts b/application/platform/ipc/request/dlt/stat.ts index be694c161b..ebb1364bea 100644 --- a/application/platform/ipc/request/dlt/stat.ts +++ b/application/platform/ipc/request/dlt/stat.ts @@ -1,5 +1,5 @@ import { Define, Interface, SignatureRequirement } from '../declarations'; -import { StatisticInfo } from '../../../types/observe/parser/dlt'; +import { DltStatisticInfo } from '../../../types/bindings'; import * as validator from '../../../env/obj'; @Define({ name: 'DltStatRequest' }) @@ -16,9 +16,9 @@ export interface Request extends Interface {} @Define({ name: 'DltStatResponse' }) export class Response extends SignatureRequirement { - public stat: StatisticInfo; + public stat: DltStatisticInfo; - constructor(input: { stat: StatisticInfo }) { + constructor(input: { stat: DltStatisticInfo }) { super(); validator.isObject(input); this.stat = validator.getAsObj(input, 'stat'); diff --git a/application/platform/ipc/request/os/shells.ts b/application/platform/ipc/request/os/shells.ts index 92e769766d..03282a87ea 100644 --- a/application/platform/ipc/request/os/shells.ts +++ b/application/platform/ipc/request/os/shells.ts @@ -1,5 +1,5 @@ import { Define, Interface, SignatureRequirement } from '../declarations'; -import { ShellProfile } from '../../../types/shells'; +import { Profile } from '../../../types/bindings'; import * as validator from '../../../env/obj'; @@ -9,9 +9,9 @@ export interface Request extends Interface {} @Define({ name: 'ShellProfilesListResponse' }) export class Response extends SignatureRequirement { - public profiles: ShellProfile[]; + public profiles: Profile[]; - constructor(input: { profiles: ShellProfile[] }) { + constructor(input: { profiles: Profile[] }) { super(); validator.isObject(input); this.profiles = validator.getAsArray(input, 'profiles'); diff --git a/application/platform/package.json b/application/platform/package.json index 746c27b76f..e764edd1ed 100644 --- a/application/platform/package.json +++ b/application/platform/package.json @@ -88,7 +88,6 @@ "./modules/system": "./dist/modules/system.js", "./types": "./dist/types/index.js", "./types/sde/index": "./dist/types/sde/index.js", - "./types/shells": "./dist/types/shells.js", "./types/files": "./dist/types/files.js", "./types/content": "./dist/types/content.js", "./types/filter": "./dist/types/filter.js", diff --git a/application/platform/types/bindings/command.ts b/application/platform/types/bindings/command.ts index d9ad7e283b..91f25851c2 100644 --- a/application/platform/types/bindings/command.ts +++ b/application/platform/types/bindings/command.ts @@ -7,6 +7,13 @@ */ export type CommandOutcomeBool = { Finished: boolean } | 'Cancelled'; +/** + * Represents the result of a command execution. + * At the core level, this type is used for all commands invoked within an `UnboundSession`. + * It is only used to indicate the successful completion or interruption of a command. + */ +export type CommandOutcomeDltStatisticInfoResult = { Finished: DltStatisticInfo } | 'Cancelled'; + /** * Represents the result of a command execution. * At the core level, this type is used for all commands invoked within an `UnboundSession`. @@ -21,6 +28,13 @@ export type CommandOutcomeFoldersScanningResult = { Finished: FoldersScanningRes */ export type CommandOutcomeOptionalString = { Finished: string | null } | 'Cancelled'; +/** + * Represents the result of a command execution. + * At the core level, this type is used for all commands invoked within an `UnboundSession`. + * It is only used to indicate the successful completion or interruption of a command. + */ +export type CommandOutcomeProfilesResult = { Finished: ProfileList } | 'Cancelled'; + /** * Represents the result of a command execution. * At the core level, this type is used for all commands invoked within an `UnboundSession`. @@ -49,6 +63,24 @@ export type CommandOutcomeVoid = 'Finished' | 'Cancelled'; */ export type CommandOutcomei64 = { Finished: number } | 'Cancelled'; +export type DltLevelDistribution = { + non_log: number; + log_fatal: number; + log_error: number; + log_warning: number; + log_info: number; + log_debug: number; + log_verbose: number; + log_invalid: number; +}; + +export type DltStatisticInfo = { + app_ids: Array<[string, DltLevelDistribution]>; + context_ids: Array<[string, DltLevelDistribution]>; + ecu_ids: Array<[string, DltLevelDistribution]>; + contained_non_verbose: boolean; +}; + /** * Represents a folder entity in the file system. */ @@ -124,6 +156,37 @@ export type FoldersScanningResult = { max_len_reached: boolean; }; +export type Profile = { + /** + * Suggested name of shell. For unix based systems it will be name of executable file, + * like "bash", "fish" etc. For windows it will be names like "GitBash", "PowerShell" + * etc. + */ + name: string; + /** + * Path to executable file of shell + */ + path: string; + /** + * List of environment variables. Because extracting operation could take some time + * by default `envvars = None`. To load data should be used method `load`, which will + * make attempt to detect environment variables. + */ + envvars: Map; + /** + * true - if path to executable file of shell is symlink to another location. + */ + symlink: boolean; +}; + +/** + * Represents a list of serial ports. + * + * This structure contains a vector of strings, where each string represents the name + * or identifier of a serial port available on the system. + */ +export type ProfileList = Array; + /** * Represents a list of serial ports. * diff --git a/application/platform/types/observe/parser/dlt/index.ts b/application/platform/types/observe/parser/dlt/index.ts index d60d943c82..94e69f696c 100644 --- a/application/platform/types/observe/parser/dlt/index.ts +++ b/application/platform/types/observe/parser/dlt/index.ts @@ -10,29 +10,11 @@ import * as obj from '../../../../env/obj'; import * as Origin from '../../origin/index'; import * as str from '../../../../env/str'; -export interface LevelDistribution { - non_log: number; - log_fatal: number; - log_error: number; - log_warning: number; - log_info: number; - log_debug: number; - log_verbose: number; - log_invalid: number; -} - export function getLogLevelName(level: number): string { const name = (DltLogLevelNames as Record)[level]; return name === undefined ? 'unknown' : name; } -export interface StatisticInfo { - app_ids: [string, LevelDistribution][]; - context_ids: [string, LevelDistribution][]; - ecu_ids: [string, LevelDistribution][]; - contained_non_verbose: boolean; -} - export const DltLogLevelNames = { 1: 'Fatal', 2: 'Error', diff --git a/application/platform/types/shells.ts b/application/platform/types/shells.ts deleted file mode 100644 index 7c0686256b..0000000000 --- a/application/platform/types/shells.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { utils } from '../log'; -import * as obj from '../env/obj'; - -export class ShellProfile { - public readonly name: string; - public readonly path: string; - public readonly envvars: Map | undefined; - public readonly symlink: boolean; - - public static fromObj(smth: unknown): ShellProfile | Error { - try { - const name: string = obj.getAsNotEmptyString(smth, 'name'); - const path: string = obj.getAsNotEmptyString(smth, 'path'); - const symlink: boolean = obj.getAsBool(smth, 'symlink'); - let envvars: Map | undefined = undefined; - if ((smth as any).envvars instanceof Map) { - envvars = (smth as any).envvars; - } else if ( - (smth as any).envvars !== null && - (smth as any).envvars !== undefined && - typeof (smth as any).envvars === 'object' - ) { - envvars = new Map(); - Object.keys((smth as any).envvars).forEach((key: string) => { - envvars?.set(key, (smth as any).envvars[key]); - }); - } - return new ShellProfile(name, path, symlink, envvars); - } catch (err) { - return new Error(utils.error(err)); - } - } - - public static fromStr(str: string): ShellProfile | Error { - try { - const profile = JSON.parse(str); - const name: string = obj.getAsNotEmptyString(profile, 'name'); - const path: string = obj.getAsNotEmptyString(profile, 'path'); - const symlink: boolean = obj.getAsBool(profile, 'symlink'); - let envvars: Map | undefined = undefined; - if ( - profile.envvars !== null && - profile.envvars !== undefined && - typeof profile.envvars === 'object' - ) { - envvars = new Map(); - Object.keys(profile.envvars).forEach((key: string) => { - envvars?.set(key, profile.envvars[key]); - }); - } - return new ShellProfile(name, path, symlink, envvars); - } catch (err) { - return new Error(utils.error(err)); - } - } - - constructor( - name: string, - path: string, - symlink: boolean, - envvars: Map | undefined, - ) { - this.path = path; - this.name = name; - this.symlink = symlink; - this.envvars = envvars; - } - - public getEnvvarsCount(): number { - return this.envvars === undefined ? 0 : this.envvars.size; - } -}