fixes from testing

This commit is contained in:
Aiden McClelland
2024-02-08 13:30:32 -07:00
parent 4b1834a490
commit dc7a86a8e8
15 changed files with 92 additions and 56 deletions

View File

@@ -14,6 +14,7 @@ export type ValueType =
| "union" | "union"
export type ValueSpec = ValueSpecOf<ValueType> export type ValueSpec = ValueSpecOf<ValueType>
/** core spec types. These types provide the metadata for performing validations */ /** core spec types. These types provide the metadata for performing validations */
// prettier-ignore
export type ValueSpecOf<T extends ValueType> = T extends "text" export type ValueSpecOf<T extends ValueType> = T extends "text"
? ValueSpecText ? ValueSpecText
: T extends "textarea" : T extends "textarea"
@@ -164,10 +165,10 @@ export type ListValueSpecType = "text" | "number" | "object"
export type ListValueSpecOf<T extends ListValueSpecType> = T extends "text" export type ListValueSpecOf<T extends ListValueSpecType> = T extends "text"
? ListValueSpecText ? ListValueSpecText
: T extends "number" : T extends "number"
? ListValueSpecNumber ? ListValueSpecNumber
: T extends "object" : T extends "object"
? ListValueSpecObject ? ListValueSpecObject
: never : never
/** represents a spec for a list */ /** represents a spec for a list */
export type ValueSpecList = ValueSpecListOf<ListValueSpecType> export type ValueSpecList = ValueSpecListOf<ListValueSpecType>
export interface ValueSpecListOf<T extends ListValueSpecType> export interface ValueSpecListOf<T extends ListValueSpecType>

View File

@@ -2,7 +2,7 @@ import { Effects, ExpectedExports } from "../types"
import { SDKManifest } from "../manifest/ManifestTypes" import { SDKManifest } from "../manifest/ManifestTypes"
import * as D from "./configDependencies" import * as D from "./configDependencies"
import { Config, ExtractConfigType } from "./builder/config" import { Config, ExtractConfigType } from "./builder/config"
import { Utils, utils } from "../util/utils" import { Utils, createUtils } from "../util/utils"
import nullIfEmpty from "../util/nullIfEmpty" import nullIfEmpty from "../util/nullIfEmpty"
import { InterfaceReceipt } from "../interfaces/interfaceReceipt" import { InterfaceReceipt } from "../interfaces/interfaceReceipt"
import { InterfacesReceipt as InterfacesReceipt } from "../interfaces/setupInterfaces" import { InterfacesReceipt as InterfacesReceipt } from "../interfaces/setupInterfaces"
@@ -72,7 +72,7 @@ export function setupConfig<
const { restart } = await write({ const { restart } = await write({
input: JSON.parse(JSON.stringify(input)), input: JSON.parse(JSON.stringify(input)),
effects, effects,
utils: utils(effects), utils: createUtils(effects),
dependencies: D.configDependenciesSet<Manifest>(), dependencies: D.configDependenciesSet<Manifest>(),
}) })
if (restart) { if (restart) {
@@ -80,7 +80,7 @@ export function setupConfig<
} }
}) as ExpectedExports.setConfig, }) as ExpectedExports.setConfig,
getConfig: (async ({ effects }) => { getConfig: (async ({ effects }) => {
const myUtils = utils<Manifest, Store>(effects) const myUtils = createUtils<Manifest, Store>(effects)
const configValue = nullIfEmpty( const configValue = nullIfEmpty(
(await read({ effects, utils: myUtils })) || null, (await read({ effects, utils: myUtils })) || null,
) )

View File

@@ -3,7 +3,7 @@ import {
DeepPartial, DeepPartial,
Effects, Effects,
} from "../types" } from "../types"
import { Utils, utils } from "../util/utils" import { Utils, createUtils } from "../util/utils"
import { deepEqual } from "../util/deepEqual" import { deepEqual } from "../util/deepEqual"
import { deepMerge } from "../util/deepMerge" import { deepMerge } from "../util/deepMerge"
import { SDKManifest } from "../manifest/ManifestTypes" import { SDKManifest } from "../manifest/ManifestTypes"
@@ -41,7 +41,7 @@ export class DependencyConfig<
return this.dependencyConfig({ return this.dependencyConfig({
localConfig: options.localConfig as Input, localConfig: options.localConfig as Input,
effects: options.effects, effects: options.effects,
utils: utils<Manifest, Store>(options.effects), utils: createUtils<Manifest, Store>(options.effects),
}) })
} }
} }

