initial cli api, some movement on tool selection

This commit is contained in:
2025-04-24 20:27:09 -06:00
parent 08bba857db
commit 7d42920dcb
18 changed files with 938 additions and 180 deletions

59
tools/checkCode.ts Normal file
View File

@@ -0,0 +1,59 @@
import { PDFDocument } from "pdf-lib";
import { loadPdfForm } from "../util/saveLoadPdf.ts";
import { callWithArgPrompt } from "util/call.ts";
export async function checkFile(pdfPath: string, csPath: string) {
while (!pdfPath || !pdfPath.endsWith(".pdf")) {
pdfPath = prompt("Please provide path to PDF file:") || "";
}
while (!csPath || !csPath.endsWith(".cs")) {
csPath = prompt("Please provide path to CS class file:") || "";
}
const form = await loadPdfForm(pdfPath);
const fields = form.getFields();
const csFiles = await Promise.all(
csPath.split(",").map((c) => Deno.readTextFile(c.trim())),
);
const fieldNames: string[] = fields.map((f) => f.getName())
.filter((f) => {
const rx = new RegExp(
`(?<!//\s?)case ?"${f.replace(/\[\d\]/, "\\[\\?\\]")}"`,
);
return !csFiles.some((c) => rx.test(c));
})
.filter((f) => !f.toLowerCase().includes("signature"));
if (fieldNames.length) {
console.log(
"%cThe following field names are not present in the CS code",
"color: red",
);
console.log(fieldNames);
alert("Your princess is in another castle...");
} else {
console.log("%cAll form fields present", "color: lime");
alert("Ok!");
}
}
class CheckCode implements ITool {
name = "checkcode";
description = "Checks if form fields are present in CS code";
help() {
console.log("Usage: checkcode <pdfPath> <csPath>");
}
async run(...args: string[]) {
await callWithArgPrompt(checkFile, [
["Please provide path to PDF file:", (p) => !!p && p.endsWith(".pdf")],
[
"Please provide path to CS file (comma separated for multiple):",
(p) => !!p && p.endsWith(".cs"),
],
], args);
}
}
export default new CheckCode();

93
tools/fieldRename.ts Normal file
View File

@@ -0,0 +1,93 @@
import {
PDFAcroField,
PDFHexString,
PDFName,
PDFString,
toHexString,
} from "pdf-lib";
import { loadPdfForm, savePdf } from "util/saveLoadPdf.ts";
import { PDFDocument } from "pdf-lib";
import { call, callWithArgPrompt } from "util/call.ts";
// const thing = PDFAcroField.prototype.getFullyQualifiedName;
// PDFAcroField.prototype.getFullyQualifiedName = function () {
// const name = thing.call(this)
// // if (name?.includes('langauge'))
// console.log(name)
// return name;
// }
// const thing = PDFHexString.prototype.copyBytesInto
// PDFHexString.prototype.copyBytesInto = function (buffer: Uint8Array, offset: number) {
// console.log((this as any).value)
// const result = thing.call(this, buffer, offset)
// return result;
// }
async function renameFields(
path: string,
pattern: string | RegExp,
change: string,
) {
if (typeof pattern === "string") pattern = new RegExp(pattern);
const form = await loadPdfForm(path);
const fields = form.getFields();
let changesMade = false;
for (const field of fields) {
const name = field.getName();
if (pattern.test(name)) {
console.log(name + " %cfound", "color: red");
const segments = name.split(".");
const matchingSegments = segments.filter((s) => pattern.test(s));
let cField: PDFAcroField | undefined = field.acroField;
while (cField) {
if (
cField.getPartialName() &&
matchingSegments.includes(cField.getPartialName()!)
) {
const mName = cField.getPartialName()?.replace(pattern, change);
if (mName) {
changesMade = true;
cField.dict.set(PDFName.of("T"), PDFString.of(mName));
// console.log(cField.getPartialName())
}
}
cField = cField.getParent();
// console.log(cField?.getPartialName())
}
console.log(field.getName());
// const newName = name.replace(pattern, change);
// console.log("Change to: %c" + newName, "color: yellow");
// if (confirm('Ok?')) {
// let parent = field.acroField.getParent();
// field.acroField.setPartialName(segments.pop())
// while (parent && segments.length) {
// console.log(parent.getPartialName())
// parent.setPartialName(segments.pop())
// parent = parent.getParent();
// }
// changesMade = true;
// console.log(field.getName())
// // dict.set(PDFName.of("T"), PDFHexString.fromText(newName))
// console.log("%cDone!", "color: lime")
// }
// break;
}
}
if (changesMade) {
savePdf(form.doc, path);
}
}
if (import.meta.main) {
// await call(renameFields)
// while (!path || !path.endsWith('.pdf')) path = prompt("Please provide path to PDF:") || '';
// while (!pattern) pattern = prompt("Please provide search string:") || '';
// while (!change) change = prompt("Please provide requested change:") || '';
await callWithArgPrompt(renameFields, [
["Please provide path to PDF:", (p) => !!p && p.endsWith(".pdf")],
"Please provide search string:",
"Please provide requested change:",
]);
}