mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
Merge branch 'next/minor' of github.com:Start9Labs/start-os into rebase/feat/domains
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Url } from '@start9labs/shared'
|
||||
import { Manifest } from '../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export type StoreURL = string
|
||||
export type StoreName = string
|
||||
@@ -42,35 +43,6 @@ export interface DependencyMetadata {
|
||||
hidden: boolean
|
||||
}
|
||||
|
||||
export interface Manifest {
|
||||
id: string
|
||||
title: string
|
||||
version: string
|
||||
gitHash?: string
|
||||
description: {
|
||||
short: string
|
||||
long: string
|
||||
}
|
||||
replaces?: string[]
|
||||
releaseNotes: string
|
||||
license: string // name of license
|
||||
wrapperRepo: Url
|
||||
upstreamRepo: Url
|
||||
supportSite: Url
|
||||
marketingSite: Url
|
||||
donationUrl: Url | null
|
||||
alerts: {
|
||||
install: string | null
|
||||
uninstall: string | null
|
||||
restore: string | null
|
||||
start: string | null
|
||||
stop: string | null
|
||||
}
|
||||
dependencies: Record<string, Dependency>
|
||||
osVersion: string
|
||||
hasConfig: boolean
|
||||
}
|
||||
|
||||
export interface Dependency {
|
||||
description: string | null
|
||||
optional: boolean
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { Manifest } from '../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
@Pipe({
|
||||
name: 'toManifest',
|
||||
@@ -11,4 +11,4 @@ export class ToManifestPipe implements PipeTransform {
|
||||
transform(pkg: PackageDataEntry): Manifest {
|
||||
return getManifest(pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,20 +5,18 @@ import {
|
||||
computed,
|
||||
inject,
|
||||
input,
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { TuiLetModule, tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiLetModule } from '@taiga-ui/cdk'
|
||||
import {
|
||||
TuiButtonModule,
|
||||
tuiButtonOptionsProvider,
|
||||
} from '@taiga-ui/experimental'
|
||||
import { map, Observable } from 'rxjs'
|
||||
import { map } from 'rxjs'
|
||||
import { UILaunchComponent } from 'src/app/apps/portal/routes/dashboard/ui.component'
|
||||
import { ActionsService } from 'src/app/apps/portal/services/actions.service'
|
||||
import { DepErrorService } from 'src/app/services/dep-error.service'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
|
||||
@@ -8,11 +8,7 @@ import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiLoaderModule } from '@taiga-ui/core'
|
||||
import { TuiIconModule } from '@taiga-ui/experimental'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
HealthStatus,
|
||||
PrimaryStatus,
|
||||
renderPkgStatus,
|
||||
} from 'src/app/services/pkg-status-rendering.service'
|
||||
import { renderPkgStatus } from 'src/app/services/pkg-status-rendering.service'
|
||||
import { InstallingProgressDisplayPipe } from '../service/pipes/install-progress.pipe'
|
||||
|
||||
@Component({
|
||||
@@ -68,7 +64,7 @@ export class StatusComponent {
|
||||
return (
|
||||
!this.hasDepErrors && // no deps error
|
||||
!!this.pkg.status.configured && // no config needed
|
||||
status.health !== HealthStatus.Failure // no health issues
|
||||
status.health !== 'failure' // no health issues
|
||||
)
|
||||
}
|
||||
|
||||
@@ -83,29 +79,29 @@ export class StatusComponent {
|
||||
|
||||
get status(): string {
|
||||
if (this.pkg.stateInfo.installingInfo) {
|
||||
return `Installing... ${this.pipe.transform(this.pkg.stateInfo.installingInfo.progress.overall)}`
|
||||
return `Installing...${this.pipe.transform(this.pkg.stateInfo.installingInfo.progress.overall)}`
|
||||
}
|
||||
|
||||
switch (this.getStatus(this.pkg).primary) {
|
||||
case PrimaryStatus.Running:
|
||||
case 'running':
|
||||
return 'Running'
|
||||
case PrimaryStatus.Stopped:
|
||||
case 'stopped':
|
||||
return 'Stopped'
|
||||
case PrimaryStatus.NeedsConfig:
|
||||
case 'needsConfig':
|
||||
return 'Needs Config'
|
||||
case PrimaryStatus.Updating:
|
||||
case 'updating':
|
||||
return 'Updating...'
|
||||
case PrimaryStatus.Stopping:
|
||||
case 'stopping':
|
||||
return 'Stopping...'
|
||||
case PrimaryStatus.Starting:
|
||||
case 'starting':
|
||||
return 'Starting...'
|
||||
case PrimaryStatus.BackingUp:
|
||||
case 'backingUp':
|
||||
return 'Backing Up...'
|
||||
case PrimaryStatus.Restarting:
|
||||
case 'restarting':
|
||||
return 'Restarting...'
|
||||
case PrimaryStatus.Removing:
|
||||
case 'removing':
|
||||
return 'Removing...'
|
||||
case PrimaryStatus.Restoring:
|
||||
case 'restoring':
|
||||
return 'Restoring...'
|
||||
default:
|
||||
return 'Unknown'
|
||||
@@ -114,18 +110,20 @@ export class StatusComponent {
|
||||
|
||||
get color(): string {
|
||||
switch (this.getStatus(this.pkg).primary) {
|
||||
case PrimaryStatus.Running:
|
||||
case 'running':
|
||||
return 'var(--tui-success-fill)'
|
||||
case PrimaryStatus.NeedsConfig:
|
||||
case 'needsConfig':
|
||||
return 'var(--tui-warning-fill)'
|
||||
case PrimaryStatus.Updating:
|
||||
case PrimaryStatus.Stopping:
|
||||
case PrimaryStatus.Starting:
|
||||
case PrimaryStatus.BackingUp:
|
||||
case PrimaryStatus.Restarting:
|
||||
case PrimaryStatus.Removing:
|
||||
case PrimaryStatus.Restoring:
|
||||
case 'installing':
|
||||
case 'updating':
|
||||
case 'stopping':
|
||||
case 'starting':
|
||||
case 'backingUp':
|
||||
case 'restarting':
|
||||
case 'removing':
|
||||
case 'restoring':
|
||||
return 'var(--tui-info-fill)'
|
||||
// stopped
|
||||
default:
|
||||
return 'var(--tui-text-02)'
|
||||
}
|
||||
|
||||
@@ -9,10 +9,7 @@ import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiDataListModule, TuiHostedDropdownModule } from '@taiga-ui/core'
|
||||
import { TuiButtonModule } from '@taiga-ui/experimental'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -73,7 +70,7 @@ export class UILaunchComponent {
|
||||
}
|
||||
|
||||
get isRunning(): boolean {
|
||||
return this.pkg.status.main.status === PackageMainStatus.Running
|
||||
return this.pkg.status.main.status === 'running'
|
||||
}
|
||||
|
||||
@tuiPure
|
||||
|
||||
@@ -9,8 +9,8 @@ import { TuiButtonModule } from '@taiga-ui/experimental'
|
||||
import { DependencyInfo } from 'src/app/apps/portal/routes/service/types/dependency-info'
|
||||
import { ActionsService } from 'src/app/apps/portal/services/actions.service'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
@Component({
|
||||
selector: 'service-actions',
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { TuiLoaderModule, TuiSvgModule } from '@taiga-ui/core'
|
||||
import {
|
||||
HealthCheckResult,
|
||||
HealthResult,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { HealthCheckResult } from '../../../../../../../../../../core/startos/bindings/HealthCheckResult'
|
||||
|
||||
@Component({
|
||||
selector: 'service-health-check',
|
||||
@@ -54,18 +51,14 @@ export class ServiceHealthCheckComponent {
|
||||
get loading(): boolean {
|
||||
const { result } = this.check
|
||||
|
||||
return (
|
||||
!result ||
|
||||
result === HealthResult.Starting ||
|
||||
result === HealthResult.Loading
|
||||
)
|
||||
return !result || result === 'starting' || result === 'loading'
|
||||
}
|
||||
|
||||
get icon(): string {
|
||||
switch (this.check.result) {
|
||||
case HealthResult.Success:
|
||||
case 'success':
|
||||
return 'tuiIconCheckLarge'
|
||||
case HealthResult.Failure:
|
||||
case 'failure':
|
||||
return 'tuiIconAlertTriangleLarge'
|
||||
default:
|
||||
return 'tuiIconMinusLarge'
|
||||
@@ -74,13 +67,14 @@ export class ServiceHealthCheckComponent {
|
||||
|
||||
get color(): string {
|
||||
switch (this.check.result) {
|
||||
case HealthResult.Success:
|
||||
case 'success':
|
||||
return 'var(--tui-success-fill)'
|
||||
case HealthResult.Failure:
|
||||
case 'failure':
|
||||
return 'var(--tui-warning-fill)'
|
||||
case HealthResult.Starting:
|
||||
case HealthResult.Loading:
|
||||
case 'starting':
|
||||
case 'loading':
|
||||
return 'var(--tui-primary)'
|
||||
// disabled
|
||||
default:
|
||||
return 'var(--tui-text-02)'
|
||||
}
|
||||
@@ -92,13 +86,14 @@ export class ServiceHealthCheckComponent {
|
||||
}
|
||||
|
||||
switch (this.check.result) {
|
||||
case HealthResult.Starting:
|
||||
case 'starting':
|
||||
return 'Starting...'
|
||||
case HealthResult.Success:
|
||||
case 'success':
|
||||
return `Success: ${this.check.message}`
|
||||
case HealthResult.Loading:
|
||||
case HealthResult.Failure:
|
||||
case 'loading':
|
||||
case 'failure':
|
||||
return this.check.message
|
||||
// disabled
|
||||
default:
|
||||
return this.check.result
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
inject,
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { HealthCheckResult } from 'src/app/services/patch-db/data-model'
|
||||
import { ConnectionService } from 'src/app/services/connection.service'
|
||||
import { ServiceHealthCheckComponent } from './health-check.component'
|
||||
import { HealthCheckResult } from '../../../../../../../../../../core/startos/bindings/HealthCheckResult'
|
||||
|
||||
@Component({
|
||||
selector: 'service-health-checks',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { TuiProgressModule } from '@taiga-ui/kit'
|
||||
import { Progress } from 'src/app/services/patch-db/data-model'
|
||||
import { InstallingProgressPipe } from '../pipes/install-progress.pipe'
|
||||
import { Progress } from '../../../../../../../../../../core/startos/bindings/Progress'
|
||||
|
||||
@Component({
|
||||
selector: '[progress]',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { Progress } from '../../../../../services/patch-db/data-model'
|
||||
import { Progress } from '../../../../../../../../../../core/startos/bindings/Progress'
|
||||
|
||||
@Pipe({
|
||||
standalone: true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { inject, Pipe, PipeTransform } from '@angular/core'
|
||||
import { TuiDialogService } from '@taiga-ui/core'
|
||||
import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { CopyService, MarkdownComponent } from '@start9labs/shared'
|
||||
import { from } from 'rxjs'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export const FALLBACK_URL = 'Not provided'
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { inject, Pipe, PipeTransform } from '@angular/core'
|
||||
import { Params } from '@angular/router'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { MarkdownComponent } from '@start9labs/shared'
|
||||
import { TuiDialogService } from '@taiga-ui/core'
|
||||
import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus'
|
||||
@@ -15,6 +14,7 @@ import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { ProxyService } from 'src/app/services/proxy.service'
|
||||
import { ServicePropertiesModal } from '../modals/properties.component'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export interface ServiceMenu {
|
||||
icon: string
|
||||
|
||||
@@ -18,7 +18,6 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import {
|
||||
DataModel,
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { hasCurrentDeps } from 'src/app/util/has-deps'
|
||||
import { FormDialogService } from 'src/app/services/form-dialog.service'
|
||||
@@ -73,7 +72,7 @@ export class ServiceActionsRoute {
|
||||
|
||||
readonly pkg$ = this.patch
|
||||
.watch$('packageData', this.id)
|
||||
.pipe(filter(pkg => pkg.stateInfo.state === PackageState.Installed))
|
||||
.pipe(filter(pkg => pkg.stateInfo.state === 'installed'))
|
||||
|
||||
readonly action = {
|
||||
icon: 'tuiIconTrash2Large',
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { isEmptyObject } from '@start9labs/shared'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { combineLatest, map, switchMap } from 'rxjs'
|
||||
import { ConnectionService } from 'src/app/services/connection.service'
|
||||
import {
|
||||
DependencyErrorType,
|
||||
DepErrorService,
|
||||
PkgDependencyErrors,
|
||||
} from 'src/app/services/dep-error.service'
|
||||
import { FormDialogService } from 'src/app/services/form-dialog.service'
|
||||
import {
|
||||
DataModel,
|
||||
HealthCheckResult,
|
||||
MainStatus,
|
||||
PackageDataEntry,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
@@ -40,6 +36,9 @@ import {
|
||||
import { DependencyInfo } from '../types/dependency-info'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
import { InstallingProgressPipe } from 'src/app/apps/portal/routes/service/pipes/install-progress.pipe'
|
||||
import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
|
||||
import { HealthCheckResult } from '../../../../../../../../../../core/startos/bindings/HealthCheckResult'
|
||||
import { MainStatus } from '../../../../../../../../../../core/startos/bindings/MainStatus'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
@@ -72,7 +71,7 @@ import { InstallingProgressPipe } from 'src/app/apps/portal/routes/service/pipes
|
||||
} @else {
|
||||
@if (
|
||||
service.pkg.stateInfo.state === 'installed' &&
|
||||
service.status.primary !== 'backing-up'
|
||||
service.status.primary !== 'backingUp'
|
||||
) {
|
||||
@if (connected$ | async) {
|
||||
<service-actions
|
||||
@@ -211,24 +210,24 @@ export class ServiceRoute {
|
||||
let fixAction: (() => any) | null = null
|
||||
|
||||
if (depError) {
|
||||
if (depError.type === DependencyErrorType.NotInstalled) {
|
||||
if (depError.type === 'notInstalled') {
|
||||
errorText = 'Not installed'
|
||||
fixText = 'Install'
|
||||
fixAction = () => this.fixDep(pkg, pkgManifest, 'install', depId)
|
||||
} else if (depError.type === DependencyErrorType.IncorrectVersion) {
|
||||
} else if (depError.type === 'incorrectVersion') {
|
||||
errorText = 'Incorrect version'
|
||||
fixText = 'Update'
|
||||
fixAction = () => this.fixDep(pkg, pkgManifest, 'update', depId)
|
||||
} else if (depError.type === DependencyErrorType.ConfigUnsatisfied) {
|
||||
} else if (depError.type === 'configUnsatisfied') {
|
||||
errorText = 'Config not satisfied'
|
||||
fixText = 'Auto config'
|
||||
fixAction = () => this.fixDep(pkg, pkgManifest, 'configure', depId)
|
||||
} else if (depError.type === DependencyErrorType.NotRunning) {
|
||||
} else if (depError.type === 'notRunning') {
|
||||
errorText = 'Not running'
|
||||
fixText = 'Start'
|
||||
} else if (depError.type === DependencyErrorType.HealthChecksFailed) {
|
||||
} else if (depError.type === 'healthChecksFailed') {
|
||||
errorText = 'Required health check not passing'
|
||||
} else if (depError.type === DependencyErrorType.Transitive) {
|
||||
} else if (depError.type === 'transitive') {
|
||||
errorText = 'Dependency has a dependency issue'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '@tinkoff/ng-polymorpheus'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { firstValueFrom, map } from 'rxjs'
|
||||
import { DataModel, PackageState } from 'src/app/services/patch-db/data-model'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { getManifest } from 'src/app/util/get-package-data'
|
||||
|
||||
interface Package {
|
||||
@@ -100,7 +100,7 @@ export class BackupsBackupModal {
|
||||
id,
|
||||
title,
|
||||
icon: pkg.icon,
|
||||
disabled: pkg.stateInfo.state !== PackageState.Installed,
|
||||
disabled: pkg.stateInfo.state !== 'installed',
|
||||
checked: false,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -24,7 +24,6 @@ import { firstValueFrom } from 'rxjs'
|
||||
import {
|
||||
DataModel,
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { ClientStorageService } from 'src/app/services/client-storage.service'
|
||||
import { MarketplaceService } from 'src/app/services/marketplace.service'
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
inject,
|
||||
} from '@angular/core'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiSvgModule } from '@taiga-ui/core'
|
||||
import { TuiLineClampModule } from '@taiga-ui/kit'
|
||||
@@ -16,6 +15,7 @@ import { ServerNotification } from 'src/app/services/api/api.types'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { NotificationService } from '../../../services/notification.service'
|
||||
import { toRouterLink } from '../../../utils/to-router-link'
|
||||
import { Manifest } from '../../../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
@Component({
|
||||
selector: '[notificationItem]',
|
||||
|
||||
@@ -47,7 +47,8 @@ export class StartOsUiComponent {
|
||||
addSsl: {
|
||||
scheme: 'https',
|
||||
preferredExternalPort: 443,
|
||||
addXForwardedHeaders: null,
|
||||
// @TODO is this alpn correct?
|
||||
alpn: { specified: ['http/1.1', 'h2'] },
|
||||
},
|
||||
secure: {
|
||||
ssl: false,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Manifest, MarketplacePkg } from '@start9labs/marketplace'
|
||||
import { MarketplacePkg } from '@start9labs/marketplace'
|
||||
import cbor from 'cbor'
|
||||
|
||||
interface Positions {
|
||||
|
||||
@@ -11,9 +11,9 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { FormDialogService } from 'src/app/services/form-dialog.service'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { hasCurrentDeps } from 'src/app/util/has-deps'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { getAllPackages } from 'src/app/util/get-package-data'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { Manifest } from '../../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import {
|
||||
InstalledState,
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
ServerStatusInfo,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
@@ -12,15 +10,12 @@ import {
|
||||
ServerNotifications,
|
||||
} from './api.types'
|
||||
import { BTC_ICON, LND_ICON, PROXY_ICON } from './api-icons'
|
||||
import {
|
||||
DependencyMetadata,
|
||||
Manifest,
|
||||
MarketplacePkg,
|
||||
} from '@start9labs/marketplace'
|
||||
import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace'
|
||||
import { Log } from '@start9labs/shared'
|
||||
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export module Mock {
|
||||
export const ServerUpdated: ServerStatusInfo = {
|
||||
@@ -83,16 +78,26 @@ export module Mock {
|
||||
osVersion: '0.2.12',
|
||||
dependencies: {},
|
||||
hasConfig: true,
|
||||
images: ['main'],
|
||||
assets: [],
|
||||
volumes: ['main'],
|
||||
hardwareRequirements: {
|
||||
device: {},
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
}
|
||||
|
||||
export const MockManifestLnd: Manifest = {
|
||||
id: 'lnd',
|
||||
title: 'Lightning Network Daemon',
|
||||
version: '0.11.1',
|
||||
gitHash: 'abcdefgh',
|
||||
description: {
|
||||
short: 'A bolt spec compliant client.',
|
||||
long: 'More info about LND. More info about LND. More info about LND.',
|
||||
},
|
||||
replaces: ['banks', 'governments'],
|
||||
releaseNotes: 'Dual funded channels!',
|
||||
license: 'MIT',
|
||||
wrapperRepo: 'https://github.com/start9labs/lnd-wrapper',
|
||||
@@ -121,6 +126,14 @@ export module Mock {
|
||||
},
|
||||
},
|
||||
hasConfig: true,
|
||||
images: ['main'],
|
||||
assets: [],
|
||||
volumes: ['main'],
|
||||
hardwareRequirements: {
|
||||
device: {},
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
}
|
||||
|
||||
export const MockManifestBitcoinProxy: Manifest = {
|
||||
@@ -153,7 +166,16 @@ export module Mock {
|
||||
optional: false,
|
||||
},
|
||||
},
|
||||
replaces: [],
|
||||
hasConfig: false,
|
||||
images: ['main'],
|
||||
assets: [],
|
||||
volumes: ['main'],
|
||||
hardwareRequirements: {
|
||||
device: {},
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
}
|
||||
|
||||
export const BitcoinDep: DependencyMetadata = {
|
||||
@@ -1260,7 +1282,7 @@ export module Mock {
|
||||
|
||||
export const bitcoind: PackageDataEntry<InstalledState> = {
|
||||
stateInfo: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: MockManifestBitcoind,
|
||||
},
|
||||
icon: '/assets/img/service-icons/bitcoind.svg',
|
||||
@@ -1269,7 +1291,7 @@ export module Mock {
|
||||
status: {
|
||||
configured: true,
|
||||
main: {
|
||||
status: PackageMainStatus.Running,
|
||||
status: 'running',
|
||||
started: new Date().toISOString(),
|
||||
health: {},
|
||||
},
|
||||
@@ -1293,9 +1315,10 @@ export module Mock {
|
||||
scheme: 'http',
|
||||
preferredExternalPort: 80,
|
||||
addSsl: {
|
||||
addXForwardedHeaders: false,
|
||||
// addXForwardedHeaders: false,
|
||||
preferredExternalPort: 443,
|
||||
scheme: 'https',
|
||||
alpn: { specified: ['http/1.1', 'h2'] },
|
||||
},
|
||||
secure: null,
|
||||
},
|
||||
@@ -1365,9 +1388,10 @@ export module Mock {
|
||||
scheme: 'http',
|
||||
preferredExternalPort: 80,
|
||||
addSsl: {
|
||||
addXForwardedHeaders: false,
|
||||
// addXForwardedHeaders: false,
|
||||
preferredExternalPort: 443,
|
||||
scheme: 'https',
|
||||
alpn: { specified: ['http/1.1'] },
|
||||
},
|
||||
secure: null,
|
||||
},
|
||||
@@ -1493,6 +1517,8 @@ export module Mock {
|
||||
},
|
||||
},
|
||||
currentDependencies: {},
|
||||
hosts: {},
|
||||
storeExposedDependents: [],
|
||||
marketplaceUrl: 'https://registry.start9.com/',
|
||||
developerKey: 'developer-key',
|
||||
outboundProxy: null,
|
||||
@@ -1500,7 +1526,7 @@ export module Mock {
|
||||
|
||||
export const bitcoinProxy: PackageDataEntry<InstalledState> = {
|
||||
stateInfo: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: MockManifestBitcoinProxy,
|
||||
},
|
||||
icon: '/assets/img/service-icons/btc-rpc-proxy.png',
|
||||
@@ -1509,7 +1535,7 @@ export module Mock {
|
||||
status: {
|
||||
configured: false,
|
||||
main: {
|
||||
status: PackageMainStatus.Stopped,
|
||||
status: 'stopped',
|
||||
},
|
||||
dependencyConfigErrors: {},
|
||||
},
|
||||
@@ -1530,9 +1556,10 @@ export module Mock {
|
||||
scheme: 'http',
|
||||
preferredExternalPort: 80,
|
||||
addSsl: {
|
||||
addXForwardedHeaders: false,
|
||||
// addXForwardedHeaders: false,
|
||||
preferredExternalPort: 443,
|
||||
scheme: 'https',
|
||||
alpn: { specified: ['http/1.1', 'h2'] },
|
||||
},
|
||||
secure: {
|
||||
ssl: true,
|
||||
@@ -1632,6 +1659,8 @@ export module Mock {
|
||||
healthChecks: [],
|
||||
},
|
||||
},
|
||||
hosts: {},
|
||||
storeExposedDependents: [],
|
||||
marketplaceUrl: 'https://registry.start9.com/',
|
||||
developerKey: 'developer-key',
|
||||
outboundProxy: null,
|
||||
@@ -1639,7 +1668,7 @@ export module Mock {
|
||||
|
||||
export const lnd: PackageDataEntry<InstalledState> = {
|
||||
stateInfo: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: MockManifestLnd,
|
||||
},
|
||||
icon: '/assets/img/service-icons/lnd.png',
|
||||
@@ -1648,7 +1677,7 @@ export module Mock {
|
||||
status: {
|
||||
configured: true,
|
||||
main: {
|
||||
status: PackageMainStatus.Stopped,
|
||||
status: 'stopped',
|
||||
},
|
||||
dependencyConfigErrors: {
|
||||
'btc-rpc-proxy': 'Username not found',
|
||||
@@ -1882,9 +1911,10 @@ export module Mock {
|
||||
kind: 'exists',
|
||||
registryUrl: 'https://community-registry.start9.com',
|
||||
versionSpec: '>2.0.0', // @TODO
|
||||
healthChecks: [],
|
||||
},
|
||||
},
|
||||
hosts: {},
|
||||
storeExposedDependents: [],
|
||||
marketplaceUrl: 'https://registry.start9.com/',
|
||||
developerKey: 'developer-key',
|
||||
outboundProxy: null,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Dump, Revision } from 'patch-db-client'
|
||||
import { MarketplacePkg, StoreInfo, Manifest } from '@start9labs/marketplace'
|
||||
import { MarketplacePkg, StoreInfo } from '@start9labs/marketplace'
|
||||
import {
|
||||
DataModel,
|
||||
DomainInfo,
|
||||
NetworkStrategy,
|
||||
HealthCheckResult,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
StartOSDiskInfo,
|
||||
@@ -15,6 +14,8 @@ import {
|
||||
} from '@start9labs/shared'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { config } from '@start9labs/start-sdk'
|
||||
import { HealthCheckResult } from '../../../../../../../core/startos/bindings/HealthCheckResult'
|
||||
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export module RR {
|
||||
// DB
|
||||
@@ -644,40 +645,29 @@ export type DependencyError =
|
||||
| DependencyErrorHealthChecksFailed
|
||||
| DependencyErrorTransitive
|
||||
|
||||
export enum DependencyErrorType {
|
||||
NotInstalled = 'not-installed',
|
||||
NotRunning = 'not-running',
|
||||
IncorrectVersion = 'incorrect-version',
|
||||
ConfigUnsatisfied = 'config-unsatisfied',
|
||||
HealthChecksFailed = 'health-checks-failed',
|
||||
InterfaceHealthChecksFailed = 'interface-health-checks-failed',
|
||||
Transitive = 'transitive',
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotInstalled {
|
||||
type: DependencyErrorType.NotInstalled
|
||||
type: 'notInstalled'
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotRunning {
|
||||
type: DependencyErrorType.NotRunning
|
||||
type: 'notRunning'
|
||||
}
|
||||
|
||||
export interface DependencyErrorIncorrectVersion {
|
||||
type: DependencyErrorType.IncorrectVersion
|
||||
type: 'incorrectVersion'
|
||||
expected: string // version range
|
||||
received: string // version
|
||||
}
|
||||
|
||||
export interface DependencyErrorConfigUnsatisfied {
|
||||
type: DependencyErrorType.ConfigUnsatisfied
|
||||
error: string
|
||||
type: 'configUnsatisfied'
|
||||
}
|
||||
|
||||
export interface DependencyErrorHealthChecksFailed {
|
||||
type: DependencyErrorType.HealthChecksFailed
|
||||
type: 'healthChecksFailed'
|
||||
check: HealthCheckResult
|
||||
}
|
||||
|
||||
export interface DependencyErrorTransitive {
|
||||
type: DependencyErrorType.Transitive
|
||||
type: 'transitive'
|
||||
}
|
||||
|
||||
@@ -10,11 +10,8 @@ import {
|
||||
} from 'patch-db-client'
|
||||
import {
|
||||
DataModel,
|
||||
FullProgress,
|
||||
InstallingState,
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
Proxy,
|
||||
StateInfo,
|
||||
UpdatingState,
|
||||
@@ -39,6 +36,7 @@ import { WebSocketSubjectConfig } from 'rxjs/webSocket'
|
||||
import { AuthService } from '../auth.service'
|
||||
import { ConnectionService } from '../connection.service'
|
||||
import { StoreInfo } from '@start9labs/marketplace'
|
||||
import { FullProgress } from '../../../../../../../core/startos/bindings/FullProgress'
|
||||
|
||||
const PROGRESS: FullProgress = {
|
||||
overall: {
|
||||
@@ -864,7 +862,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: appPath,
|
||||
value: PackageMainStatus.BackingUp,
|
||||
value: 'backingUp',
|
||||
},
|
||||
]
|
||||
this.mockRevision(appPatch)
|
||||
@@ -874,7 +872,7 @@ export class MockApiService extends ApiService {
|
||||
this.mockRevision([
|
||||
{
|
||||
...appPatch[0],
|
||||
value: PackageMainStatus.Stopped,
|
||||
value: 'stopped',
|
||||
},
|
||||
])
|
||||
this.mockRevision([
|
||||
@@ -979,10 +977,10 @@ export class MockApiService extends ApiService {
|
||||
...Mock.LocalPkgs[params.id],
|
||||
stateInfo: {
|
||||
// if installing
|
||||
// state: PackageState.Installing,
|
||||
// state: 'installing',
|
||||
|
||||
// if updating
|
||||
state: PackageState.Updating,
|
||||
state: 'updating',
|
||||
manifest: mockPatchData.packageData[params.id].stateInfo.manifest!,
|
||||
|
||||
// both
|
||||
@@ -1047,7 +1045,7 @@ export class MockApiService extends ApiService {
|
||||
value: {
|
||||
...Mock.LocalPkgs[id],
|
||||
stateInfo: {
|
||||
state: PackageState.Restoring,
|
||||
state: 'restoring',
|
||||
installingInfo: {
|
||||
newManifest: Mock.LocalPkgs[id].stateInfo.manifest!,
|
||||
progress: PROGRESS,
|
||||
@@ -1090,7 +1088,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: path + '/status',
|
||||
value: PackageMainStatus.Running,
|
||||
value: 'running',
|
||||
},
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
@@ -1105,7 +1103,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: path + '/status',
|
||||
value: PackageMainStatus.Starting,
|
||||
value: 'starting',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1126,7 +1124,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: path + '/status',
|
||||
value: PackageMainStatus.Starting,
|
||||
value: 'starting',
|
||||
},
|
||||
{
|
||||
op: PatchOp.ADD,
|
||||
@@ -1142,7 +1140,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: path + '/status',
|
||||
value: PackageMainStatus.Running,
|
||||
value: 'running',
|
||||
},
|
||||
{
|
||||
op: PatchOp.REMOVE,
|
||||
@@ -1179,7 +1177,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: path + '/status',
|
||||
value: PackageMainStatus.Restarting,
|
||||
value: 'restarting',
|
||||
},
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
@@ -1203,7 +1201,7 @@ export class MockApiService extends ApiService {
|
||||
op: PatchOp.REPLACE,
|
||||
path: path,
|
||||
value: {
|
||||
status: PackageMainStatus.Stopped,
|
||||
status: 'stopped',
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -1215,7 +1213,7 @@ export class MockApiService extends ApiService {
|
||||
op: PatchOp.REPLACE,
|
||||
path: path,
|
||||
value: {
|
||||
status: PackageMainStatus.Stopping,
|
||||
status: 'stopping',
|
||||
timeout: '35s',
|
||||
},
|
||||
},
|
||||
@@ -1245,7 +1243,7 @@ export class MockApiService extends ApiService {
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: `/packageData/${params.id}/stateInfo/state`,
|
||||
value: PackageState.Removing,
|
||||
value: 'removing',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1397,7 +1395,7 @@ export class MockApiService extends ApiService {
|
||||
op: PatchOp.REPLACE,
|
||||
path: `/packageData/${id}/stateInfo`,
|
||||
value: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: Mock.LocalPkgs[id].stateInfo.manifest,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
DataModel,
|
||||
HealthResult,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { Mock } from './api.fixures'
|
||||
|
||||
export const mockPatchData: DataModel = {
|
||||
@@ -12,7 +7,6 @@ export const mockPatchData: DataModel = {
|
||||
ackWelcome: '1.0.0',
|
||||
theme: 'Dark',
|
||||
desktop: ['lnd'],
|
||||
widgets: [],
|
||||
marketplace: {
|
||||
selectedUrl: 'https://registry.start9.com/',
|
||||
knownHosts: {
|
||||
@@ -138,11 +132,13 @@ export const mockPatchData: DataModel = {
|
||||
passwordHash:
|
||||
'$argon2d$v=19$m=1024,t=1,p=1$YXNkZmFzZGZhc2RmYXNkZg$Ceev1I901G6UwU+hY0sHrFZ56D+o+LNJ',
|
||||
platform: 'x86_64-nonfree',
|
||||
arch: 'x86_64',
|
||||
governor: 'performance',
|
||||
},
|
||||
packageData: {
|
||||
bitcoind: {
|
||||
stateInfo: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: {
|
||||
...Mock.MockManifestBitcoind,
|
||||
version: '0.20.0',
|
||||
@@ -154,31 +150,33 @@ export const mockPatchData: DataModel = {
|
||||
status: {
|
||||
configured: true,
|
||||
main: {
|
||||
status: PackageMainStatus.Running,
|
||||
status: 'running',
|
||||
started: '2021-06-14T20:49:17.774Z',
|
||||
health: {
|
||||
'ephemeral-health-check': {
|
||||
name: 'Ephemeral Health Check',
|
||||
result: HealthResult.Starting,
|
||||
result: 'starting',
|
||||
message: null,
|
||||
},
|
||||
'chain-state': {
|
||||
name: 'Chain State',
|
||||
result: HealthResult.Loading,
|
||||
result: 'loading',
|
||||
message: 'Bitcoin is syncing from genesis',
|
||||
},
|
||||
'p2p-interface': {
|
||||
name: 'P2P',
|
||||
result: HealthResult.Success,
|
||||
result: 'success',
|
||||
message: 'Health check successful',
|
||||
},
|
||||
'rpc-interface': {
|
||||
name: 'RPC',
|
||||
result: HealthResult.Failure,
|
||||
result: 'failure',
|
||||
message: 'RPC interface unreachable.',
|
||||
},
|
||||
'unnecessary-health-check': {
|
||||
name: 'Unnecessary Health Check',
|
||||
result: HealthResult.Disabled,
|
||||
result: 'disabled',
|
||||
message: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -202,9 +200,10 @@ export const mockPatchData: DataModel = {
|
||||
scheme: 'http',
|
||||
preferredExternalPort: 80,
|
||||
addSsl: {
|
||||
addXForwardedHeaders: false,
|
||||
// addXForwardedHeaders: false,
|
||||
preferredExternalPort: 443,
|
||||
scheme: 'https',
|
||||
alpn: { specified: ['http/1.1', 'h2'] },
|
||||
},
|
||||
secure: null,
|
||||
},
|
||||
@@ -274,9 +273,10 @@ export const mockPatchData: DataModel = {
|
||||
scheme: 'http',
|
||||
preferredExternalPort: 80,
|
||||
addSsl: {
|
||||
addXForwardedHeaders: false,
|
||||
// addXForwardedHeaders: false,
|
||||
preferredExternalPort: 443,
|
||||
scheme: 'https',
|
||||
alpn: { specified: ['http/1.1'] },
|
||||
},
|
||||
secure: null,
|
||||
},
|
||||
@@ -402,13 +402,15 @@ export const mockPatchData: DataModel = {
|
||||
},
|
||||
},
|
||||
currentDependencies: {},
|
||||
hosts: {},
|
||||
storeExposedDependents: [],
|
||||
marketplaceUrl: 'https://registry.start9.com/',
|
||||
developerKey: 'developer-key',
|
||||
outboundProxy: null,
|
||||
},
|
||||
lnd: {
|
||||
stateInfo: {
|
||||
state: PackageState.Installed,
|
||||
state: 'installed',
|
||||
manifest: {
|
||||
...Mock.MockManifestLnd,
|
||||
version: '0.11.0',
|
||||
@@ -420,7 +422,7 @@ export const mockPatchData: DataModel = {
|
||||
status: {
|
||||
configured: true,
|
||||
main: {
|
||||
status: PackageMainStatus.Stopped,
|
||||
status: 'stopped',
|
||||
},
|
||||
dependencyConfigErrors: {
|
||||
'btc-rpc-proxy': 'This is a config unsatisfied error',
|
||||
@@ -655,6 +657,8 @@ export const mockPatchData: DataModel = {
|
||||
healthChecks: [],
|
||||
},
|
||||
},
|
||||
hosts: {},
|
||||
storeExposedDependents: [],
|
||||
marketplaceUrl: 'https://registry.start9.com/',
|
||||
developerKey: 'developer-key',
|
||||
outboundProxy: null,
|
||||
|
||||
@@ -2,11 +2,12 @@ import { DOCUMENT } from '@angular/common'
|
||||
import { Inject, Injectable } from '@angular/core'
|
||||
import { WorkspaceConfig } from '@start9labs/shared'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PackageState } from '../../../../../../core/startos/bindings/PackageState'
|
||||
import { MainStatus } from '../../../../../../core/startos/bindings/MainStatus'
|
||||
import { ExportedOnionHostname } from '../../../../../../core/startos/bindings/ExportedOnionHostname'
|
||||
import { ExportedIpHostname } from '../../../../../../core/startos/bindings/ExportedIpHostname'
|
||||
import { ExportedHostnameInfo } from '../../../../../../core/startos/bindings/ExportedHostnameInfo'
|
||||
|
||||
const {
|
||||
gitHash,
|
||||
@@ -77,10 +78,11 @@ export class ConfigService {
|
||||
return window.isSecureContext || this.isTor()
|
||||
}
|
||||
|
||||
isLaunchable(state: PackageState, status: PackageMainStatus): boolean {
|
||||
return (
|
||||
state === PackageState.Installed && status === PackageMainStatus.Running
|
||||
)
|
||||
isLaunchable(
|
||||
state: PackageState['state'],
|
||||
status: MainStatus['status'],
|
||||
): boolean {
|
||||
return state === 'installed' && status === 'running'
|
||||
}
|
||||
|
||||
/** ${scheme}://${username}@${host}:${externalPort}${suffix} */
|
||||
@@ -95,31 +97,28 @@ export class ConfigService {
|
||||
const url = new URL(`${scheme}://${username}placeholder${suffix}`)
|
||||
|
||||
if (host.kind === 'multi') {
|
||||
const onionHostname = host.hostnames.find(
|
||||
(h: any) => h.kind === 'onion',
|
||||
) as T.HostnameInfoOnion
|
||||
const onionHostname = host.hostnames.find(h => h.kind === 'onion')
|
||||
?.hostname as ExportedOnionHostname
|
||||
|
||||
if (this.isTor() && onionHostname) {
|
||||
url.hostname = onionHostname.hostname.value
|
||||
url.hostname = onionHostname.value
|
||||
} else {
|
||||
const ipHostname = host.hostnames.find(
|
||||
(h: any) => h.kind === 'ip',
|
||||
) as T.HostnameInfoIp
|
||||
const ipHostname = host.hostnames.find(h => h.kind === 'ip')
|
||||
?.hostname as ExportedIpHostname
|
||||
|
||||
if (!ipHostname) return ''
|
||||
|
||||
url.hostname = this.hostname
|
||||
url.port = String(
|
||||
ipHostname.hostname.sslPort || ipHostname.hostname.port,
|
||||
)
|
||||
url.port = String(ipHostname.sslPort || ipHostname.port)
|
||||
}
|
||||
} else {
|
||||
const hostname = host.hostname
|
||||
throw new Error('unimplemented')
|
||||
const hostname = {} as ExportedHostnameInfo // host.hostname
|
||||
|
||||
if (!hostname) return ''
|
||||
|
||||
if (this.isTor() && hostname.kind === 'onion') {
|
||||
url.hostname = hostname.hostname.value
|
||||
url.hostname = (hostname.hostname as ExportedOnionHostname).value
|
||||
} else {
|
||||
url.hostname = this.hostname
|
||||
url.port = String(hostname.hostname.sslPort || hostname.hostname.port)
|
||||
|
||||
@@ -4,15 +4,13 @@ import { distinctUntilChanged, map, shareReplay } from 'rxjs/operators'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import {
|
||||
DataModel,
|
||||
HealthResult,
|
||||
InstalledState,
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
} from './patch-db/data-model'
|
||||
import * as deepEqual from 'fast-deep-equal'
|
||||
import { Observable } from 'rxjs'
|
||||
import { isInstalled } from '../util/get-package-data'
|
||||
import { DependencyError } from './api/api.types'
|
||||
|
||||
export type AllDependencyErrors = Record<string, PkgDependencyErrors>
|
||||
export type PkgDependencyErrors = Record<string, DependencyError | null>
|
||||
@@ -82,9 +80,9 @@ export class DepErrorService {
|
||||
const dep = pkgs[depId]
|
||||
|
||||
// not installed
|
||||
if (!dep || dep.stateInfo.state !== PackageState.Installed) {
|
||||
if (!dep || dep.stateInfo.state !== 'installed') {
|
||||
return {
|
||||
type: DependencyErrorType.NotInstalled,
|
||||
type: 'notInstalled',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +92,7 @@ export class DepErrorService {
|
||||
// incorrect version
|
||||
if (!this.emver.satisfies(depManifest.version, versionSpec)) {
|
||||
return {
|
||||
type: DependencyErrorType.IncorrectVersion,
|
||||
type: 'incorrectVersion',
|
||||
expected: versionSpec,
|
||||
received: depManifest.version,
|
||||
}
|
||||
@@ -103,28 +101,29 @@ export class DepErrorService {
|
||||
// invalid config
|
||||
if (Object.values(pkg.status.dependencyConfigErrors).some(err => !!err)) {
|
||||
return {
|
||||
type: DependencyErrorType.ConfigUnsatisfied,
|
||||
type: 'configUnsatisfied',
|
||||
}
|
||||
}
|
||||
|
||||
const depStatus = dep.status.main.status
|
||||
|
||||
// not running
|
||||
if (
|
||||
depStatus !== PackageMainStatus.Running &&
|
||||
depStatus !== PackageMainStatus.Starting
|
||||
) {
|
||||
if (depStatus !== 'running' && depStatus !== 'starting') {
|
||||
return {
|
||||
type: DependencyErrorType.NotRunning,
|
||||
type: 'notRunning',
|
||||
}
|
||||
}
|
||||
|
||||
const currentDep = pkg.currentDependencies[depId]
|
||||
|
||||
// health check failure
|
||||
if (depStatus === PackageMainStatus.Running) {
|
||||
for (let id of pkg.currentDependencies[depId].healthChecks) {
|
||||
if (dep.status.main.health[id]?.result !== HealthResult.Success) {
|
||||
if (depStatus === 'running' && currentDep.kind === 'running') {
|
||||
for (let id of currentDep.healthChecks) {
|
||||
const check = dep.status.main.health[id]
|
||||
if (check?.result !== 'success') {
|
||||
return {
|
||||
type: DependencyErrorType.HealthChecksFailed,
|
||||
type: 'healthChecksFailed',
|
||||
check,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,7 +136,7 @@ export class DepErrorService {
|
||||
|
||||
if (transitiveError) {
|
||||
return {
|
||||
type: DependencyErrorType.Transitive,
|
||||
type: 'transitive',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,46 +160,3 @@ function dependencyDepth(
|
||||
depth,
|
||||
)
|
||||
}
|
||||
|
||||
export type DependencyError =
|
||||
| DependencyErrorNotInstalled
|
||||
| DependencyErrorNotRunning
|
||||
| DependencyErrorIncorrectVersion
|
||||
| DependencyErrorConfigUnsatisfied
|
||||
| DependencyErrorHealthChecksFailed
|
||||
| DependencyErrorTransitive
|
||||
|
||||
export enum DependencyErrorType {
|
||||
NotInstalled = 'notInstalled',
|
||||
NotRunning = 'notRunning',
|
||||
IncorrectVersion = 'incorrectVersion',
|
||||
ConfigUnsatisfied = 'configUnsatisfied',
|
||||
HealthChecksFailed = 'healthChecksFailed',
|
||||
Transitive = 'transitive',
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotInstalled {
|
||||
type: DependencyErrorType.NotInstalled
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotRunning {
|
||||
type: DependencyErrorType.NotRunning
|
||||
}
|
||||
|
||||
export interface DependencyErrorIncorrectVersion {
|
||||
type: DependencyErrorType.IncorrectVersion
|
||||
expected: string // version range
|
||||
received: string // version
|
||||
}
|
||||
|
||||
export interface DependencyErrorConfigUnsatisfied {
|
||||
type: DependencyErrorType.ConfigUnsatisfied
|
||||
}
|
||||
|
||||
export interface DependencyErrorHealthChecksFailed {
|
||||
type: DependencyErrorType.HealthChecksFailed
|
||||
}
|
||||
|
||||
export interface DependencyErrorTransitive {
|
||||
type: DependencyErrorType.Transitive
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
MarketplacePkg,
|
||||
StoreData,
|
||||
StoreIdentity,
|
||||
StoreIdentityWithData,
|
||||
StoreInfo,
|
||||
} from '@start9labs/marketplace'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { BackupJob, ServerNotifications } from '../api/api.types'
|
||||
import { Url } from '@start9labs/shared'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { config } from '@start9labs/start-sdk'
|
||||
import { PackageDataEntry as PDE } from '../../../../../../../core/startos/bindings/PackageDataEntry'
|
||||
import { FullProgress } from '../../../../../../../core/startos/bindings/FullProgress'
|
||||
import { Manifest } from '../../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export interface DataModel {
|
||||
serverInfo: ServerInfo
|
||||
packageData: { [id: string]: PackageDataEntry }
|
||||
export type DataModel = {
|
||||
ui: UIData
|
||||
serverInfo: ServerInfo
|
||||
packageData: Record<string, PackageDataEntry>
|
||||
}
|
||||
|
||||
export interface UIData {
|
||||
export type UIData = {
|
||||
name: string | null
|
||||
ackWelcome: string // emver
|
||||
marketplace: UIMarketplaceData
|
||||
@@ -21,24 +22,10 @@ export interface UIData {
|
||||
}
|
||||
ackInstructions: Record<string, boolean>
|
||||
theme: string
|
||||
widgets: readonly Widget[]
|
||||
desktop: readonly string[]
|
||||
}
|
||||
|
||||
export interface Widget {
|
||||
id: string
|
||||
meta: {
|
||||
name: string
|
||||
width: number
|
||||
height: number
|
||||
mobileWidth: number
|
||||
mobileHeight: number
|
||||
}
|
||||
url?: string
|
||||
settings?: string
|
||||
}
|
||||
|
||||
export interface UIMarketplaceData {
|
||||
export type UIMarketplaceData = {
|
||||
selectedUrl: string
|
||||
knownHosts: {
|
||||
'https://registry.start9.com/': UIStore
|
||||
@@ -47,11 +34,11 @@ export interface UIMarketplaceData {
|
||||
}
|
||||
}
|
||||
|
||||
export interface UIStore {
|
||||
export type UIStore = {
|
||||
name?: string
|
||||
}
|
||||
|
||||
export interface ServerInfo {
|
||||
export type ServerInfo = {
|
||||
id: string
|
||||
version: string
|
||||
country: string
|
||||
@@ -70,6 +57,8 @@ export interface ServerInfo {
|
||||
smtp: typeof config.constants.customSmtp.validator._TYPE
|
||||
passwordHash: string
|
||||
platform: string
|
||||
arch: string
|
||||
governor: string | null
|
||||
}
|
||||
|
||||
export type NetworkInfo = {
|
||||
@@ -129,14 +118,6 @@ export type Proxy = {
|
||||
}
|
||||
}
|
||||
|
||||
export interface IpInfo {
|
||||
[iface: string]: {
|
||||
wireless: boolean
|
||||
ipv4: string | null
|
||||
ipv6: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface ServerStatusInfo {
|
||||
currentBackup: null | {
|
||||
job: BackupJob
|
||||
@@ -148,16 +129,8 @@ export interface ServerStatusInfo {
|
||||
shuttingDown: boolean
|
||||
}
|
||||
|
||||
export type PackageDataEntry<T extends StateInfo = StateInfo> = {
|
||||
export type PackageDataEntry<T extends StateInfo = StateInfo> = PDE & {
|
||||
stateInfo: T
|
||||
icon: Url
|
||||
status: Status
|
||||
actions: Record<string, T.ActionMetadata>
|
||||
lastBackup: string | null
|
||||
currentDependencies: Record<string, CurrentDependencyInfo>
|
||||
serviceInterfaces: Record<string, T.ServiceInterfaceWithHostInfo>
|
||||
marketplaceUrl: string | null
|
||||
developerKey: string
|
||||
installedAt: string
|
||||
outboundProxy: string | null
|
||||
}
|
||||
@@ -165,142 +138,24 @@ export type PackageDataEntry<T extends StateInfo = StateInfo> = {
|
||||
export type StateInfo = InstalledState | InstallingState | UpdatingState
|
||||
|
||||
export type InstalledState = {
|
||||
state: PackageState.Installed | PackageState.Removing
|
||||
state: 'installed' | 'removing'
|
||||
manifest: Manifest
|
||||
installingInfo?: undefined
|
||||
}
|
||||
|
||||
export type InstallingState = {
|
||||
state: PackageState.Installing | PackageState.Restoring
|
||||
state: 'installing' | 'restoring'
|
||||
installingInfo: InstallingInfo
|
||||
manifest?: undefined
|
||||
}
|
||||
|
||||
export type UpdatingState = {
|
||||
state: PackageState.Updating
|
||||
state: 'updating'
|
||||
installingInfo: InstallingInfo
|
||||
manifest: Manifest
|
||||
}
|
||||
|
||||
export enum PackageState {
|
||||
Installing = 'installing',
|
||||
Installed = 'installed',
|
||||
Updating = 'updating',
|
||||
Removing = 'removing',
|
||||
Restoring = 'restoring',
|
||||
}
|
||||
|
||||
export interface CurrentDependencyInfo {
|
||||
title: string
|
||||
icon: string
|
||||
kind: 'exists' | 'running'
|
||||
registryUrl: string
|
||||
versionSpec: string
|
||||
healthChecks: string[] // array of health check IDs
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
configured: boolean
|
||||
main: MainStatus
|
||||
dependencyConfigErrors: { [id: string]: string | null }
|
||||
}
|
||||
|
||||
export type MainStatus =
|
||||
| MainStatusStopped
|
||||
| MainStatusStopping
|
||||
| MainStatusStarting
|
||||
| MainStatusRunning
|
||||
| MainStatusBackingUp
|
||||
| MainStatusRestarting
|
||||
| MainStatusConfiguring
|
||||
|
||||
export interface MainStatusStopped {
|
||||
status: PackageMainStatus.Stopped
|
||||
}
|
||||
|
||||
export interface MainStatusStopping {
|
||||
status: PackageMainStatus.Stopping
|
||||
timeout: string
|
||||
}
|
||||
|
||||
export interface MainStatusStarting {
|
||||
status: PackageMainStatus.Starting
|
||||
}
|
||||
|
||||
export interface MainStatusRunning {
|
||||
status: PackageMainStatus.Running
|
||||
started: string // UTC date string
|
||||
health: Record<string, HealthCheckResult>
|
||||
}
|
||||
|
||||
export interface MainStatusBackingUp {
|
||||
status: PackageMainStatus.BackingUp
|
||||
}
|
||||
|
||||
export interface MainStatusRestarting {
|
||||
status: PackageMainStatus.Restarting
|
||||
}
|
||||
|
||||
export interface MainStatusConfiguring {
|
||||
status: PackageMainStatus.Configuring
|
||||
}
|
||||
|
||||
export enum PackageMainStatus {
|
||||
Starting = 'starting',
|
||||
Running = 'running',
|
||||
Stopping = 'stopping',
|
||||
Stopped = 'stopped',
|
||||
BackingUp = 'backing-up',
|
||||
Restarting = 'restarting',
|
||||
Configuring = 'configuring',
|
||||
}
|
||||
|
||||
export type HealthCheckResult = { name: string } & (
|
||||
| HealthCheckResultStarting
|
||||
| HealthCheckResultLoading
|
||||
| HealthCheckResultDisabled
|
||||
| HealthCheckResultSuccess
|
||||
| HealthCheckResultFailure
|
||||
)
|
||||
|
||||
export enum HealthResult {
|
||||
Starting = 'starting',
|
||||
Loading = 'loading',
|
||||
Disabled = 'disabled',
|
||||
Success = 'success',
|
||||
Failure = 'failure',
|
||||
}
|
||||
|
||||
export interface HealthCheckResultStarting {
|
||||
result: HealthResult.Starting
|
||||
}
|
||||
|
||||
export interface HealthCheckResultDisabled {
|
||||
result: HealthResult.Disabled
|
||||
}
|
||||
|
||||
export interface HealthCheckResultSuccess {
|
||||
result: HealthResult.Success
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface HealthCheckResultLoading {
|
||||
result: HealthResult.Loading
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface HealthCheckResultFailure {
|
||||
result: HealthResult.Failure
|
||||
message: string
|
||||
}
|
||||
|
||||
export type InstallingInfo = {
|
||||
progress: FullProgress
|
||||
newManifest: Manifest
|
||||
}
|
||||
|
||||
export type FullProgress = {
|
||||
overall: Progress
|
||||
phases: { name: string; progress: Progress }[]
|
||||
}
|
||||
export type Progress = boolean | { done: number; total: number | null } // false means indeterminate. true means complete
|
||||
|
||||
@@ -1,70 +1,65 @@
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
Status,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PkgDependencyErrors } from './dep-error.service'
|
||||
import { Status } from '../../../../../../core/startos/bindings/Status'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
|
||||
export interface PackageStatus {
|
||||
primary: PrimaryStatus | PackageState | PackageMainStatus
|
||||
primary: PrimaryStatus
|
||||
dependency: DependencyStatus | null
|
||||
health: HealthStatus | null
|
||||
health: T.HealthStatus | null
|
||||
}
|
||||
|
||||
export function renderPkgStatus(
|
||||
pkg: PackageDataEntry,
|
||||
depErrors: PkgDependencyErrors,
|
||||
): PackageStatus {
|
||||
let primary: PrimaryStatus | PackageState | PackageMainStatus
|
||||
let primary: PrimaryStatus
|
||||
let dependency: DependencyStatus | null = null
|
||||
let health: HealthStatus | null = null
|
||||
let health: T.HealthStatus | null = null
|
||||
|
||||
if (pkg.stateInfo.state === PackageState.Installed) {
|
||||
primary = getPrimaryStatus(pkg.status)
|
||||
if (pkg.stateInfo.state === 'installed') {
|
||||
primary = getInstalledPrimaryStatus(pkg.status)
|
||||
dependency = getDependencyStatus(depErrors)
|
||||
health = getHealthStatus(pkg.status)
|
||||
} else {
|
||||
primary = pkg.stateInfo.state as string as PrimaryStatus
|
||||
primary = pkg.stateInfo.state
|
||||
}
|
||||
|
||||
return { primary, dependency, health }
|
||||
}
|
||||
|
||||
function getPrimaryStatus(status: Status): PrimaryStatus | PackageMainStatus {
|
||||
function getInstalledPrimaryStatus(status: Status): PrimaryStatus {
|
||||
if (!status.configured) {
|
||||
return PrimaryStatus.NeedsConfig
|
||||
return 'needsConfig'
|
||||
} else {
|
||||
return status.main.status
|
||||
}
|
||||
}
|
||||
|
||||
function getDependencyStatus(depErrors: PkgDependencyErrors): DependencyStatus {
|
||||
return Object.values(depErrors).some(err => !!err)
|
||||
? DependencyStatus.Warning
|
||||
: DependencyStatus.Satisfied
|
||||
return Object.values(depErrors).some(err => !!err) ? 'warning' : 'satisfied'
|
||||
}
|
||||
|
||||
function getHealthStatus(status: Status): HealthStatus | null {
|
||||
if (status.main.status !== PackageMainStatus.Running || !status.main.health) {
|
||||
function getHealthStatus(status: Status): T.HealthStatus | null {
|
||||
if (status.main.status !== 'running' || !status.main.health) {
|
||||
return null
|
||||
}
|
||||
|
||||
const values = Object.values(status.main.health)
|
||||
|
||||
if (values.some(h => h.result === 'failure')) {
|
||||
return HealthStatus.Failure
|
||||
return 'failure'
|
||||
}
|
||||
|
||||
if (values.some(h => h.result === 'loading')) {
|
||||
return HealthStatus.Loading
|
||||
return 'loading'
|
||||
}
|
||||
|
||||
if (values.some(h => h.result === 'starting')) {
|
||||
return HealthStatus.Starting
|
||||
return 'starting'
|
||||
}
|
||||
|
||||
return HealthStatus.Healthy
|
||||
return 'success'
|
||||
}
|
||||
|
||||
export interface StatusRendering {
|
||||
@@ -73,101 +68,88 @@ export interface StatusRendering {
|
||||
showDots?: boolean
|
||||
}
|
||||
|
||||
export enum PrimaryStatus {
|
||||
// state
|
||||
Installing = 'installing',
|
||||
Updating = 'updating',
|
||||
Removing = 'removing',
|
||||
Restoring = 'restoring',
|
||||
// status
|
||||
Starting = 'starting',
|
||||
Running = 'running',
|
||||
Stopping = 'stopping',
|
||||
Restarting = 'restarting',
|
||||
Stopped = 'stopped',
|
||||
BackingUp = 'backing-up',
|
||||
// config
|
||||
NeedsConfig = 'needs-config',
|
||||
}
|
||||
export type PrimaryStatus =
|
||||
| 'installing'
|
||||
| 'updating'
|
||||
| 'removing'
|
||||
| 'restoring'
|
||||
| 'starting'
|
||||
| 'running'
|
||||
| 'stopping'
|
||||
| 'restarting'
|
||||
| 'stopped'
|
||||
| 'backingUp'
|
||||
| 'needsConfig'
|
||||
|
||||
export enum DependencyStatus {
|
||||
Warning = 'warning',
|
||||
Satisfied = 'satisfied',
|
||||
}
|
||||
export type DependencyStatus = 'warning' | 'satisfied'
|
||||
|
||||
export enum HealthStatus {
|
||||
Failure = 'failure',
|
||||
Starting = 'starting',
|
||||
Loading = 'loading',
|
||||
Healthy = 'healthy',
|
||||
}
|
||||
|
||||
export const PrimaryRendering: Record<string, StatusRendering> = {
|
||||
[PrimaryStatus.Installing]: {
|
||||
export const PrimaryRendering: Record<PrimaryStatus, StatusRendering> = {
|
||||
installing: {
|
||||
display: 'Installing',
|
||||
color: 'primary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Updating]: {
|
||||
updating: {
|
||||
display: 'Updating',
|
||||
color: 'primary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Removing]: {
|
||||
removing: {
|
||||
display: 'Removing',
|
||||
color: 'danger',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Restoring]: {
|
||||
restoring: {
|
||||
display: 'Restoring',
|
||||
color: 'primary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Stopping]: {
|
||||
stopping: {
|
||||
display: 'Stopping',
|
||||
color: 'dark-shade',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Restarting]: {
|
||||
restarting: {
|
||||
display: 'Restarting',
|
||||
color: 'tertiary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Stopped]: {
|
||||
stopped: {
|
||||
display: 'Stopped',
|
||||
color: 'dark-shade',
|
||||
showDots: false,
|
||||
},
|
||||
[PrimaryStatus.BackingUp]: {
|
||||
backingUp: {
|
||||
display: 'Backing Up',
|
||||
color: 'primary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Starting]: {
|
||||
starting: {
|
||||
display: 'Starting',
|
||||
color: 'primary',
|
||||
showDots: true,
|
||||
},
|
||||
[PrimaryStatus.Running]: {
|
||||
running: {
|
||||
display: 'Running',
|
||||
color: 'success',
|
||||
showDots: false,
|
||||
},
|
||||
[PrimaryStatus.NeedsConfig]: {
|
||||
needsConfig: {
|
||||
display: 'Needs Config',
|
||||
color: 'warning',
|
||||
showDots: false,
|
||||
},
|
||||
}
|
||||
|
||||
export const DependencyRendering: Record<string, StatusRendering> = {
|
||||
[DependencyStatus.Warning]: { display: 'Issue', color: 'warning' },
|
||||
[DependencyStatus.Satisfied]: { display: 'Satisfied', color: 'success' },
|
||||
export const DependencyRendering: Record<DependencyStatus, StatusRendering> = {
|
||||
warning: { display: 'Issue', color: 'warning' },
|
||||
satisfied: { display: 'Satisfied', color: 'success' },
|
||||
}
|
||||
|
||||
export const HealthRendering: Record<string, StatusRendering> = {
|
||||
[HealthStatus.Failure]: { display: 'Failure', color: 'danger' },
|
||||
[HealthStatus.Starting]: { display: 'Starting', color: 'primary' },
|
||||
[HealthStatus.Loading]: { display: 'Loading', color: 'primary' },
|
||||
[HealthStatus.Healthy]: { display: 'Healthy', color: 'success' },
|
||||
export const HealthRendering: Record<T.HealthStatus, StatusRendering> = {
|
||||
failure: { display: 'Failure', color: 'danger' },
|
||||
starting: { display: 'Starting', color: 'primary' },
|
||||
loading: { display: 'Loading', color: 'primary' },
|
||||
success: { display: 'Healthy', color: 'success' },
|
||||
disabled: { display: 'Disabled', color: 'dark' },
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { Subscription } from 'rxjs'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
PackageState,
|
||||
} from '../services/patch-db/data-model'
|
||||
import { PackageDataEntry } from '../services/patch-db/data-model'
|
||||
import {
|
||||
PrimaryStatus,
|
||||
StatusRendering,
|
||||
@@ -12,7 +8,7 @@ import {
|
||||
export interface PkgInfo {
|
||||
entry: PackageDataEntry
|
||||
primaryRendering: StatusRendering
|
||||
primaryStatus: PrimaryStatus | PackageState | PackageMainStatus
|
||||
primaryStatus: PrimaryStatus
|
||||
error: boolean
|
||||
warning: boolean
|
||||
transitioning: boolean
|
||||
|
||||
@@ -4,11 +4,10 @@ import {
|
||||
InstalledState,
|
||||
InstallingState,
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
UpdatingState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { firstValueFrom } from 'rxjs'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { Manifest } from '../../../../../../core/startos/bindings/Manifest'
|
||||
|
||||
export async function getPackage(
|
||||
patch: PatchDB<DataModel>,
|
||||
@@ -32,29 +31,29 @@ export function getManifest(pkg: PackageDataEntry): Manifest {
|
||||
export function isInstalled(
|
||||
pkg: PackageDataEntry,
|
||||
): pkg is PackageDataEntry<InstalledState> {
|
||||
return pkg.stateInfo.state === PackageState.Installed
|
||||
return pkg.stateInfo.state === 'installed'
|
||||
}
|
||||
|
||||
export function isRemoving(
|
||||
pkg: PackageDataEntry,
|
||||
): pkg is PackageDataEntry<InstalledState> {
|
||||
return pkg.stateInfo.state === PackageState.Removing
|
||||
return pkg.stateInfo.state === 'removing'
|
||||
}
|
||||
|
||||
export function isInstalling(
|
||||
pkg: PackageDataEntry,
|
||||
): pkg is PackageDataEntry<InstallingState> {
|
||||
return pkg.stateInfo.state === PackageState.Installing
|
||||
return pkg.stateInfo.state === 'installing'
|
||||
}
|
||||
|
||||
export function isRestoring(
|
||||
pkg: PackageDataEntry,
|
||||
): pkg is PackageDataEntry<InstallingState> {
|
||||
return pkg.stateInfo.state === PackageState.Restoring
|
||||
return pkg.stateInfo.state === 'restoring'
|
||||
}
|
||||
|
||||
export function isUpdating(
|
||||
pkg: PackageDataEntry,
|
||||
): pkg is PackageDataEntry<UpdatingState> {
|
||||
return pkg.stateInfo.state === PackageState.Updating
|
||||
return pkg.stateInfo.state === 'updating'
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { PackageDataEntry } from '../services/patch-db/data-model'
|
||||
import {
|
||||
DependencyStatus,
|
||||
HealthStatus,
|
||||
PrimaryRendering,
|
||||
PrimaryStatus,
|
||||
renderPkgStatus,
|
||||
} from '../services/pkg-status-rendering.service'
|
||||
import { PkgInfo } from '../types/pkg-info'
|
||||
@@ -20,13 +17,11 @@ export function getPackageInfo(
|
||||
entry,
|
||||
primaryRendering,
|
||||
primaryStatus: statuses.primary,
|
||||
error:
|
||||
statuses.health === HealthStatus.Failure ||
|
||||
statuses.dependency === DependencyStatus.Warning,
|
||||
warning: statuses.primary === PrimaryStatus.NeedsConfig,
|
||||
error: statuses.health === 'failure' || statuses.dependency === 'warning',
|
||||
warning: statuses.primary === 'needsConfig',
|
||||
transitioning:
|
||||
primaryRendering.showDots ||
|
||||
statuses.health === HealthStatus.Loading ||
|
||||
statuses.health === HealthStatus.Starting,
|
||||
statuses.health === 'loading' ||
|
||||
statuses.health === 'starting',
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user