feat: Complain on the volume that doesn't exist, remove unique set of Name, Manifest, Volume

This commit is contained in:
BluJ
2023-05-11 11:18:20 -06:00
parent df2ca832c5
commit c7feab7747
3 changed files with 47 additions and 48 deletions

View File

@@ -1,4 +1,5 @@
import { Effects } from "../types" import { Effects } from "../types"
import { _ } from "../util"
import { import {
Path, Path,
ManifestId, ManifestId,
@@ -7,11 +8,12 @@ import {
matchPath, matchPath,
} from "./setupDependencyMounts" } from "./setupDependencyMounts"
export type MountDependenciesOut<A> = export type MountDependenciesOut<A> = _<
// prettier-ignore // prettier-ignore
A extends Path ? string : A extends Record<string, unknown> ? { A extends Path ? string : A extends Record<string, unknown> ? {
[P in keyof A]: MountDependenciesOut<A[P]>; [P in keyof A]: MountDependenciesOut<A[P]>;
} : never } : never
>
export async function mountDependencies< export async function mountDependencies<
In extends In extends
| Record<ManifestId, Record<VolumeName, Record<NamedPath, Path>>> | Record<ManifestId, Record<VolumeName, Record<NamedPath, Path>>>
@@ -20,14 +22,14 @@ export async function mountDependencies<
| Path, | Path,
>(effects: Effects, value: In): Promise<MountDependenciesOut<In>> { >(effects: Effects, value: In): Promise<MountDependenciesOut<In>> {
if (matchPath.test(value)) { 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({ return (await effects.mount({
location: { location: {
path: mountPath, path: mountPath,
}, },
target: { target: {
packageId: value.manifest.id, packageId: value.manifestId,
path: value.path, path: value.path,
readonly: value.readonly, readonly: value.readonly,
volumeId: value.volume, volumeId: value.volume,

View File

@@ -10,23 +10,22 @@ export const matchPath = object({
name: string, name: string,
volume: string, volume: string,
path: string, path: string,
manifest: object({ manifestId: string,
id: string,
}),
readonly: boolean, readonly: boolean,
}) })
export type Path = typeof matchPath._TYPE export type Path = typeof matchPath._TYPE
export type BuildPath<M extends Path> = { export type BuildPath<
[PId in M["manifest"]["id"]]: { ManifestId extends string,
[V in M["volume"]]: { VolumeId extends string,
[N in M["name"]]: M 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<M> ? never : M
class SetupDependencyMounts<Building> { class SetupDependencyMounts<Building> {
private constructor(readonly building: Building) {} private constructor(readonly building: Building) {}
@@ -35,29 +34,32 @@ class SetupDependencyMounts<Building> {
} }
addPath< addPath<
NamedPath extends string, Name extends string,
VolumeName extends string, Volume extends keyof M["volumes"] & string,
PathNamed extends string, Path extends string,
ManifestId extends M["id"],
M extends SDKManifest, M extends SDKManifest,
>( >(addPath: {
newPath: ValidIfNotInNested< name: Name
Building, volume: Volume
{ path: Path
name: NamedPath manifest: M
volume: VolumeName readonly: boolean
path: PathNamed }) {
manifest: M const { manifest, ...restPath } = addPath
readonly: boolean const newPath = {
} ...restPath,
>, manifestId: manifest.id as ManifestId,
) { } as const
type NewBuilding = Building &
BuildPath<ManifestId, Volume, Name, typeof newPath>
const building = deepMerge(this.building, { const building = deepMerge(this.building, {
[newPath.manifest.id]: { [newPath.manifestId]: {
[newPath.volume]: { [newPath.volume]: {
[newPath.name]: newPath, [newPath.name]: newPath,
}, },
}, },
}) as Building & BuildPath<typeof newPath> }) as NewBuilding
return new SetupDependencyMounts(building) return new SetupDependencyMounts(building)
} }
build() { build() {

View File

@@ -61,7 +61,9 @@ describe("mountDependencies", () => {
license: "", license: "",
}, },
containers: {}, containers: {},
volumes: {}, volumes: {
main2: "data",
},
alerts: { alerts: {
install: null, install: null,
update: null, update: null,
@@ -73,21 +75,6 @@ describe("mountDependencies", () => {
dependencies: {}, dependencies: {},
}) })
clnManifest.id 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", () => { test("Types work", () => {
const dependencyMounts = setupDependencyMounts() const dependencyMounts = setupDependencyMounts()
@@ -101,6 +88,14 @@ describe("mountDependencies", () => {
.addPath({ .addPath({
name: "root", name: "root",
manifest: lndManifest, 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", volume: "main",
path: "/", path: "/",
readonly: true, readonly: true,
@@ -117,7 +112,7 @@ describe("mountDependencies", () => {
} }
} }
lnd: { lnd: {
main: { main2: {
root: string root: string
} }
} }