Fix StartOS 0.4 TypeScript packaging to match SDK API

This commit is contained in:
MacPro
2026-04-09 15:10:44 -05:00
parent d5046a0daf
commit 0b70cbb2bf
3436 changed files with 867051 additions and 92 deletions
@@ -0,0 +1,21 @@
import { PackageId, HealthCheckId, DependencyRequirement, CheckDependenciesResult } from '../types';
import { Effects } from '../Effects';
export type CheckDependencies<DependencyId extends PackageId = PackageId> = {
infoFor: (packageId: DependencyId) => {
requirement: DependencyRequirement;
result: CheckDependenciesResult;
};
installedSatisfied: (packageId: DependencyId) => boolean;
installedVersionSatisfied: (packageId: DependencyId) => boolean;
runningSatisfied: (packageId: DependencyId) => boolean;
tasksSatisfied: (packageId: DependencyId) => boolean;
healthCheckSatisfied: (packageId: DependencyId, healthCheckId: HealthCheckId) => boolean;
satisfied: () => boolean;
throwIfInstalledNotSatisfied: (packageId: DependencyId) => null;
throwIfInstalledVersionNotSatisfied: (packageId: DependencyId) => null;
throwIfRunningNotSatisfied: (packageId: DependencyId) => null;
throwIfTasksNotSatisfied: (packageId: DependencyId) => null;
throwIfHealthNotSatisfied: (packageId: DependencyId, healthCheckId?: HealthCheckId) => null;
throwIfNotSatisfied: (packageId?: DependencyId) => null;
};
export declare function checkDependencies<DependencyId extends PackageId = PackageId>(effects: Effects, packageIds?: DependencyId[]): Promise<CheckDependencies<DependencyId>>;
@@ -0,0 +1,156 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkDependencies = checkDependencies;
const exver_1 = require("../exver");
async function checkDependencies(effects, packageIds) {
let [dependencies, results] = await Promise.all([
effects.getDependencies(),
effects.checkDependencies({
packageIds,
}),
]);
if (packageIds) {
dependencies = dependencies.filter((d) => packageIds.includes(d.id));
}
const infoFor = (packageId) => {
const dependencyRequirement = dependencies.find((d) => d.id === packageId);
const dependencyResult = results.find((d) => d.packageId === packageId);
if (!dependencyRequirement || !dependencyResult) {
throw new Error(`Unknown DependencyId ${packageId}`);
}
return { requirement: dependencyRequirement, result: dependencyResult };
};
const installedSatisfied = (packageId) => !!infoFor(packageId).result.installedVersion;
const installedVersionSatisfied = (packageId) => {
const dep = infoFor(packageId);
return (!!dep.result.installedVersion &&
exver_1.ExtendedVersion.parse(dep.result.installedVersion).satisfies(exver_1.VersionRange.parse(dep.requirement.versionRange)));
};
const runningSatisfied = (packageId) => {
const dep = infoFor(packageId);
return dep.requirement.kind !== 'running' || dep.result.isRunning;
};
const tasksSatisfied = (packageId) => Object.entries(infoFor(packageId).result.tasks).filter(([_, t]) => t?.active && t.task.severity === 'critical').length === 0;
const healthCheckSatisfied = (packageId, healthCheckId) => {
const dep = infoFor(packageId);
if (healthCheckId &&
(dep.requirement.kind !== 'running' ||
!dep.requirement.healthChecks.includes(healthCheckId))) {
throw new Error(`Unknown HealthCheckId ${healthCheckId}`);
}
const errors = dep.requirement.kind === 'running'
? dep.requirement.healthChecks
.map((id) => [id, dep.result.healthChecks[id] ?? null])
.filter(([id, _]) => (healthCheckId ? id === healthCheckId : true))
.filter(([_, res]) => res?.result !== 'success')
: [];
return errors.length === 0;
};
const pkgSatisfied = (packageId) => installedSatisfied(packageId) &&
installedVersionSatisfied(packageId) &&
runningSatisfied(packageId) &&
tasksSatisfied(packageId) &&
healthCheckSatisfied(packageId);
const satisfied = (packageId) => packageId
? pkgSatisfied(packageId)
: dependencies.every((d) => pkgSatisfied(d.id));
const throwIfInstalledNotSatisfied = (packageId) => {
const dep = infoFor(packageId);
if (!dep.result.installedVersion) {
throw new Error(`${dep.result.title || packageId} is not installed`);
}
return null;
};
const throwIfInstalledVersionNotSatisfied = (packageId) => {
const dep = infoFor(packageId);
if (!dep.result.installedVersion) {
throw new Error(`${dep.result.title || packageId} is not installed`);
}
if (![dep.result.installedVersion, ...dep.result.satisfies].find((v) => exver_1.ExtendedVersion.parse(v).satisfies(exver_1.VersionRange.parse(dep.requirement.versionRange)))) {
throw new Error(`Installed version ${dep.result.installedVersion} of ${dep.result.title || packageId} does not match expected version range ${dep.requirement.versionRange}`);
}
return null;
};
const throwIfRunningNotSatisfied = (packageId) => {
const dep = infoFor(packageId);
if (dep.requirement.kind === 'running' && !dep.result.isRunning) {
throw new Error(`${dep.result.title || packageId} is not running`);
}
return null;
};
const throwIfTasksNotSatisfied = (packageId) => {
const dep = infoFor(packageId);
const reqs = Object.entries(dep.result.tasks)
.filter(([_, t]) => t?.active && t.task.severity === 'critical')
.map(([id, _]) => id);
if (reqs.length) {
throw new Error(`The following action requests have not been fulfilled: ${reqs.join(', ')}`);
}
return null;
};
const throwIfHealthNotSatisfied = (packageId, healthCheckId) => {
const dep = infoFor(packageId);
if (healthCheckId &&
(dep.requirement.kind !== 'running' ||
!dep.requirement.healthChecks.includes(healthCheckId))) {
throw new Error(`Unknown HealthCheckId ${healthCheckId}`);
}
const errors = dep.requirement.kind === 'running'
? dep.requirement.healthChecks
.map((id) => [id, dep.result.healthChecks[id] ?? null])
.filter(([id, _]) => (healthCheckId ? id === healthCheckId : true))
.filter(([_, res]) => res?.result !== 'success')
: [];
if (errors.length) {
throw new Error(errors
.map(([id, e]) => e
? `Health Check ${e.name} of ${dep.result.title || packageId} failed with status ${e.result}${e.message ? `: ${e.message}` : ''}`
: `Health Check ${id} of ${dep.result.title} does not exist`)
.join('; '));
}
return null;
};
const throwIfPkgNotSatisfied = (packageId) => {
throwIfInstalledNotSatisfied(packageId);
throwIfInstalledVersionNotSatisfied(packageId);
throwIfRunningNotSatisfied(packageId);
throwIfTasksNotSatisfied(packageId);
throwIfHealthNotSatisfied(packageId);
return null;
};
const throwIfNotSatisfied = (packageId) => packageId
? throwIfPkgNotSatisfied(packageId)
: (() => {
const err = dependencies.flatMap((d) => {
try {
throwIfPkgNotSatisfied(d.id);
}
catch (e) {
if (e instanceof Error)
return [e.message];
throw e;
}
return [];
});
if (err.length) {
throw new Error(err.join('; '));
}
return null;
})();
return {
infoFor,
installedSatisfied,
installedVersionSatisfied,
runningSatisfied,
tasksSatisfied,
healthCheckSatisfied,
satisfied,
throwIfInstalledNotSatisfied,
throwIfInstalledVersionNotSatisfied,
throwIfRunningNotSatisfied,
throwIfTasksNotSatisfied,
throwIfHealthNotSatisfied,
throwIfNotSatisfied,
};
}
//# sourceMappingURL=dependencies.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
import * as T from '../types';
export type RequiredDependenciesOf<Manifest extends T.SDKManifest> = {
[K in keyof Manifest['dependencies']]: Exclude<Manifest['dependencies'][K], undefined>['optional'] extends false ? K : never;
}[keyof Manifest['dependencies']];
export type OptionalDependenciesOf<Manifest extends T.SDKManifest> = Exclude<keyof Manifest['dependencies'], RequiredDependenciesOf<Manifest>>;
type DependencyRequirement = {
kind: 'running';
healthChecks: Array<T.HealthCheckId>;
versionRange: string;
} | {
kind: 'exists';
versionRange: string;
};
export type CurrentDependenciesResult<Manifest extends T.SDKManifest> = {
[K in RequiredDependenciesOf<Manifest>]: DependencyRequirement;
} & {
[K in OptionalDependenciesOf<Manifest>]?: DependencyRequirement;
};
export declare function setupDependencies<Manifest extends T.SDKManifest>(fn: (options: {
effects: T.Effects;
}) => Promise<CurrentDependenciesResult<Manifest>>): (effects: T.Effects) => Promise<null>;
export {};
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupDependencies = setupDependencies;
const _checkType = null;
function setupDependencies(fn) {
return async (effects) => {
const dependencyType = await fn({ effects });
return await effects.setDependencies({
dependencies: Object.entries(dependencyType)
.map(([k, v]) => [k, v])
.map(([id, { versionRange, ...x }]) => ({
id,
...x,
versionRange: versionRange.toString(),
})),
});
};
}
//# sourceMappingURL=setupDependencies.js.map
@@ -0,0 +1 @@
{"version":3,"file":"setupDependencies.js","sourceRoot":"","sources":["../../../../base/lib/dependencies/setupDependencies.ts"],"names":[],"mappings":";;AAsCA,8CAoBC;AA/BD,MAAM,UAAU,GAGZ,IAAI,CAAA;AAQR,SAAgB,iBAAiB,CAC/B,EAEkD;IAElD,OAAO,KAAK,EAAE,OAAkB,EAAE,EAAE;QAClC,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QAC5C,OAAO,MAAM,OAAO,CAAC,eAAe,CAAC;YACnC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAA0B,CAAU,CAAC;iBACzD,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAC/B,CAAC;gBACC,EAAE;gBACF,GAAG,CAAC;gBACJ,YAAY,EAAE,YAAY,CAAC,QAAQ,EAAE;aACtC,CAA4B,CAChC;SACJ,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}