fix(hosts): validate suppressed resolver names

This commit is contained in:
t
2026-07-14 12:56:10 -07:00
parent 0b869898ed
commit 239d73afc4
3 changed files with 45 additions and 5 deletions
+2 -1
View File
@@ -15,6 +15,7 @@
import { ALL_HOST_CONFIGS, getHostConfig, ALL_HOST_NAMES } from '../hosts/index';
import { validateAllConfigs } from './host-config';
import { RESOLVERS } from './resolvers';
import { execSync } from 'child_process';
const CLI_REGEX = /^[a-z][a-z0-9_-]*$/;
@@ -82,7 +83,7 @@ switch (command) {
}
case 'validate': {
const errors = validateAllConfigs(ALL_HOST_CONFIGS);
const errors = validateAllConfigs(ALL_HOST_CONFIGS, new Set(Object.keys(RESOLVERS)));
if (errors.length > 0) {
for (const error of errors) {
console.error(`ERROR: ${error}`);
+15 -3
View File
@@ -117,7 +117,7 @@ const NAME_REGEX = /^[a-z][a-z0-9-]*$/;
const PATH_REGEX = /^[a-zA-Z0-9_.\/${}~-]+$/;
const CLI_REGEX = /^[a-z][a-z0-9_-]*$/;
export function validateHostConfig(config: HostConfig): string[] {
export function validateHostConfig(config: HostConfig, validResolverNames?: ReadonlySet<string>): string[] {
const errors: string[] = [];
if (!NAME_REGEX.test(config.name)) {
@@ -152,15 +152,27 @@ export function validateHostConfig(config: HostConfig): string[] {
errors.push(`install.linkingStrategy must be 'real-dir-symlink' or 'symlink-generated'`);
}
// Cross-check suppressedResolvers against the known resolver names (injected to avoid a
// circular import on the resolver registry). A typo would otherwise silently no-op: the
// generator short-circuits suppressed names before the "unknown placeholder" throw, so an
// unknown entry never surfaces at generation time either.
if (validResolverNames && config.suppressedResolvers) {
for (const name of config.suppressedResolvers) {
if (!validResolverNames.has(name)) {
errors.push(`suppressedResolvers entry '${name}' is not a known resolver`);
}
}
}
return errors;
}
export function validateAllConfigs(configs: HostConfig[]): string[] {
export function validateAllConfigs(configs: HostConfig[], validResolverNames?: ReadonlySet<string>): string[] {
const errors: string[] = [];
// Per-config validation
for (const config of configs) {
const configErrors = validateHostConfig(config);
const configErrors = validateHostConfig(config, validResolverNames);
errors.push(...configErrors.map(e => `[${config.name}] ${e}`));
}