@intactfile/cli 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/dist/index.js +43 -1
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { basename, dirname, extname, join, parse } from "node:path";
8
8
  import { createInterface } from "node:readline";
9
9
  import { Command } from "commander";
10
10
  import { ApiError, balance, clearAuth, consume, EntitlementError, getToken, login as apiLogin, magic as apiMagic, recover as apiRecover, repairPath, diagnosePath, requireBusiness, setToken, UnsupportedError, } from "@intactfile/node-core";
11
+ import { generateRepairReportPdf } from "@intactfile/report";
11
12
  const program = new Command();
12
13
  program
13
14
  .name("intactfile")
@@ -85,6 +86,34 @@ function writeResult(input, out, r) {
85
86
  writeFileSync(dest, r.bytes);
86
87
  return [dest];
87
88
  }
89
+ /** Map a repair result into the report package's minimal input shape. */
90
+ function toReportInput(input, r) {
91
+ const report = r.report;
92
+ const num = (v) => {
93
+ const n = typeof v === "number" ? v : v == null ? NaN : Number(v);
94
+ return Number.isFinite(n) ? n : undefined;
95
+ };
96
+ const base = {
97
+ fileName: basename(input),
98
+ family: r.family,
99
+ outcome: report.outcome != null ? String(report.outcome) : undefined,
100
+ damageClass: report.damageClass != null ? String(report.damageClass) : undefined,
101
+ bytesIn: num(report.bytesIn),
102
+ bytesOut: num(report.bytesOut),
103
+ notes: Array.isArray(report.notes) ? report.notes.map((n) => String(n)) : undefined,
104
+ };
105
+ if (r.kind === "archive") {
106
+ base.files = r.files.map((f) => ({ name: f.name, status: f.status }));
107
+ }
108
+ return base;
109
+ }
110
+ /** Generate and write a white-label PDF repair report; prints the path. */
111
+ async function writeReportPdf(input, r, path, company) {
112
+ const bytes = await generateRepairReportPdf(toReportInput(input, r), company ? { company } : {});
113
+ mkdirSync(dirname(path), { recursive: true });
114
+ writeFileSync(path, bytes);
115
+ console.log(`✓ Report: ${path}`);
116
+ }
88
117
  /* -------------------------------- login -------------------------------- */
89
118
  program
90
119
  .command("login")
@@ -182,13 +211,18 @@ program
182
211
  .option("-o, --out <path>", "output path (or directory for archives)")
183
212
  .option("-r, --reference <clip>", "healthy reference clip/photo (missing-moov video, JPEG donor)")
184
213
  .option("-p, --password <pw>", "archive password (RAR/7z)")
214
+ .option("--report <path.pdf>", "also write a white-label PDF repair report to this path")
215
+ .option("--company <name>", "company name for the white-label report header")
185
216
  .action(async (file, opts) => {
186
217
  try {
187
218
  const sub = await requireBusiness();
188
219
  if (sub.monthlyRemaining <= 0) {
189
220
  return die("Monthly repair allowance exhausted — it resets on your billing cycle.");
190
221
  }
191
- const r = await repairPath(file, { referencePath: opts.reference, password: opts.password });
222
+ const r = await repairPath(file, {
223
+ referencePath: opts.reference,
224
+ password: opts.password,
225
+ });
192
226
  printReport(r.family, r.report);
193
227
  if (!r.usable) {
194
228
  return die("Couldn't produce a usable result — nothing was charged.");
@@ -196,6 +230,8 @@ program
196
230
  const written = writeResult(file, opts.out, r);
197
231
  await meter();
198
232
  console.log(`✓ Wrote:\n${written.map((w) => ` ${w}`).join("\n")}`);
233
+ if (opts.report)
234
+ await writeReportPdf(file, r, opts.report, opts.company);
199
235
  }
200
236
  catch (e) {
201
237
  handle(e);
@@ -206,6 +242,8 @@ program
206
242
  .command("batch <files...>")
207
243
  .description("Repair up to 100 files (Business plan). Each is metered separately.")
208
244
  .option("-o, --outdir <dir>", "directory to write results into")
245
+ .option("--report-dir <dir>", "also write a white-label PDF repair report per file into this dir")
246
+ .option("--company <name>", "company name for the white-label report header")
209
247
  .action(async (files, opts) => {
210
248
  try {
211
249
  await requireBusiness();
@@ -234,6 +272,10 @@ program
234
272
  const written = writeResult(file, out, r);
235
273
  await meter();
236
274
  console.log(`✓ ${basename(file)} → ${written[0] ?? "(extracted)"}`);
275
+ if (opts.reportDir) {
276
+ const pdfPath = join(opts.reportDir, `${parse(file).name}.report.pdf`);
277
+ await writeReportPdf(file, r, pdfPath, opts.company);
278
+ }
237
279
  ok++;
238
280
  }
239
281
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intactfile/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "IntactFile CLI — repair corrupted files locally (video, ZIP/Office, PDF, JPEG, PNG, SQLite, RAR/7z). Your files never leave your machine. Business plan for repairs; diagnosis is free.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -15,7 +15,8 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "commander": "^12.1.0",
18
- "@intactfile/node-core": "0.1.0"
18
+ "@intactfile/node-core": "0.1.0",
19
+ "@intactfile/report": "0.1.0"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@types/node": "^22.15.0",