From dc7a86a8e8332cb5c416a23c40d719bacaa8340c Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Thu, 8 Feb 2024 13:30:32 -0700 Subject: [PATCH] fixes from testing --- lib/config/configTypes.ts | 9 ++-- lib/config/setupConfig.ts | 6 +-- lib/dependencyConfig/DependencyConfig.ts | 4 +- lib/inits/setupInstall.ts | 4 +- lib/inits/setupUninstall.ts | 4 +- lib/interfaces/Origin.ts | 5 +-- lib/mainFn/Daemons.ts | 6 +-- lib/mainFn/index.ts | 2 +- lib/test/store.test.ts | 24 +++++------ lib/types.ts | 4 +- lib/util/Overlay.ts | 55 +++++++++++++++++++++--- lib/util/getNetworkInterface.ts | 4 +- lib/util/index.ts | 4 +- lib/util/utils.ts | 2 +- tsconfig.json | 15 +++---- 15 files changed, 92 insertions(+), 56 deletions(-) diff --git a/lib/config/configTypes.ts b/lib/config/configTypes.ts index 55e5041..64c3fb5 100644 --- a/lib/config/configTypes.ts +++ b/lib/config/configTypes.ts @@ -14,6 +14,7 @@ export type ValueType = | "union" export type ValueSpec = ValueSpecOf /** core spec types. These types provide the metadata for performing validations */ +// prettier-ignore export type ValueSpecOf = T extends "text" ? ValueSpecText : T extends "textarea" @@ -164,10 +165,10 @@ export type ListValueSpecType = "text" | "number" | "object" export type ListValueSpecOf = T extends "text" ? ListValueSpecText : T extends "number" - ? ListValueSpecNumber - : T extends "object" - ? ListValueSpecObject - : never + ? ListValueSpecNumber + : T extends "object" + ? ListValueSpecObject + : never /** represents a spec for a list */ export type ValueSpecList = ValueSpecListOf export interface ValueSpecListOf diff --git a/lib/config/setupConfig.ts b/lib/config/setupConfig.ts index 92680a5..ee693dd 100644 --- a/lib/config/setupConfig.ts +++ b/lib/config/setupConfig.ts @@ -2,7 +2,7 @@ import { Effects, ExpectedExports } from "../types" import { SDKManifest } from "../manifest/ManifestTypes" import * as D from "./configDependencies" import { Config, ExtractConfigType } from "./builder/config" -import { Utils, utils } from "../util/utils" +import { Utils, createUtils } from "../util/utils" import nullIfEmpty from "../util/nullIfEmpty" import { InterfaceReceipt } from "../interfaces/interfaceReceipt" import { InterfacesReceipt as InterfacesReceipt } from "../interfaces/setupInterfaces" @@ -72,7 +72,7 @@ export function setupConfig< const { restart } = await write({ input: JSON.parse(JSON.stringify(input)), effects, - utils: utils(effects), + utils: createUtils(effects), dependencies: D.configDependenciesSet(), }) if (restart) { @@ -80,7 +80,7 @@ export function setupConfig< } }) as ExpectedExports.setConfig, getConfig: (async ({ effects }) => { - const myUtils = utils(effects) + const myUtils = createUtils(effects) const configValue = nullIfEmpty( (await read({ effects, utils: myUtils })) || null, ) diff --git a/lib/dependencyConfig/DependencyConfig.ts b/lib/dependencyConfig/DependencyConfig.ts index dc01058..10dcb4b 100644 --- a/lib/dependencyConfig/DependencyConfig.ts +++ b/lib/dependencyConfig/DependencyConfig.ts @@ -3,7 +3,7 @@ import { DeepPartial, Effects, } from "../types" -import { Utils, utils } from "../util/utils" +import { Utils, createUtils } from "../util/utils" import { deepEqual } from "../util/deepEqual" import { deepMerge } from "../util/deepMerge" import { SDKManifest } from "../manifest/ManifestTypes" @@ -41,7 +41,7 @@ export class DependencyConfig< return this.dependencyConfig({ localConfig: options.localConfig as Input, effects: options.effects, - utils: utils(options.effects), + utils: createUtils(options.effects), }) } } diff --git a/lib/inits/setupInstall.ts b/lib/inits/setupInstall.ts index 82489c8..e49c0b5 100644 --- a/lib/inits/setupInstall.ts +++ b/lib/inits/setupInstall.ts @@ -1,6 +1,6 @@ import { SDKManifest } from "../manifest/ManifestTypes" import { Effects, ExpectedExports } from "../types" -import { Utils, utils } from "../util/utils" +import { Utils, createUtils } from "../util/utils" export type InstallFn = (opts: { effects: Effects @@ -21,7 +21,7 @@ export class Install { if (!previousVersion) await this.fn({ effects, - utils: utils(effects), + utils: createUtils(effects), }) } } diff --git a/lib/inits/setupUninstall.ts b/lib/inits/setupUninstall.ts index bfb72bd..b411d2f 100644 --- a/lib/inits/setupUninstall.ts +++ b/lib/inits/setupUninstall.ts @@ -1,6 +1,6 @@ import { SDKManifest } from "../manifest/ManifestTypes" import { Effects, ExpectedExports } from "../types" -import { Utils, utils } from "../util/utils" +import { Utils, createUtils } from "../util/utils" export type UninstallFn = (opts: { effects: Effects @@ -21,7 +21,7 @@ export class Uninstall { if (!nextVersion) await this.fn({ effects, - utils: utils(effects), + utils: createUtils(effects), }) } } diff --git a/lib/interfaces/Origin.ts b/lib/interfaces/Origin.ts index 1bab628..08ad3f8 100644 --- a/lib/interfaces/Origin.ts +++ b/lib/interfaces/Origin.ts @@ -2,10 +2,7 @@ import { Address } from "../types" import { Host, PortOptions } from "./Host" export class Origin { - constructor( - readonly host: T, - readonly options: PortOptions, - ) {} + constructor(readonly host: T, readonly options: PortOptions) {} build({ username, path, search }: BuildOptions): Address { const qpEntries = Object.entries(search) diff --git a/lib/mainFn/Daemons.ts b/lib/mainFn/Daemons.ts index 9fd94dd..26b4c0e 100644 --- a/lib/mainFn/Daemons.ts +++ b/lib/mainFn/Daemons.ts @@ -52,7 +52,7 @@ Daemons.of({ export class Daemons { private constructor( readonly effects: Effects, - readonly started: (onTerm: () => void) => null, + readonly started: (onTerm: () => PromiseLike) => PromiseLike, readonly daemons?: Daemon[], ) {} /** @@ -67,7 +67,7 @@ export class Daemons { */ static of(config: { effects: Effects - started: (onTerm: () => void) => null + started: (onTerm: () => PromiseLike) => PromiseLike healthReceipts: HealthReceipt[] }) { return new Daemons(config.effects, config.started) @@ -123,7 +123,7 @@ export class Daemons { ({ status: "failing", message: "message" in err ? err.message : String(err), - }) as CheckResult, + } as CheckResult), ) currentInput.lastResult = response.status || null if (!currentInput.hadSuccess && response.status === "passing") { diff --git a/lib/mainFn/index.ts b/lib/mainFn/index.ts index ba79880..7a6e11c 100644 --- a/lib/mainFn/index.ts +++ b/lib/mainFn/index.ts @@ -1,6 +1,6 @@ import { Effects, ExpectedExports } from "../types" import { createMainUtils } from "../util" -import { Utils, utils } from "../util/utils" +import { Utils, createUtils } from "../util/utils" import { Daemons } from "./Daemons" import "../interfaces/NetworkInterfaceBuilder" import "../interfaces/Origin" diff --git a/lib/test/store.test.ts b/lib/test/store.test.ts index 9291c31..2ed8c4d 100644 --- a/lib/test/store.test.ts +++ b/lib/test/store.test.ts @@ -1,6 +1,6 @@ import { Effects } from "../types" import { createMainUtils } from "../util" -import { utils } from "../util/utils" +import { createUtils } from "../util/utils" type Store = { config: { @@ -15,23 +15,23 @@ const noop = () => {} describe("Store", () => { test("types", async () => { ;async () => { - utils(todo()).store.setOwn("/config", { + createUtils(todo()).store.setOwn("/config", { someValue: "a", }) - utils(todo()).store.setOwn( + createUtils(todo()).store.setOwn( "/config/someValue", "b", ) - utils(todo()).store.setOwn("", { + createUtils(todo()).store.setOwn("", { config: { someValue: "b" }, }) - utils(todo()).store.setOwn( + createUtils(todo()).store.setOwn( "/config/someValue", // @ts-expect-error Type is wrong for the setting value 5, ) - utils(todo()).store.setOwn( + createUtils(todo()).store.setOwn( // @ts-expect-error Path is wrong "/config/someVae3lue", "someValue", @@ -64,31 +64,31 @@ describe("Store", () => { .const() /// ----------------- ERRORS ----------------- - utils(todo()).store.setOwn("", { + createUtils(todo()).store.setOwn("", { // @ts-expect-error Type is wrong for the setting value config: { someValue: "notInAOrB" }, }) - utils(todo()).store.setOwn( + createUtils(todo()).store.setOwn( "/config/someValue", // @ts-expect-error Type is wrong for the setting value "notInAOrB", ) - ;(await utils(todo()) + ;(await createUtils(todo()) .store.getOwn("/config/someValue") // @ts-expect-error Const should normally not be callable .const()) satisfies string - ;(await utils(todo()) + ;(await createUtils(todo()) .store.getOwn("/config") // @ts-expect-error Const should normally not be callable .const()) satisfies Store["config"] - await utils(todo()) + await createUtils(todo()) // @ts-expect-error Path is wrong .store.getOwn("/config/somdsfeValue") // @ts-expect-error Const should normally not be callable .const() /// - ;(await utils(todo()) + ;(await createUtils(todo()) .store.getOwn("/config/someValue") // @ts-expect-error satisfies type is wrong .const()) satisfies number diff --git a/lib/types.ts b/lib/types.ts index 657c09c..338e7a7 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -114,8 +114,8 @@ export type ValidIfNoStupidEscape = A extends | `${string}\\"${string}` ? never : "" extends A & "" - ? never - : A + ? never + : A export type ConfigRes = { /** This should be the previous config, that way during set config we start with the previous */ diff --git a/lib/util/Overlay.ts b/lib/util/Overlay.ts index 3a8984b..dee14ca 100644 --- a/lib/util/Overlay.ts +++ b/lib/util/Overlay.ts @@ -8,18 +8,22 @@ export const execFile = promisify(cp.execFile) export class Overlay { private constructor( readonly effects: T.Effects, + readonly imageId: string, readonly rootfs: string, ) {} static async of(effects: T.Effects, imageId: string) { const rootfs = await effects.createOverlayedImage({ imageId }) for (const dirPart of ["dev", "sys", "proc", "run"] as const) { - const dir = await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true }) - if (!dir) break - await execFile("mount", ["--bind", `/${dirPart}`, dir]) + await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true }) + await execFile("mount", [ + "--rbind", + `/${dirPart}`, + `${rootfs}/${dirPart}`, + ]) } - return new Overlay(effects, rootfs) + return new Overlay(effects, imageId, rootfs) } async mount(options: MountOptions, path: string): Promise { @@ -55,20 +59,59 @@ export class Overlay { command: string[], options?: CommandOptions, ): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> { - return await execFile("chroot", [this.rootfs, ...command], options) + let extra: string[] = [] + if (options?.cwd) { + extra.push(`--workdir=${options.cwd}`) + delete options.cwd + } + if (options?.user) { + extra.push(`--user=${options.user}`) + delete options.user + } + return await execFile( + "start-cli", + [ + "chroot", + `--env=/media/startos/env/${this.imageId}.env`, + ...extra, + this.rootfs, + ...command, + ], + options, + ) } spawn( command: string[], options?: CommandOptions, ): cp.ChildProcessWithoutNullStreams { - return cp.spawn("chroot", [this.rootfs, ...command], options) + let extra: string[] = [] + if (options?.cwd) { + extra.push(`--workdir=${options.cwd}`) + delete options.cwd + } + if (options?.user) { + extra.push(`--user=${options.user}`) + delete options.user + } + return cp.spawn( + "start-cli", + [ + "chroot", + `--env=/media/startos/env/${this.imageId}.env`, + ...extra, + this.rootfs, + ...command, + ], + options, + ) } } export type CommandOptions = { env?: { [variable: string]: string } cwd?: string + user?: string } export type MountOptions = diff --git a/lib/util/getNetworkInterface.ts b/lib/util/getNetworkInterface.ts index 91c4014..9f78474 100644 --- a/lib/util/getNetworkInterface.ts +++ b/lib/util/getNetworkInterface.ts @@ -69,8 +69,8 @@ const addressHostToUrl = ( const scheme = host.endsWith(".onion") ? options.scheme : options.addSsl - ? options.addSsl.scheme - : options.scheme // TODO: encode whether hostname transport is "secure"? + ? options.addSsl.scheme + : options.scheme // TODO: encode whether hostname transport is "secure"? return `${scheme ? `${scheme}//` : ""}${ username ? `${username}@` : "" }${host}${suffix}` diff --git a/lib/util/index.ts b/lib/util/index.ts index 7ed65b1..81bd88d 100644 --- a/lib/util/index.ts +++ b/lib/util/index.ts @@ -7,7 +7,7 @@ import "./deepEqual" import "./deepMerge" import "./Overlay" import "./once" -import { utils } from "./utils" +import * as utils from "./utils" import { SDKManifest } from "../manifest/ManifestTypes" // prettier-ignore @@ -23,7 +23,7 @@ export const isKnownError = (e: unknown): e is T.KnownError => declare const affine: unique symbol -export const createUtils = utils +export const createUtils = utils.createUtils export const createMainUtils = ( effects: T.Effects, ) => createUtils(effects) diff --git a/lib/util/utils.ts b/lib/util/utils.ts index 04a45b2..a4bb80c 100644 --- a/lib/util/utils.ts +++ b/lib/util/utils.ts @@ -141,7 +141,7 @@ export type Utils< ) => Promise } } -export const utils = < +export const createUtils = < Manifest extends SDKManifest, Store = never, WrapperOverWrite = { const: never }, diff --git a/tsconfig.json b/tsconfig.json index ac07a10..4ada3b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,10 @@ { - "include": [ - "./lib/**/*.ts", - "scripts/oldSpecToBuilder.ts" - ], - "inputs": [ - "./lib/index.ts" - ], + "include": ["./lib/**/*.ts", "scripts/oldSpecToBuilder.ts"], + "inputs": ["./lib/index.ts"], "compilerOptions": { "target": "es2022", - "module": "es2022", - "moduleResolution": "node", + "module": "Node16", + "moduleResolution": "Node16", "declaration": true, "outDir": "./dist/", "esModuleInterop": true, @@ -22,4 +17,4 @@ "module": "commonjs" } } -} \ No newline at end of file +}