@drantoniou/uploadcheck 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/request-builder.mjs +4 -0
- package/watch.mjs +26 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drantoniou/uploadcheck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The quality gate for AI-generated media. Check videos, podcasts, and clips before you publish — or `watch` a folder to auto-QC every render.",
|
|
5
5
|
"homepage": "https://uploadcheck.app",
|
|
6
6
|
"repository": {
|
package/request-builder.mjs
CHANGED
|
@@ -190,6 +190,10 @@ export function parseArgs(argv) {
|
|
|
190
190
|
options.settleMs = requireValue(arg, args.shift());
|
|
191
191
|
} else if (arg === "--poll-ms") {
|
|
192
192
|
options.pollMs = requireValue(arg, args.shift());
|
|
193
|
+
} else if (arg === "--on-pass") {
|
|
194
|
+
options.onPass = requireValue(arg, args.shift());
|
|
195
|
+
} else if (arg === "--on-fail") {
|
|
196
|
+
options.onFail = requireValue(arg, args.shift());
|
|
193
197
|
} else {
|
|
194
198
|
throw new Error(`Unknown option: ${arg}`);
|
|
195
199
|
}
|
package/watch.mjs
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { readdirSync, statSync, existsSync, writeFileSync, readFileSync, watch as fsWatch } from "node:fs";
|
|
21
21
|
import { join, extname, basename, dirname, resolve, relative } from "node:path";
|
|
22
22
|
import { createHash } from "node:crypto";
|
|
23
|
+
import { spawn } from "node:child_process";
|
|
23
24
|
import { buildJobRequest, CONTENT_TYPES } from "./request-builder.mjs";
|
|
24
25
|
import { submitJob, pollJobUntilDone, fetchReport, fetchMarkerCsv, sleep } from "./api-client.mjs";
|
|
25
26
|
|
|
@@ -84,6 +85,23 @@ function appendAggregateRow(dir, row) {
|
|
|
84
85
|
} catch { /* best-effort */ }
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
// Run a user-supplied shell command after a verdict (--on-pass / --on-fail).
|
|
89
|
+
// The file path is exposed to the command as $UPLOADCHECK_FILE (and the verdict as
|
|
90
|
+
// $UPLOADCHECK_VERDICT), so `mv "$UPLOADCHECK_FILE" done/` style commands work.
|
|
91
|
+
// Failures are logged, never fatal.
|
|
92
|
+
function runHook(command, filePath, verdict) {
|
|
93
|
+
if (!command) return Promise.resolve();
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
const child = spawn(command, {
|
|
96
|
+
shell: true,
|
|
97
|
+
stdio: "inherit",
|
|
98
|
+
env: { ...process.env, UPLOADCHECK_FILE: filePath, UPLOADCHECK_VERDICT: String(verdict || "") }
|
|
99
|
+
});
|
|
100
|
+
child.on("error", (e) => { console.error(`[watch] hook error: ${e.message}`); resolve(); });
|
|
101
|
+
child.on("exit", () => resolve());
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
87
105
|
async function processFile(filePath, { apiBaseUrl, apiKey, options, dir, ledger, nowIso }) {
|
|
88
106
|
const name = basename(filePath);
|
|
89
107
|
// Build the job exactly like `uploadcheck check` (inline vs signed-upload auto-switch).
|
|
@@ -119,8 +137,15 @@ async function processFile(filePath, { apiBaseUrl, apiKey, options, dir, ledger,
|
|
|
119
137
|
ledger.done[sourceKey] = { file: name, jobId, verdict, status: finished.status, at: nowIso };
|
|
120
138
|
saveLedger(dir, ledger);
|
|
121
139
|
|
|
122
|
-
const
|
|
140
|
+
const verdictUpper = String(verdict).toUpperCase();
|
|
141
|
+
const passed = finished.status === "completed" && !verdictUpper.includes("BLOCK");
|
|
142
|
+
const mark = finished.status !== "completed" ? "⚠️" : (verdictUpper.includes("BLOCK") ? "❌ BLOCK" : (verdictUpper.includes("WATCH") ? "⚠️ WATCH" : "✅"));
|
|
123
143
|
console.log(`[watch] ${name}: ${mark} (${flagCount} flag${flagCount === 1 ? "" : "s"}) → ${basename(reportPathFor(filePath))}`);
|
|
144
|
+
|
|
145
|
+
// Pipeline glue: run --on-pass when nothing blocks (a clean PASS or WATCH), or
|
|
146
|
+
// --on-fail on a BLOCK / failed job. WATCH counts as a pass — it ships with notes.
|
|
147
|
+
if (passed && options.onPass) await runHook(options.onPass, filePath, verdict);
|
|
148
|
+
else if (!passed && options.onFail) await runHook(options.onFail, filePath, verdict);
|
|
124
149
|
}
|
|
125
150
|
|
|
126
151
|
// Run a list of files through processFile with bounded concurrency.
|