@reportforge/playwright-pdf 0.22.0 → 0.23.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/README.md +68 -21
- package/SECURITY.md +13 -2
- package/dist/cli/index.js +228 -118
- package/dist/index.d.mts +31 -10
- package/dist/index.d.ts +31 -10
- package/dist/index.js +296 -117
- package/dist/index.mjs +290 -111
- package/package.json +2 -2
- package/CHANGELOG.md +0 -602
package/dist/cli/index.js
CHANGED
|
@@ -1588,13 +1588,13 @@ var require_ast = __commonJS({
|
|
|
1588
1588
|
helperExpression: function helperExpression(node) {
|
|
1589
1589
|
return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
|
|
1590
1590
|
},
|
|
1591
|
-
scopedId: function scopedId(
|
|
1592
|
-
return /^\.|this\b/.test(
|
|
1591
|
+
scopedId: function scopedId(path13) {
|
|
1592
|
+
return /^\.|this\b/.test(path13.original);
|
|
1593
1593
|
},
|
|
1594
1594
|
// an ID is simple if it only has one part, and that part is not
|
|
1595
1595
|
// `..` or `this`.
|
|
1596
|
-
simpleId: function simpleId(
|
|
1597
|
-
return
|
|
1596
|
+
simpleId: function simpleId(path13) {
|
|
1597
|
+
return path13.parts.length === 1 && !AST.helpers.scopedId(path13) && !path13.depth;
|
|
1598
1598
|
}
|
|
1599
1599
|
}
|
|
1600
1600
|
};
|
|
@@ -2668,12 +2668,12 @@ var require_helpers2 = __commonJS({
|
|
|
2668
2668
|
loc
|
|
2669
2669
|
};
|
|
2670
2670
|
}
|
|
2671
|
-
function prepareMustache(
|
|
2671
|
+
function prepareMustache(path13, params, hash, open, strip, locInfo) {
|
|
2672
2672
|
var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
|
|
2673
2673
|
var decorator = /\*/.test(open);
|
|
2674
2674
|
return {
|
|
2675
2675
|
type: decorator ? "Decorator" : "MustacheStatement",
|
|
2676
|
-
path:
|
|
2676
|
+
path: path13,
|
|
2677
2677
|
params,
|
|
2678
2678
|
hash,
|
|
2679
2679
|
escaped,
|
|
@@ -2993,9 +2993,9 @@ var require_compiler = __commonJS({
|
|
|
2993
2993
|
},
|
|
2994
2994
|
DecoratorBlock: function DecoratorBlock(decorator) {
|
|
2995
2995
|
var program = decorator.program && this.compileProgram(decorator.program);
|
|
2996
|
-
var params = this.setupFullMustacheParams(decorator, program, void 0),
|
|
2996
|
+
var params = this.setupFullMustacheParams(decorator, program, void 0), path13 = decorator.path;
|
|
2997
2997
|
this.useDecorators = true;
|
|
2998
|
-
this.opcode("registerDecorator", params.length,
|
|
2998
|
+
this.opcode("registerDecorator", params.length, path13.original);
|
|
2999
2999
|
},
|
|
3000
3000
|
PartialStatement: function PartialStatement(partial) {
|
|
3001
3001
|
this.usePartial = true;
|
|
@@ -3059,46 +3059,46 @@ var require_compiler = __commonJS({
|
|
|
3059
3059
|
}
|
|
3060
3060
|
},
|
|
3061
3061
|
ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
|
|
3062
|
-
var
|
|
3063
|
-
this.opcode("getContext",
|
|
3062
|
+
var path13 = sexpr.path, name = path13.parts[0], isBlock = program != null || inverse != null;
|
|
3063
|
+
this.opcode("getContext", path13.depth);
|
|
3064
3064
|
this.opcode("pushProgram", program);
|
|
3065
3065
|
this.opcode("pushProgram", inverse);
|
|
3066
|
-
|
|
3067
|
-
this.accept(
|
|
3066
|
+
path13.strict = true;
|
|
3067
|
+
this.accept(path13);
|
|
3068
3068
|
this.opcode("invokeAmbiguous", name, isBlock);
|
|
3069
3069
|
},
|
|
3070
3070
|
simpleSexpr: function simpleSexpr(sexpr) {
|
|
3071
|
-
var
|
|
3072
|
-
|
|
3073
|
-
this.accept(
|
|
3071
|
+
var path13 = sexpr.path;
|
|
3072
|
+
path13.strict = true;
|
|
3073
|
+
this.accept(path13);
|
|
3074
3074
|
this.opcode("resolvePossibleLambda");
|
|
3075
3075
|
},
|
|
3076
3076
|
helperSexpr: function helperSexpr(sexpr, program, inverse) {
|
|
3077
|
-
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
|
3077
|
+
var params = this.setupFullMustacheParams(sexpr, program, inverse), path13 = sexpr.path, name = path13.parts[0];
|
|
3078
3078
|
if (this.options.knownHelpers[name]) {
|
|
3079
3079
|
this.opcode("invokeKnownHelper", params.length, name);
|
|
3080
3080
|
} else if (this.options.knownHelpersOnly) {
|
|
3081
3081
|
throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
|
3082
3082
|
} else {
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
this.accept(
|
|
3086
|
-
this.opcode("invokeHelper", params.length,
|
|
3083
|
+
path13.strict = true;
|
|
3084
|
+
path13.falsy = true;
|
|
3085
|
+
this.accept(path13);
|
|
3086
|
+
this.opcode("invokeHelper", params.length, path13.original, _ast2["default"].helpers.simpleId(path13));
|
|
3087
3087
|
}
|
|
3088
3088
|
},
|
|
3089
|
-
PathExpression: function PathExpression(
|
|
3090
|
-
this.addDepth(
|
|
3091
|
-
this.opcode("getContext",
|
|
3092
|
-
var name =
|
|
3089
|
+
PathExpression: function PathExpression(path13) {
|
|
3090
|
+
this.addDepth(path13.depth);
|
|
3091
|
+
this.opcode("getContext", path13.depth);
|
|
3092
|
+
var name = path13.parts[0], scoped = _ast2["default"].helpers.scopedId(path13), blockParamId = !path13.depth && !scoped && this.blockParamIndex(name);
|
|
3093
3093
|
if (blockParamId) {
|
|
3094
|
-
this.opcode("lookupBlockParam", blockParamId,
|
|
3094
|
+
this.opcode("lookupBlockParam", blockParamId, path13.parts);
|
|
3095
3095
|
} else if (!name) {
|
|
3096
3096
|
this.opcode("pushContext");
|
|
3097
|
-
} else if (
|
|
3097
|
+
} else if (path13.data) {
|
|
3098
3098
|
this.options.data = true;
|
|
3099
|
-
this.opcode("lookupData",
|
|
3099
|
+
this.opcode("lookupData", path13.depth, path13.parts, path13.strict);
|
|
3100
3100
|
} else {
|
|
3101
|
-
this.opcode("lookupOnContext",
|
|
3101
|
+
this.opcode("lookupOnContext", path13.parts, path13.falsy, path13.strict, scoped);
|
|
3102
3102
|
}
|
|
3103
3103
|
},
|
|
3104
3104
|
StringLiteral: function StringLiteral(string) {
|
|
@@ -3454,16 +3454,16 @@ var require_util = __commonJS({
|
|
|
3454
3454
|
}
|
|
3455
3455
|
exports2.urlGenerate = urlGenerate;
|
|
3456
3456
|
function normalize(aPath) {
|
|
3457
|
-
var
|
|
3457
|
+
var path13 = aPath;
|
|
3458
3458
|
var url = urlParse(aPath);
|
|
3459
3459
|
if (url) {
|
|
3460
3460
|
if (!url.path) {
|
|
3461
3461
|
return aPath;
|
|
3462
3462
|
}
|
|
3463
|
-
|
|
3463
|
+
path13 = url.path;
|
|
3464
3464
|
}
|
|
3465
|
-
var isAbsolute = exports2.isAbsolute(
|
|
3466
|
-
var parts =
|
|
3465
|
+
var isAbsolute = exports2.isAbsolute(path13);
|
|
3466
|
+
var parts = path13.split(/\/+/);
|
|
3467
3467
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
3468
3468
|
part = parts[i];
|
|
3469
3469
|
if (part === ".") {
|
|
@@ -3480,15 +3480,15 @@ var require_util = __commonJS({
|
|
|
3480
3480
|
}
|
|
3481
3481
|
}
|
|
3482
3482
|
}
|
|
3483
|
-
|
|
3484
|
-
if (
|
|
3485
|
-
|
|
3483
|
+
path13 = parts.join("/");
|
|
3484
|
+
if (path13 === "") {
|
|
3485
|
+
path13 = isAbsolute ? "/" : ".";
|
|
3486
3486
|
}
|
|
3487
3487
|
if (url) {
|
|
3488
|
-
url.path =
|
|
3488
|
+
url.path = path13;
|
|
3489
3489
|
return urlGenerate(url);
|
|
3490
3490
|
}
|
|
3491
|
-
return
|
|
3491
|
+
return path13;
|
|
3492
3492
|
}
|
|
3493
3493
|
exports2.normalize = normalize;
|
|
3494
3494
|
function join(aRoot, aPath) {
|
|
@@ -6291,8 +6291,8 @@ var require_printer = __commonJS({
|
|
|
6291
6291
|
return this.accept(sexpr.path) + " " + params + hash;
|
|
6292
6292
|
};
|
|
6293
6293
|
PrintVisitor.prototype.PathExpression = function(id) {
|
|
6294
|
-
var
|
|
6295
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
6294
|
+
var path13 = id.parts.join("/");
|
|
6295
|
+
return (id.data ? "@" : "") + "PATH:" + path13;
|
|
6296
6296
|
};
|
|
6297
6297
|
PrintVisitor.prototype.StringLiteral = function(string) {
|
|
6298
6298
|
return '"' + string.value + '"';
|
|
@@ -6333,8 +6333,8 @@ var require_lib = __commonJS({
|
|
|
6333
6333
|
handlebars.print = printer.print;
|
|
6334
6334
|
module2.exports = handlebars;
|
|
6335
6335
|
function extension(module3, filename) {
|
|
6336
|
-
var
|
|
6337
|
-
var templateString =
|
|
6336
|
+
var fs15 = require("fs");
|
|
6337
|
+
var templateString = fs15.readFileSync(filename, "utf8");
|
|
6338
6338
|
module3.exports = handlebars.compile(templateString);
|
|
6339
6339
|
}
|
|
6340
6340
|
if (typeof require !== "undefined" && require.extensions) {
|
|
@@ -7005,7 +7005,7 @@ var require_util2 = __commonJS({
|
|
|
7005
7005
|
"node_modules/chrome-finder/lib/util.js"(exports2, module2) {
|
|
7006
7006
|
"use strict";
|
|
7007
7007
|
init_cjs_shims();
|
|
7008
|
-
var
|
|
7008
|
+
var fs15 = require("fs");
|
|
7009
7009
|
var newLineRegex = /\r?\n/;
|
|
7010
7010
|
function sort(installations, priorities) {
|
|
7011
7011
|
const defaultPriority = 10;
|
|
@@ -7023,7 +7023,7 @@ var require_util2 = __commonJS({
|
|
|
7023
7023
|
return false;
|
|
7024
7024
|
}
|
|
7025
7025
|
try {
|
|
7026
|
-
|
|
7026
|
+
fs15.accessSync(file);
|
|
7027
7027
|
return true;
|
|
7028
7028
|
} catch (e) {
|
|
7029
7029
|
return false;
|
|
@@ -7034,7 +7034,7 @@ var require_util2 = __commonJS({
|
|
|
7034
7034
|
return false;
|
|
7035
7035
|
}
|
|
7036
7036
|
try {
|
|
7037
|
-
var stat =
|
|
7037
|
+
var stat = fs15.statSync(file);
|
|
7038
7038
|
return stat && typeof stat.isFile === "function" && stat.isFile();
|
|
7039
7039
|
} catch (e) {
|
|
7040
7040
|
return false;
|
|
@@ -7054,7 +7054,7 @@ var require_win32 = __commonJS({
|
|
|
7054
7054
|
"node_modules/chrome-finder/lib/win32.js"(exports2, module2) {
|
|
7055
7055
|
"use strict";
|
|
7056
7056
|
init_cjs_shims();
|
|
7057
|
-
var
|
|
7057
|
+
var path13 = require("path");
|
|
7058
7058
|
var { canAccess } = require_util2();
|
|
7059
7059
|
function win32() {
|
|
7060
7060
|
const installations = [];
|
|
@@ -7068,7 +7068,7 @@ var require_win32 = __commonJS({
|
|
|
7068
7068
|
const prefixes = [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env["PROGRAMFILES(X86)"]];
|
|
7069
7069
|
prefixes.forEach((prefix) => suffixes.forEach((suffix) => {
|
|
7070
7070
|
if (prefix) {
|
|
7071
|
-
const chromePath =
|
|
7071
|
+
const chromePath = path13.join(prefix, suffix);
|
|
7072
7072
|
if (canAccess(chromePath)) {
|
|
7073
7073
|
installations.push(chromePath);
|
|
7074
7074
|
}
|
|
@@ -7086,7 +7086,7 @@ var require_darwin = __commonJS({
|
|
|
7086
7086
|
"use strict";
|
|
7087
7087
|
init_cjs_shims();
|
|
7088
7088
|
var { execSync: execSync2 } = require("child_process");
|
|
7089
|
-
var
|
|
7089
|
+
var path13 = require("path");
|
|
7090
7090
|
var { canAccess, newLineRegex, sort } = require_util2();
|
|
7091
7091
|
function darwin() {
|
|
7092
7092
|
const suffixes = ["/Contents/MacOS/Google Chrome Canary", "/Contents/MacOS/Google Chrome", "/Contents/MacOS/Chromium"];
|
|
@@ -7096,7 +7096,7 @@ var require_darwin = __commonJS({
|
|
|
7096
7096
|
${LSREGISTER} -dump | grep -E -i -o '/.+(google chrome( canary)?|chromium)\\.app(\\s|$)' | grep -E -v 'Caches|TimeMachine|Temporary|/Volumes|\\.Trash'
|
|
7097
7097
|
`).toString().split(newLineRegex).forEach((inst) => {
|
|
7098
7098
|
suffixes.forEach((suffix) => {
|
|
7099
|
-
const execPath =
|
|
7099
|
+
const execPath = path13.join(inst.trim(), suffix);
|
|
7100
7100
|
if (canAccess(execPath)) {
|
|
7101
7101
|
installations.push(execPath);
|
|
7102
7102
|
}
|
|
@@ -7124,9 +7124,9 @@ var require_linux = __commonJS({
|
|
|
7124
7124
|
"node_modules/chrome-finder/lib/linux.js"(exports2, module2) {
|
|
7125
7125
|
"use strict";
|
|
7126
7126
|
init_cjs_shims();
|
|
7127
|
-
var { execSync: execSync2, execFileSync
|
|
7128
|
-
var
|
|
7129
|
-
var
|
|
7127
|
+
var { execSync: execSync2, execFileSync } = require("child_process");
|
|
7128
|
+
var path13 = require("path");
|
|
7129
|
+
var fs15 = require("fs");
|
|
7130
7130
|
var { canAccess, sort, isExecutable, newLineRegex } = require_util2();
|
|
7131
7131
|
function findChromeExecutablesForLinuxDesktop(folder) {
|
|
7132
7132
|
const argumentsRegex = /(^[^ ]+).*/;
|
|
@@ -7143,7 +7143,7 @@ var require_linux = __commonJS({
|
|
|
7143
7143
|
function linux() {
|
|
7144
7144
|
let installations = [];
|
|
7145
7145
|
const desktopInstallationFolders = [
|
|
7146
|
-
|
|
7146
|
+
path13.join(require("os").homedir(), ".local/share/applications/"),
|
|
7147
7147
|
"/usr/share/applications/"
|
|
7148
7148
|
];
|
|
7149
7149
|
desktopInstallationFolders.forEach((folder) => {
|
|
@@ -7169,7 +7169,7 @@ var require_linux = __commonJS({
|
|
|
7169
7169
|
].map((possiblePath) => {
|
|
7170
7170
|
try {
|
|
7171
7171
|
const chromePathToTest = possiblePath + "/" + executable;
|
|
7172
|
-
if (
|
|
7172
|
+
if (fs15.existsSync(chromePathToTest) && canAccess(chromePathToTest) && isExecutable(chromePathToTest)) {
|
|
7173
7173
|
installations.push(chromePathToTest);
|
|
7174
7174
|
return chromePathToTest;
|
|
7175
7175
|
}
|
|
@@ -7181,7 +7181,7 @@ var require_linux = __commonJS({
|
|
|
7181
7181
|
return;
|
|
7182
7182
|
}
|
|
7183
7183
|
try {
|
|
7184
|
-
const chromePath =
|
|
7184
|
+
const chromePath = execFileSync("which", [executable]).toString().split(newLineRegex)[0];
|
|
7185
7185
|
if (canAccess(chromePath)) {
|
|
7186
7186
|
installations.push(chromePath);
|
|
7187
7187
|
}
|
|
@@ -7384,48 +7384,37 @@ var init_ChartRenderer = __esm({
|
|
|
7384
7384
|
});
|
|
7385
7385
|
|
|
7386
7386
|
// src/pdf/PdfEncryptor.ts
|
|
7387
|
-
var
|
|
7387
|
+
var import_fs5, import_pdf_lib, AES256_HEADER_MINOR, PdfEncryptor;
|
|
7388
7388
|
var init_PdfEncryptor = __esm({
|
|
7389
7389
|
"src/pdf/PdfEncryptor.ts"() {
|
|
7390
7390
|
"use strict";
|
|
7391
7391
|
init_cjs_shims();
|
|
7392
|
-
import_child_process2 = require("child_process");
|
|
7393
7392
|
import_fs5 = __toESM(require("fs"));
|
|
7394
|
-
|
|
7395
|
-
import_os2 = __toESM(require("os"));
|
|
7396
|
-
import_crypto2 = __toESM(require("crypto"));
|
|
7393
|
+
import_pdf_lib = require("@cantoo/pdf-lib");
|
|
7397
7394
|
init_logger();
|
|
7395
|
+
AES256_HEADER_MINOR = "7ext3";
|
|
7398
7396
|
PdfEncryptor = class {
|
|
7399
7397
|
async encrypt(pdfPath, password) {
|
|
7400
7398
|
if (!password) return;
|
|
7401
|
-
if (!this.isQpdfAvailable()) {
|
|
7402
|
-
logger.warn(
|
|
7403
|
-
"pdfPassword is set but qpdf is not installed \u2014 PDF will NOT be encrypted. Install qpdf: https://qpdf.readthedocs.io/en/stable/installation.html"
|
|
7404
|
-
);
|
|
7405
|
-
return;
|
|
7406
|
-
}
|
|
7407
|
-
const tmpPath = import_path3.default.join(import_os2.default.tmpdir(), `rf-encrypted-${Date.now()}.pdf`);
|
|
7408
|
-
const argFile = import_path3.default.join(import_os2.default.tmpdir(), `rf-qpdf-args-${import_crypto2.default.randomBytes(8).toString("hex")}`);
|
|
7409
7399
|
try {
|
|
7410
|
-
const
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7400
|
+
const doc = await import_pdf_lib.PDFDocument.load(await import_fs5.default.promises.readFile(pdfPath));
|
|
7401
|
+
doc.context.header = import_pdf_lib.PDFHeader.forVersion(1, AES256_HEADER_MINOR);
|
|
7402
|
+
doc.encrypt({
|
|
7403
|
+
userPassword: password,
|
|
7404
|
+
ownerPassword: password,
|
|
7405
|
+
permissions: { printing: "highResolution", copying: false, modifying: false }
|
|
7406
|
+
});
|
|
7407
|
+
const encryptedBytes = await doc.save();
|
|
7408
|
+
const tmpPath = `${pdfPath}.rf-enc-tmp`;
|
|
7409
|
+
try {
|
|
7410
|
+
await import_fs5.default.promises.writeFile(tmpPath, encryptedBytes);
|
|
7411
|
+
await import_fs5.default.promises.rename(tmpPath, pdfPath);
|
|
7412
|
+
} finally {
|
|
7413
|
+
import_fs5.default.rmSync(tmpPath, { force: true });
|
|
7414
|
+
}
|
|
7415
|
+
logger.info("PDF encrypted with password (AES-256).");
|
|
7415
7416
|
} catch (e) {
|
|
7416
|
-
throw new Error(`
|
|
7417
|
-
} finally {
|
|
7418
|
-
if (import_fs5.default.existsSync(tmpPath)) import_fs5.default.unlinkSync(tmpPath);
|
|
7419
|
-
import_fs5.default.rmSync(argFile, { force: true });
|
|
7420
|
-
}
|
|
7421
|
-
}
|
|
7422
|
-
isQpdfAvailable() {
|
|
7423
|
-
try {
|
|
7424
|
-
(0, import_child_process2.execFileSync)("qpdf", ["--version"], { stdio: "pipe" });
|
|
7425
|
-
return true;
|
|
7426
|
-
} catch (err) {
|
|
7427
|
-
logger.debug("qpdf probe failed \u2014 treating as not installed", { error: err.message });
|
|
7428
|
-
return false;
|
|
7417
|
+
throw new Error(`PDF encryption failed: ${e.message}`);
|
|
7429
7418
|
}
|
|
7430
7419
|
}
|
|
7431
7420
|
};
|
|
@@ -7433,12 +7422,12 @@ var init_PdfEncryptor = __esm({
|
|
|
7433
7422
|
});
|
|
7434
7423
|
|
|
7435
7424
|
// src/filename/FilenameResolver.ts
|
|
7436
|
-
var
|
|
7425
|
+
var import_path3, import_fs6, MAX_BRANCH_LENGTH, FilenameResolver;
|
|
7437
7426
|
var init_FilenameResolver = __esm({
|
|
7438
7427
|
"src/filename/FilenameResolver.ts"() {
|
|
7439
7428
|
"use strict";
|
|
7440
7429
|
init_cjs_shims();
|
|
7441
|
-
|
|
7430
|
+
import_path3 = __toESM(require("path"));
|
|
7442
7431
|
import_fs6 = __toESM(require("fs"));
|
|
7443
7432
|
MAX_BRANCH_LENGTH = 50;
|
|
7444
7433
|
FilenameResolver = class {
|
|
@@ -7456,8 +7445,8 @@ var init_FilenameResolver = __esm({
|
|
|
7456
7445
|
const branch = this.sanitiseBranch(ctx.branch);
|
|
7457
7446
|
const status = ctx.status;
|
|
7458
7447
|
const resolved = template.replace(/\{date\}/g, date).replace(/\{branch\}/g, branch).replace(/\{status\}/g, status);
|
|
7459
|
-
const absolute =
|
|
7460
|
-
import_fs6.default.mkdirSync(
|
|
7448
|
+
const absolute = import_path3.default.isAbsolute(resolved) ? resolved : import_path3.default.resolve(process.cwd(), resolved);
|
|
7449
|
+
import_fs6.default.mkdirSync(import_path3.default.dirname(absolute), { recursive: true });
|
|
7461
7450
|
return absolute;
|
|
7462
7451
|
}
|
|
7463
7452
|
/**
|
|
@@ -7469,7 +7458,7 @@ var init_FilenameResolver = __esm({
|
|
|
7469
7458
|
* // → '/out/2026-report-executive.pdf'
|
|
7470
7459
|
*/
|
|
7471
7460
|
injectTemplateSuffix(outputPath, suffix) {
|
|
7472
|
-
const ext =
|
|
7461
|
+
const ext = import_path3.default.extname(outputPath);
|
|
7473
7462
|
const base = outputPath.slice(0, outputPath.length - ext.length);
|
|
7474
7463
|
return `${base}-${suffix}${ext}`;
|
|
7475
7464
|
}
|
|
@@ -7534,13 +7523,18 @@ var init_compression = __esm({
|
|
|
7534
7523
|
});
|
|
7535
7524
|
|
|
7536
7525
|
// src/pdf/FailurePaginator.ts
|
|
7537
|
-
|
|
7526
|
+
function sidecarPathFor(pdfPath) {
|
|
7527
|
+
const dir = import_path4.default.dirname(pdfPath);
|
|
7528
|
+
const base = import_path4.default.basename(pdfPath, import_path4.default.extname(pdfPath));
|
|
7529
|
+
return import_path4.default.join(dir, `${base}-failures.json`);
|
|
7530
|
+
}
|
|
7531
|
+
var import_fs7, import_path4, FailurePaginator;
|
|
7538
7532
|
var init_FailurePaginator = __esm({
|
|
7539
7533
|
"src/pdf/FailurePaginator.ts"() {
|
|
7540
7534
|
"use strict";
|
|
7541
7535
|
init_cjs_shims();
|
|
7542
7536
|
import_fs7 = __toESM(require("fs"));
|
|
7543
|
-
|
|
7537
|
+
import_path4 = __toESM(require("path"));
|
|
7544
7538
|
init_logger();
|
|
7545
7539
|
FailurePaginator = class {
|
|
7546
7540
|
async paginate(failures, maxInline, pdfOutputPath) {
|
|
@@ -7549,7 +7543,7 @@ var init_FailurePaginator = __esm({
|
|
|
7549
7543
|
}
|
|
7550
7544
|
const inline = failures.slice(0, maxInline);
|
|
7551
7545
|
const overflow = failures.slice(maxInline);
|
|
7552
|
-
const sidecarPath =
|
|
7546
|
+
const sidecarPath = sidecarPathFor(pdfOutputPath);
|
|
7553
7547
|
try {
|
|
7554
7548
|
await import_fs7.default.promises.writeFile(
|
|
7555
7549
|
sidecarPath,
|
|
@@ -7557,7 +7551,7 @@ var init_FailurePaginator = __esm({
|
|
|
7557
7551
|
"utf8"
|
|
7558
7552
|
);
|
|
7559
7553
|
logger.info(
|
|
7560
|
-
`Emitted ${overflow.length} overflow failures \u2192 ${
|
|
7554
|
+
`Emitted ${overflow.length} overflow failures \u2192 ${import_path4.default.basename(sidecarPath)}`
|
|
7561
7555
|
);
|
|
7562
7556
|
} catch (e) {
|
|
7563
7557
|
logger.warn(`Could not write failure sidecar: ${e.message}`);
|
|
@@ -7565,11 +7559,6 @@ var init_FailurePaginator = __esm({
|
|
|
7565
7559
|
}
|
|
7566
7560
|
return { inline, overflowCount: overflow.length, sidecarPath };
|
|
7567
7561
|
}
|
|
7568
|
-
sidecarPathFor(pdfPath) {
|
|
7569
|
-
const dir = import_path5.default.dirname(pdfPath);
|
|
7570
|
-
const base = import_path5.default.basename(pdfPath, import_path5.default.extname(pdfPath));
|
|
7571
|
-
return import_path5.default.join(dir, `${base}-failures.json`);
|
|
7572
|
-
}
|
|
7573
7562
|
/**
|
|
7574
7563
|
* Drops the inlined image bytes — a 150-entry overflow would otherwise
|
|
7575
7564
|
* produce a 40 MB JSON. The path still references the on-disk screenshot
|
|
@@ -7586,6 +7575,41 @@ var init_FailurePaginator = __esm({
|
|
|
7586
7575
|
}
|
|
7587
7576
|
});
|
|
7588
7577
|
|
|
7578
|
+
// src/pdf/sidecar-crypto.ts
|
|
7579
|
+
function encryptSidecar(plain, password) {
|
|
7580
|
+
const salt = import_crypto2.default.randomBytes(SALT_LEN);
|
|
7581
|
+
const key = import_crypto2.default.scryptSync(password, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
7582
|
+
const iv = import_crypto2.default.randomBytes(IV_LEN);
|
|
7583
|
+
const cipher = import_crypto2.default.createCipheriv("aes-256-gcm", key, iv);
|
|
7584
|
+
const enc = Buffer.concat([cipher.update(plain), cipher.final()]);
|
|
7585
|
+
return Buffer.concat([MAGIC, salt, iv, cipher.getAuthTag(), enc]);
|
|
7586
|
+
}
|
|
7587
|
+
function decryptSidecar(blob, password) {
|
|
7588
|
+
if (blob.length < MAGIC.length + SALT_LEN + IV_LEN + TAG_LEN || !blob.subarray(0, MAGIC.length).equals(MAGIC)) {
|
|
7589
|
+
throw new Error("Not an RFENC1-encrypted file");
|
|
7590
|
+
}
|
|
7591
|
+
let o = MAGIC.length;
|
|
7592
|
+
const salt = blob.subarray(o, o += SALT_LEN);
|
|
7593
|
+
const iv = blob.subarray(o, o += IV_LEN);
|
|
7594
|
+
const tag = blob.subarray(o, o += TAG_LEN);
|
|
7595
|
+
const key = import_crypto2.default.scryptSync(password, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
7596
|
+
const decipher = import_crypto2.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
7597
|
+
decipher.setAuthTag(tag);
|
|
7598
|
+
return Buffer.concat([decipher.update(blob.subarray(o)), decipher.final()]);
|
|
7599
|
+
}
|
|
7600
|
+
var import_crypto2, MAGIC, SALT_LEN, IV_LEN, TAG_LEN;
|
|
7601
|
+
var init_sidecar_crypto = __esm({
|
|
7602
|
+
"src/pdf/sidecar-crypto.ts"() {
|
|
7603
|
+
"use strict";
|
|
7604
|
+
init_cjs_shims();
|
|
7605
|
+
import_crypto2 = __toESM(require("crypto"));
|
|
7606
|
+
MAGIC = Buffer.from("RFENC1");
|
|
7607
|
+
SALT_LEN = 16;
|
|
7608
|
+
IV_LEN = 12;
|
|
7609
|
+
TAG_LEN = 16;
|
|
7610
|
+
}
|
|
7611
|
+
});
|
|
7612
|
+
|
|
7589
7613
|
// src/license/JwtVerifier.ts
|
|
7590
7614
|
var init_JwtVerifier = __esm({
|
|
7591
7615
|
"src/license/JwtVerifier.ts"() {
|
|
@@ -7622,13 +7646,13 @@ var init_chartjs_bundle = __esm({
|
|
|
7622
7646
|
function fmtMb(bytes) {
|
|
7623
7647
|
return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
|
|
7624
7648
|
}
|
|
7625
|
-
var import_fs8,
|
|
7649
|
+
var import_fs8, import_path5, PdfGenerator;
|
|
7626
7650
|
var init_PdfGenerator = __esm({
|
|
7627
7651
|
"src/pdf/PdfGenerator.ts"() {
|
|
7628
7652
|
"use strict";
|
|
7629
7653
|
init_cjs_shims();
|
|
7630
7654
|
import_fs8 = __toESM(require("fs"));
|
|
7631
|
-
|
|
7655
|
+
import_path5 = __toESM(require("path"));
|
|
7632
7656
|
init_engine();
|
|
7633
7657
|
init_ScreenshotEmbedder();
|
|
7634
7658
|
init_BrowserManager();
|
|
@@ -7638,6 +7662,7 @@ var init_PdfGenerator = __esm({
|
|
|
7638
7662
|
init_FilenameResolver();
|
|
7639
7663
|
init_compression();
|
|
7640
7664
|
init_FailurePaginator();
|
|
7665
|
+
init_sidecar_crypto();
|
|
7641
7666
|
init_logger();
|
|
7642
7667
|
init_sections();
|
|
7643
7668
|
init_JwtVerifier();
|
|
@@ -7738,7 +7763,7 @@ var init_PdfGenerator = __esm({
|
|
|
7738
7763
|
const templateId = source.kind === "builtin" ? source.id : "detailed";
|
|
7739
7764
|
const templateData = { ...data, meta: { ...data.meta, template: templateId } };
|
|
7740
7765
|
const templateOptions = { ...options, template: templateId };
|
|
7741
|
-
await this.renderPdf(templateData, templateOptions, source, compression, outputPath, page);
|
|
7766
|
+
let { sidecarPath } = await this.renderPdf(templateData, templateOptions, source, compression, outputPath, page);
|
|
7742
7767
|
const capBytes = (options.maxFileSizeMb ?? 0) * 1024 * 1024;
|
|
7743
7768
|
if (capBytes > 0) {
|
|
7744
7769
|
const sizeBytes = (await import_fs8.default.promises.stat(outputPath)).size;
|
|
@@ -7748,7 +7773,8 @@ var init_PdfGenerator = __esm({
|
|
|
7748
7773
|
logger.warn(
|
|
7749
7774
|
`PDF size ${fmtMb(sizeBytes)} exceeds cap ${fmtMb(capBytes)} \u2014 re-rendering (jpeg-q=${tighter.quality}, max-w=${tighter.maxWidth}px, inline-failures\u2264${tighter.maxInlineFailures}).`
|
|
7750
7775
|
);
|
|
7751
|
-
await this.renderPdf(templateData, templateOptions, source, tighter, outputPath, page);
|
|
7776
|
+
const retuned = await this.renderPdf(templateData, templateOptions, source, tighter, outputPath, page);
|
|
7777
|
+
sidecarPath = retuned.sidecarPath ?? sidecarPath;
|
|
7752
7778
|
const finalSize = (await import_fs8.default.promises.stat(outputPath)).size;
|
|
7753
7779
|
if (finalSize > capBytes) {
|
|
7754
7780
|
logger.warn(
|
|
@@ -7760,7 +7786,36 @@ var init_PdfGenerator = __esm({
|
|
|
7760
7786
|
}
|
|
7761
7787
|
}
|
|
7762
7788
|
if (options.pdfPassword) {
|
|
7763
|
-
|
|
7789
|
+
let pdfEncrypted = false;
|
|
7790
|
+
try {
|
|
7791
|
+
await this.pdfEncryptor.encrypt(outputPath, options.pdfPassword);
|
|
7792
|
+
pdfEncrypted = true;
|
|
7793
|
+
if (sidecarPath && import_fs8.default.existsSync(sidecarPath)) {
|
|
7794
|
+
const blob = encryptSidecar(await import_fs8.default.promises.readFile(sidecarPath), options.pdfPassword);
|
|
7795
|
+
await import_fs8.default.promises.writeFile(`${sidecarPath}.enc`, blob);
|
|
7796
|
+
await import_fs8.default.promises.unlink(sidecarPath);
|
|
7797
|
+
logger.info(`Overflow sidecar encrypted \u2192 ${import_path5.default.basename(sidecarPath)}.enc`);
|
|
7798
|
+
} else {
|
|
7799
|
+
const staleSidecarPath = sidecarPathFor(outputPath);
|
|
7800
|
+
if (import_fs8.default.existsSync(staleSidecarPath)) {
|
|
7801
|
+
import_fs8.default.rmSync(staleSidecarPath, { force: true });
|
|
7802
|
+
logger.info(`Removed stale plaintext sidecar: ${import_path5.default.basename(staleSidecarPath)}`);
|
|
7803
|
+
}
|
|
7804
|
+
}
|
|
7805
|
+
} catch (err) {
|
|
7806
|
+
const sidecarTargets = sidecarPath ? [sidecarPath, `${sidecarPath}.enc`] : [];
|
|
7807
|
+
const cleanupTargets = pdfEncrypted ? sidecarTargets : [outputPath, ...sidecarTargets];
|
|
7808
|
+
for (const target of cleanupTargets) {
|
|
7809
|
+
try {
|
|
7810
|
+
import_fs8.default.rmSync(target, { force: true });
|
|
7811
|
+
} catch (cleanupErr) {
|
|
7812
|
+
logger.warn(
|
|
7813
|
+
`Could not remove leftover file after encryption failure: ${target} (${cleanupErr.message})`
|
|
7814
|
+
);
|
|
7815
|
+
}
|
|
7816
|
+
}
|
|
7817
|
+
throw err;
|
|
7818
|
+
}
|
|
7764
7819
|
}
|
|
7765
7820
|
const finalSizeMb = fmtMb((await import_fs8.default.promises.stat(outputPath)).size);
|
|
7766
7821
|
logger.info(`PDF report generated: ${outputPath} (${finalSizeMb})`);
|
|
@@ -7775,17 +7830,17 @@ var init_PdfGenerator = __esm({
|
|
|
7775
7830
|
if (options.templatePath && options.templatePath.length > 0) {
|
|
7776
7831
|
const byAbsolutePath = /* @__PURE__ */ new Map();
|
|
7777
7832
|
for (const p of options.templatePath) {
|
|
7778
|
-
const absolutePath =
|
|
7833
|
+
const absolutePath = import_path5.default.isAbsolute(p) ? p : import_path5.default.resolve(process.cwd(), p);
|
|
7779
7834
|
if (!byAbsolutePath.has(absolutePath)) byAbsolutePath.set(absolutePath, p);
|
|
7780
7835
|
}
|
|
7781
7836
|
const labelCounts = /* @__PURE__ */ new Map();
|
|
7782
7837
|
for (const rawPath of byAbsolutePath.values()) {
|
|
7783
|
-
const label =
|
|
7838
|
+
const label = import_path5.default.basename(rawPath, ".hbs");
|
|
7784
7839
|
labelCounts.set(label, (labelCounts.get(label) ?? 0) + 1);
|
|
7785
7840
|
}
|
|
7786
7841
|
const seenPerLabel = /* @__PURE__ */ new Map();
|
|
7787
7842
|
return Array.from(byAbsolutePath.entries()).map(([absolutePath, rawPath]) => {
|
|
7788
|
-
const baseLabel =
|
|
7843
|
+
const baseLabel = import_path5.default.basename(rawPath, ".hbs");
|
|
7789
7844
|
let label = baseLabel;
|
|
7790
7845
|
if ((labelCounts.get(baseLabel) ?? 0) > 1) {
|
|
7791
7846
|
const n = (seenPerLabel.get(baseLabel) ?? 0) + 1;
|
|
@@ -7845,7 +7900,7 @@ var init_PdfGenerator = __esm({
|
|
|
7845
7900
|
...data,
|
|
7846
7901
|
failures: paginated.inline,
|
|
7847
7902
|
overflowFailureCount: paginated.overflowCount,
|
|
7848
|
-
overflowSidecarName: paginated.sidecarPath ?
|
|
7903
|
+
overflowSidecarName: paginated.sidecarPath ? import_path5.default.basename(paginated.sidecarPath) + (options.pdfPassword ? ".enc" : "") : void 0
|
|
7849
7904
|
};
|
|
7850
7905
|
for (const f of renderData.failures) f.screenshotBase64 = void 0;
|
|
7851
7906
|
if (options.includeScreenshots !== false) {
|
|
@@ -7870,7 +7925,7 @@ var init_PdfGenerator = __esm({
|
|
|
7870
7925
|
await page.goto(fileUrl, { waitUntil: "domcontentloaded", timeout: 6e4 });
|
|
7871
7926
|
const showCharts = source.kind === "builtin" ? resolveSections(source.id, options.sections).charts : true;
|
|
7872
7927
|
await this.chartRenderer.waitForCharts(page, showCharts);
|
|
7873
|
-
logger.info(`Generating PDF \u2192 ${
|
|
7928
|
+
logger.info(`Generating PDF \u2192 ${import_path5.default.relative(process.cwd(), outputPath)}`);
|
|
7874
7929
|
await page.pdf({
|
|
7875
7930
|
path: outputPath,
|
|
7876
7931
|
format: "A4",
|
|
@@ -7880,6 +7935,7 @@ var init_PdfGenerator = __esm({
|
|
|
7880
7935
|
} finally {
|
|
7881
7936
|
await this.htmlWriter.cleanup();
|
|
7882
7937
|
}
|
|
7938
|
+
return { sidecarPath: paginated.overflowCount > 0 ? paginated.sidecarPath : void 0 };
|
|
7883
7939
|
}
|
|
7884
7940
|
};
|
|
7885
7941
|
}
|
|
@@ -8307,8 +8363,8 @@ var init_parseUtil = __esm({
|
|
|
8307
8363
|
init_errors();
|
|
8308
8364
|
init_en();
|
|
8309
8365
|
makeIssue = (params) => {
|
|
8310
|
-
const { data, path:
|
|
8311
|
-
const fullPath = [...
|
|
8366
|
+
const { data, path: path13, errorMaps, issueData } = params;
|
|
8367
|
+
const fullPath = [...path13, ...issueData.path || []];
|
|
8312
8368
|
const fullIssue = {
|
|
8313
8369
|
...issueData,
|
|
8314
8370
|
path: fullPath
|
|
@@ -8622,11 +8678,11 @@ var init_types = __esm({
|
|
|
8622
8678
|
init_parseUtil();
|
|
8623
8679
|
init_util();
|
|
8624
8680
|
ParseInputLazyPath = class {
|
|
8625
|
-
constructor(parent, value,
|
|
8681
|
+
constructor(parent, value, path13, key) {
|
|
8626
8682
|
this._cachedPath = [];
|
|
8627
8683
|
this.parent = parent;
|
|
8628
8684
|
this.data = value;
|
|
8629
|
-
this._path =
|
|
8685
|
+
this._path = path13;
|
|
8630
8686
|
this._key = key;
|
|
8631
8687
|
}
|
|
8632
8688
|
get path() {
|
|
@@ -12021,7 +12077,7 @@ ${issues}`);
|
|
|
12021
12077
|
}
|
|
12022
12078
|
return result.data;
|
|
12023
12079
|
}
|
|
12024
|
-
var hexColor, channelConfigSchema, discordChannelConfigSchema, emailChannelConfigSchema, notifyConfigSchema, failureAnalysisConfigSchema, captureConfigSchema, liveConfigSchema, sectionFlagsShape, sectionFlagsSchema, sectionsSchema, ReporterOptionsSchema;
|
|
12080
|
+
var hexColor, channelConfigSchema, discordChannelConfigSchema, emailChannelConfigSchema, notifyConfigSchema, failureAnalysisConfigSchema, captureConfigSchema, liveConfigSchema, redactConfigSchema, sectionFlagsShape, sectionFlagsSchema, sectionsSchema, ReporterOptionsSchema;
|
|
12025
12081
|
var init_schema = __esm({
|
|
12026
12082
|
"src/config/schema.ts"() {
|
|
12027
12083
|
"use strict";
|
|
@@ -12094,6 +12150,21 @@ var init_schema = __esm({
|
|
|
12094
12150
|
// Debounce window for batched flushes (ms).
|
|
12095
12151
|
flushMs: external_exports.number().int().min(500).max(1e4).default(2e3)
|
|
12096
12152
|
}).default({});
|
|
12153
|
+
redactConfigSchema = external_exports.object({
|
|
12154
|
+
enabled: external_exports.boolean().default(false),
|
|
12155
|
+
builtins: external_exports.boolean().default(true),
|
|
12156
|
+
patterns: external_exports.array(
|
|
12157
|
+
external_exports.string().refine((v) => {
|
|
12158
|
+
try {
|
|
12159
|
+
new RegExp(v);
|
|
12160
|
+
return true;
|
|
12161
|
+
} catch {
|
|
12162
|
+
return false;
|
|
12163
|
+
}
|
|
12164
|
+
}, "Each redact.patterns entry must be a valid regular expression")
|
|
12165
|
+
).default([]),
|
|
12166
|
+
mask: external_exports.string().default("[REDACTED]")
|
|
12167
|
+
}).default({});
|
|
12097
12168
|
sectionFlagsShape = Object.fromEntries(
|
|
12098
12169
|
SECTION_KEYS.map((k) => [k, external_exports.boolean().optional()])
|
|
12099
12170
|
);
|
|
@@ -12114,7 +12185,7 @@ var init_schema = __esm({
|
|
|
12114
12185
|
primaryColor: hexColor.optional().default(DEFAULT_OPTIONS.primaryColor),
|
|
12115
12186
|
accentColor: hexColor.optional().default(DEFAULT_OPTIONS.accentColor),
|
|
12116
12187
|
watermark: external_exports.string().optional(),
|
|
12117
|
-
pdfPassword: external_exports.string().optional(),
|
|
12188
|
+
pdfPassword: external_exports.string().min(1, "pdfPassword must not be empty. Omit the option (or leave the env var unset) to disable encryption.").optional(),
|
|
12118
12189
|
reportTitle: external_exports.string().optional().default(DEFAULT_OPTIONS.reportTitle),
|
|
12119
12190
|
projectName: external_exports.string().optional(),
|
|
12120
12191
|
open: external_exports.boolean().optional().default(DEFAULT_OPTIONS.open),
|
|
@@ -12147,6 +12218,7 @@ var init_schema = __esm({
|
|
|
12147
12218
|
}, "requirementTagPattern must be a valid regular expression").optional().default(DEFAULT_OPTIONS.requirementTagPattern),
|
|
12148
12219
|
failureAnalysis: failureAnalysisConfigSchema,
|
|
12149
12220
|
capture: captureConfigSchema,
|
|
12221
|
+
redact: redactConfigSchema,
|
|
12150
12222
|
live: liveConfigSchema,
|
|
12151
12223
|
templatePath: external_exports.union([
|
|
12152
12224
|
external_exports.string().regex(/\.hbs$/, "templatePath must end with .hbs").refine((v) => v.slice(0, -4).trim().length > 0, "templatePath basename must not be empty"),
|
|
@@ -12858,7 +12930,7 @@ function parseArgs() {
|
|
|
12858
12930
|
console.warn(`[reportforge] Unknown template '${rawTemplate}', using 'detailed'. Valid: ${TEMPLATE_IDS.join(", ")}`);
|
|
12859
12931
|
}
|
|
12860
12932
|
const template = rawTemplate && VALID_TEMPLATES.has(rawTemplate) ? rawTemplate : "detailed";
|
|
12861
|
-
const outputFile = rawOutput ??
|
|
12933
|
+
const outputFile = rawOutput ?? import_path6.default.join("playwright-report", "demo-report.pdf");
|
|
12862
12934
|
return { template, outputFile };
|
|
12863
12935
|
}
|
|
12864
12936
|
async function run() {
|
|
@@ -12900,12 +12972,12 @@ async function runDemo() {
|
|
|
12900
12972
|
process.exit(1);
|
|
12901
12973
|
}
|
|
12902
12974
|
}
|
|
12903
|
-
var
|
|
12975
|
+
var import_path6, DEMO_LICENSE_INFO2, VALID_TEMPLATES;
|
|
12904
12976
|
var init_cli = __esm({
|
|
12905
12977
|
"src/demo/cli.ts"() {
|
|
12906
12978
|
"use strict";
|
|
12907
12979
|
init_cjs_shims();
|
|
12908
|
-
|
|
12980
|
+
import_path6 = __toESM(require("path"));
|
|
12909
12981
|
init_fixture();
|
|
12910
12982
|
init_PdfGenerator();
|
|
12911
12983
|
init_schema();
|
|
@@ -13508,6 +13580,32 @@ var init_evaluate_model = __esm({
|
|
|
13508
13580
|
}
|
|
13509
13581
|
});
|
|
13510
13582
|
|
|
13583
|
+
// src/cli/decrypt-failures.ts
|
|
13584
|
+
var decrypt_failures_exports = {};
|
|
13585
|
+
__export(decrypt_failures_exports, {
|
|
13586
|
+
decryptFailuresCli: () => decryptFailuresCli
|
|
13587
|
+
});
|
|
13588
|
+
function decryptFailuresCli(argv) {
|
|
13589
|
+
const input = argv.find((a) => !a.startsWith("--"));
|
|
13590
|
+
if (!input) throw new Error("Usage: decrypt-failures <file.json.enc> [--password=\u2026] [--out=\u2026]");
|
|
13591
|
+
const password = flagValue(argv, "--password") ?? process.env.RF_PDF_PASSWORD;
|
|
13592
|
+
if (!password) throw new Error("No password: pass --password=\u2026 or set RF_PDF_PASSWORD.");
|
|
13593
|
+
const out = flagValue(argv, "--out") ?? (input.endsWith(".enc") ? input.slice(0, -".enc".length) : `${input}.json`);
|
|
13594
|
+
const plain = decryptSidecar(import_fs9.default.readFileSync(input), password);
|
|
13595
|
+
import_fs9.default.writeFileSync(out, plain);
|
|
13596
|
+
return out;
|
|
13597
|
+
}
|
|
13598
|
+
var import_fs9;
|
|
13599
|
+
var init_decrypt_failures = __esm({
|
|
13600
|
+
"src/cli/decrypt-failures.ts"() {
|
|
13601
|
+
"use strict";
|
|
13602
|
+
init_cjs_shims();
|
|
13603
|
+
import_fs9 = __toESM(require("fs"));
|
|
13604
|
+
init_sidecar_crypto();
|
|
13605
|
+
init_model_cli_shared();
|
|
13606
|
+
}
|
|
13607
|
+
});
|
|
13608
|
+
|
|
13511
13609
|
// src/cli/index.ts
|
|
13512
13610
|
init_cjs_shims();
|
|
13513
13611
|
|
|
@@ -13528,6 +13626,9 @@ Commands:
|
|
|
13528
13626
|
--project train only on feedback from the current directory's project
|
|
13529
13627
|
evaluate-model Compare base vs. base+local on your labeled feedback without writing anything.
|
|
13530
13628
|
--model=<path> also print a stored model file's metadata and metrics
|
|
13629
|
+
decrypt-failures Decrypt an encrypted failure-overflow sidecar (*.json.enc).
|
|
13630
|
+
--password=<pw> (or RF_PDF_PASSWORD env)
|
|
13631
|
+
--out=<path> (default: input path minus .enc)
|
|
13531
13632
|
|
|
13532
13633
|
Run "npx @reportforge/playwright-pdf demo" to see the report ReportForge produces.`;
|
|
13533
13634
|
function pickCommand(arg) {
|
|
@@ -13542,6 +13643,8 @@ function pickCommand(arg) {
|
|
|
13542
13643
|
return "train-model";
|
|
13543
13644
|
case "evaluate-model":
|
|
13544
13645
|
return "evaluate-model";
|
|
13646
|
+
case "decrypt-failures":
|
|
13647
|
+
return "decrypt-failures";
|
|
13545
13648
|
default:
|
|
13546
13649
|
return "help";
|
|
13547
13650
|
}
|
|
@@ -13590,6 +13693,13 @@ async function main() {
|
|
|
13590
13693
|
evaluateModelCli2(process.argv.slice(3));
|
|
13591
13694
|
return;
|
|
13592
13695
|
}
|
|
13696
|
+
case "decrypt-failures": {
|
|
13697
|
+
const { decryptFailuresCli: decryptFailuresCli2 } = await Promise.resolve().then(() => (init_decrypt_failures(), decrypt_failures_exports));
|
|
13698
|
+
const out = decryptFailuresCli2(process.argv.slice(3));
|
|
13699
|
+
process.stdout.write(`Decrypted \u2192 ${out}
|
|
13700
|
+
`);
|
|
13701
|
+
return;
|
|
13702
|
+
}
|
|
13593
13703
|
case "help": {
|
|
13594
13704
|
const { text, stream, code } = helpOutput(arg);
|
|
13595
13705
|
(stream === "stdout" ? process.stdout : process.stderr).write(text);
|