View File

@@ -1,6 +1,6 @@
import { SDKManifest } from "../manifest/ManifestTypes" import { SDKManifest } from "../manifest/ManifestTypes"
import { Effects, ExpectedExports } from "../types" import { Effects, ExpectedExports } from "../types"
import { Utils, utils } from "../util/utils" import { Utils, createUtils } from "../util/utils"
export type InstallFn<Manifest extends SDKManifest, Store> = (opts: { export type InstallFn<Manifest extends SDKManifest, Store> = (opts: {
effects: Effects effects: Effects
@@ -21,7 +21,7 @@ export class Install<Manifest extends SDKManifest, Store> {
if (!previousVersion) if (!previousVersion)
await this.fn({ await this.fn({
effects, effects,
utils: utils(effects), utils: createUtils(effects),
}) })
} }
} }

View File

@@ -1,6 +1,6 @@
import { SDKManifest } from "../manifest/ManifestTypes" import { SDKManifest } from "../manifest/ManifestTypes"
import { Effects, ExpectedExports } from "../types" import { Effects, ExpectedExports } from "../types"
import { Utils, utils } from "../util/utils" import { Utils, createUtils } from "../util/utils"
export type UninstallFn<Manifest extends SDKManifest, Store> = (opts: { export type UninstallFn<Manifest extends SDKManifest, Store> = (opts: {
effects: Effects effects: Effects
@@ -21,7 +21,7 @@ export class Uninstall<Manifest extends SDKManifest, Store> {
if (!nextVersion) if (!nextVersion)
await this.fn({ await this.fn({
effects, effects,
utils: utils(effects), utils: createUtils(effects),
}) })
} }
} }

View File

@@ -2,10 +2,7 @@ import { Address } from "../types"
import { Host, PortOptions } from "./Host" import { Host, PortOptions } from "./Host"
export class Origin<T extends Host> { export class Origin<T extends Host> {
constructor( constructor(readonly host: T, readonly options: PortOptions) {}
readonly host: T,
readonly options: PortOptions,
) {}
build({ username, path, search }: BuildOptions): Address { build({ username, path, search }: BuildOptions): Address {
const qpEntries = Object.entries(search) const qpEntries = Object.entries(search)

View File

@@ -52,7 +52,7 @@ Daemons.of({
export class Daemons<Manifest extends SDKManifest, Ids extends string> { export class Daemons<Manifest extends SDKManifest, Ids extends string> {
private constructor( private constructor(
readonly effects: Effects, readonly effects: Effects,
readonly started: (onTerm: () => void) => null, readonly started: (onTerm: () => PromiseLike<void>) => PromiseLike<void>,
readonly daemons?: Daemon<Manifest, Ids, "command", Ids>[], readonly daemons?: Daemon<Manifest, Ids, "command", Ids>[],
) {} ) {}
/** /**
@@ -67,7 +67,7 @@ export class Daemons<Manifest extends SDKManifest, Ids extends string> {
*/ */
static of<Manifest extends SDKManifest>(config: { static of<Manifest extends SDKManifest>(config: {
effects: Effects effects: Effects
started: (onTerm: () => void) => null started: (onTerm: () => PromiseLike<void>) => PromiseLike<void>
healthReceipts: HealthReceipt[] healthReceipts: HealthReceipt[]
}) { }) {
return new Daemons<Manifest, never>(config.effects, config.started) return new Daemons<Manifest, never>(config.effects, config.started)
@@ -123,7 +123,7 @@ export class Daemons<Manifest extends SDKManifest, Ids extends string> {
({ ({
status: "failing", status: "failing",
message: "message" in err ? err.message : String(err), message: "message" in err ? err.message : String(err),
}) as CheckResult, } as CheckResult),
) )
currentInput.lastResult = response.status || null currentInput.lastResult = response.status || null
if (!currentInput.hadSuccess && response.status === "passing") { if (!currentInput.hadSuccess && response.status === "passing") {

View File

@@ -1,6 +1,6 @@
import { Effects, ExpectedExports } from "../types" import { Effects, ExpectedExports } from "../types"
import { createMainUtils } from "../util" import { createMainUtils } from "../util"
import { Utils, utils } from "../util/utils" import { Utils, createUtils } from "../util/utils"
import { Daemons } from "./Daemons" import { Daemons } from "./Daemons"
import "../interfaces/NetworkInterfaceBuilder" import "../interfaces/NetworkInterfaceBuilder"
import "../interfaces/Origin" import "../interfaces/Origin"

View File

@@ -1,6 +1,6 @@
import { Effects } from "../types" import { Effects } from "../types"
import { createMainUtils } from "../util" import { createMainUtils } from "../util"
import { utils } from "../util/utils" import { createUtils } from "../util/utils"
type Store = { type Store = {
config: { config: {
@@ -15,23 +15,23 @@ const noop = () => {}
describe("Store", () => { describe("Store", () => {
test("types", async () => { test("types", async () => {
;async () => { ;async () => {
utils<Manifest, Store>(todo<Effects>()).store.setOwn("/config", { createUtils<Manifest, Store>(todo<Effects>()).store.setOwn("/config", {
someValue: "a", someValue: "a",
}) })
utils<Manifest, Store>(todo<Effects>()).store.setOwn( createUtils<Manifest, Store>(todo<Effects>()).store.setOwn(
"/config/someValue", "/config/someValue",
"b", "b",
) )
utils<Manifest, Store>(todo<Effects>()).store.setOwn("", { createUtils<Manifest, Store>(todo<Effects>()).store.setOwn("", {
config: { someValue: "b" }, config: { someValue: "b" },
}) })
utils<Manifest, Store>(todo<Effects>()).store.setOwn( createUtils<Manifest, Store>(todo<Effects>()).store.setOwn(
"/config/someValue", "/config/someValue",
// @ts-expect-error Type is wrong for the setting value // @ts-expect-error Type is wrong for the setting value
5, 5,
) )
utils(todo<Effects>()).store.setOwn( createUtils(todo<Effects>()).store.setOwn(
// @ts-expect-error Path is wrong // @ts-expect-error Path is wrong
"/config/someVae3lue", "/config/someVae3lue",
"someValue", "someValue",
@@ -64,31 +64,31 @@ describe("Store", () => {
.const() .const()
/// ----------------- ERRORS ----------------- /// ----------------- ERRORS -----------------
utils<Manifest, Store>(todo<Effects>()).store.setOwn("", { createUtils<Manifest, Store>(todo<Effects>()).store.setOwn("", {
// @ts-expect-error Type is wrong for the setting value // @ts-expect-error Type is wrong for the setting value
config: { someValue: "notInAOrB" }, config: { someValue: "notInAOrB" },
}) })
utils<Manifest, Store>(todo<Effects>()).store.setOwn( createUtils<Manifest, Store>(todo<Effects>()).store.setOwn(
"/config/someValue", "/config/someValue",
// @ts-expect-error Type is wrong for the setting value // @ts-expect-error Type is wrong for the setting value
"notInAOrB", "notInAOrB",
) )
;(await utils<Manifest, Store>(todo<Effects>()) ;(await createUtils<Manifest, Store>(todo<Effects>())
.store.getOwn("/config/someValue") .store.getOwn("/config/someValue")
// @ts-expect-error Const should normally not be callable // @ts-expect-error Const should normally not be callable
.const()) satisfies string .const()) satisfies string
;(await utils<Manifest, Store>(todo<Effects>()) ;(await createUtils<Manifest, Store>(todo<Effects>())
.store.getOwn("/config") .store.getOwn("/config")
// @ts-expect-error Const should normally not be callable // @ts-expect-error Const should normally not be callable
.const()) satisfies Store["config"] .const()) satisfies Store["config"]
await utils<Manifest, Store>(todo<Effects>()) await createUtils<Manifest, Store>(todo<Effects>())
// @ts-expect-error Path is wrong // @ts-expect-error Path is wrong
.store.getOwn("/config/somdsfeValue") .store.getOwn("/config/somdsfeValue")
// @ts-expect-error Const should normally not be callable // @ts-expect-error Const should normally not be callable
.const() .const()
/// ///
;(await utils<Manifest, Store>(todo<Effects>()) ;(await createUtils<Manifest, Store>(todo<Effects>())
.store.getOwn("/config/someValue") .store.getOwn("/config/someValue")
// @ts-expect-error satisfies type is wrong // @ts-expect-error satisfies type is wrong
.const()) satisfies number .const()) satisfies number

View File

@@ -114,8 +114,8 @@ export type ValidIfNoStupidEscape<A> = A extends
| `${string}\\"${string}` | `${string}\\"${string}`
? never ? never
: "" extends A & "" : "" extends A & ""
? never ? never
: A : A
export type ConfigRes = { export type ConfigRes = {
/** This should be the previous config, that way during set config we start with the previous */ /** This should be the previous config, that way during set config we start with the previous */

View File

@@ -8,18 +8,22 @@ export const execFile = promisify(cp.execFile)
export class Overlay { export class Overlay {
private constructor( private constructor(
readonly effects: T.Effects, readonly effects: T.Effects,
readonly imageId: string,
readonly rootfs: string, readonly rootfs: string,
) {} ) {}
static async of(effects: T.Effects, imageId: string) { static async of(effects: T.Effects, imageId: string) {
const rootfs = await effects.createOverlayedImage({ imageId }) const rootfs = await effects.createOverlayedImage({ imageId })
for (const dirPart of ["dev", "sys", "proc", "run"] as const) { for (const dirPart of ["dev", "sys", "proc", "run"] as const) {
const dir = await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true }) await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true })
if (!dir) break await execFile("mount", [
await execFile("mount", ["--bind", `/${dirPart}`, dir]) "--rbind",
`/${dirPart}`,
`${rootfs}/${dirPart}`,
])
} }
return new Overlay(effects, rootfs) return new Overlay(effects, imageId, rootfs)
} }
async mount(options: MountOptions, path: string): Promise<Overlay> { async mount(options: MountOptions, path: string): Promise<Overlay> {
@@ -55,20 +59,59 @@ export class Overlay {
command: string[], command: string[],
options?: CommandOptions, options?: CommandOptions,
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> { ): 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( spawn(
command: string[], command: string[],
options?: CommandOptions, options?: CommandOptions,
): cp.ChildProcessWithoutNullStreams { ): 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 = { export type CommandOptions = {
env?: { [variable: string]: string } env?: { [variable: string]: string }
cwd?: string cwd?: string
user?: string
} }
export type MountOptions = export type MountOptions =

View File

@@ -69,8 +69,8 @@ const addressHostToUrl = (
const scheme = host.endsWith(".onion") const scheme = host.endsWith(".onion")
? options.scheme ? options.scheme
: options.addSsl : options.addSsl
? options.addSsl.scheme ? options.addSsl.scheme
: options.scheme // TODO: encode whether hostname transport is "secure"? : options.scheme // TODO: encode whether hostname transport is "secure"?
return `${scheme ? `${scheme}//` : ""}${ return `${scheme ? `${scheme}//` : ""}${
username ? `${username}@` : "" username ? `${username}@` : ""
}${host}${suffix}` }${host}${suffix}`

View File

@@ -7,7 +7,7 @@ import "./deepEqual"
import "./deepMerge" import "./deepMerge"
import "./Overlay" import "./Overlay"
import "./once" import "./once"
import { utils } from "./utils" import * as utils from "./utils"
import { SDKManifest } from "../manifest/ManifestTypes" import { SDKManifest } from "../manifest/ManifestTypes"
// prettier-ignore // prettier-ignore
@@ -23,7 +23,7 @@ export const isKnownError = (e: unknown): e is T.KnownError =>
declare const affine: unique symbol declare const affine: unique symbol
export const createUtils = utils export const createUtils = utils.createUtils
export const createMainUtils = <Manifest extends SDKManifest, Store>( export const createMainUtils = <Manifest extends SDKManifest, Store>(
effects: T.Effects, effects: T.Effects,
) => createUtils<Manifest, Store, {}>(effects) ) => createUtils<Manifest, Store, {}>(effects)

View File

@@ -141,7 +141,7 @@ export type Utils<
) => Promise<void> ) => Promise<void>
} }
} }
export const utils = < export const createUtils = <
Manifest extends SDKManifest, Manifest extends SDKManifest,
Store = never, Store = never,
WrapperOverWrite = { const: never }, WrapperOverWrite = { const: never },

View File

@@ -1,15 +1,10 @@
{ {
"include": [ "include": ["./lib/**/*.ts", "scripts/oldSpecToBuilder.ts"],
"./lib/**/*.ts", "inputs": ["./lib/index.ts"],
"scripts/oldSpecToBuilder.ts"
],
"inputs": [
"./lib/index.ts"
],
"compilerOptions": { "compilerOptions": {
"target": "es2022", "target": "es2022",
"module": "es2022", "module": "Node16",
"moduleResolution": "node", "moduleResolution": "Node16",
"declaration": true, "declaration": true,
"outDir": "./dist/", "outDir": "./dist/",
"esModuleInterop": true, "esModuleInterop": true,