diff --git a/src/commander/uploadPdf.ts b/src/commander/uploadPdf.ts index 1ec464f..7167417 100644 --- a/src/commander/uploadPdf.ts +++ b/src/commander/uploadPdf.ts @@ -18,6 +18,9 @@ command .option('--buildName ', 'Specify the build name') .option('--markBaseline', 'Mark this build baseline') .option('--pdfNames ', 'Specify PDF names for the upload') + .option('--approvalThreshold ', 'Mismatch % at or below which every PDF in this upload is auto-approved (0-100)') + .option('--rejectionThreshold ', 'Mismatch % at or above which every PDF in this upload is auto-rejected (0-100)') + .option('--thresholds ', 'Per-PDF overrides keyed by name, inline JSON or a path to a JSON file, e.g. {"invoice.pdf":{"approval":2,"rejection":5}}') .option('--sync', 'Wait for the uploaded PDFs to be compared and return the results') .action(async function(directory, _, command) { const options = command.optsWithGlobals(); diff --git a/src/lib/ctx.ts b/src/lib/ctx.ts index 1b176e6..58065e2 100644 --- a/src/lib/ctx.ts +++ b/src/lib/ctx.ts @@ -288,6 +288,10 @@ export default (options: Record): Context => { userName: options.userName || '', accessKey: options.accessKey || '', pdfNames: options.pdfNames || '', + // kept as strings so the backend does the range/band validation and "0" survives + approvalThreshold: options.approvalThreshold || '', + rejectionThreshold: options.rejectionThreshold || '', + thresholds: options.thresholds || '', sync: options.sync ? true : false }, cliVersion: version, diff --git a/src/lib/httpClient.ts b/src/lib/httpClient.ts index bd740dd..054464b 100644 --- a/src/lib/httpClient.ts +++ b/src/lib/httpClient.ts @@ -831,6 +831,10 @@ export default class httpClient { if (snapshotUuids && snapshotUuids !== '') { form.append('snapshotUuids', snapshotUuids); } + // call-level thresholds apply to every pdf; the per-pdf map wins where it names a file + if (ctx.options.approvalThreshold) form.append('approvalThreshold', ctx.options.approvalThreshold); + if (ctx.options.rejectionThreshold) form.append('rejectionThreshold', ctx.options.rejectionThreshold); + if (ctx.options.thresholds) form.append('thresholds', ctx.options.thresholds); if (ctx.git?.branch) form.append('branch', ctx.git.branch); if (ctx.git?.commitId) form.append('commitId', ctx.git.commitId); diff --git a/src/tasks/uploadPdfs.ts b/src/tasks/uploadPdfs.ts index 072c6ed..56c2861 100644 --- a/src/tasks/uploadPdfs.ts +++ b/src/tasks/uploadPdfs.ts @@ -50,6 +50,11 @@ async function uploadPdfs(ctx: Context, pdfPath: string): Promise { const buildName = ctx.options.buildName; const pdfNames = ctx.options.pdfNames; + // --thresholds takes inline JSON or a path; either way the backend validates it against the names + if (ctx.options.thresholds && fs.existsSync(ctx.options.thresholds)) { + ctx.options.thresholds = fs.readFileSync(ctx.options.thresholds, 'utf8'); + } + // The backend names each document from pdfNames when given, else the uploaded file name. // Sync polling asks by that same name, so resolve it here rather than guessing later. const providedNames = pdfNames ? pdfNames.split(',').map(name => name.trim()) : []; diff --git a/src/types.ts b/src/types.ts index 364f07f..1efede9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -88,6 +88,9 @@ export interface Context { gitURL?: string, showRenderErrors?: boolean, pdfNames?: string, + approvalThreshold?: string, + rejectionThreshold?: string, + thresholds?: string, sync?: boolean, userName?: string, accessKey?: string