mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 10:21:55 +00:00
feat: Complain on the volume that doesn't exist, remove unique set of Name, Manifest, Volume
This commit is contained in:
@@ -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<A> =
|
||||
export type MountDependenciesOut<A> = _<
|
||||
// prettier-ignore
|
||||
A extends Path ? string : A extends Record<string, unknown> ? {
|
||||
[P in keyof A]: MountDependenciesOut<A[P]>;
|
||||
} : never
|
||||
>
|
||||
export async function mountDependencies<
|
||||
In extends
|
||||
| Record<ManifestId, Record<VolumeName, Record<NamedPath, Path>>>
|
||||
@@ -20,14 +22,14 @@ export async function mountDependencies<
|
||||
| Path,
|
||||
>(effects: Effects, value: In): Promise<MountDependenciesOut<In>> {
|
||||
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,
|
||||
|
||||
@@ -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<M extends Path> = {
|
||||
[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<M> ? never : M
|
||||
class SetupDependencyMounts<Building> {
|
||||
private constructor(readonly building: Building) {}
|
||||
|
||||
@@ -35,29 +34,32 @@ class SetupDependencyMounts<Building> {
|
||||
}
|
||||
|
||||
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<ManifestId, Volume, Name, typeof newPath>
|
||||
const building = deepMerge(this.building, {
|
||||
[newPath.manifest.id]: {
|
||||
[newPath.manifestId]: {
|
||||
[newPath.volume]: {
|
||||
[newPath.name]: newPath,
|
||||
},
|
||||
},
|
||||
}) as Building & BuildPath<typeof newPath>
|
||||
}) as NewBuilding
|
||||
return new SetupDependencyMounts(building)
|
||||
}
|
||||
build() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user