diff --git a/lib/dependency/mountDependencies.ts b/lib/dependency/mountDependencies.ts index 4721d26..de22932 100644 --- a/lib/dependency/mountDependencies.ts +++ b/lib/dependency/mountDependencies.ts @@ -1,4 +1,5 @@ import { Effects } from "../types" +import { _ } from "../util" import { Path, ManifestId, @@ -7,11 +8,12 @@ import { matchPath, } from "./setupDependencyMounts" -export type MountDependenciesOut = +export type MountDependenciesOut = _< // prettier-ignore A extends Path ? string : A extends Record ? { [P in keyof A]: MountDependenciesOut; } : never +> export async function mountDependencies< In extends | Record>> @@ -20,14 +22,14 @@ export async function mountDependencies< | Path, >(effects: Effects, value: In): Promise> { if (matchPath.test(value)) { - const mountPath = `${value.manifest.id}/${value.volume}/${value.name}` + const mountPath = `${value.manifestId}/${value.volume}/${value.name}` return (await effects.mount({ location: { path: mountPath, }, target: { - packageId: value.manifest.id, + packageId: value.manifestId, path: value.path, readonly: value.readonly, volumeId: value.volume, diff --git a/lib/dependency/setupDependencyMounts.ts b/lib/dependency/setupDependencyMounts.ts index e3c8cdd..f867b13 100644 --- a/lib/dependency/setupDependencyMounts.ts +++ b/lib/dependency/setupDependencyMounts.ts @@ -10,23 +10,22 @@ export const matchPath = object({ name: string, volume: string, path: string, - manifest: object({ - id: string, - }), + manifestId: string, readonly: boolean, }) export type Path = typeof matchPath._TYPE -export type BuildPath = { - [PId in M["manifest"]["id"]]: { - [V in M["volume"]]: { - [N in M["name"]]: M +export type BuildPath< + ManifestId extends string, + VolumeId extends string, + PathName extends string, + Value extends Path, +> = { + [PId in ManifestId]: { + [V in VolumeId]: { + [N in PathName]: Value } } } -type ValidIfNotInNested< - Building, - M extends Path, -> = Building extends BuildPath ? never : M class SetupDependencyMounts { private constructor(readonly building: Building) {} @@ -35,29 +34,32 @@ class SetupDependencyMounts { } addPath< - NamedPath extends string, - VolumeName extends string, - PathNamed extends string, + Name extends string, + Volume extends keyof M["volumes"] & string, + Path extends string, + ManifestId extends M["id"], M extends SDKManifest, - >( - newPath: ValidIfNotInNested< - Building, - { - name: NamedPath - volume: VolumeName - path: PathNamed - manifest: M - readonly: boolean - } - >, - ) { + >(addPath: { + name: Name + volume: Volume + path: Path + manifest: M + readonly: boolean + }) { + const { manifest, ...restPath } = addPath + const newPath = { + ...restPath, + manifestId: manifest.id as ManifestId, + } as const + type NewBuilding = Building & + BuildPath const building = deepMerge(this.building, { - [newPath.manifest.id]: { + [newPath.manifestId]: { [newPath.volume]: { [newPath.name]: newPath, }, }, - }) as Building & BuildPath + }) as NewBuilding return new SetupDependencyMounts(building) } build() { diff --git a/lib/test/mountDependencies.test.ts b/lib/test/mountDependencies.test.ts index c6b9e01..7c84c7e 100644 --- a/lib/test/mountDependencies.test.ts +++ b/lib/test/mountDependencies.test.ts @@ -61,7 +61,9 @@ describe("mountDependencies", () => { license: "", }, containers: {}, - volumes: {}, + volumes: { + main2: "data", + }, alerts: { install: null, update: null, @@ -73,21 +75,6 @@ describe("mountDependencies", () => { dependencies: {}, }) clnManifest.id - type test = BuildPath<{ - name: "root" - manifest: typeof clnManifest - volume: "main" - path: "/" - readonly: true - }> extends BuildPath<{ - name: "root" - manifest: typeof clnManifest - volume: "main2" - path: "/" - readonly: true - }> - ? true - : false test("Types work", () => { const dependencyMounts = setupDependencyMounts() @@ -101,6 +88,14 @@ describe("mountDependencies", () => { .addPath({ name: "root", manifest: lndManifest, + volume: "main2", + path: "/", + readonly: true, + }) + .addPath({ + name: "root", + manifest: lndManifest, + // @ts-expect-error Expect that main will throw because it is not in the thing volume: "main", path: "/", readonly: true, @@ -117,7 +112,7 @@ describe("mountDependencies", () => { } } lnd: { - main: { + main2: { root: string } }