Files
start-os/sdk/lib/dependencies/dependencies.ts
Jade 8a38666105 Feature/sdk040dependencies (#2609)
* update registry upload to take id for new admin permissions (#2605)

* wip

* wip: Get the get dependencies

* wip check_dependencies

* wip: Get the build working to the vm

* wip: Add in the last of the things that where needed for the new sdk

* Add fix

* wip: implement the changes

* wip: Fix the naming

---------

Co-authored-by: Lucy <12953208+elvece@users.noreply.github.com>
2024-04-26 17:51:33 -06:00

116 lines
3.3 KiB
TypeScript

import {
Effects,
PackageId,
DependencyRequirement,
SetHealth,
CheckDependencyResult,
} from "../types"
export type CheckAllDependencies = {
notRunning: () => Promise<CheckDependencyResult[]>
notInstalled: () => Promise<CheckDependencyResult[]>
healthErrors: () => Promise<{ [id: string]: SetHealth[] }>
throwIfNotRunning: () => Promise<void>
throwIfNotValid: () => Promise<undefined>
throwIfNotInstalled: () => Promise<void>
throwIfError: () => Promise<void>
isValid: () => Promise<boolean>
}
export function checkAllDependencies(effects: Effects): CheckAllDependencies {
const dependenciesPromise = effects.getDependencies()
const resultsPromise = dependenciesPromise.then((dependencies) =>
effects.checkDependencies({
packageIds: dependencies.map((dep) => dep.id),
}),
)
const dependenciesByIdPromise = dependenciesPromise.then((d) =>
d.reduce(
(acc, dep) => {
acc[dep.id] = dep
return acc
},
{} as { [id: PackageId]: DependencyRequirement },
),
)
const healthErrors = async () => {
const results = await resultsPromise
const dependenciesById = await dependenciesByIdPromise
const answer: { [id: PackageId]: SetHealth[] } = {}
for (const result of results) {
const dependency = dependenciesById[result.packageId]
if (!dependency) continue
if (dependency.kind !== "running") continue
const healthChecks = result.healthChecks
.filter((x) => dependency.healthChecks.includes(x.id))
.filter((x) => !!x.message)
if (healthChecks.length === 0) continue
answer[result.packageId] = healthChecks
}
return answer
}
const notInstalled = () =>
resultsPromise.then((x) => x.filter((x) => !x.isInstalled))
const notRunning = async () => {
const results = await resultsPromise
const dependenciesById = await dependenciesByIdPromise
return results.filter((x) => {
const dependency = dependenciesById[x.packageId]
if (!dependency) return false
if (dependency.kind !== "running") return false
return !x.isRunning
})
}
const entries = <B>(x: { [k: string]: B }) => Object.entries(x)
const first = <A>(x: A[]): A | undefined => x[0]
const sinkVoid = <A>(x: A) => void 0
const throwIfError = () =>
healthErrors()
.then(entries)
.then(first)
.then((x) => {
if (!x) return
const [id, healthChecks] = x
if (healthChecks.length > 0)
throw `Package ${id} has the following errors: ${healthChecks.map((x) => x.message).join(", ")}`
})
const throwIfNotRunning = () =>
notRunning().then((results) => {
if (results[0])
throw new Error(`Package ${results[0].packageId} is not running`)
})
const throwIfNotInstalled = () =>
notInstalled().then((results) => {
if (results[0])
throw new Error(`Package ${results[0].packageId} is not installed`)
})
const throwIfNotValid = async () =>
Promise.all([
throwIfNotRunning(),
throwIfNotInstalled(),
throwIfError(),
]).then(sinkVoid)
const isValid = () =>
throwIfNotValid().then(
() => true,
() => false,
)
return {
notRunning,
notInstalled,
healthErrors,
throwIfNotRunning,
throwIfNotValid,
throwIfNotInstalled,
throwIfError,
isValid,
}
}