mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
update sdk imports
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"projects": {
|
||||
"ui": {
|
||||
"name": "ui",
|
||||
"integrations": {},
|
||||
"type": "angular",
|
||||
"root": "projects/ui"
|
||||
},
|
||||
"install-wizard": {
|
||||
"name": "install-wizard",
|
||||
"integrations": {},
|
||||
"type": "angular",
|
||||
"root": "projects/install-wizard"
|
||||
},
|
||||
"setup-wizard": {
|
||||
"name": "setup-wizard",
|
||||
"integrations": {},
|
||||
"type": "angular",
|
||||
"root": "projects/setup-wizard"
|
||||
}
|
||||
},
|
||||
"defaultProject": "ui"
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": null,
|
||||
"ack-welcome": "0.3.4.4",
|
||||
"ackWelcome": "0.3.4.4",
|
||||
"marketplace": {
|
||||
"selected-url": "https://registry.start9.com/",
|
||||
"known-hosts": {
|
||||
"selectedUrl": "https://registry.start9.com/",
|
||||
"knownHosts": {
|
||||
"https://registry.start9.com/": {},
|
||||
"https://community-registry.start9.com/": {}
|
||||
}
|
||||
@@ -11,10 +11,10 @@
|
||||
"dev": {},
|
||||
"gaming": {
|
||||
"snake": {
|
||||
"high-score": 0
|
||||
"highScore": 0
|
||||
}
|
||||
},
|
||||
"ack-instructions": {},
|
||||
"ackInstructions": {},
|
||||
"theme": "Dark",
|
||||
"widgets": []
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
} from '@angular/core'
|
||||
import { FormGroup, ReactiveFormsModule } from '@angular/forms'
|
||||
import { RouterModule } from '@angular/router'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
import {
|
||||
tuiMarkControlAsTouchedAndValidate,
|
||||
TuiValueChangesModule,
|
||||
@@ -29,7 +30,7 @@ export interface ActionButton<T> {
|
||||
}
|
||||
|
||||
export interface FormContext<T> {
|
||||
spec: InputSpec
|
||||
spec: CT.InputSpec
|
||||
buttons: ActionButton<T>[]
|
||||
value?: T
|
||||
patch?: Operation[]
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CB, CT, T } from '@start9labs/start-sdk'
|
||||
import { TuiDialogOptions } from '@taiga-ui/core'
|
||||
import { TuiPromptData } from '@taiga-ui/kit'
|
||||
import { NetworkInfo } from 'src/app/services/patch-db/data-model'
|
||||
@@ -20,7 +17,7 @@ export const REMOVE: Partial<TuiDialogOptions<TuiPromptData>> = {
|
||||
export function getClearnetSpec({
|
||||
domains,
|
||||
start9ToSubdomain,
|
||||
}: NetworkInfo): Promise<InputSpec> {
|
||||
}: NetworkInfo): Promise<CT.InputSpec> {
|
||||
const start9ToDomain = `${start9ToSubdomain?.value}.start9.to`
|
||||
const base = start9ToSubdomain ? { [start9ToDomain]: start9ToDomain } : {}
|
||||
|
||||
@@ -32,13 +29,13 @@ export function getClearnetSpec({
|
||||
}, base)
|
||||
|
||||
return configBuilderToSpec(
|
||||
Config.of({
|
||||
domain: Value.select({
|
||||
CB.Config.of({
|
||||
domain: CB.Value.select({
|
||||
name: 'Domain',
|
||||
required: { default: null },
|
||||
values,
|
||||
}),
|
||||
subdomain: Value.text({
|
||||
subdomain: CB.Value.text({
|
||||
name: 'Subdomain',
|
||||
required: false,
|
||||
}),
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
isEmptyObject,
|
||||
LoadingService,
|
||||
} from '@start9labs/shared'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { TuiButtonModule } from '@taiga-ui/experimental'
|
||||
import {
|
||||
TuiDialogContext,
|
||||
@@ -131,7 +131,7 @@ export class ServiceConfigModal {
|
||||
: 'Loading Config'
|
||||
|
||||
pkg?: PackageDataEntry
|
||||
spec: InputSpec = {}
|
||||
spec: CT.InputSpec = {}
|
||||
patch: Operation[] = []
|
||||
buttons: ActionButton<any>[] = [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { WithId } from '@start9labs/shared'
|
||||
import { ActionMetadata } from '@start9labs/start-sdk/cjs/sdk/lib/types'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
|
||||
@Pipe({
|
||||
@@ -10,12 +10,12 @@ import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
export class GroupActionsPipe implements PipeTransform {
|
||||
transform(
|
||||
actions: PackageDataEntry['actions'],
|
||||
): Array<Array<WithId<ActionMetadata>>> | null {
|
||||
): Array<Array<WithId<T.ActionMetadata>>> | null {
|
||||
if (!actions) return null
|
||||
|
||||
const noGroup = 'noGroup'
|
||||
const grouped = Object.entries(actions).reduce<
|
||||
Record<string, WithId<ActionMetadata>[]>
|
||||
Record<string, WithId<T.ActionMetadata>[]>
|
||||
>((groups, [id, action]) => {
|
||||
const actionWithId = { id, ...action }
|
||||
const groupKey = action.group || noGroup
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { ServiceInterfaceWithHostInfo } from '@start9labs/start-sdk/cjs/sdk/lib/types'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
|
||||
export interface ExtendedInterfaceInfo extends ServiceInterfaceWithHostInfo {
|
||||
export interface ExtendedInterfaceInfo extends T.ServiceInterfaceWithHostInfo {
|
||||
id: string
|
||||
icon: string
|
||||
color: string
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ServiceActionComponent } from '../components/action.component'
|
||||
import { ServiceActionSuccessComponent } from '../components/action-success.component'
|
||||
import { GroupActionsPipe } from '../pipes/group-actions.pipe'
|
||||
import { ToManifestPipe } from 'src/app/apps/portal/pipes/to-manifest'
|
||||
import { ActionMetadata } from '@start9labs/start-sdk/cjs/sdk/lib/types'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { getAllPackages, getManifest } from 'src/app/util/get-package-data'
|
||||
|
||||
@Component({
|
||||
@@ -61,7 +61,12 @@ import { getAllPackages, getManifest } from 'src/app/util/get-package-data'
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, ServiceActionComponent, GroupActionsPipe, ToManifestPipe],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ServiceActionComponent,
|
||||
GroupActionsPipe,
|
||||
ToManifestPipe,
|
||||
],
|
||||
})
|
||||
export class ServiceActionsRoute {
|
||||
private readonly id = getPkgId(inject(ActivatedRoute))
|
||||
@@ -87,7 +92,7 @@ export class ServiceActionsRoute {
|
||||
private readonly formDialog: FormDialogService,
|
||||
) {}
|
||||
|
||||
async handleAction(action: WithId<ActionMetadata>) {
|
||||
async handleAction(action: WithId<T.ActionMetadata>) {
|
||||
if (action.disabled) {
|
||||
this.dialogs
|
||||
.open(action.disabled, {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { Component, inject, OnInit } from '@angular/core'
|
||||
import { ErrorService, LoadingService } from '@start9labs/shared'
|
||||
import {
|
||||
unionSelectKey,
|
||||
unionValueKey,
|
||||
} from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { TuiNotificationModule } from '@taiga-ui/core'
|
||||
import { TuiButtonModule, TuiFadeModule } from '@taiga-ui/experimental'
|
||||
import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus'
|
||||
@@ -182,8 +179,8 @@ export class BackupsTargetsModal implements OnInit {
|
||||
text: 'Save',
|
||||
handler: ({ type }: BackupConfig) =>
|
||||
this.add(
|
||||
type[unionSelectKey] === 'cifs' ? 'cifs' : 'cloud',
|
||||
type[unionValueKey],
|
||||
type[CT.unionSelectKey] === 'cifs' ? 'cifs' : 'cloud',
|
||||
type[CT.unionValueKey],
|
||||
),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
import {
|
||||
unionSelectKey,
|
||||
unionValueKey,
|
||||
} from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { RR } from 'src/app/services/api/api.types'
|
||||
|
||||
export type BackupConfig =
|
||||
| {
|
||||
type: {
|
||||
[unionSelectKey]: 'dropbox' | 'google-drive'
|
||||
[unionValueKey]: RR.AddCloudBackupTargetReq
|
||||
[CT.unionSelectKey]: 'dropbox' | 'google-drive'
|
||||
[CT.unionValueKey]: RR.AddCloudBackupTargetReq
|
||||
}
|
||||
}
|
||||
| {
|
||||
type: {
|
||||
[unionSelectKey]: 'cifs'
|
||||
[unionValueKey]: RR.AddCifsBackupTargetReq
|
||||
[CT.unionSelectKey]: 'cifs'
|
||||
[CT.unionValueKey]: RR.AddCifsBackupTargetReq
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { Variants } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/variants'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
export const dropboxSpec = Config.of({
|
||||
name: Value.text({
|
||||
export const dropboxSpec = CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
description: 'A friendly name for this Dropbox target',
|
||||
placeholder: 'My Dropbox',
|
||||
required: { default: null },
|
||||
}),
|
||||
token: Value.text({
|
||||
token: CB.Value.text({
|
||||
name: 'Access Token',
|
||||
description: 'The secret access token for your custom Dropbox app',
|
||||
required: { default: null },
|
||||
masked: true,
|
||||
}),
|
||||
path: Value.text({
|
||||
path: CB.Value.text({
|
||||
name: 'Path',
|
||||
description: 'The fully qualified path to the backup directory',
|
||||
placeholder: 'e.g. /Desktop/my-folder',
|
||||
@@ -23,20 +21,20 @@ export const dropboxSpec = Config.of({
|
||||
}),
|
||||
})
|
||||
|
||||
export const googleDriveSpec = Config.of({
|
||||
name: Value.text({
|
||||
export const googleDriveSpec = CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
description: 'A friendly name for this Google Drive target',
|
||||
placeholder: 'My Google Drive',
|
||||
required: { default: null },
|
||||
}),
|
||||
path: Value.text({
|
||||
path: CB.Value.text({
|
||||
name: 'Path',
|
||||
description: 'The fully qualified path to the backup directory',
|
||||
placeholder: 'e.g. /Desktop/my-folder',
|
||||
required: { default: null },
|
||||
}),
|
||||
key: Value.file({
|
||||
key: CB.Value.file({
|
||||
name: 'Private Key File',
|
||||
description:
|
||||
'Your Google Drive service account private key file (.json file)',
|
||||
@@ -45,14 +43,14 @@ export const googleDriveSpec = Config.of({
|
||||
}),
|
||||
})
|
||||
|
||||
export const cifsSpec = Config.of({
|
||||
name: Value.text({
|
||||
export const cifsSpec = CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
description: 'A friendly name for this Network Folder',
|
||||
placeholder: 'My Network Folder',
|
||||
required: { default: null },
|
||||
}),
|
||||
hostname: Value.text({
|
||||
hostname: CB.Value.text({
|
||||
name: 'Hostname',
|
||||
description:
|
||||
'The hostname of your target device on the Local Area Network.',
|
||||
@@ -61,19 +59,19 @@ export const cifsSpec = Config.of({
|
||||
required: { default: null },
|
||||
patterns: [],
|
||||
}),
|
||||
path: Value.text({
|
||||
path: CB.Value.text({
|
||||
name: 'Path',
|
||||
description: `On Windows, this is the fully qualified path to the shared folder, (e.g. /Desktop/my-folder).\n\n On Linux and Mac, this is the literal name of the shared folder (e.g. my-shared-folder).`,
|
||||
placeholder: 'e.g. my-shared-folder or /Desktop/my-folder',
|
||||
required: { default: null },
|
||||
}),
|
||||
username: Value.text({
|
||||
username: CB.Value.text({
|
||||
name: 'Username',
|
||||
description: `On Linux, this is the samba username you created when sharing the folder.\n\n On Mac and Windows, this is the username of the user who is sharing the folder.`,
|
||||
required: { default: null },
|
||||
placeholder: 'My Network Folder',
|
||||
}),
|
||||
password: Value.text({
|
||||
password: CB.Value.text({
|
||||
name: 'Password',
|
||||
description: `On Linux, this is the samba password you created when sharing the folder.\n\n On Mac and Windows, this is the password of the user who is sharing the folder.`,
|
||||
required: false,
|
||||
@@ -82,13 +80,13 @@ export const cifsSpec = Config.of({
|
||||
}),
|
||||
})
|
||||
|
||||
export const remoteBackupTargetSpec = Config.of({
|
||||
type: Value.union(
|
||||
export const remoteBackupTargetSpec = CB.Config.of({
|
||||
type: CB.Value.union(
|
||||
{
|
||||
name: 'Target Type',
|
||||
required: { default: 'dropbox' },
|
||||
},
|
||||
Variants.of({
|
||||
CB.Variants.of({
|
||||
dropbox: {
|
||||
name: 'Dropbox',
|
||||
spec: dropboxSpec,
|
||||
@@ -105,14 +103,14 @@ export const remoteBackupTargetSpec = Config.of({
|
||||
),
|
||||
})
|
||||
|
||||
export const diskBackupTargetSpec = Config.of({
|
||||
name: Value.text({
|
||||
export const diskBackupTargetSpec = CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
description: 'A friendly name for this physical target',
|
||||
placeholder: 'My Physical Target',
|
||||
required: { default: null },
|
||||
}),
|
||||
path: Value.text({
|
||||
path: CB.Value.text({
|
||||
name: 'Path',
|
||||
description: 'The fully qualified path to the backup directory',
|
||||
placeholder: 'e.g. /Backups/my-folder',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ValueSpecObject } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { TuiDialogOptions } from '@taiga-ui/core'
|
||||
import { TuiPromptData } from '@taiga-ui/kit'
|
||||
|
||||
export function getMarketplaceValueSpec(): ValueSpecObject {
|
||||
export function getMarketplaceValueSpec(): CT.ValueSpecObject {
|
||||
return {
|
||||
type: 'object',
|
||||
name: 'Add Custom Registry',
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { Variants } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/variants'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
import { Proxy } from 'src/app/services/patch-db/data-model'
|
||||
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
||||
|
||||
const auth = Config.of({
|
||||
username: Value.text({
|
||||
const auth = CB.Config.of({
|
||||
username: CB.Value.text({
|
||||
name: 'Username',
|
||||
required: { default: null },
|
||||
}),
|
||||
password: Value.text({
|
||||
password: CB.Value.text({
|
||||
name: 'Password',
|
||||
required: { default: null },
|
||||
masked: true,
|
||||
@@ -26,7 +24,7 @@ function getStrategyUnion(proxies: Proxy[]) {
|
||||
}
|
||||
}, {})
|
||||
|
||||
return Value.union(
|
||||
return CB.Value.union(
|
||||
{
|
||||
name: 'Networking Strategy',
|
||||
required: { default: null },
|
||||
@@ -34,11 +32,11 @@ function getStrategyUnion(proxies: Proxy[]) {
|
||||
<h5>Proxy</h5>Select this option is you prefer to hide your home/business IP address from the Internet. This option requires running your own Virtual Private Server (VPS) <i>or</i> paying service provider such as Static Wire
|
||||
`,
|
||||
},
|
||||
Variants.of({
|
||||
CB.Variants.of({
|
||||
local: {
|
||||
name: 'Local',
|
||||
spec: Config.of({
|
||||
ipStrategy: Value.select({
|
||||
spec: CB.Config.of({
|
||||
ipStrategy: CB.Value.select({
|
||||
name: 'IP Strategy',
|
||||
description: `<h5>IPv6 Only (recommended)</h5><b>Requirements</b>:<ol><li>ISP IPv6 support</li><li>OpenWRT (recommended) or Linksys router</li></ol><b>Pros</b>: Ready for IPv6 Internet. Enhanced privacy. Run multiple clearnet servers from the same network
|
||||
<b>Cons</b>: Interfaces using this domain will only be accessible to people whose ISP supports IPv6
|
||||
@@ -58,8 +56,8 @@ function getStrategyUnion(proxies: Proxy[]) {
|
||||
},
|
||||
proxy: {
|
||||
name: 'Proxy',
|
||||
spec: Config.of({
|
||||
proxyId: Value.select({
|
||||
spec: CB.Config.of({
|
||||
proxyId: CB.Value.select({
|
||||
name: 'Select Proxy',
|
||||
required: { default: null },
|
||||
values: inboundProxies,
|
||||
@@ -72,7 +70,7 @@ function getStrategyUnion(proxies: Proxy[]) {
|
||||
|
||||
export function getStart9ToSpec(proxies: Proxy[]) {
|
||||
return configBuilderToSpec(
|
||||
Config.of({
|
||||
CB.Config.of({
|
||||
strategy: getStrategyUnion(proxies),
|
||||
}),
|
||||
)
|
||||
@@ -80,21 +78,21 @@ export function getStart9ToSpec(proxies: Proxy[]) {
|
||||
|
||||
export function getCustomSpec(proxies: Proxy[]) {
|
||||
return configBuilderToSpec(
|
||||
Config.of({
|
||||
hostname: Value.text({
|
||||
CB.Config.of({
|
||||
hostname: CB.Value.text({
|
||||
name: 'Hostname',
|
||||
required: { default: null },
|
||||
placeholder: 'yourdomain.com',
|
||||
}),
|
||||
provider: Value.union(
|
||||
provider: CB.Value.union(
|
||||
{
|
||||
name: 'Dynamic DNS Provider',
|
||||
required: { default: 'start9' },
|
||||
},
|
||||
Variants.of({
|
||||
CB.Variants.of({
|
||||
start9: {
|
||||
name: 'Start9',
|
||||
spec: Config.of({}),
|
||||
spec: CB.Config.of({}),
|
||||
},
|
||||
njalla: {
|
||||
name: 'Njalla',
|
||||
|
||||
@@ -17,8 +17,7 @@ import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { FormService } from 'src/app/services/form.service'
|
||||
import { EmailInfoComponent } from './info.component'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { customSmtp } from '@start9labs/start-sdk/cjs/sdk/lib/config/configConstants'
|
||||
import { CT, config } from '@start9labs/start-sdk'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
@@ -82,7 +81,9 @@ export class SettingsEmailComponent {
|
||||
private readonly api = inject(ApiService)
|
||||
|
||||
testAddress = ''
|
||||
readonly spec: Promise<InputSpec> = configBuilderToSpec(customSmtp)
|
||||
readonly spec: Promise<CT.InputSpec> = configBuilderToSpec(
|
||||
config.constants.customSmtp,
|
||||
)
|
||||
readonly form$ = this.patch
|
||||
.watch$('serverInfo', 'smtp')
|
||||
.pipe(
|
||||
@@ -95,7 +96,9 @@ export class SettingsEmailComponent {
|
||||
const loader = this.loader.open('Saving...').subscribe()
|
||||
|
||||
try {
|
||||
await this.api.configureEmail(customSmtp.validator.unsafeCast(value))
|
||||
await this.api.configureEmail(
|
||||
config.constants.customSmtp.validator.unsafeCast(value),
|
||||
)
|
||||
} catch (e: any) {
|
||||
this.errorService.handleError(e)
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
import { TuiDialogOptions } from '@taiga-ui/core'
|
||||
import { TuiPromptData } from '@taiga-ui/kit'
|
||||
|
||||
@@ -13,13 +12,13 @@ export const DELETE_OPTIONS: Partial<TuiDialogOptions<TuiPromptData>> = {
|
||||
},
|
||||
}
|
||||
|
||||
export const wireguardSpec = Config.of({
|
||||
name: Value.text({
|
||||
export const wireguardSpec = CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
description: 'A friendly name to help you remember and identify this proxy',
|
||||
required: { default: null },
|
||||
}),
|
||||
config: Value.file({
|
||||
config: CB.Value.file({
|
||||
name: 'Wiregaurd Config',
|
||||
required: { default: null },
|
||||
extensions: ['.conf'],
|
||||
|
||||
@@ -24,7 +24,7 @@ import { Proxy } from 'src/app/services/patch-db/data-model'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { FormDialogService } from 'src/app/services/form-dialog.service'
|
||||
import { DELETE_OPTIONS, ProxyUpdate } from './constants'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
@Component({
|
||||
selector: 'proxies-menu',
|
||||
@@ -90,7 +90,7 @@ export class ProxiesMenuComponent {
|
||||
|
||||
async rename() {
|
||||
const spec = { name: 'Name', required: { default: this.proxy.name } }
|
||||
const name = await Value.text(spec).build({} as any)
|
||||
const name = await CB.Value.text(spec).build({} as any)
|
||||
const options: Partial<TuiDialogOptions<FormContext<{ name: string }>>> = {
|
||||
label: `Rename ${this.proxy.name}`,
|
||||
data: {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { HostnameInfo } from '@start9labs/start-sdk/cjs/sdk/lib/types'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
|
||||
@Pipe({
|
||||
standalone: true,
|
||||
name: 'primaryIp',
|
||||
})
|
||||
export class PrimaryIpPipe implements PipeTransform {
|
||||
transform(hostnames: HostnameInfo[]): string {
|
||||
transform(hostnames: T.HostnameInfo[]): string {
|
||||
return (
|
||||
hostnames.map(
|
||||
h => h.kind === 'ip' && h.hostname.kind === 'ipv4' && h.hostname.value,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ValueSpecObject } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { AvailableWifi } from 'src/app/services/api/api.types'
|
||||
import { RR } from 'src/app/services/api/api.types'
|
||||
|
||||
@@ -28,7 +28,7 @@ export function parseWifi(res: RR.GetWifiRes): WifiData {
|
||||
}
|
||||
}
|
||||
|
||||
export const wifiSpec: ValueSpecObject = {
|
||||
export const wifiSpec: CT.ValueSpecObject = {
|
||||
type: 'object',
|
||||
name: 'WiFi Credentials',
|
||||
description:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ValueSpecObject } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
export const wifiSpec: ValueSpecObject = {
|
||||
export const wifiSpec: CT.ValueSpecObject = {
|
||||
type: 'object',
|
||||
name: 'WiFi Credentials',
|
||||
description:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
export interface SettingBtn {
|
||||
title: string
|
||||
@@ -9,22 +8,22 @@ export interface SettingBtn {
|
||||
routerLink?: string
|
||||
}
|
||||
|
||||
export const passwordSpec = Config.of({
|
||||
currentPassword: Value.text({
|
||||
export const passwordSpec = CB.Config.of({
|
||||
currentPassword: CB.Value.text({
|
||||
name: 'Current Password',
|
||||
required: {
|
||||
default: null,
|
||||
},
|
||||
masked: true,
|
||||
}),
|
||||
newPassword1: Value.text({
|
||||
newPassword1: CB.Value.text({
|
||||
name: 'New Password',
|
||||
required: {
|
||||
default: null,
|
||||
},
|
||||
masked: true,
|
||||
}),
|
||||
newPassword2: Value.text({
|
||||
newPassword2: CB.Value.text({
|
||||
name: 'Retype New Password',
|
||||
required: {
|
||||
default: null,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { inject } from '@angular/core'
|
||||
import { FormControlComponent } from './form-control/form-control.component'
|
||||
import { ValueSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
export abstract class Control<Spec extends ValueSpec, Value> {
|
||||
export abstract class Control<Spec extends CT.ValueSpec, Value> {
|
||||
private readonly control: FormControlComponent<Spec, Value> =
|
||||
inject(FormControlComponent)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
tuiHeightCollapse,
|
||||
} from '@taiga-ui/core'
|
||||
import { TUI_PROMPT } from '@taiga-ui/kit'
|
||||
import { ValueSpecList } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { filter, takeUntil } from 'rxjs'
|
||||
import { FormService } from 'src/app/services/form.service'
|
||||
import { ERRORS } from '../form-group/form-group.component'
|
||||
@@ -22,7 +22,7 @@ import { ERRORS } from '../form-group/form-group.component'
|
||||
})
|
||||
export class FormArrayComponent {
|
||||
@Input({ required: true })
|
||||
spec!: ValueSpecList
|
||||
spec!: CT.ValueSpecList
|
||||
|
||||
@HostBinding('@tuiParentStop')
|
||||
readonly animation = { value: '', ...inject(TUI_ANIMATION_OPTIONS) }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecColor } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
import { MaskitoOptions } from '@maskito/core'
|
||||
|
||||
@@ -8,7 +8,7 @@ import { MaskitoOptions } from '@maskito/core'
|
||||
templateUrl: './form-color.component.html',
|
||||
styleUrls: ['./form-color.component.scss'],
|
||||
})
|
||||
export class FormColorComponent extends Control<ValueSpecColor, string> {
|
||||
export class FormColorComponent extends Control<CT.ValueSpecColor, string> {
|
||||
readonly mask: MaskitoOptions = {
|
||||
mask: ['#', ...Array(6).fill(/[0-9a-f]/i)],
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
TuiNotification,
|
||||
} from '@taiga-ui/core'
|
||||
import { filter, takeUntil } from 'rxjs'
|
||||
import { ValueSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { ERRORS } from '../form-group/form-group.component'
|
||||
import { FORM_CONTROL_PROVIDERS } from './form-control.providers'
|
||||
|
||||
@@ -25,7 +25,7 @@ import { FORM_CONTROL_PROVIDERS } from './form-control.providers'
|
||||
providers: FORM_CONTROL_PROVIDERS,
|
||||
})
|
||||
export class FormControlComponent<
|
||||
T extends ValueSpec,
|
||||
T extends CT.ValueSpec,
|
||||
V,
|
||||
> extends AbstractTuiNullableControl<V> {
|
||||
@Input({ required: true })
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { forwardRef, Provider } from '@angular/core'
|
||||
import { TUI_VALIDATION_ERRORS } from '@taiga-ui/kit'
|
||||
import { ValueSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { FormControlComponent } from './form-control.component'
|
||||
|
||||
interface ValidatorsPatternError {
|
||||
@@ -12,7 +12,7 @@ export const FORM_CONTROL_PROVIDERS: Provider[] = [
|
||||
{
|
||||
provide: TUI_VALIDATION_ERRORS,
|
||||
deps: [forwardRef(() => FormControlComponent)],
|
||||
useFactory: (control: FormControlComponent<ValueSpec, string>) => ({
|
||||
useFactory: (control: FormControlComponent<CT.ValueSpec, string>) => ({
|
||||
required: 'Required',
|
||||
pattern: ({ requiredPattern }: ValidatorsPatternError) =>
|
||||
('patterns' in control.spec &&
|
||||
|
||||
@@ -6,14 +6,17 @@ import {
|
||||
tuiPure,
|
||||
TuiTime,
|
||||
} from '@taiga-ui/cdk'
|
||||
import { ValueSpecDatetime } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
|
||||
@Component({
|
||||
selector: 'form-datetime',
|
||||
templateUrl: './form-datetime.component.html',
|
||||
})
|
||||
export class FormDatetimeComponent extends Control<ValueSpecDatetime, string> {
|
||||
export class FormDatetimeComponent extends Control<
|
||||
CT.ValueSpecDatetime,
|
||||
string
|
||||
> {
|
||||
readonly min = TUI_FIRST_DAY
|
||||
readonly max = TUI_LAST_DAY
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { TuiFileLike } from '@taiga-ui/kit'
|
||||
import { ValueSpecFile } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
|
||||
@Component({
|
||||
@@ -8,4 +8,4 @@ import { Control } from '../control'
|
||||
templateUrl: './form-file.component.html',
|
||||
styleUrls: ['./form-file.component.scss'],
|
||||
})
|
||||
export class FormFileComponent extends Control<ValueSpecFile, TuiFileLike> {}
|
||||
export class FormFileComponent extends Control<CT.ValueSpecFile, TuiFileLike> {}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
Input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { FORM_GROUP_PROVIDERS } from './form-group.providers'
|
||||
|
||||
export const ERRORS = [
|
||||
@@ -27,7 +27,7 @@ export const ERRORS = [
|
||||
viewProviders: [FORM_GROUP_PROVIDERS],
|
||||
})
|
||||
export class FormGroupComponent {
|
||||
@Input() spec: InputSpec = {}
|
||||
@Input() spec: CT.InputSpec = {}
|
||||
|
||||
asIsOrder() {
|
||||
return 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecMultiselect } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { invert } from '@start9labs/shared'
|
||||
@@ -9,7 +9,7 @@ import { invert } from '@start9labs/shared'
|
||||
templateUrl: './form-multiselect.component.html',
|
||||
})
|
||||
export class FormMultiselectComponent extends Control<
|
||||
ValueSpecMultiselect,
|
||||
CT.ValueSpecMultiselect,
|
||||
readonly string[]
|
||||
> {
|
||||
private readonly inverted = invert(this.spec.values)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecNumber } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
|
||||
@Component({
|
||||
selector: 'form-number',
|
||||
templateUrl: './form-number.component.html',
|
||||
})
|
||||
export class FormNumberComponent extends Control<ValueSpecNumber, number> {
|
||||
export class FormNumberComponent extends Control<CT.ValueSpecNumber, number> {
|
||||
protected readonly Infinity = Infinity
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
Output,
|
||||
} from '@angular/core'
|
||||
import { ControlContainer } from '@angular/forms'
|
||||
import { ValueSpecObject } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
@Component({
|
||||
selector: 'form-object',
|
||||
@@ -17,7 +17,7 @@ import { ValueSpecObject } from '@start9labs/start-sdk/cjs/sdk/lib/config/config
|
||||
})
|
||||
export class FormObjectComponent {
|
||||
@Input({ required: true })
|
||||
spec!: ValueSpecObject
|
||||
spec!: CT.ValueSpecObject
|
||||
|
||||
@Input()
|
||||
open = false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecSelect } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { invert } from '@start9labs/shared'
|
||||
import { Control } from '../control'
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Control } from '../control'
|
||||
selector: 'form-select',
|
||||
templateUrl: './form-select.component.html',
|
||||
})
|
||||
export class FormSelectComponent extends Control<ValueSpecSelect, string> {
|
||||
export class FormSelectComponent extends Control<CT.ValueSpecSelect, string> {
|
||||
private readonly inverted = invert(this.spec.values)
|
||||
|
||||
readonly items = Object.values(this.spec.values)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecText } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
import { getDefaultString } from 'src/app/util/config-utilities'
|
||||
|
||||
@@ -8,7 +8,7 @@ import { getDefaultString } from 'src/app/util/config-utilities'
|
||||
templateUrl: './form-text.component.html',
|
||||
styleUrls: ['./form-text.component.scss'],
|
||||
})
|
||||
export class FormTextComponent extends Control<ValueSpecText, string> {
|
||||
export class FormTextComponent extends Control<CT.ValueSpecText, string> {
|
||||
masked = true
|
||||
|
||||
generate() {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecTextarea } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
|
||||
@Component({
|
||||
selector: 'form-textarea',
|
||||
templateUrl: './form-textarea.component.html',
|
||||
})
|
||||
export class FormTextareaComponent extends Control<ValueSpecTextarea, string> {}
|
||||
export class FormTextareaComponent extends Control<
|
||||
CT.ValueSpecTextarea,
|
||||
string
|
||||
> {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecToggle } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { Control } from '../control'
|
||||
|
||||
@Component({
|
||||
@@ -7,4 +7,4 @@ import { Control } from '../control'
|
||||
templateUrl: './form-toggle.component.html',
|
||||
host: { class: 'g-toggle' },
|
||||
})
|
||||
export class FormToggleComponent extends Control<ValueSpecToggle, boolean> {}
|
||||
export class FormToggleComponent extends Control<CT.ValueSpecToggle, boolean> {}
|
||||
|
||||
@@ -6,12 +6,7 @@ import {
|
||||
OnChanges,
|
||||
} from '@angular/core'
|
||||
import { ControlContainer, FormGroupName } from '@angular/forms'
|
||||
import {
|
||||
unionSelectKey,
|
||||
unionValueKey,
|
||||
ValueSpecSelect,
|
||||
ValueSpecUnion,
|
||||
} from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { FormService } from 'src/app/services/form.service'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
|
||||
@@ -29,24 +24,24 @@ import { tuiPure } from '@taiga-ui/cdk'
|
||||
})
|
||||
export class FormUnionComponent implements OnChanges {
|
||||
@Input({ required: true })
|
||||
spec!: ValueSpecUnion
|
||||
spec!: CT.ValueSpecUnion
|
||||
|
||||
selectSpec!: ValueSpecSelect
|
||||
selectSpec!: CT.ValueSpecSelect
|
||||
|
||||
readonly select = unionSelectKey
|
||||
readonly value = unionValueKey
|
||||
readonly select = CT.unionSelectKey
|
||||
readonly value = CT.unionValueKey
|
||||
|
||||
private readonly form = inject(FormGroupName)
|
||||
private readonly formService = inject(FormService)
|
||||
|
||||
get union(): string {
|
||||
return this.form.value[unionSelectKey]
|
||||
return this.form.value[CT.unionSelectKey]
|
||||
}
|
||||
|
||||
@tuiPure
|
||||
onUnion(union: string) {
|
||||
this.form.control.setControl(
|
||||
unionValueKey,
|
||||
CT.unionValueKey,
|
||||
this.formService.getFormGroup(
|
||||
union ? this.spec.variants[union].spec : {},
|
||||
),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { ValueSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
@Pipe({
|
||||
name: 'hint',
|
||||
})
|
||||
export class HintPipe implements PipeTransform {
|
||||
transform(spec: ValueSpec): string {
|
||||
transform(spec: CT.ValueSpec): string {
|
||||
const hint = []
|
||||
|
||||
if (spec.description) {
|
||||
|
||||
@@ -19,11 +19,8 @@ import {
|
||||
} from '@start9labs/marketplace'
|
||||
import { Log } from '@start9labs/shared'
|
||||
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { Variants } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/variants'
|
||||
import { List } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/list'
|
||||
import { unionSelectKey } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
export module Mock {
|
||||
export const ServerUpdated: ServerStatusInfo = {
|
||||
@@ -715,27 +712,27 @@ export module Mock {
|
||||
RR.GetPackageConfigRes['spec']
|
||||
> =>
|
||||
configBuilderToSpec(
|
||||
Config.of({
|
||||
bitcoin: Value.object(
|
||||
CB.Config.of({
|
||||
bitcoin: CB.Value.object(
|
||||
{
|
||||
name: 'Bitcoin Settings',
|
||||
description:
|
||||
'RPC and P2P interface configuration options for Bitcoin Core',
|
||||
},
|
||||
Config.of({
|
||||
'bitcoind-p2p': Value.union(
|
||||
CB.Config.of({
|
||||
'bitcoind-p2p': CB.Value.union(
|
||||
{
|
||||
name: 'P2P Settings',
|
||||
description:
|
||||
'<p>The Bitcoin Core node to connect to over the peer-to-peer (P2P) interface:</p><ul><li><strong>Bitcoin Core</strong>: The Bitcoin Core service installed on this device</li><li><strong>External Node</strong>: A Bitcoin node running on a different device</li></ul>',
|
||||
required: { default: 'internal' },
|
||||
},
|
||||
Variants.of({
|
||||
internal: { name: 'Bitcoin Core', spec: Config.of({}) },
|
||||
CB.Variants.of({
|
||||
internal: { name: 'Bitcoin Core', spec: CB.Config.of({}) },
|
||||
external: {
|
||||
name: 'External Node',
|
||||
spec: Config.of({
|
||||
'p2p-host': Value.text({
|
||||
spec: CB.Config.of({
|
||||
'p2p-host': CB.Value.text({
|
||||
name: 'Public Address',
|
||||
required: {
|
||||
default: null,
|
||||
@@ -743,7 +740,7 @@ export module Mock {
|
||||
description:
|
||||
'The public address of your Bitcoin Core server',
|
||||
}),
|
||||
'p2p-port': Value.number({
|
||||
'p2p-port': CB.Value.number({
|
||||
name: 'P2P Port',
|
||||
description:
|
||||
'The port that your Bitcoin Core P2P server is bound to',
|
||||
@@ -760,7 +757,7 @@ export module Mock {
|
||||
),
|
||||
}),
|
||||
),
|
||||
users: Value.multiselect({
|
||||
users: CB.Value.multiselect({
|
||||
name: 'Users',
|
||||
default: [],
|
||||
maxLength: 2,
|
||||
@@ -772,21 +769,21 @@ export module Mock {
|
||||
lucy: 'Lucy',
|
||||
},
|
||||
}),
|
||||
advanced: Value.object(
|
||||
advanced: CB.Value.object(
|
||||
{
|
||||
name: 'Advanced',
|
||||
description: 'Advanced settings',
|
||||
},
|
||||
Config.of({
|
||||
rpcsettings: Value.object(
|
||||
CB.Config.of({
|
||||
rpcsettings: CB.Value.object(
|
||||
{
|
||||
name: 'RPC Settings',
|
||||
description: 'rpc username and password',
|
||||
warning:
|
||||
'Adding RPC users gives them special permissions on your node.',
|
||||
},
|
||||
Config.of({
|
||||
rpcuser2: Value.text({
|
||||
CB.Config.of({
|
||||
rpcuser2: CB.Value.text({
|
||||
name: 'RPC Username',
|
||||
required: {
|
||||
default: 'defaultrpcusername',
|
||||
@@ -799,7 +796,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
rpcuser: Value.text({
|
||||
rpcuser: CB.Value.text({
|
||||
name: 'RPC Username',
|
||||
required: {
|
||||
default: 'defaultrpcusername',
|
||||
@@ -812,7 +809,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
rpcpass: Value.text({
|
||||
rpcpass: CB.Value.text({
|
||||
name: 'RPC User Password',
|
||||
required: {
|
||||
default: {
|
||||
@@ -822,7 +819,7 @@ export module Mock {
|
||||
},
|
||||
description: 'rpc password',
|
||||
}),
|
||||
rpcpass2: Value.text({
|
||||
rpcpass2: CB.Value.text({
|
||||
name: 'RPC User Password',
|
||||
required: {
|
||||
default: {
|
||||
@@ -836,15 +833,15 @@ export module Mock {
|
||||
),
|
||||
}),
|
||||
),
|
||||
testnet: Value.toggle({
|
||||
testnet: CB.Value.toggle({
|
||||
name: 'Testnet',
|
||||
default: true,
|
||||
description:
|
||||
'<ul><li>determines whether your node is running on testnet or mainnet</li></ul><script src="fake"></script>',
|
||||
warning: 'Chain will have to resync!',
|
||||
}),
|
||||
'object-list': Value.list(
|
||||
List.obj(
|
||||
'object-list': CB.Value.list(
|
||||
CB.List.obj(
|
||||
{
|
||||
name: 'Object List',
|
||||
minLength: 0,
|
||||
@@ -856,13 +853,13 @@ export module Mock {
|
||||
description: 'This is a list of objects, like users or something',
|
||||
},
|
||||
{
|
||||
spec: Config.of({
|
||||
'first-name': Value.text({
|
||||
spec: CB.Config.of({
|
||||
'first-name': CB.Value.text({
|
||||
name: 'First Name',
|
||||
required: false,
|
||||
description: 'User first name',
|
||||
}),
|
||||
'last-name': Value.text({
|
||||
'last-name': CB.Value.text({
|
||||
name: 'Last Name',
|
||||
required: {
|
||||
default: {
|
||||
@@ -878,7 +875,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
age: Value.number({
|
||||
age: CB.Value.number({
|
||||
name: 'Age',
|
||||
description: 'The age of the user',
|
||||
warning: 'User must be at least 18.',
|
||||
@@ -887,13 +884,13 @@ export module Mock {
|
||||
integer: false,
|
||||
}),
|
||||
}),
|
||||
displayAs: "I'm {{last-name}}, {{first-name}} {{last-name}}",
|
||||
displayAs: 'I\'m {{last-name}}, {{first-name}} {{last-name}}',
|
||||
uniqueBy: 'last-name',
|
||||
},
|
||||
),
|
||||
),
|
||||
'union-list': Value.list(
|
||||
List.obj(
|
||||
'union-list': CB.Value.list(
|
||||
CB.List.obj(
|
||||
{
|
||||
name: 'Union List',
|
||||
minLength: 0,
|
||||
@@ -903,27 +900,27 @@ export module Mock {
|
||||
warning: 'If you change this, things may work.',
|
||||
},
|
||||
{
|
||||
spec: Config.of({
|
||||
spec: CB.Config.of({
|
||||
/* TODO: Convert range for this value ([0, 2])*/
|
||||
union: Value.union(
|
||||
union: CB.Value.union(
|
||||
{
|
||||
name: 'Preference',
|
||||
description: null,
|
||||
warning: null,
|
||||
required: { default: 'summer' },
|
||||
},
|
||||
Variants.of({
|
||||
CB.Variants.of({
|
||||
summer: {
|
||||
name: 'summer',
|
||||
spec: Config.of({
|
||||
'favorite-tree': Value.text({
|
||||
spec: CB.Config.of({
|
||||
'favorite-tree': CB.Value.text({
|
||||
name: 'Favorite Tree',
|
||||
required: {
|
||||
default: 'Maple',
|
||||
},
|
||||
description: 'What is your favorite tree?',
|
||||
}),
|
||||
'favorite-flower': Value.select({
|
||||
'favorite-flower': CB.Value.select({
|
||||
name: 'Favorite Flower',
|
||||
description: 'Select your favorite flower',
|
||||
required: {
|
||||
@@ -940,8 +937,8 @@ export module Mock {
|
||||
},
|
||||
winter: {
|
||||
name: 'winter',
|
||||
spec: Config.of({
|
||||
'like-snow': Value.toggle({
|
||||
spec: CB.Config.of({
|
||||
'like-snow': CB.Value.toggle({
|
||||
name: 'Like Snow?',
|
||||
default: true,
|
||||
description: 'Do you like snow or not?',
|
||||
@@ -955,7 +952,7 @@ export module Mock {
|
||||
},
|
||||
),
|
||||
),
|
||||
'random-select': Value.select({
|
||||
'random-select': CB.Value.select({
|
||||
name: 'Random select',
|
||||
description: 'This is not even real.',
|
||||
warning: 'Be careful changing this!',
|
||||
@@ -970,7 +967,7 @@ export module Mock {
|
||||
disabled: ['option2'],
|
||||
}),
|
||||
'favorite-number':
|
||||
/* TODO: Convert range for this value ((-100,100])*/ Value.number({
|
||||
/* TODO: Convert range for this value ((-100,100])*/ CB.Value.number({
|
||||
name: 'Favorite Number',
|
||||
description: 'Your favorite number of all time',
|
||||
warning:
|
||||
@@ -981,8 +978,8 @@ export module Mock {
|
||||
integer: false,
|
||||
units: 'BTC',
|
||||
}),
|
||||
'unlucky-numbers': Value.list(
|
||||
List.number(
|
||||
'unlucky-numbers': CB.Value.list(
|
||||
CB.List.number(
|
||||
{
|
||||
name: 'Unlucky Numbers',
|
||||
minLength: 0,
|
||||
@@ -996,34 +993,34 @@ export module Mock {
|
||||
},
|
||||
),
|
||||
),
|
||||
rpcsettings: Value.object(
|
||||
rpcsettings: CB.Value.object(
|
||||
{
|
||||
name: 'RPC Settings',
|
||||
description: 'rpc username and password',
|
||||
warning:
|
||||
'Adding RPC users gives them special permissions on your node.',
|
||||
},
|
||||
Config.of({
|
||||
laws: Value.object(
|
||||
CB.Config.of({
|
||||
laws: CB.Value.object(
|
||||
{
|
||||
name: 'Laws',
|
||||
description: 'the law of the realm',
|
||||
},
|
||||
Config.of({
|
||||
law1: Value.text({
|
||||
CB.Config.of({
|
||||
law1: CB.Value.text({
|
||||
name: 'First Law',
|
||||
required: false,
|
||||
description: 'the first law',
|
||||
}),
|
||||
law2: Value.text({
|
||||
law2: CB.Value.text({
|
||||
name: 'Second Law',
|
||||
required: false,
|
||||
description: 'the second law',
|
||||
}),
|
||||
}),
|
||||
),
|
||||
rulemakers: Value.list(
|
||||
List.obj(
|
||||
rulemakers: CB.Value.list(
|
||||
CB.List.obj(
|
||||
{
|
||||
name: 'Rule Makers',
|
||||
minLength: 0,
|
||||
@@ -1031,8 +1028,8 @@ export module Mock {
|
||||
description: 'the people who make the rules',
|
||||
},
|
||||
{
|
||||
spec: Config.of({
|
||||
rulemakername: Value.text({
|
||||
spec: CB.Config.of({
|
||||
rulemakername: CB.Value.text({
|
||||
name: 'Rulemaker Name',
|
||||
required: {
|
||||
default: {
|
||||
@@ -1042,7 +1039,7 @@ export module Mock {
|
||||
},
|
||||
description: 'the name of the rule maker',
|
||||
}),
|
||||
rulemakerip: Value.text({
|
||||
rulemakerip: CB.Value.text({
|
||||
name: 'Rulemaker IP',
|
||||
required: {
|
||||
default: '192.168.1.0',
|
||||
@@ -1060,7 +1057,7 @@ export module Mock {
|
||||
},
|
||||
),
|
||||
),
|
||||
rpcuser: Value.text({
|
||||
rpcuser: CB.Value.text({
|
||||
name: 'RPC Username',
|
||||
required: {
|
||||
default: 'defaultrpcusername',
|
||||
@@ -1073,7 +1070,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
rpcpass: Value.text({
|
||||
rpcpass: CB.Value.text({
|
||||
name: 'RPC User Password',
|
||||
required: {
|
||||
default: {
|
||||
@@ -1086,7 +1083,7 @@ export module Mock {
|
||||
}),
|
||||
}),
|
||||
),
|
||||
'bitcoin-node': Value.union(
|
||||
'bitcoin-node': CB.Value.union(
|
||||
{
|
||||
name: 'Bitcoin Node',
|
||||
description: 'Options<ul><li>Item 1</li><li>Item 2</li></ul>',
|
||||
@@ -1094,25 +1091,25 @@ export module Mock {
|
||||
required: { default: 'internal' },
|
||||
disabled: ['fake'],
|
||||
},
|
||||
Variants.of({
|
||||
CB.Variants.of({
|
||||
fake: {
|
||||
name: 'Fake',
|
||||
spec: Config.of({}),
|
||||
spec: CB.Config.of({}),
|
||||
},
|
||||
internal: {
|
||||
name: 'Internal',
|
||||
spec: Config.of({}),
|
||||
spec: CB.Config.of({}),
|
||||
},
|
||||
external: {
|
||||
name: 'External',
|
||||
spec: Config.of({
|
||||
'emergency-contact': Value.object(
|
||||
spec: CB.Config.of({
|
||||
'emergency-contact': CB.Value.object(
|
||||
{
|
||||
name: 'Emergency Contact',
|
||||
description: 'The person to contact in case of emergency.',
|
||||
},
|
||||
Config.of({
|
||||
name: Value.text({
|
||||
CB.Config.of({
|
||||
name: CB.Value.text({
|
||||
name: 'Name',
|
||||
required: {
|
||||
default: null,
|
||||
@@ -1124,7 +1121,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
email: Value.text({
|
||||
email: CB.Value.text({
|
||||
name: 'Email',
|
||||
inputmode: 'email',
|
||||
required: {
|
||||
@@ -1133,7 +1130,7 @@ export module Mock {
|
||||
}),
|
||||
}),
|
||||
),
|
||||
'public-domain': Value.text({
|
||||
'public-domain': CB.Value.text({
|
||||
name: 'Public Domain',
|
||||
required: {
|
||||
default: 'bitcoinnode.com',
|
||||
@@ -1146,7 +1143,7 @@ export module Mock {
|
||||
},
|
||||
],
|
||||
}),
|
||||
'private-domain': Value.text({
|
||||
'private-domain': CB.Value.text({
|
||||
name: 'Private Domain',
|
||||
required: {
|
||||
default: null,
|
||||
@@ -1159,7 +1156,7 @@ export module Mock {
|
||||
},
|
||||
}),
|
||||
),
|
||||
port: Value.number({
|
||||
port: CB.Value.number({
|
||||
name: 'Port',
|
||||
description:
|
||||
'the default port for your Bitcoin node. default: 8333, testnet: 18333, regtest: 18444',
|
||||
@@ -1171,7 +1168,7 @@ export module Mock {
|
||||
step: 1,
|
||||
integer: true,
|
||||
}),
|
||||
'favorite-slogan': Value.text({
|
||||
'favorite-slogan': CB.Value.text({
|
||||
name: 'Favorite Slogan',
|
||||
generate: {
|
||||
charset: 'a-z,A-Z,2-9',
|
||||
@@ -1182,8 +1179,8 @@ export module Mock {
|
||||
'You most favorite slogan in the whole world, used for paying you.',
|
||||
masked: true,
|
||||
}),
|
||||
rpcallowip: Value.list(
|
||||
List.text(
|
||||
rpcallowip: CB.Value.list(
|
||||
CB.List.text(
|
||||
{
|
||||
name: 'RPC Allowed IPs',
|
||||
minLength: 1,
|
||||
@@ -1205,8 +1202,8 @@ export module Mock {
|
||||
},
|
||||
),
|
||||
),
|
||||
rpcauth: Value.list(
|
||||
List.text(
|
||||
rpcauth: CB.Value.list(
|
||||
CB.List.text(
|
||||
{
|
||||
name: 'RPC Auth',
|
||||
description:
|
||||
@@ -1251,7 +1248,7 @@ export module Mock {
|
||||
rulemakers: [],
|
||||
},
|
||||
'bitcoin-node': {
|
||||
[unionSelectKey]: 'internal',
|
||||
[CT.unionSelectKey]: 'internal',
|
||||
},
|
||||
port: 20,
|
||||
rpcallowip: undefined,
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
FollowLogsRes,
|
||||
FollowLogsReq,
|
||||
} from '@start9labs/shared'
|
||||
import { customSmtp } from '@start9labs/start-sdk/cjs/sdk/lib/config/configConstants'
|
||||
import { InputSpec } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
import { config } from '@start9labs/start-sdk'
|
||||
|
||||
export module RR {
|
||||
// DB
|
||||
@@ -205,7 +205,8 @@ export module RR {
|
||||
|
||||
// email
|
||||
|
||||
export type ConfigureEmailReq = typeof customSmtp.validator._TYPE // email.configure
|
||||
export type ConfigureEmailReq =
|
||||
typeof config.constants.customSmtp.validator._TYPE // email.configure
|
||||
export type ConfigureEmailRes = null
|
||||
|
||||
export type TestEmailReq = ConfigureEmailReq & { to: string } // email.test
|
||||
@@ -319,7 +320,7 @@ export module RR {
|
||||
export type InstallPackageRes = null
|
||||
|
||||
export type GetPackageConfigReq = { id: string } // package.config.get
|
||||
export type GetPackageConfigRes = { spec: InputSpec; config: object }
|
||||
export type GetPackageConfigRes = { spec: CT.InputSpec; config: object }
|
||||
|
||||
export type DrySetPackageConfigReq = { id: string; config: object } // package.config.set.dry
|
||||
export type DrySetPackageConfigRes = Breakages
|
||||
@@ -361,7 +362,7 @@ export module RR {
|
||||
export type DryConfigureDependencyRes = {
|
||||
oldConfig: object
|
||||
newConfig: object
|
||||
spec: InputSpec
|
||||
spec: CT.InputSpec
|
||||
}
|
||||
|
||||
export type SideloadPackageReq = {
|
||||
|
||||
@@ -8,29 +8,7 @@ import {
|
||||
Validators,
|
||||
} from '@angular/forms'
|
||||
import { getDefaultString } from '../util/config-utilities'
|
||||
import {
|
||||
InputSpec,
|
||||
ListValueSpecNumber,
|
||||
ListValueSpecObject,
|
||||
ListValueSpecOf,
|
||||
ListValueSpecText,
|
||||
UniqueBy,
|
||||
ValueSpec,
|
||||
ValueSpecSelect,
|
||||
ValueSpecMultiselect,
|
||||
ValueSpecFile,
|
||||
ValueSpecList,
|
||||
ValueSpecNumber,
|
||||
ValueSpecObject,
|
||||
ValueSpecText,
|
||||
ValueSpecUnion,
|
||||
ValueSpecTextarea,
|
||||
ValueSpecColor,
|
||||
ValueSpecDatetime,
|
||||
unionSelectKey,
|
||||
unionValueKey,
|
||||
isValueSpecListOf,
|
||||
} from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
const Mustache = require('mustache')
|
||||
|
||||
@Injectable({
|
||||
@@ -40,16 +18,16 @@ export class FormService {
|
||||
constructor(private readonly formBuilder: UntypedFormBuilder) {}
|
||||
|
||||
createForm(
|
||||
spec: InputSpec,
|
||||
spec: CT.InputSpec,
|
||||
current: Record<string, any> = {},
|
||||
): UntypedFormGroup {
|
||||
return this.getFormGroup(spec, [], current)
|
||||
}
|
||||
|
||||
getUnionSelectSpec(
|
||||
spec: ValueSpecUnion,
|
||||
spec: CT.ValueSpecUnion,
|
||||
selection: string | null,
|
||||
): ValueSpecSelect {
|
||||
): CT.ValueSpecSelect {
|
||||
return {
|
||||
...spec,
|
||||
type: 'select',
|
||||
@@ -61,34 +39,34 @@ export class FormService {
|
||||
}
|
||||
|
||||
getUnionObject(
|
||||
spec: ValueSpecUnion,
|
||||
spec: CT.ValueSpecUnion,
|
||||
selection: string | null,
|
||||
): UntypedFormGroup {
|
||||
const group = this.getFormGroup({
|
||||
[unionSelectKey]: this.getUnionSelectSpec(spec, selection),
|
||||
[CT.unionSelectKey]: this.getUnionSelectSpec(spec, selection),
|
||||
})
|
||||
|
||||
group.setControl(
|
||||
unionValueKey,
|
||||
CT.unionValueKey,
|
||||
this.getFormGroup(selection ? spec.variants[selection].spec : {}),
|
||||
)
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
getListItem(spec: ValueSpecList, entry?: any) {
|
||||
getListItem(spec: CT.ValueSpecList, entry?: any) {
|
||||
const listItemValidators = getListItemValidators(spec)
|
||||
if (isValueSpecListOf(spec, 'text')) {
|
||||
if (CT.isValueSpecListOf(spec, 'text')) {
|
||||
return this.formBuilder.control(entry, listItemValidators)
|
||||
} else if (isValueSpecListOf(spec, 'number')) {
|
||||
} else if (CT.isValueSpecListOf(spec, 'number')) {
|
||||
return this.formBuilder.control(entry, listItemValidators)
|
||||
} else if (isValueSpecListOf(spec, 'object')) {
|
||||
} else if (CT.isValueSpecListOf(spec, 'object')) {
|
||||
return this.getFormGroup(spec.spec.spec, listItemValidators, entry)
|
||||
}
|
||||
}
|
||||
|
||||
getFormGroup(
|
||||
config: InputSpec,
|
||||
config: CT.InputSpec,
|
||||
validators: ValidatorFn[] = [],
|
||||
current?: Record<string, any> | null,
|
||||
): UntypedFormGroup {
|
||||
@@ -103,7 +81,7 @@ export class FormService {
|
||||
}
|
||||
|
||||
private getFormEntry(
|
||||
spec: ValueSpec,
|
||||
spec: CT.ValueSpec,
|
||||
currentValue?: any,
|
||||
): UntypedFormGroup | UntypedFormArray | UntypedFormControl {
|
||||
let value: any
|
||||
@@ -154,7 +132,7 @@ export class FormService {
|
||||
fileValidators(spec),
|
||||
)
|
||||
case 'union':
|
||||
const currentSelection = currentValue?.[unionSelectKey]
|
||||
const currentSelection = currentValue?.[CT.unionSelectKey]
|
||||
const isValid = !!spec.variants[currentSelection]
|
||||
|
||||
return this.getUnionObject(
|
||||
@@ -176,20 +154,20 @@ export class FormService {
|
||||
}
|
||||
}
|
||||
|
||||
function getListItemValidators(spec: ValueSpecList) {
|
||||
if (isValueSpecListOf(spec, 'text')) {
|
||||
function getListItemValidators(spec: CT.ValueSpecList) {
|
||||
if (CT.isValueSpecListOf(spec, 'text')) {
|
||||
return stringValidators(spec.spec)
|
||||
} else if (isValueSpecListOf(spec, 'number')) {
|
||||
} else if (CT.isValueSpecListOf(spec, 'number')) {
|
||||
return numberValidators(spec.spec)
|
||||
}
|
||||
}
|
||||
|
||||
function stringValidators(
|
||||
spec: ValueSpecText | ListValueSpecText,
|
||||
spec: CT.ValueSpecText | CT.ListValueSpecText,
|
||||
): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
if ((spec as ValueSpecText).required) {
|
||||
if ((spec as CT.ValueSpecText).required) {
|
||||
validators.push(Validators.required)
|
||||
}
|
||||
|
||||
@@ -202,7 +180,7 @@ function stringValidators(
|
||||
return validators
|
||||
}
|
||||
|
||||
function textareaValidators(spec: ValueSpecTextarea): ValidatorFn[] {
|
||||
function textareaValidators(spec: CT.ValueSpecTextarea): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
if (spec.required) {
|
||||
@@ -214,7 +192,7 @@ function textareaValidators(spec: ValueSpecTextarea): ValidatorFn[] {
|
||||
return validators
|
||||
}
|
||||
|
||||
function colorValidators({ required }: ValueSpecColor): ValidatorFn[] {
|
||||
function colorValidators({ required }: CT.ValueSpecColor): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = [Validators.pattern(/^#[0-9a-f]{6}$/i)]
|
||||
|
||||
if (required) {
|
||||
@@ -228,7 +206,7 @@ function datetimeValidators({
|
||||
required,
|
||||
min,
|
||||
max,
|
||||
}: ValueSpecDatetime): ValidatorFn[] {
|
||||
}: CT.ValueSpecDatetime): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
if (required) {
|
||||
@@ -247,13 +225,13 @@ function datetimeValidators({
|
||||
}
|
||||
|
||||
function numberValidators(
|
||||
spec: ValueSpecNumber | ListValueSpecNumber,
|
||||
spec: CT.ValueSpecNumber | CT.ListValueSpecNumber,
|
||||
): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
validators.push(isNumber())
|
||||
|
||||
if ((spec as ValueSpecNumber).required) {
|
||||
if ((spec as CT.ValueSpecNumber).required) {
|
||||
validators.push(Validators.required)
|
||||
}
|
||||
|
||||
@@ -266,7 +244,7 @@ function numberValidators(
|
||||
return validators
|
||||
}
|
||||
|
||||
function selectValidators(spec: ValueSpecSelect): ValidatorFn[] {
|
||||
function selectValidators(spec: CT.ValueSpecSelect): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
if (spec.required) {
|
||||
@@ -276,20 +254,20 @@ function selectValidators(spec: ValueSpecSelect): ValidatorFn[] {
|
||||
return validators
|
||||
}
|
||||
|
||||
function multiselectValidators(spec: ValueSpecMultiselect): ValidatorFn[] {
|
||||
function multiselectValidators(spec: CT.ValueSpecMultiselect): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
validators.push(listInRange(spec.minLength, spec.maxLength))
|
||||
return validators
|
||||
}
|
||||
|
||||
function listValidators(spec: ValueSpecList): ValidatorFn[] {
|
||||
function listValidators(spec: CT.ValueSpecList): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
validators.push(listInRange(spec.minLength, spec.maxLength))
|
||||
validators.push(listItemIssue())
|
||||
return validators
|
||||
}
|
||||
|
||||
function fileValidators(spec: ValueSpecFile): ValidatorFn[] {
|
||||
function fileValidators(spec: CT.ValueSpecFile): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = []
|
||||
|
||||
if (spec.required) {
|
||||
@@ -397,7 +375,7 @@ export function listItemIssue(): ValidatorFn {
|
||||
}
|
||||
}
|
||||
|
||||
export function listUnique(spec: ValueSpecList): ValidatorFn {
|
||||
export function listUnique(spec: CT.ValueSpecList): ValidatorFn {
|
||||
return control => {
|
||||
const list = control.value
|
||||
for (let idx = 0; idx < list.length; idx++) {
|
||||
@@ -407,7 +385,7 @@ export function listUnique(spec: ValueSpecList): ValidatorFn {
|
||||
let display1: string
|
||||
let display2: string
|
||||
let uniqueMessage = isObject(objSpec)
|
||||
? uniqueByMessageWrapper(objSpec.uniqueBy, objSpec, list[idx])
|
||||
? uniqueByMessageWrapper(objSpec.uniqueBy, objSpec)
|
||||
: ''
|
||||
|
||||
if (isObject(objSpec) && objSpec.displayAs) {
|
||||
@@ -434,7 +412,7 @@ export function listUnique(spec: ValueSpecList): ValidatorFn {
|
||||
}
|
||||
}
|
||||
|
||||
function listItemEquals(spec: ValueSpecList, val1: any, val2: any): boolean {
|
||||
function listItemEquals(spec: CT.ValueSpecList, val1: any, val2: any): boolean {
|
||||
// TODO: fix types
|
||||
switch (spec.spec.type) {
|
||||
case 'text':
|
||||
@@ -448,7 +426,7 @@ function listItemEquals(spec: ValueSpecList, val1: any, val2: any): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean {
|
||||
function itemEquals(spec: CT.ValueSpec, val1: any, val2: any): boolean {
|
||||
switch (spec.type) {
|
||||
case 'text':
|
||||
case 'textarea':
|
||||
@@ -460,15 +438,15 @@ function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean {
|
||||
// TODO: 'unique-by' does not exist on ValueSpecObject, fix types
|
||||
return objEquals(
|
||||
(spec as any)['unique-by'],
|
||||
spec as ValueSpecObject,
|
||||
spec as CT.ValueSpecObject,
|
||||
val1,
|
||||
val2,
|
||||
)
|
||||
case 'union':
|
||||
// TODO: 'unique-by' does not exist on ValueSpecUnion, fix types
|
||||
// TODO: 'unique-by' does not exist on CT.ValueSpecUnion, fix types
|
||||
return unionEquals(
|
||||
(spec as any)['unique-by'],
|
||||
spec as ValueSpecUnion,
|
||||
spec as CT.ValueSpecUnion,
|
||||
val1,
|
||||
val2,
|
||||
)
|
||||
@@ -488,8 +466,8 @@ function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean {
|
||||
}
|
||||
|
||||
function listObjEquals(
|
||||
uniqueBy: UniqueBy,
|
||||
spec: ListValueSpecObject,
|
||||
uniqueBy: CT.UniqueBy,
|
||||
spec: CT.ListValueSpecObject,
|
||||
val1: any,
|
||||
val2: any,
|
||||
): boolean {
|
||||
@@ -516,8 +494,8 @@ function listObjEquals(
|
||||
}
|
||||
|
||||
function objEquals(
|
||||
uniqueBy: UniqueBy,
|
||||
spec: ValueSpecObject,
|
||||
uniqueBy: CT.UniqueBy,
|
||||
spec: CT.ValueSpecObject,
|
||||
val1: any,
|
||||
val2: any,
|
||||
): boolean {
|
||||
@@ -545,17 +523,17 @@ function objEquals(
|
||||
}
|
||||
|
||||
function unionEquals(
|
||||
uniqueBy: UniqueBy,
|
||||
spec: ValueSpecUnion,
|
||||
uniqueBy: CT.UniqueBy,
|
||||
spec: CT.ValueSpecUnion,
|
||||
val1: any,
|
||||
val2: any,
|
||||
): boolean {
|
||||
const variantSpec = spec.variants[val1[unionSelectKey]].spec
|
||||
const variantSpec = spec.variants[val1[CT.unionSelectKey]].spec
|
||||
if (!uniqueBy) {
|
||||
return false
|
||||
} else if (typeof uniqueBy === 'string') {
|
||||
if (uniqueBy === unionSelectKey) {
|
||||
return val1[unionSelectKey] === val2[unionSelectKey]
|
||||
if (uniqueBy === CT.unionSelectKey) {
|
||||
return val1[CT.unionSelectKey] === val2[CT.unionSelectKey]
|
||||
} else {
|
||||
return itemEquals(variantSpec[uniqueBy], val1[uniqueBy], val2[uniqueBy])
|
||||
}
|
||||
@@ -578,9 +556,8 @@ function unionEquals(
|
||||
}
|
||||
|
||||
function uniqueByMessageWrapper(
|
||||
uniqueBy: UniqueBy,
|
||||
spec: ListValueSpecObject,
|
||||
obj: Record<string, string>,
|
||||
uniqueBy: CT.UniqueBy,
|
||||
spec: CT.ListValueSpecObject,
|
||||
) {
|
||||
let configSpec = spec.spec
|
||||
|
||||
@@ -591,8 +568,8 @@ function uniqueByMessageWrapper(
|
||||
}
|
||||
|
||||
function uniqueByMessage(
|
||||
uniqueBy: UniqueBy,
|
||||
configSpec: InputSpec,
|
||||
uniqueBy: CT.UniqueBy,
|
||||
configSpec: CT.InputSpec,
|
||||
outermost = true,
|
||||
): string {
|
||||
let joinFunc
|
||||
@@ -601,7 +578,7 @@ function uniqueByMessage(
|
||||
return ''
|
||||
} else if (typeof uniqueBy === 'string') {
|
||||
return configSpec[uniqueBy]
|
||||
? (configSpec[uniqueBy] as ValueSpecObject).name
|
||||
? (configSpec[uniqueBy] as CT.ValueSpecObject).name
|
||||
: uniqueBy
|
||||
} else if ('any' in uniqueBy) {
|
||||
joinFunc = ' OR '
|
||||
@@ -620,13 +597,15 @@ function uniqueByMessage(
|
||||
: '(' + ret + ')'
|
||||
}
|
||||
|
||||
function isObject(spec: ListValueSpecOf<any>): spec is ListValueSpecObject {
|
||||
function isObject(
|
||||
spec: CT.ListValueSpecOf<any>,
|
||||
): spec is CT.ListValueSpecObject {
|
||||
// only lists of objects have uniqueBy
|
||||
return 'uniqueBy' in spec
|
||||
}
|
||||
|
||||
export function convertValuesRecursive(
|
||||
configSpec: InputSpec,
|
||||
configSpec: CT.InputSpec,
|
||||
group: UntypedFormGroup,
|
||||
) {
|
||||
Object.entries(configSpec).forEach(([key, valueSpec]) => {
|
||||
@@ -645,7 +624,7 @@ export function convertValuesRecursive(
|
||||
} else if (valueSpec.type === 'union') {
|
||||
const formGr = group.get(key) as UntypedFormGroup
|
||||
const spec =
|
||||
valueSpec.variants[formGr.controls[unionSelectKey].value].spec
|
||||
valueSpec.variants[formGr.controls[CT.unionSelectKey].value].spec
|
||||
convertValuesRecursive(spec, formGr)
|
||||
} else if (valueSpec.type === 'list') {
|
||||
const formArr = group.get(key) as UntypedFormArray
|
||||
@@ -661,7 +640,7 @@ export function convertValuesRecursive(
|
||||
})
|
||||
} else if (valueSpec.spec.type === 'object') {
|
||||
controls.forEach(formGroup => {
|
||||
const objectSpec = valueSpec.spec as ListValueSpecObject
|
||||
const objectSpec = valueSpec.spec as CT.ListValueSpecObject
|
||||
convertValuesRecursive(objectSpec.spec, formGroup as UntypedFormGroup)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ import { BackupJob, ServerNotifications } from '../api/api.types'
|
||||
import { Url } from '@start9labs/shared'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import {
|
||||
ActionMetadata,
|
||||
HostnameInfo,
|
||||
} from '@start9labs/start-sdk/cjs/sdk/lib/types'
|
||||
import { customSmtp } from '@start9labs/start-sdk/cjs/sdk/lib/config/configConstants'
|
||||
import { config } from '@start9labs/start-sdk'
|
||||
|
||||
export interface DataModel {
|
||||
serverInfo: ServerInfo
|
||||
@@ -59,7 +55,7 @@ export interface ServerInfo {
|
||||
id: string
|
||||
version: string
|
||||
country: string
|
||||
ui: HostnameInfo[]
|
||||
ui: T.HostnameInfo[]
|
||||
network: NetworkInfo
|
||||
lastBackup: string | null
|
||||
unreadNotifications: {
|
||||
@@ -71,7 +67,7 @@ export interface ServerInfo {
|
||||
pubkey: string
|
||||
caFingerprint: string
|
||||
ntpSynced: boolean
|
||||
smtp: typeof customSmtp.validator._TYPE
|
||||
smtp: typeof config.constants.customSmtp.validator._TYPE
|
||||
passwordHash: string
|
||||
platform: string
|
||||
}
|
||||
@@ -156,7 +152,7 @@ export type PackageDataEntry<T extends StateInfo = StateInfo> = {
|
||||
stateInfo: T
|
||||
icon: Url
|
||||
status: Status
|
||||
actions: Record<string, ActionMetadata>
|
||||
actions: Record<string, T.ActionMetadata>
|
||||
lastBackup: string | null
|
||||
currentDependencies: { [id: string]: CurrentDependencyInfo }
|
||||
dependencyInfo: {
|
||||
|
||||
@@ -11,8 +11,7 @@ import { FormDialogService } from 'src/app/services/form-dialog.service'
|
||||
import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec'
|
||||
import { ApiService } from './api/embassy-api.service'
|
||||
import { DataModel } from './patch-db/data-model'
|
||||
import { Config } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/config'
|
||||
import { Value } from '@start9labs/start-sdk/cjs/sdk/lib/config/builder/value'
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -30,14 +29,12 @@ export class ProxyService {
|
||||
const network = await firstValueFrom(
|
||||
this.patch.watch$('serverInfo', 'network'),
|
||||
)
|
||||
const config = Config.of({
|
||||
proxyId: Value.select({
|
||||
const config = CB.Config.of({
|
||||
proxyId: CB.Value.select({
|
||||
name: 'Select Proxy',
|
||||
required: { default: current },
|
||||
values: network.proxies
|
||||
.filter(
|
||||
p => p.type === 'outbound' || p.type === 'inbound-outbound',
|
||||
)
|
||||
.filter(p => p.type === 'outbound' || p.type === 'inbound-outbound')
|
||||
.reduce((prev, curr) => {
|
||||
return {
|
||||
[curr.id]: curr.name,
|
||||
@@ -71,10 +68,7 @@ export class ProxyService {
|
||||
this.formDialog.open(FormComponent, options)
|
||||
}
|
||||
|
||||
private async saveOutboundProxy(
|
||||
proxy: string | null,
|
||||
packageId?: string,
|
||||
) {
|
||||
private async saveOutboundProxy(proxy: string | null, packageId?: string) {
|
||||
const loader = this.loader.open(`Saving`).subscribe()
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DefaultString } from '@start9labs/start-sdk/cjs/sdk/lib/config/configTypes'
|
||||
import { CT } from '@start9labs/start-sdk'
|
||||
|
||||
export class Range {
|
||||
min?: number
|
||||
@@ -48,7 +48,7 @@ export class Range {
|
||||
}
|
||||
}
|
||||
|
||||
export function getDefaultString(defaultSpec: DefaultString): string {
|
||||
export function getDefaultString(defaultSpec: CT.DefaultString): string {
|
||||
if (typeof defaultSpec === 'string') {
|
||||
return defaultSpec
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Config } from "@start9labs/start-sdk/cjs/sdk/lib/config/builder/config";
|
||||
import { CB } from '@start9labs/start-sdk'
|
||||
|
||||
export async function configBuilderToSpec(
|
||||
builder:
|
||||
| Config<Record<string, unknown>, unknown>
|
||||
| Config<Record<string, unknown>, never>,
|
||||
| CB.Config<Record<string, unknown>, unknown>
|
||||
| CB.Config<Record<string, unknown>, never>,
|
||||
) {
|
||||
return builder.build({} as any)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user