mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
delegate pointer removal to config transformer
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
|||||||
OldConfigSpec,
|
OldConfigSpec,
|
||||||
matchOldConfigSpec,
|
matchOldConfigSpec,
|
||||||
transformConfigSpec,
|
transformConfigSpec,
|
||||||
|
transformNewConfigToOld,
|
||||||
transformOldConfigToNew,
|
transformOldConfigToNew,
|
||||||
} from "./transformConfigSpec"
|
} from "./transformConfigSpec"
|
||||||
import { MainEffects } from "@start9labs/start-sdk/cjs/lib/StartSdk"
|
import { MainEffects } from "@start9labs/start-sdk/cjs/lib/StartSdk"
|
||||||
@@ -101,6 +102,11 @@ const matchSetResult = object(
|
|||||||
["depends-on", "dependsOn"],
|
["depends-on", "dependsOn"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type OldGetConfigRes = {
|
||||||
|
config?: null | Record<string, unknown>
|
||||||
|
spec: OldConfigSpec
|
||||||
|
}
|
||||||
|
|
||||||
export type PackagePropertiesV2 = {
|
export type PackagePropertiesV2 = {
|
||||||
[name: string]: PackagePropertyObject | PackagePropertyString
|
[name: string]: PackagePropertyObject | PackagePropertyString
|
||||||
}
|
}
|
||||||
@@ -546,14 +552,12 @@ export class SystemForEmbassy implements System {
|
|||||||
effects: Effects,
|
effects: Effects,
|
||||||
timeoutMs: number | null,
|
timeoutMs: number | null,
|
||||||
): Promise<T.ConfigRes> {
|
): Promise<T.ConfigRes> {
|
||||||
return this.getConfigUncleaned(effects, timeoutMs)
|
return this.getConfigUncleaned(effects, timeoutMs).then(convertToNewConfig)
|
||||||
.then(removePointers)
|
|
||||||
.then(convertToNewConfig)
|
|
||||||
}
|
}
|
||||||
private async getConfigUncleaned(
|
private async getConfigUncleaned(
|
||||||
effects: Effects,
|
effects: Effects,
|
||||||
timeoutMs: number | null,
|
timeoutMs: number | null,
|
||||||
): Promise<T.ConfigRes> {
|
): Promise<OldGetConfigRes> {
|
||||||
const config = this.manifest.config?.get
|
const config = this.manifest.config?.get
|
||||||
if (!config) return { spec: {} }
|
if (!config) return { spec: {} }
|
||||||
if (config.type === "docker") {
|
if (config.type === "docker") {
|
||||||
@@ -590,13 +594,14 @@ export class SystemForEmbassy implements System {
|
|||||||
newConfigWithoutPointers: unknown,
|
newConfigWithoutPointers: unknown,
|
||||||
timeoutMs: number | null,
|
timeoutMs: number | null,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const newConfig = structuredClone(newConfigWithoutPointers)
|
const spec = await this.getConfigUncleaned(effects, timeoutMs).then(
|
||||||
await updateConfig(
|
(x) => x.spec,
|
||||||
effects,
|
|
||||||
this.manifest,
|
|
||||||
await this.getConfigUncleaned(effects, timeoutMs).then((x) => x.spec),
|
|
||||||
newConfig,
|
|
||||||
)
|
)
|
||||||
|
const newConfig = transformNewConfigToOld(
|
||||||
|
spec,
|
||||||
|
structuredClone(newConfigWithoutPointers as Record<string, unknown>),
|
||||||
|
)
|
||||||
|
await updateConfig(effects, this.manifest, spec, newConfig)
|
||||||
const setConfigValue = this.manifest.config?.set
|
const setConfigValue = this.manifest.config?.set
|
||||||
if (!setConfigValue) return
|
if (!setConfigValue) return
|
||||||
if (setConfigValue.type === "docker") {
|
if (setConfigValue.type === "docker") {
|
||||||
@@ -895,14 +900,6 @@ export class SystemForEmbassy implements System {
|
|||||||
})) as any
|
})) as any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function removePointers(value: T.ConfigRes): Promise<T.ConfigRes> {
|
|
||||||
const startingSpec = structuredClone(value.spec)
|
|
||||||
const config =
|
|
||||||
value.config && cleanConfigFromPointers(value.config, startingSpec)
|
|
||||||
const spec = cleanSpecOfPointers(startingSpec)
|
|
||||||
|
|
||||||
return { config, spec }
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchPointer = object({
|
const matchPointer = object({
|
||||||
type: literal("pointer"),
|
type: literal("pointer"),
|
||||||
@@ -962,27 +959,6 @@ type CleanConfigFromPointers<C, S> =
|
|||||||
} :
|
} :
|
||||||
null
|
null
|
||||||
|
|
||||||
function cleanConfigFromPointers<C, S>(
|
|
||||||
config: C,
|
|
||||||
spec: S,
|
|
||||||
): CleanConfigFromPointers<C, S> {
|
|
||||||
const newConfig = {} as CleanConfigFromPointers<C, S>
|
|
||||||
|
|
||||||
if (!(object.test(config) && object.test(spec)) || newConfig == null)
|
|
||||||
return null as CleanConfigFromPointers<C, S>
|
|
||||||
|
|
||||||
for (const key of Object.keys(spec)) {
|
|
||||||
if (!isKeyOf(key, spec)) continue
|
|
||||||
if (!isKeyOf(key, config)) continue
|
|
||||||
const partSpec = spec[key]
|
|
||||||
if (matchPointer.test(partSpec)) continue
|
|
||||||
;(newConfig as any)[key] = matchSpec.test(partSpec)
|
|
||||||
? cleanConfigFromPointers(config[key], partSpec.spec)
|
|
||||||
: config[key]
|
|
||||||
}
|
|
||||||
return newConfig as CleanConfigFromPointers<C, S>
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateConfig(
|
async function updateConfig(
|
||||||
effects: Effects,
|
effects: Effects,
|
||||||
manifest: Manifest,
|
manifest: Manifest,
|
||||||
@@ -1081,7 +1057,9 @@ function extractServiceInterfaceId(manifest: Manifest, specInterface: string) {
|
|||||||
const serviceInterfaceId = `${specInterface}-${internalPort}`
|
const serviceInterfaceId = `${specInterface}-${internalPort}`
|
||||||
return serviceInterfaceId
|
return serviceInterfaceId
|
||||||
}
|
}
|
||||||
async function convertToNewConfig(value: T.ConfigRes): Promise<T.ConfigRes> {
|
async function convertToNewConfig(
|
||||||
|
value: OldGetConfigRes,
|
||||||
|
): Promise<T.ConfigRes> {
|
||||||
const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec)
|
const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec)
|
||||||
const spec = transformConfigSpec(valueSpec)
|
const spec = transformConfigSpec(valueSpec)
|
||||||
if (!value.config) return { spec, config: null }
|
if (!value.config) return { spec, config: null }
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
deferred,
|
deferred,
|
||||||
every,
|
every,
|
||||||
nill,
|
nill,
|
||||||
|
literal,
|
||||||
} from "ts-matches"
|
} from "ts-matches"
|
||||||
|
|
||||||
export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
||||||
@@ -38,7 +39,7 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
|||||||
values: oldVal.values.reduce(
|
values: oldVal.values.reduce(
|
||||||
(obj, curr) => ({
|
(obj, curr) => ({
|
||||||
...obj,
|
...obj,
|
||||||
[curr]: oldVal["value-names"][curr],
|
[curr]: oldVal["value-names"][curr] || curr,
|
||||||
}),
|
}),
|
||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
@@ -109,7 +110,7 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
|||||||
inputmode: "text",
|
inputmode: "text",
|
||||||
placeholder: oldVal.placeholder || null,
|
placeholder: oldVal.placeholder || null,
|
||||||
}
|
}
|
||||||
} else {
|
} else if (oldVal.type === "union") {
|
||||||
newVal = {
|
newVal = {
|
||||||
type: "union",
|
type: "union",
|
||||||
name: oldVal.tag.name,
|
name: oldVal.tag.name,
|
||||||
@@ -119,7 +120,7 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
|||||||
(obj, [id, spec]) => ({
|
(obj, [id, spec]) => ({
|
||||||
...obj,
|
...obj,
|
||||||
[id]: {
|
[id]: {
|
||||||
name: oldVal.tag["variant-names"][id],
|
name: oldVal.tag["variant-names"][id] || id,
|
||||||
spec: transformConfigSpec(matchOldConfigSpec.unsafeCast(spec)),
|
spec: transformConfigSpec(matchOldConfigSpec.unsafeCast(spec)),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -130,6 +131,10 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
|
|||||||
default: oldVal.default,
|
default: oldVal.default,
|
||||||
immutable: false,
|
immutable: false,
|
||||||
}
|
}
|
||||||
|
} else if (oldVal.type === "pointer") {
|
||||||
|
return inputSpec
|
||||||
|
} else {
|
||||||
|
throw new Error(`unknown spec ${JSON.stringify(oldVal)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -175,6 +180,10 @@ export function transformOldConfigToNew(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPointer(val)) {
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...obj,
|
...obj,
|
||||||
[key]: newVal,
|
[key]: newVal,
|
||||||
@@ -201,7 +210,7 @@ export function transformNewConfigToOld(
|
|||||||
[val.tag.id]: config[key].selection,
|
[val.tag.id]: config[key].selection,
|
||||||
...transformNewConfigToOld(
|
...transformNewConfigToOld(
|
||||||
matchOldConfigSpec.unsafeCast(val.variants[config[key].selection]),
|
matchOldConfigSpec.unsafeCast(val.variants[config[key].selection]),
|
||||||
config[key].unionSelectValue,
|
config[key].value,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,6 +322,10 @@ function isList(val: OldValueSpec): val is OldValueSpecList {
|
|||||||
return val.type === "list"
|
return val.type === "list"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPointer(val: OldValueSpec): val is OldValueSpecPointer {
|
||||||
|
return val.type === "pointer"
|
||||||
|
}
|
||||||
|
|
||||||
function isEnumList(
|
function isEnumList(
|
||||||
val: OldValueSpecList,
|
val: OldValueSpecList,
|
||||||
): val is OldValueSpecList & { subtype: "enum" } {
|
): val is OldValueSpecList & { subtype: "enum" } {
|
||||||
@@ -522,6 +535,28 @@ const matchOldValueSpecList = every(
|
|||||||
)
|
)
|
||||||
type OldValueSpecList = typeof matchOldValueSpecList._TYPE
|
type OldValueSpecList = typeof matchOldValueSpecList._TYPE
|
||||||
|
|
||||||
|
const matchOldValueSpecPointer = every(
|
||||||
|
object({
|
||||||
|
type: literal("pointer"),
|
||||||
|
}),
|
||||||
|
anyOf(
|
||||||
|
object({
|
||||||
|
subtype: literal("package"),
|
||||||
|
target: literals("tor-key", "tor-address", "lan-address"),
|
||||||
|
"package-id": string,
|
||||||
|
interface: string,
|
||||||
|
}),
|
||||||
|
object({
|
||||||
|
subtype: literal("package"),
|
||||||
|
target: literals("config"),
|
||||||
|
"package-id": string,
|
||||||
|
selector: string,
|
||||||
|
multi: boolean,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
type OldValueSpecPointer = typeof matchOldValueSpecPointer._TYPE
|
||||||
|
|
||||||
export const matchOldValueSpec = anyOf(
|
export const matchOldValueSpec = anyOf(
|
||||||
matchOldValueSpecString,
|
matchOldValueSpecString,
|
||||||
matchOldValueSpecNumber,
|
matchOldValueSpecNumber,
|
||||||
@@ -530,6 +565,7 @@ export const matchOldValueSpec = anyOf(
|
|||||||
matchOldValueSpecEnum,
|
matchOldValueSpecEnum,
|
||||||
matchOldValueSpecList,
|
matchOldValueSpecList,
|
||||||
matchOldValueSpecUnion,
|
matchOldValueSpecUnion,
|
||||||
|
matchOldValueSpecPointer,
|
||||||
)
|
)
|
||||||
type OldValueSpec = typeof matchOldValueSpec._TYPE
|
type OldValueSpec = typeof matchOldValueSpec._TYPE
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user