mirror of
https://github.com/paperclipai/paperclip
synced 2026-03-25 11:21:48 +00:00
Confirm company imports after preview
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
buildSelectedFilesFromImportSelection,
|
||||
renderCompanyImportPreview,
|
||||
renderCompanyImportResult,
|
||||
resolveCompanyImportApplyConfirmationMode,
|
||||
resolveCompanyImportApiPath,
|
||||
} from "../commands/client/company.js";
|
||||
|
||||
@@ -58,6 +59,48 @@ describe("resolveCompanyImportApiPath", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveCompanyImportApplyConfirmationMode", () => {
|
||||
it("skips confirmation when --yes is set", () => {
|
||||
expect(
|
||||
resolveCompanyImportApplyConfirmationMode({
|
||||
yes: true,
|
||||
interactive: false,
|
||||
json: false,
|
||||
}),
|
||||
).toBe("skip");
|
||||
});
|
||||
|
||||
it("prompts in interactive text mode when --yes is not set", () => {
|
||||
expect(
|
||||
resolveCompanyImportApplyConfirmationMode({
|
||||
yes: false,
|
||||
interactive: true,
|
||||
json: false,
|
||||
}),
|
||||
).toBe("prompt");
|
||||
});
|
||||
|
||||
it("requires --yes for non-interactive apply", () => {
|
||||
expect(() =>
|
||||
resolveCompanyImportApplyConfirmationMode({
|
||||
yes: false,
|
||||
interactive: false,
|
||||
json: false,
|
||||
})
|
||||
).toThrow(/non-interactive terminal requires --yes/i);
|
||||
});
|
||||
|
||||
it("requires --yes for json apply", () => {
|
||||
expect(() =>
|
||||
resolveCompanyImportApplyConfirmationMode({
|
||||
yes: false,
|
||||
interactive: false,
|
||||
json: true,
|
||||
})
|
||||
).toThrow(/with --json requires --yes/i);
|
||||
});
|
||||
});
|
||||
|
||||
describe("renderCompanyImportPreview", () => {
|
||||
it("summarizes the preview with counts, selection info, and truncated examples", () => {
|
||||
const preview: CompanyPortabilityPreviewResult = {
|
||||
|
||||
@@ -704,6 +704,27 @@ export function resolveCompanyImportApiPath(input: {
|
||||
return input.dryRun ? "/api/companies/import/preview" : "/api/companies/import";
|
||||
}
|
||||
|
||||
export function resolveCompanyImportApplyConfirmationMode(input: {
|
||||
yes?: boolean;
|
||||
interactive: boolean;
|
||||
json: boolean;
|
||||
}): "skip" | "prompt" {
|
||||
if (input.yes) {
|
||||
return "skip";
|
||||
}
|
||||
if (input.json) {
|
||||
throw new Error(
|
||||
"Applying a company import with --json requires --yes. Use --dry-run first to inspect the preview.",
|
||||
);
|
||||
}
|
||||
if (!input.interactive) {
|
||||
throw new Error(
|
||||
"Applying a company import from a non-interactive terminal requires --yes. Use --dry-run first to inspect the preview.",
|
||||
);
|
||||
}
|
||||
return "prompt";
|
||||
}
|
||||
|
||||
export function isHttpUrl(input: string): boolean {
|
||||
return /^https?:\/\//i.test(input.trim());
|
||||
}
|
||||
@@ -1095,7 +1116,7 @@ export function registerCompanyCommands(program: Command): void {
|
||||
.option("--collision <mode>", "Collision strategy: rename | skip | replace", "rename")
|
||||
.option("--ref <value>", "Git ref to use for GitHub imports (branch, tag, or commit)")
|
||||
.option("--paperclip-url <url>", "Alias for --api-base on this command")
|
||||
.option("--yes", "Accept the default import selection without opening the TUI", false)
|
||||
.option("--yes", "Accept default selection and skip the pre-import confirmation prompt", false)
|
||||
.option("--dry-run", "Run preview only without applying", false)
|
||||
.action(async (fromPathOrUrl: string, opts: CompanyImportOptions) => {
|
||||
try {
|
||||
@@ -1220,6 +1241,34 @@ export function registerCompanyCommands(program: Command): void {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctx.json) {
|
||||
printCompanyImportView(
|
||||
"Import Preview",
|
||||
renderCompanyImportPreview(preview, {
|
||||
sourceLabel,
|
||||
targetLabel: formatTargetLabel(targetPayload, preview),
|
||||
infoMessages: adapterMessages,
|
||||
}),
|
||||
{ interactive: interactiveView },
|
||||
);
|
||||
}
|
||||
|
||||
const confirmationMode = resolveCompanyImportApplyConfirmationMode({
|
||||
yes: opts.yes,
|
||||
interactive: interactiveView,
|
||||
json: ctx.json,
|
||||
});
|
||||
if (confirmationMode === "prompt") {
|
||||
const confirmed = await p.confirm({
|
||||
message: "Apply this import? (y/N)",
|
||||
initialValue: false,
|
||||
});
|
||||
if (p.isCancel(confirmed) || !confirmed) {
|
||||
p.log.warn("Import cancelled.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const importApiPath = resolveCompanyImportApiPath({
|
||||
dryRun: false,
|
||||
targetMode: targetPayload.mode,
|
||||
|
||||
Reference in New Issue
Block a user