mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
port 040 config (#2657)
* port 040 config, WIP * update fixtures * use taiga modal for backups too * fix: update Taiga UI and refactor everything to work * chore: package-lock * fix interfaces and mocks for interfaces * better mocks * function to transform old spec to new * delete unused fns * delete unused FE config utils * fix exports from sdk * reorganize exports * functions to translate config * rename unionSelectKey and unionValueKey * Adding in the transformation of the getConfig to the new types. * chore: add Taiga UI to preloader --------- Co-authored-by: waterplea <alexander@inkin.ru> Co-authored-by: Aiden McClelland <me@drbonez.dev> Co-authored-by: J H <dragondef@gmail.com>
This commit is contained in:
@@ -480,7 +480,6 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
||||
},
|
||||
List: {
|
||||
text: List.text,
|
||||
number: List.number,
|
||||
obj: <Type extends Record<string, any>>(
|
||||
a: {
|
||||
name: string
|
||||
@@ -523,29 +522,6 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
||||
}
|
||||
>,
|
||||
) => List.dynamicText<Store>(getA),
|
||||
dynamicNumber: (
|
||||
getA: LazyBuild<
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
/** Default = [] */
|
||||
default?: string[]
|
||||
minLength?: number | null
|
||||
maxLength?: number | null
|
||||
disabled?: false | string
|
||||
spec: {
|
||||
integer: boolean
|
||||
min?: number | null
|
||||
max?: number | null
|
||||
step?: number | null
|
||||
units?: string | null
|
||||
placeholder?: string | null
|
||||
}
|
||||
}
|
||||
>,
|
||||
) => List.dynamicNumber<Store>(getA),
|
||||
},
|
||||
Migration: {
|
||||
of: <Version extends ManifestVersion>(options: {
|
||||
|
||||
@@ -125,96 +125,6 @@ export class List<Type, Store> {
|
||||
return built
|
||||
}, arrayOf(string))
|
||||
}
|
||||
static number(
|
||||
a: {
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
/** Default = [] */
|
||||
default?: string[]
|
||||
minLength?: number | null
|
||||
maxLength?: number | null
|
||||
},
|
||||
aSpec: {
|
||||
integer: boolean
|
||||
min?: number | null
|
||||
max?: number | null
|
||||
step?: number | null
|
||||
units?: string | null
|
||||
placeholder?: string | null
|
||||
},
|
||||
) {
|
||||
return new List<number[], never>(() => {
|
||||
const spec = {
|
||||
type: "number" as const,
|
||||
placeholder: null,
|
||||
min: null,
|
||||
max: null,
|
||||
step: null,
|
||||
units: null,
|
||||
...aSpec,
|
||||
}
|
||||
const built: ValueSpecListOf<"number"> = {
|
||||
description: null,
|
||||
warning: null,
|
||||
minLength: null,
|
||||
maxLength: null,
|
||||
default: [],
|
||||
type: "list" as const,
|
||||
disabled: false,
|
||||
...a,
|
||||
spec,
|
||||
}
|
||||
return built
|
||||
}, arrayOf(number))
|
||||
}
|
||||
static dynamicNumber<Store = never>(
|
||||
getA: LazyBuild<
|
||||
Store,
|
||||
{
|
||||
name: string
|
||||
description?: string | null
|
||||
warning?: string | null
|
||||
/** Default = [] */
|
||||
default?: string[]
|
||||
minLength?: number | null
|
||||
maxLength?: number | null
|
||||
disabled?: false | string
|
||||
spec: {
|
||||
integer: boolean
|
||||
min?: number | null
|
||||
max?: number | null
|
||||
step?: number | null
|
||||
units?: string | null
|
||||
placeholder?: string | null
|
||||
}
|
||||
}
|
||||
>,
|
||||
) {
|
||||
return new List<number[], Store>(async (options) => {
|
||||
const { spec: aSpec, ...a } = await getA(options)
|
||||
const spec = {
|
||||
type: "number" as const,
|
||||
placeholder: null,
|
||||
min: null,
|
||||
max: null,
|
||||
step: null,
|
||||
units: null,
|
||||
...aSpec,
|
||||
}
|
||||
return {
|
||||
description: null,
|
||||
warning: null,
|
||||
minLength: null,
|
||||
maxLength: null,
|
||||
default: [],
|
||||
type: "list" as const,
|
||||
disabled: false,
|
||||
...a,
|
||||
spec,
|
||||
}
|
||||
}, arrayOf(number))
|
||||
}
|
||||
static obj<Type extends Record<string, any>, Store>(
|
||||
a: {
|
||||
name: string
|
||||
|
||||
@@ -69,8 +69,8 @@ export class Variants<Type, Store> {
|
||||
const validator = anyOf(
|
||||
...Object.entries(a).map(([name, { spec }]) =>
|
||||
object({
|
||||
unionSelectKey: literals(name),
|
||||
unionValueKey: spec.validator,
|
||||
selection: literals(name),
|
||||
value: spec.validator,
|
||||
}),
|
||||
),
|
||||
) as Parser<unknown, any>
|
||||
@@ -78,9 +78,9 @@ export class Variants<Type, Store> {
|
||||
return new Variants<
|
||||
{
|
||||
[K in keyof VariantValues]: {
|
||||
unionSelectKey: K
|
||||
selection: K
|
||||
// prettier-ignore
|
||||
unionValueKey:
|
||||
value:
|
||||
VariantValues[K]["spec"] extends (Config<infer B, Store> | Config<infer B, never>) ? B :
|
||||
never
|
||||
}
|
||||
|
||||
@@ -15,70 +15,93 @@ export type ValueType =
|
||||
export type ValueSpec = ValueSpecOf<ValueType>
|
||||
/** core spec types. These types provide the metadata for performing validations */
|
||||
// prettier-ignore
|
||||
export type ValueSpecOf<T extends ValueType> = T extends "text"
|
||||
? ValueSpecText
|
||||
: T extends "textarea"
|
||||
? ValueSpecTextarea
|
||||
: T extends "number"
|
||||
? ValueSpecNumber
|
||||
: T extends "color"
|
||||
? ValueSpecColor
|
||||
: T extends "datetime"
|
||||
? ValueSpecDatetime
|
||||
: T extends "toggle"
|
||||
? ValueSpecToggle
|
||||
: T extends "select"
|
||||
? ValueSpecSelect
|
||||
: T extends "multiselect"
|
||||
? ValueSpecMultiselect
|
||||
: T extends "list"
|
||||
? ValueSpecList
|
||||
: T extends "object"
|
||||
? ValueSpecObject
|
||||
: T extends "file"
|
||||
? ValueSpecFile
|
||||
: T extends "union"
|
||||
? ValueSpecUnion
|
||||
: never
|
||||
export type ValueSpecOf<T extends ValueType> =
|
||||
T extends "text" ? ValueSpecText :
|
||||
T extends "textarea" ? ValueSpecTextarea :
|
||||
T extends "number" ? ValueSpecNumber :
|
||||
T extends "color" ? ValueSpecColor :
|
||||
T extends "datetime" ? ValueSpecDatetime :
|
||||
T extends "toggle" ? ValueSpecToggle :
|
||||
T extends "select" ? ValueSpecSelect :
|
||||
T extends "multiselect" ? ValueSpecMultiselect :
|
||||
T extends "list" ? ValueSpecList :
|
||||
T extends "object" ? ValueSpecObject :
|
||||
T extends "file" ? ValueSpecFile :
|
||||
T extends "union" ? ValueSpecUnion :
|
||||
never
|
||||
|
||||
export type ValueSpecText = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "text"
|
||||
patterns: Pattern[]
|
||||
minLength: number | null
|
||||
maxLength: number | null
|
||||
masked: boolean
|
||||
|
||||
inputmode: "text" | "email" | "tel" | "url"
|
||||
placeholder: string | null
|
||||
|
||||
export interface ValueSpecText extends ListValueSpecText, WithStandalone {
|
||||
required: boolean
|
||||
default: DefaultString | null
|
||||
disabled: false | string
|
||||
generate: null | RandomString
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecTextarea extends WithStandalone {
|
||||
export type ValueSpecTextarea = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "textarea"
|
||||
placeholder: string | null
|
||||
minLength: number | null
|
||||
maxLength: number | null
|
||||
required: boolean
|
||||
disabled: false | string
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
|
||||
export type FilePath = {
|
||||
filePath: string
|
||||
}
|
||||
export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone {
|
||||
export type ValueSpecNumber = {
|
||||
type: "number"
|
||||
min: number | null
|
||||
max: number | null
|
||||
integer: boolean
|
||||
step: number | null
|
||||
units: string | null
|
||||
placeholder: string | null
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
required: boolean
|
||||
default: number | null
|
||||
disabled: false | string
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecColor extends WithStandalone {
|
||||
export type ValueSpecColor = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "color"
|
||||
required: boolean
|
||||
default: string | null
|
||||
disabled: false | string
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecDatetime extends WithStandalone {
|
||||
export type ValueSpecDatetime = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
type: "datetime"
|
||||
required: boolean
|
||||
inputmode: "date" | "time" | "datetime-local"
|
||||
@@ -86,10 +109,14 @@ export interface ValueSpecDatetime extends WithStandalone {
|
||||
max: string | null
|
||||
default: string | null
|
||||
disabled: false | string
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecSelect extends SelectBase, WithStandalone {
|
||||
export type ValueSpecSelect = {
|
||||
values: Record<string, string>
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
type: "select"
|
||||
required: boolean
|
||||
default: string | null
|
||||
@@ -99,10 +126,16 @@ export interface ValueSpecSelect extends SelectBase, WithStandalone {
|
||||
* string[] means that the options are disabled
|
||||
*/
|
||||
disabled: false | string | string[]
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecMultiselect extends SelectBase, WithStandalone {
|
||||
export type ValueSpecMultiselect = {
|
||||
values: Record<string, string>
|
||||
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "multiselect"
|
||||
minLength: number | null
|
||||
maxLength: number | null
|
||||
@@ -113,17 +146,25 @@ export interface ValueSpecMultiselect extends SelectBase, WithStandalone {
|
||||
*/
|
||||
disabled: false | string | string[]
|
||||
default: string[]
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecToggle extends WithStandalone {
|
||||
export type ValueSpecToggle = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "toggle"
|
||||
default: boolean | null
|
||||
disabled: false | string
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecUnion extends WithStandalone {
|
||||
export type ValueSpecUnion = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
|
||||
type: "union"
|
||||
variants: Record<
|
||||
string,
|
||||
@@ -140,39 +181,37 @@ export interface ValueSpecUnion extends WithStandalone {
|
||||
disabled: false | string | string[]
|
||||
required: boolean
|
||||
default: string | null
|
||||
/** Immutable means it can only be configed at the first config then never again */
|
||||
/** Immutable means it can only be configured at the first config then never again */
|
||||
immutable: boolean
|
||||
}
|
||||
export interface ValueSpecFile extends WithStandalone {
|
||||
export type ValueSpecFile = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
type: "file"
|
||||
extensions: string[]
|
||||
required: boolean
|
||||
}
|
||||
export interface ValueSpecObject extends WithStandalone {
|
||||
type: "object"
|
||||
spec: InputSpec
|
||||
}
|
||||
export interface WithStandalone {
|
||||
export type ValueSpecObject = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
type: "object"
|
||||
spec: InputSpec
|
||||
}
|
||||
export interface SelectBase {
|
||||
values: Record<string, string>
|
||||
}
|
||||
export type ListValueSpecType = "text" | "number" | "object"
|
||||
export type ListValueSpecType = "text" | "object"
|
||||
/** represents a spec for the values of a list */
|
||||
export type ListValueSpecOf<T extends ListValueSpecType> = T extends "text"
|
||||
? ListValueSpecText
|
||||
: T extends "number"
|
||||
? ListValueSpecNumber
|
||||
: T extends "object"
|
||||
? ListValueSpecObject
|
||||
: never
|
||||
// prettier-ignore
|
||||
export type ListValueSpecOf<T extends ListValueSpecType> =
|
||||
T extends "text" ? ListValueSpecText :
|
||||
T extends "object" ? ListValueSpecObject :
|
||||
never
|
||||
/** represents a spec for a list */
|
||||
export type ValueSpecList = ValueSpecListOf<ListValueSpecType>
|
||||
export interface ValueSpecListOf<T extends ListValueSpecType>
|
||||
extends WithStandalone {
|
||||
export type ValueSpecListOf<T extends ListValueSpecType> = {
|
||||
name: string
|
||||
description: string | null
|
||||
warning: string | null
|
||||
type: "list"
|
||||
spec: ListValueSpecOf<T>
|
||||
minLength: number | null
|
||||
@@ -180,19 +219,17 @@ export interface ValueSpecListOf<T extends ListValueSpecType>
|
||||
disabled: false | string
|
||||
default:
|
||||
| string[]
|
||||
| number[]
|
||||
| DefaultString[]
|
||||
| Record<string, unknown>[]
|
||||
| readonly string[]
|
||||
| readonly number[]
|
||||
| readonly DefaultString[]
|
||||
| readonly Record<string, unknown>[]
|
||||
}
|
||||
export interface Pattern {
|
||||
export type Pattern = {
|
||||
regex: string
|
||||
description: string
|
||||
}
|
||||
export interface ListValueSpecText {
|
||||
export type ListValueSpecText = {
|
||||
type: "text"
|
||||
patterns: Pattern[]
|
||||
minLength: number | null
|
||||
@@ -203,16 +240,8 @@ export interface ListValueSpecText {
|
||||
inputmode: "text" | "email" | "tel" | "url"
|
||||
placeholder: string | null
|
||||
}
|
||||
export interface ListValueSpecNumber {
|
||||
type: "number"
|
||||
min: number | null
|
||||
max: number | null
|
||||
integer: boolean
|
||||
step: number | null
|
||||
units: string | null
|
||||
placeholder: string | null
|
||||
}
|
||||
export interface ListValueSpecObject {
|
||||
|
||||
export type ListValueSpecObject = {
|
||||
type: "object"
|
||||
/** this is a mapped type of the config object at this level, replacing the object's values with specs on those values */
|
||||
spec: InputSpec
|
||||
@@ -242,8 +271,3 @@ export function isValueSpecListOf<S extends ListValueSpecType>(
|
||||
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<S> } {
|
||||
return "spec" in t && t.spec.type === s
|
||||
}
|
||||
export const unionSelectKey = "unionSelectKey" as const
|
||||
export type UnionSelectKey = typeof unionSelectKey
|
||||
|
||||
export const unionValueKey = "unionValueKey" as const
|
||||
export type UnionValueKey = typeof unionValueKey
|
||||
|
||||
@@ -12,4 +12,4 @@ export * as T from "./types"
|
||||
export * as yaml from "yaml"
|
||||
export * as matches from "ts-matches"
|
||||
|
||||
export * as util from "./util/index.browser"
|
||||
export * as utils from "./util/index.browser"
|
||||
|
||||
4
sdk/lib/osBindings/InstalledVersionParams.ts
Normal file
4
sdk/lib/osBindings/InstalledVersionParams.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { PackageId } from "./PackageId"
|
||||
|
||||
export type InstalledVersionParams = { id: PackageId }
|
||||
@@ -79,6 +79,7 @@ export { ImageMetadata } from "./ImageMetadata"
|
||||
export { ImageSource } from "./ImageSource"
|
||||
export { InitProgressRes } from "./InitProgressRes"
|
||||
export { InstalledState } from "./InstalledState"
|
||||
export { InstalledVersionParams } from "./InstalledVersionParams"
|
||||
export { InstallingInfo } from "./InstallingInfo"
|
||||
export { InstallingState } from "./InstallingState"
|
||||
export { IpHostname } from "./IpHostname"
|
||||
|
||||
@@ -268,26 +268,9 @@ describe("values", () => {
|
||||
}),
|
||||
)
|
||||
const validator = value.validator
|
||||
validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } })
|
||||
validator.unsafeCast({ selection: "a", value: { b: false } })
|
||||
type Test = typeof validator._TYPE
|
||||
testOutput<Test, { unionSelectKey: "a"; unionValueKey: { b: boolean } }>()(
|
||||
null,
|
||||
)
|
||||
})
|
||||
test("list", async () => {
|
||||
const value = Value.list(
|
||||
List.number(
|
||||
{
|
||||
name: "test",
|
||||
},
|
||||
{
|
||||
integer: false,
|
||||
},
|
||||
),
|
||||
)
|
||||
const validator = value.validator
|
||||
validator.unsafeCast([1, 2, 3])
|
||||
testOutput<typeof validator._TYPE, number[]>()(null)
|
||||
testOutput<Test, { selection: "a"; value: { b: boolean } }>()(null)
|
||||
})
|
||||
|
||||
describe("dynamic", () => {
|
||||
@@ -577,12 +560,12 @@ describe("values", () => {
|
||||
}),
|
||||
)
|
||||
const validator = value.validator
|
||||
validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } })
|
||||
validator.unsafeCast({ selection: "a", value: { b: false } })
|
||||
type Test = typeof validator._TYPE
|
||||
testOutput<
|
||||
Test,
|
||||
| { unionSelectKey: "a"; unionValueKey: { b: boolean } }
|
||||
| { unionSelectKey: "b"; unionValueKey: { b: boolean } }
|
||||
| { selection: "a"; value: { b: boolean } }
|
||||
| { selection: "b"; value: { b: boolean } }
|
||||
>()(null)
|
||||
|
||||
const built = await value.build({} as any)
|
||||
@@ -644,12 +627,12 @@ describe("values", () => {
|
||||
}),
|
||||
)
|
||||
const validator = value.validator
|
||||
validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } })
|
||||
validator.unsafeCast({ selection: "a", value: { b: false } })
|
||||
type Test = typeof validator._TYPE
|
||||
testOutput<
|
||||
Test,
|
||||
| { unionSelectKey: "a"; unionValueKey: { b: boolean } }
|
||||
| { unionSelectKey: "b"; unionValueKey: { b: boolean } }
|
||||
| { selection: "a"; value: { b: boolean } }
|
||||
| { selection: "b"; value: { b: boolean } }
|
||||
| null
|
||||
| undefined
|
||||
>()(null)
|
||||
@@ -736,24 +719,6 @@ describe("Builder List", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
test("number", async () => {
|
||||
const value = Value.list(
|
||||
List.dynamicNumber(() => ({
|
||||
name: "test",
|
||||
spec: { integer: true },
|
||||
})),
|
||||
)
|
||||
const validator = value.validator
|
||||
expect(() => validator.unsafeCast(["test", "text"])).toThrowError()
|
||||
validator.unsafeCast([4, 2])
|
||||
expect(() => validator.unsafeCast(null)).toThrowError()
|
||||
validator.unsafeCast([])
|
||||
testOutput<typeof validator._TYPE, number[]>()(null)
|
||||
expect(await value.build({} as any)).toMatchObject({
|
||||
name: "test",
|
||||
spec: { integer: true },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Nested nullable values", () => {
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import {
|
||||
ListValueSpecOf,
|
||||
ValueSpec,
|
||||
isValueSpecListOf,
|
||||
} from "../config/configTypes"
|
||||
import { ListValueSpecOf, isValueSpecListOf } from "../config/configTypes"
|
||||
import { Config } from "../config/builder/config"
|
||||
import { List } from "../config/builder/list"
|
||||
import { Value } from "../config/builder/value"
|
||||
|
||||
describe("Config Types", () => {
|
||||
test("isValueSpecListOf", async () => {
|
||||
const options = [List.obj, List.text, List.number]
|
||||
const options = [List.obj, List.text]
|
||||
for (const option of options) {
|
||||
const test = (option as any)(
|
||||
{} as any,
|
||||
@@ -18,8 +14,6 @@ describe("Config Types", () => {
|
||||
const someList = await Value.list(test).build({} as any)
|
||||
if (isValueSpecListOf(someList, "text")) {
|
||||
someList.spec satisfies ListValueSpecOf<"text">
|
||||
} else if (isValueSpecListOf(someList, "number")) {
|
||||
someList.spec satisfies ListValueSpecOf<"number">
|
||||
} else if (isValueSpecListOf(someList, "object")) {
|
||||
someList.spec satisfies ListValueSpecOf<"object">
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
UnionSelectKey,
|
||||
unionSelectKey,
|
||||
UnionValueKey,
|
||||
unionValueKey,
|
||||
} from "../config/configTypes"
|
||||
import { ConfigSpec, matchConfigSpec } from "./output"
|
||||
import * as _I from "../index"
|
||||
import { camelCase } from "../../scripts/oldSpecToBuilder"
|
||||
@@ -30,13 +24,10 @@ testOutput<
|
||||
ConfigSpec["advanced"]["peers"]["addnode"][0]["hostname"],
|
||||
string | null | undefined
|
||||
>()(null)
|
||||
testOutput<
|
||||
ConfigSpec["testListUnion"][0]["union"][UnionValueKey]["name"],
|
||||
string
|
||||
>()(null)
|
||||
testOutput<ConfigSpec["testListUnion"][0]["union"][UnionSelectKey], "lnd">()(
|
||||
testOutput<ConfigSpec["testListUnion"][0]["union"]["value"]["name"], string>()(
|
||||
null,
|
||||
)
|
||||
testOutput<ConfigSpec["testListUnion"][0]["union"]["selection"], "lnd">()(null)
|
||||
testOutput<ConfigSpec["mediasources"], Array<"filebrowser" | "nextcloud">>()(
|
||||
null,
|
||||
)
|
||||
@@ -45,7 +36,7 @@ testOutput<ConfigSpec["mediasources"], Array<"filebrowser" | "nextcloud">>()(
|
||||
testOutput<ConfigSpec["rpc"]["enable"], string>()(null)
|
||||
// prettier-ignore
|
||||
// @ts-expect-error Expect that the string is the one above
|
||||
testOutput<ConfigSpec["testListUnion"][0][UnionSelectKey][UnionSelectKey], "unionSelectKey">()(null);
|
||||
testOutput<ConfigSpec["testListUnion"][0]['selection']['selection'], "selection">()(null);
|
||||
|
||||
/// Here we test the output of the matchConfigSpec function
|
||||
describe("Inputs", () => {
|
||||
@@ -53,7 +44,7 @@ describe("Inputs", () => {
|
||||
mediasources: ["filebrowser"],
|
||||
testListUnion: [
|
||||
{
|
||||
union: { [unionSelectKey]: "lnd", [unionValueKey]: { name: "string" } },
|
||||
union: { selection: "lnd", value: { name: "string" } },
|
||||
},
|
||||
],
|
||||
rpc: {
|
||||
@@ -92,8 +83,8 @@ describe("Inputs", () => {
|
||||
},
|
||||
dbcache: 5,
|
||||
pruning: {
|
||||
unionSelectKey: "disabled",
|
||||
unionValueKey: {},
|
||||
selection: "disabled",
|
||||
value: {},
|
||||
},
|
||||
blockfilters: {
|
||||
blockfilterindex: false,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// a,g,h,A-Z,,,,-
|
||||
|
||||
import * as crypto from "crypto"
|
||||
export function getRandomCharInSet(charset: string): string {
|
||||
const set = stringToCharSet(charset)
|
||||
let charIdx = crypto.randomInt(0, set.len)
|
||||
let charIdx = Math.floor(
|
||||
(crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32) * set.len,
|
||||
)
|
||||
for (let range of set.ranges) {
|
||||
if (range.len > charIdx) {
|
||||
return String.fromCharCode(range.start.charCodeAt(0) + charIdx)
|
||||
|
||||
@@ -80,7 +80,7 @@ export const addressHostToUrl = (
|
||||
): UrlString[] => {
|
||||
const res = []
|
||||
const fmt = (scheme: string | null, host: HostnameInfo, port: number) => {
|
||||
const includePort =
|
||||
const excludePort =
|
||||
scheme &&
|
||||
scheme in knownProtocols &&
|
||||
port === knownProtocols[scheme as keyof typeof knownProtocols].defaultPort
|
||||
@@ -96,7 +96,7 @@ export const addressHostToUrl = (
|
||||
}
|
||||
return `${scheme ? `${scheme}://` : ""}${
|
||||
username ? `${username}@` : ""
|
||||
}${hostname}${includePort ? `:${port}` : ""}${suffix}`
|
||||
}${hostname}${excludePort ? "" : `:${port}`}${suffix}`
|
||||
}
|
||||
if (host.hostname.sslPort !== null) {
|
||||
res.push(fmt(sslScheme, host, host.hostname.sslPort))
|
||||
|
||||
@@ -1,25 +1,10 @@
|
||||
import * as T from "../types"
|
||||
|
||||
/// Currently being used
|
||||
export { addressHostToUrl } from "./getServiceInterface"
|
||||
export { getDefaultString } from "./getDefaultString"
|
||||
|
||||
/// Not being used, but known to be browser compatible
|
||||
export { GetServiceInterface, getServiceInterface } from "./getServiceInterface"
|
||||
export { getServiceInterfaces } from "./getServiceInterfaces"
|
||||
// prettier-ignore
|
||||
export type FlattenIntersection<T> =
|
||||
T extends ArrayLike<any> ? T :
|
||||
T extends object ? {} & {[P in keyof T]: T[P]} :
|
||||
T;
|
||||
|
||||
export type _<T> = FlattenIntersection<T>
|
||||
|
||||
export const isKnownError = (e: unknown): e is T.KnownError =>
|
||||
e instanceof Object && ("error" in e || "error-code" in e)
|
||||
|
||||
declare const affine: unique symbol
|
||||
|
||||
export type Affine<A> = { [affine]: A }
|
||||
|
||||
type NeverPossible = { [affine]: string }
|
||||
export type NoAny<A> = NeverPossible extends A
|
||||
? keyof NeverPossible extends keyof A
|
||||
? never
|
||||
: A
|
||||
: A
|
||||
export * from "./typeHelpers"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import * as T from "../types"
|
||||
|
||||
import "./nullIfEmpty"
|
||||
import "./fileHelper"
|
||||
import "../store/getStore"
|
||||
@@ -12,26 +10,5 @@ export { GetServiceInterface, getServiceInterface } from "./getServiceInterface"
|
||||
export { getServiceInterfaces } from "./getServiceInterfaces"
|
||||
export { addressHostToUrl } from "./getServiceInterface"
|
||||
export { hostnameInfoToAddress } from "./Hostname"
|
||||
// prettier-ignore
|
||||
export type FlattenIntersection<T> =
|
||||
T extends ArrayLike<any> ? T :
|
||||
T extends object ? {} & {[P in keyof T]: T[P]} :
|
||||
T;
|
||||
|
||||
export type _<T> = FlattenIntersection<T>
|
||||
|
||||
export const isKnownError = (e: unknown): e is T.KnownError =>
|
||||
e instanceof Object && ("error" in e || "error-code" in e)
|
||||
|
||||
declare const affine: unique symbol
|
||||
|
||||
export type Affine<A> = { [affine]: A }
|
||||
|
||||
type NeverPossible = { [affine]: string }
|
||||
export type NoAny<A> = NeverPossible extends A
|
||||
? keyof NeverPossible extends keyof A
|
||||
? never
|
||||
: A
|
||||
: A
|
||||
|
||||
export * from "./typeHelpers"
|
||||
export { getDefaultString } from "./getDefaultString"
|
||||
|
||||
23
sdk/lib/util/typeHelpers.ts
Normal file
23
sdk/lib/util/typeHelpers.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import * as T from "../types"
|
||||
|
||||
// prettier-ignore
|
||||
export type FlattenIntersection<T> =
|
||||
T extends ArrayLike<any> ? T :
|
||||
T extends object ? {} & {[P in keyof T]: T[P]} :
|
||||
T;
|
||||
|
||||
export type _<T> = FlattenIntersection<T>
|
||||
|
||||
export const isKnownError = (e: unknown): e is T.KnownError =>
|
||||
e instanceof Object && ("error" in e || "error-code" in e)
|
||||
|
||||
declare const affine: unique symbol
|
||||
|
||||
export type Affine<A> = { [affine]: A }
|
||||
|
||||
type NeverPossible = { [affine]: string }
|
||||
export type NoAny<A> = NeverPossible extends A
|
||||
? keyof NeverPossible extends keyof A
|
||||
? never
|
||||
: A
|
||||
: A
|
||||
Reference in New Issue
Block a user