From 10ede0d21c145e42a0cc63d2f4202361220bbca7 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Fri, 26 Jul 2024 14:47:43 -0600 Subject: [PATCH] delegate pointer removal to config transformer --- .../Systems/SystemForEmbassy/index.ts | 58 ++++++------------- .../SystemForEmbassy/transformConfigSpec.ts | 44 ++++++++++++-- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts index df67dd962..5f8000f25 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts @@ -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 + spec: OldConfigSpec +} + export type PackagePropertiesV2 = { [name: string]: PackagePropertyObject | PackagePropertyString } @@ -546,14 +552,12 @@ export class SystemForEmbassy implements System { effects: Effects, timeoutMs: number | null, ): Promise { - 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 { + ): Promise { 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 { - 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), + ) + 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 { - 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 = } : null -function cleanConfigFromPointers( - config: C, - spec: S, -): CleanConfigFromPointers { - const newConfig = {} as CleanConfigFromPointers - - if (!(object.test(config) && object.test(spec)) || newConfig == null) - return null as CleanConfigFromPointers - - 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 -} - 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 { +async function convertToNewConfig( + value: OldGetConfigRes, +): Promise { const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec) const spec = transformConfigSpec(valueSpec) if (!value.config) return { spec, config: null } diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts index be3aa89b3..9a82d5c16 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts @@ -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