mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-13 19:10:39 +00:00
222 lines
5.9 KiB
TypeScript
222 lines
5.9 KiB
TypeScript
export type Requirements = {
|
|
bins: string[];
|
|
anyBins: string[];
|
|
env: string[];
|
|
config: string[];
|
|
os: string[];
|
|
};
|
|
|
|
export type RequirementConfigCheck = {
|
|
path: string;
|
|
satisfied: boolean;
|
|
};
|
|
|
|
export type RequirementsMetadata = {
|
|
requires?: Partial<Pick<Requirements, "bins" | "anyBins" | "env" | "config">>;
|
|
os?: string[];
|
|
};
|
|
|
|
export type RequirementRemote = {
|
|
hasBin?: (bin: string) => boolean;
|
|
hasAnyBin?: (bins: string[]) => boolean;
|
|
platforms?: string[];
|
|
};
|
|
|
|
type RequirementsEvaluationContext = {
|
|
always: boolean;
|
|
hasLocalBin: (bin: string) => boolean;
|
|
localPlatform: string;
|
|
isEnvSatisfied: (envName: string) => boolean;
|
|
isConfigSatisfied: (pathStr: string) => boolean;
|
|
};
|
|
|
|
type RequirementsEvaluationRemoteContext = {
|
|
hasRemoteBin?: (bin: string) => boolean;
|
|
hasRemoteAnyBin?: (bins: string[]) => boolean;
|
|
remotePlatforms?: string[];
|
|
};
|
|
|
|
export function resolveMissingBins(params: {
|
|
required: string[];
|
|
hasLocalBin: (bin: string) => boolean;
|
|
hasRemoteBin?: (bin: string) => boolean;
|
|
}): string[] {
|
|
const remote = params.hasRemoteBin;
|
|
return params.required.filter((bin) => {
|
|
if (params.hasLocalBin(bin)) {
|
|
return false;
|
|
}
|
|
if (remote?.(bin)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
export function resolveMissingAnyBins(params: {
|
|
required: string[];
|
|
hasLocalBin: (bin: string) => boolean;
|
|
hasRemoteAnyBin?: (bins: string[]) => boolean;
|
|
}): string[] {
|
|
if (params.required.length === 0) {
|
|
return [];
|
|
}
|
|
if (params.required.some((bin) => params.hasLocalBin(bin))) {
|
|
return [];
|
|
}
|
|
if (params.hasRemoteAnyBin?.(params.required)) {
|
|
return [];
|
|
}
|
|
return params.required;
|
|
}
|
|
|
|
export function resolveMissingOs(params: {
|
|
required: string[];
|
|
localPlatform: string;
|
|
remotePlatforms?: string[];
|
|
}): string[] {
|
|
if (params.required.length === 0) {
|
|
return [];
|
|
}
|
|
if (params.required.includes(params.localPlatform)) {
|
|
return [];
|
|
}
|
|
if (params.remotePlatforms?.some((platform) => params.required.includes(platform))) {
|
|
return [];
|
|
}
|
|
return params.required;
|
|
}
|
|
|
|
export function resolveMissingEnv(params: {
|
|
required: string[];
|
|
isSatisfied: (envName: string) => boolean;
|
|
}): string[] {
|
|
const missing: string[] = [];
|
|
for (const envName of params.required) {
|
|
if (params.isSatisfied(envName)) {
|
|
continue;
|
|
}
|
|
missing.push(envName);
|
|
}
|
|
return missing;
|
|
}
|
|
|
|
export function buildConfigChecks(params: {
|
|
required: string[];
|
|
isSatisfied: (pathStr: string) => boolean;
|
|
}): RequirementConfigCheck[] {
|
|
return params.required.map((pathStr) => {
|
|
const satisfied = params.isSatisfied(pathStr);
|
|
return { path: pathStr, satisfied };
|
|
});
|
|
}
|
|
|
|
export function evaluateRequirements(
|
|
params: RequirementsEvaluationContext &
|
|
RequirementsEvaluationRemoteContext & {
|
|
required: Requirements;
|
|
},
|
|
): { missing: Requirements; eligible: boolean; configChecks: RequirementConfigCheck[] } {
|
|
const missingBins = resolveMissingBins({
|
|
required: params.required.bins,
|
|
hasLocalBin: params.hasLocalBin,
|
|
hasRemoteBin: params.hasRemoteBin,
|
|
});
|
|
const missingAnyBins = resolveMissingAnyBins({
|
|
required: params.required.anyBins,
|
|
hasLocalBin: params.hasLocalBin,
|
|
hasRemoteAnyBin: params.hasRemoteAnyBin,
|
|
});
|
|
const missingOs = resolveMissingOs({
|
|
required: params.required.os,
|
|
localPlatform: params.localPlatform,
|
|
remotePlatforms: params.remotePlatforms,
|
|
});
|
|
const missingEnv = resolveMissingEnv({
|
|
required: params.required.env,
|
|
isSatisfied: params.isEnvSatisfied,
|
|
});
|
|
const configChecks = buildConfigChecks({
|
|
required: params.required.config,
|
|
isSatisfied: params.isConfigSatisfied,
|
|
});
|
|
const missingConfig = configChecks.filter((check) => !check.satisfied).map((check) => check.path);
|
|
|
|
const missing = params.always
|
|
? { bins: [], anyBins: [], env: [], config: [], os: [] }
|
|
: {
|
|
bins: missingBins,
|
|
anyBins: missingAnyBins,
|
|
env: missingEnv,
|
|
config: missingConfig,
|
|
os: missingOs,
|
|
};
|
|
|
|
const eligible =
|
|
params.always ||
|
|
(missing.bins.length === 0 &&
|
|
missing.anyBins.length === 0 &&
|
|
missing.env.length === 0 &&
|
|
missing.config.length === 0 &&
|
|
missing.os.length === 0);
|
|
|
|
return { missing, eligible, configChecks };
|
|
}
|
|
|
|
export function evaluateRequirementsFromMetadata(
|
|
params: RequirementsEvaluationContext &
|
|
RequirementsEvaluationRemoteContext & {
|
|
metadata?: RequirementsMetadata;
|
|
},
|
|
): {
|
|
required: Requirements;
|
|
missing: Requirements;
|
|
eligible: boolean;
|
|
configChecks: RequirementConfigCheck[];
|
|
} {
|
|
const required: Requirements = {
|
|
bins: params.metadata?.requires?.bins ?? [],
|
|
anyBins: params.metadata?.requires?.anyBins ?? [],
|
|
env: params.metadata?.requires?.env ?? [],
|
|
config: params.metadata?.requires?.config ?? [],
|
|
os: params.metadata?.os ?? [],
|
|
};
|
|
|
|
const result = evaluateRequirements({
|
|
always: params.always,
|
|
required,
|
|
hasLocalBin: params.hasLocalBin,
|
|
hasRemoteBin: params.hasRemoteBin,
|
|
hasRemoteAnyBin: params.hasRemoteAnyBin,
|
|
localPlatform: params.localPlatform,
|
|
remotePlatforms: params.remotePlatforms,
|
|
isEnvSatisfied: params.isEnvSatisfied,
|
|
isConfigSatisfied: params.isConfigSatisfied,
|
|
});
|
|
return { required, ...result };
|
|
}
|
|
|
|
export function evaluateRequirementsFromMetadataWithRemote(
|
|
params: RequirementsEvaluationContext & {
|
|
metadata?: RequirementsMetadata;
|
|
remote?: RequirementRemote;
|
|
},
|
|
): {
|
|
required: Requirements;
|
|
missing: Requirements;
|
|
eligible: boolean;
|
|
configChecks: RequirementConfigCheck[];
|
|
} {
|
|
return evaluateRequirementsFromMetadata({
|
|
always: params.always,
|
|
metadata: params.metadata,
|
|
hasLocalBin: params.hasLocalBin,
|
|
hasRemoteBin: params.remote?.hasBin,
|
|
hasRemoteAnyBin: params.remote?.hasAnyBin,
|
|
localPlatform: params.localPlatform,
|
|
remotePlatforms: params.remote?.platforms,
|
|
isEnvSatisfied: params.isEnvSatisfied,
|
|
isConfigSatisfied: params.isConfigSatisfied,
|
|
});
|
|
}
|