feat(doctor): add repair/force flows
This commit is contained in:
@@ -167,10 +167,31 @@ export async function maybeRepairGatewayServiceConfig(
|
||||
"Gateway service config",
|
||||
);
|
||||
|
||||
const repair = await prompter.confirmSkipInNonInteractive({
|
||||
message: "Update gateway service config to the recommended defaults now?",
|
||||
initialValue: true,
|
||||
});
|
||||
const aggressiveIssues = audit.issues.filter(
|
||||
(issue) => issue.level === "aggressive",
|
||||
);
|
||||
const recommendedIssues = audit.issues.filter(
|
||||
(issue) => issue.level !== "aggressive",
|
||||
);
|
||||
const needsAggressive = aggressiveIssues.length > 0;
|
||||
|
||||
if (needsAggressive && !prompter.shouldForce) {
|
||||
note(
|
||||
"Custom or unexpected service edits detected. Rerun with --force to overwrite.",
|
||||
"Gateway service config",
|
||||
);
|
||||
}
|
||||
|
||||
const repair = needsAggressive
|
||||
? await prompter.confirmAggressive({
|
||||
message:
|
||||
"Overwrite gateway service config with current defaults now?",
|
||||
initialValue: Boolean(prompter.shouldForce),
|
||||
})
|
||||
: await prompter.confirmRepair({
|
||||
message: "Update gateway service config to the recommended defaults now?",
|
||||
initialValue: true,
|
||||
});
|
||||
if (!repair) return;
|
||||
|
||||
const devMode =
|
||||
|
||||
@@ -8,14 +8,20 @@ export type DoctorOptions = {
|
||||
yes?: boolean;
|
||||
nonInteractive?: boolean;
|
||||
deep?: boolean;
|
||||
repair?: boolean;
|
||||
force?: boolean;
|
||||
};
|
||||
|
||||
export type DoctorPrompter = {
|
||||
confirm: (params: Parameters<typeof confirm>[0]) => Promise<boolean>;
|
||||
confirmRepair: (params: Parameters<typeof confirm>[0]) => Promise<boolean>;
|
||||
confirmAggressive: (params: Parameters<typeof confirm>[0]) => Promise<boolean>;
|
||||
confirmSkipInNonInteractive: (
|
||||
params: Parameters<typeof confirm>[0],
|
||||
) => Promise<boolean>;
|
||||
select: <T>(params: Parameters<typeof select>[0], fallback: T) => Promise<T>;
|
||||
shouldRepair: boolean;
|
||||
shouldForce: boolean;
|
||||
};
|
||||
|
||||
export function createDoctorPrompter(params: {
|
||||
@@ -24,24 +30,42 @@ export function createDoctorPrompter(params: {
|
||||
}): DoctorPrompter {
|
||||
const yes = params.options.yes === true;
|
||||
const requestedNonInteractive = params.options.nonInteractive === true;
|
||||
const shouldRepair = params.options.repair === true || yes;
|
||||
const shouldForce = params.options.force === true;
|
||||
const isTty = Boolean(process.stdin.isTTY);
|
||||
const nonInteractive = requestedNonInteractive || (!isTty && !yes);
|
||||
|
||||
const canPrompt = isTty && !yes && !nonInteractive;
|
||||
const confirmDefault = async (p: Parameters<typeof confirm>[0]) => {
|
||||
if (nonInteractive) return false;
|
||||
if (shouldRepair) return true;
|
||||
if (!canPrompt) return Boolean(p.initialValue ?? false);
|
||||
return guardCancel(await confirm(p), params.runtime) === true;
|
||||
};
|
||||
|
||||
return {
|
||||
confirm: confirmDefault,
|
||||
confirmSkipInNonInteractive: async (p) => {
|
||||
confirmRepair: async (p) => {
|
||||
if (nonInteractive) return false;
|
||||
return confirmDefault(p);
|
||||
},
|
||||
confirmAggressive: async (p) => {
|
||||
if (nonInteractive) return false;
|
||||
if (shouldRepair && shouldForce) return true;
|
||||
if (shouldRepair && !shouldForce) return false;
|
||||
if (!canPrompt) return Boolean(p.initialValue ?? false);
|
||||
return guardCancel(await confirm(p), params.runtime) === true;
|
||||
},
|
||||
confirmSkipInNonInteractive: async (p) => {
|
||||
if (nonInteractive) return false;
|
||||
if (shouldRepair) return true;
|
||||
return confirmDefault(p);
|
||||
},
|
||||
select: async <T>(p: Parameters<typeof select>[0], fallback: T) => {
|
||||
if (!canPrompt) return fallback;
|
||||
if (!canPrompt || shouldRepair) return fallback;
|
||||
return guardCancel(await select(p), params.runtime) as T;
|
||||
},
|
||||
shouldRepair,
|
||||
shouldForce,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user