delegate pointer removal to config transformer

This commit is contained in:
Aiden McClelland
2024-07-26 14:47:43 -06:00
parent 698bdd619f
commit 10ede0d21c
2 changed files with 58 additions and 44 deletions

View File

@@ -45,6 +45,7 @@ import {
OldConfigSpec,
matchOldConfigSpec,
transformConfigSpec,
transformNewConfigToOld,
transformOldConfigToNew,
} from "./transformConfigSpec"
import { MainEffects } from "@start9labs/start-sdk/cjs/lib/StartSdk"
@@ -101,6 +102,11 @@ const matchSetResult = object(
["depends-on", "dependsOn"],
)
type OldGetConfigRes = {
config?: null | Record<string, unknown>
spec: OldConfigSpec
}
export type PackagePropertiesV2 = {
[name: string]: PackagePropertyObject | PackagePropertyString
}
@@ -546,14 +552,12 @@ export class SystemForEmbassy implements System {
effects: Effects,
timeoutMs: number | null,
): Promise<T.ConfigRes> {
return this.getConfigUncleaned(effects, timeoutMs)
.then(removePointers)
.then(convertToNewConfig)
return this.getConfigUncleaned(effects, timeoutMs).then(convertToNewConfig)
}
private async getConfigUncleaned(
effects: Effects,
timeoutMs: number | null,
): Promise<T.ConfigRes> {
): Promise<OldGetConfigRes> {
const config = this.manifest.config?.get
if (!config) return { spec: {} }
if (config.type === "docker") {
@@ -590,13 +594,14 @@ export class SystemForEmbassy implements System {
newConfigWithoutPointers: unknown,
timeoutMs: number | null,
): Promise<void> {
const newConfig = structuredClone(newConfigWithoutPointers)
await updateConfig(
effects,
this.manifest,
await this.getConfigUncleaned(effects, timeoutMs).then((x) => x.spec),
newConfig,
const spec = await this.getConfigUncleaned(effects, timeoutMs).then(
(x) => x.spec,
)
const newConfig = transformNewConfigToOld(
spec,
structuredClone(newConfigWithoutPointers as Record<string, unknown>),
)
await updateConfig(effects, this.manifest, spec, newConfig)
const setConfigValue = this.manifest.config?.set
if (!setConfigValue) return
if (setConfigValue.type === "docker") {
@@ -895,14 +900,6 @@ export class SystemForEmbassy implements System {
})) 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({
type: literal("pointer"),
@@ -962,27 +959,6 @@ type CleanConfigFromPointers<C, S> =
} :
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(
effects: Effects,
manifest: Manifest,
@@ -1081,7 +1057,9 @@ function extractServiceInterfaceId(manifest: Manifest, specInterface: string) {
const serviceInterfaceId = `${specInterface}-${internalPort}`
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 spec = transformConfigSpec(valueSpec)
if (!value.config) return { spec, config: null }

View File

@@ -12,6 +12,7 @@ import {
deferred,
every,
nill,
literal,
} from "ts-matches"
export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
@@ -38,7 +39,7 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
values: oldVal.values.reduce(
(obj, curr) => ({
...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",
placeholder: oldVal.placeholder || null,
}
} else {
} else if (oldVal.type === "union") {
newVal = {
type: "union",
name: oldVal.tag.name,
@@ -119,7 +120,7 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
(obj, [id, spec]) => ({
...obj,
[id]: {
name: oldVal.tag["variant-names"][id],
name: oldVal.tag["variant-names"][id] || id,
spec: transformConfigSpec(matchOldConfigSpec.unsafeCast(spec)),
},
}),
@@ -130,6 +131,10 @@ export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec {
default: oldVal.default,
immutable: false,
}
} else if (oldVal.type === "pointer") {
return inputSpec
} else {
throw new Error(`unknown spec ${JSON.stringify(oldVal)}`)
}
return {
@@ -175,6 +180,10 @@ export function transformOldConfigToNew(
)
}
if (isPointer(val)) {
return obj
}
return {
...obj,
[key]: newVal,
@@ -201,7 +210,7 @@ export function transformNewConfigToOld(
[val.tag.id]: config[key].selection,
...transformNewConfigToOld(
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"
}
function isPointer(val: OldValueSpec): val is OldValueSpecPointer {
return val.type === "pointer"
}
function isEnumList(
val: OldValueSpecList,
): val is OldValueSpecList & { subtype: "enum" } {
@@ -522,6 +535,28 @@ const matchOldValueSpecList = every(
)
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(
matchOldValueSpecString,
matchOldValueSpecNumber,
@@ -530,6 +565,7 @@ export const matchOldValueSpec = anyOf(
matchOldValueSpecEnum,
matchOldValueSpecList,
matchOldValueSpecUnion,
matchOldValueSpecPointer,
)
type OldValueSpec = typeof matchOldValueSpec._TYPE