@unlev/exeq 0.3.1 → 0.3.2
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 +102 -2
- package/dist/index.d.mts +116 -2
- package/dist/index.d.ts +116 -2
- package/dist/index.js +254 -139
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +253 -140
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -614,6 +614,13 @@ function FieldPropertyPanel({ field, signerRoles, onUpdate, onDelete, prefillCon
|
|
|
614
614
|
/* @__PURE__ */ jsx2("input", { type: "number", min: "0", max: "9999", value: field.maxLength || 0, onChange: (e) => onUpdate(field.id, { maxLength: Number(e.target.value) }) })
|
|
615
615
|
] })
|
|
616
616
|
] }),
|
|
617
|
+
isTextField && /* @__PURE__ */ jsxs2("div", { className: "panel-field", children: [
|
|
618
|
+
/* @__PURE__ */ jsxs2("label", { className: "panel-checkbox-label", children: [
|
|
619
|
+
/* @__PURE__ */ jsx2("input", { type: "checkbox", checked: field.autoShrink || false, onChange: (e) => onUpdate(field.id, { autoShrink: e.target.checked }) }),
|
|
620
|
+
"Auto-shrink to fit"
|
|
621
|
+
] }),
|
|
622
|
+
field.autoShrink && /* @__PURE__ */ jsx2("span", { className: "panel-hint", children: "Font size reduces to fit text within the field width" })
|
|
623
|
+
] }),
|
|
617
624
|
(field.type === "text" || field.type === "dropdown") && /* @__PURE__ */ jsxs2("div", { className: "panel-field", children: [
|
|
618
625
|
/* @__PURE__ */ jsx2("label", { children: field.type === "dropdown" ? "Options" : "Predefined Options" }),
|
|
619
626
|
/* @__PURE__ */ jsxs2("div", { className: "panel-options-list", children: [
|
|
@@ -1982,34 +1989,137 @@ function DesignerView({
|
|
|
1982
1989
|
import { useState as useState7, useCallback as useCallback5, useEffect as useEffect3, useRef as useRef5 } from "react";
|
|
1983
1990
|
|
|
1984
1991
|
// src/utils/pdfFiller.ts
|
|
1985
|
-
import {
|
|
1992
|
+
import {
|
|
1993
|
+
PDFDocument,
|
|
1994
|
+
rgb,
|
|
1995
|
+
StandardFonts
|
|
1996
|
+
} from "pdf-lib";
|
|
1997
|
+
|
|
1998
|
+
// src/utils/formulaResolver.ts
|
|
1999
|
+
var BUILTIN_TRANSFORMS = {
|
|
2000
|
+
// Date transforms (expects a parseable date string)
|
|
2001
|
+
month: (v) => {
|
|
2002
|
+
const d = new Date(v);
|
|
2003
|
+
return isNaN(d.getTime()) ? "" : String(d.getMonth() + 1);
|
|
2004
|
+
},
|
|
2005
|
+
month2: (v) => {
|
|
2006
|
+
const d = new Date(v);
|
|
2007
|
+
return isNaN(d.getTime()) ? "" : String(d.getMonth() + 1).padStart(2, "0");
|
|
2008
|
+
},
|
|
2009
|
+
monthname: (v) => {
|
|
2010
|
+
const d = new Date(v);
|
|
2011
|
+
return isNaN(d.getTime()) ? "" : d.toLocaleString("en", { month: "long" });
|
|
2012
|
+
},
|
|
2013
|
+
monthshort: (v) => {
|
|
2014
|
+
const d = new Date(v);
|
|
2015
|
+
return isNaN(d.getTime()) ? "" : d.toLocaleString("en", { month: "short" });
|
|
2016
|
+
},
|
|
2017
|
+
day: (v) => {
|
|
2018
|
+
const d = new Date(v);
|
|
2019
|
+
return isNaN(d.getTime()) ? "" : String(d.getDate());
|
|
2020
|
+
},
|
|
2021
|
+
day2: (v) => {
|
|
2022
|
+
const d = new Date(v);
|
|
2023
|
+
return isNaN(d.getTime()) ? "" : String(d.getDate()).padStart(2, "0");
|
|
2024
|
+
},
|
|
2025
|
+
year: (v) => {
|
|
2026
|
+
const d = new Date(v);
|
|
2027
|
+
return isNaN(d.getTime()) ? "" : String(d.getFullYear());
|
|
2028
|
+
},
|
|
2029
|
+
year2: (v) => {
|
|
2030
|
+
const d = new Date(v);
|
|
2031
|
+
return isNaN(d.getTime()) ? "" : String(d.getFullYear()).slice(-2);
|
|
2032
|
+
},
|
|
2033
|
+
// String transforms
|
|
2034
|
+
upper: (v) => v.toUpperCase(),
|
|
2035
|
+
lower: (v) => v.toLowerCase(),
|
|
2036
|
+
trim: (v) => v.trim(),
|
|
2037
|
+
first: (v) => v.split(/\s+/)[0] || "",
|
|
2038
|
+
last: (v) => {
|
|
2039
|
+
const parts = v.split(/\s+/);
|
|
2040
|
+
return parts[parts.length - 1] || "";
|
|
2041
|
+
},
|
|
2042
|
+
initials: (v) => v.split(/\s+/).map((w) => w[0] || "").join("").toUpperCase(),
|
|
2043
|
+
// Numeric / substring
|
|
2044
|
+
last4: (v) => v.slice(-4),
|
|
2045
|
+
last2: (v) => v.slice(-2),
|
|
2046
|
+
first4: (v) => v.slice(0, 4),
|
|
2047
|
+
first2: (v) => v.slice(0, 2),
|
|
2048
|
+
digits: (v) => v.replace(/\D/g, ""),
|
|
2049
|
+
number: (v) => {
|
|
2050
|
+
const n = parseFloat(v);
|
|
2051
|
+
return isNaN(n) ? "" : String(n);
|
|
2052
|
+
},
|
|
2053
|
+
currency: (v) => {
|
|
2054
|
+
const n = parseFloat(v.replace(/[^0-9.-]/g, ""));
|
|
2055
|
+
return isNaN(n) ? "" : `$${n.toFixed(2)}`;
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
2058
|
+
var FORMULA_RE = /\{\{(.+?)\}\}/g;
|
|
2059
|
+
var PIPE_RE = /^(.+?)\s*\|\s*(.+)$/;
|
|
2060
|
+
function resolveFormula(formula, fields, customTransforms) {
|
|
2061
|
+
const transforms = { ...BUILTIN_TRANSFORMS, ...customTransforms };
|
|
2062
|
+
return formula.replace(FORMULA_RE, (_match, expr) => {
|
|
2063
|
+
const pipeMatch = expr.match(PIPE_RE);
|
|
2064
|
+
const sourceLabel = (pipeMatch ? pipeMatch[1] : expr).trim();
|
|
2065
|
+
const transformName = pipeMatch ? pipeMatch[2].trim() : null;
|
|
2066
|
+
const sourceField = fields.find((f) => f.label.toLowerCase() === sourceLabel.toLowerCase()) || fields.find((f) => f.id === sourceLabel);
|
|
2067
|
+
if (!sourceField) return "";
|
|
2068
|
+
const rawValue = sourceField.value || "";
|
|
2069
|
+
if (!transformName) return rawValue;
|
|
2070
|
+
const fn = transforms[transformName];
|
|
2071
|
+
if (!fn) return rawValue;
|
|
2072
|
+
try {
|
|
2073
|
+
return fn(rawValue);
|
|
2074
|
+
} catch {
|
|
2075
|
+
return rawValue;
|
|
2076
|
+
}
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
function resolveAllFormulas(fields, customTransforms) {
|
|
2080
|
+
return fields.map((f) => {
|
|
2081
|
+
if (!f.formula) return f;
|
|
2082
|
+
const computed = resolveFormula(f.formula, fields, customTransforms);
|
|
2083
|
+
return computed !== f.value ? { ...f, value: computed } : f;
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
// src/utils/pdfFiller.ts
|
|
1986
2088
|
var FONT_MAP = {
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
2089
|
+
Helvetica: StandardFonts.Helvetica,
|
|
2090
|
+
Courier: StandardFonts.Courier,
|
|
2091
|
+
TimesRoman: StandardFonts.TimesRoman
|
|
1990
2092
|
};
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
const stdFont = FONT_MAP[key] || StandardFonts.Helvetica;
|
|
2004
|
-
fontCache.set(key, await pdfDoc.embedFont(stdFont));
|
|
2005
|
-
}
|
|
2006
|
-
const pages = pdfDoc.getPages();
|
|
2007
|
-
function hexToRgb(hex) {
|
|
2008
|
-
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
2009
|
-
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
2010
|
-
const b = parseInt(hex.slice(5, 7), 16) / 255;
|
|
2011
|
-
return rgb(r, g, b);
|
|
2093
|
+
var US_LETTER = [612, 792];
|
|
2094
|
+
var US_LEGAL = [612, 1008];
|
|
2095
|
+
var A4 = [595.28, 841.89];
|
|
2096
|
+
var DEFAULT_CALIBRATION = {
|
|
2097
|
+
xOffset: 0,
|
|
2098
|
+
yOffset: 0,
|
|
2099
|
+
xScale: 1,
|
|
2100
|
+
yScale: 1
|
|
2101
|
+
};
|
|
2102
|
+
function applyCalibration(fields, calibration, pageSize = US_LETTER) {
|
|
2103
|
+
if (calibration.xOffset === 0 && calibration.yOffset === 0 && calibration.xScale === 1 && calibration.yScale === 1) {
|
|
2104
|
+
return fields;
|
|
2012
2105
|
}
|
|
2106
|
+
const xPctOff = calibration.xOffset / pageSize[0] * 100;
|
|
2107
|
+
const yPctOff = calibration.yOffset / pageSize[1] * 100;
|
|
2108
|
+
return fields.map((f) => ({
|
|
2109
|
+
...f,
|
|
2110
|
+
x: f.x * calibration.xScale + xPctOff,
|
|
2111
|
+
y: f.y * calibration.yScale + yPctOff,
|
|
2112
|
+
width: f.width * calibration.xScale,
|
|
2113
|
+
height: f.height * calibration.yScale
|
|
2114
|
+
}));
|
|
2115
|
+
}
|
|
2116
|
+
function hexToRgb(hex) {
|
|
2117
|
+
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
2118
|
+
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
2119
|
+
const b = parseInt(hex.slice(5, 7), 16) / 255;
|
|
2120
|
+
return rgb(r, g, b);
|
|
2121
|
+
}
|
|
2122
|
+
async function renderFieldsOnPages(pages, fields, getFont, getSignature) {
|
|
2013
2123
|
for (const field of fields) {
|
|
2014
2124
|
const page = pages[field.page];
|
|
2015
2125
|
if (!page) continue;
|
|
@@ -2050,37 +2160,32 @@ async function generateFilledPdf(pdfSource, fields) {
|
|
|
2050
2160
|
}
|
|
2051
2161
|
} else if (field.type === "signature" || field.type === "initials") {
|
|
2052
2162
|
if (field.value.startsWith("data:image/png")) {
|
|
2053
|
-
const
|
|
2054
|
-
|
|
2055
|
-
(c) => c.charCodeAt(0)
|
|
2056
|
-
);
|
|
2057
|
-
const pngImage = await pdfDoc.embedPng(pngBytes);
|
|
2058
|
-
page.drawImage(pngImage, {
|
|
2059
|
-
x,
|
|
2060
|
-
y,
|
|
2061
|
-
width: w,
|
|
2062
|
-
height: h
|
|
2063
|
-
});
|
|
2163
|
+
const img = await getSignature(field.value);
|
|
2164
|
+
page.drawImage(img, { x, y, width: w, height: h });
|
|
2064
2165
|
}
|
|
2065
2166
|
} else {
|
|
2066
|
-
const font =
|
|
2167
|
+
const font = await getFont(field.fontFamily || "Helvetica");
|
|
2067
2168
|
const spacing = field.letterSpacing || 0;
|
|
2068
|
-
const textWidthAtSize = (text, size) =>
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
if (textWidthAtSize(field.value, fontSize) <= w - padding) break;
|
|
2077
|
-
fontSize -= 0.5;
|
|
2169
|
+
const textWidthAtSize = (text, size) => font.widthOfTextAtSize(text, size) + spacing * (text.length - 1);
|
|
2170
|
+
let fontSize = Math.min(field.fontSize, h * 0.7);
|
|
2171
|
+
if (field.autoShrink) {
|
|
2172
|
+
const padding = 4;
|
|
2173
|
+
while (fontSize > 4) {
|
|
2174
|
+
if (textWidthAtSize(field.value, fontSize) <= w - padding) break;
|
|
2175
|
+
fontSize -= 0.5;
|
|
2176
|
+
}
|
|
2078
2177
|
}
|
|
2079
2178
|
if (spacing > 0) {
|
|
2080
2179
|
let cx = x + 2;
|
|
2081
2180
|
const cy = y + h * 0.3;
|
|
2082
2181
|
for (const char of field.value) {
|
|
2083
|
-
page.drawText(char, {
|
|
2182
|
+
page.drawText(char, {
|
|
2183
|
+
x: cx,
|
|
2184
|
+
y: cy,
|
|
2185
|
+
size: fontSize,
|
|
2186
|
+
font,
|
|
2187
|
+
color: inkColor
|
|
2188
|
+
});
|
|
2084
2189
|
cx += font.widthOfTextAtSize(char, fontSize) + spacing;
|
|
2085
2190
|
}
|
|
2086
2191
|
} else {
|
|
@@ -2094,7 +2199,98 @@ async function generateFilledPdf(pdfSource, fields) {
|
|
|
2094
2199
|
}
|
|
2095
2200
|
}
|
|
2096
2201
|
}
|
|
2097
|
-
|
|
2202
|
+
}
|
|
2203
|
+
async function generateFilledPdf(opts) {
|
|
2204
|
+
const builder = await createPdfBuilder({ pageSize: opts.pageSize });
|
|
2205
|
+
await builder.addRecord(opts);
|
|
2206
|
+
return builder.save();
|
|
2207
|
+
}
|
|
2208
|
+
async function createPdfBuilder(defaults = {}) {
|
|
2209
|
+
const doc = await PDFDocument.create();
|
|
2210
|
+
const fontCache = /* @__PURE__ */ new Map();
|
|
2211
|
+
const embeddedPagesByUrl = /* @__PURE__ */ new Map();
|
|
2212
|
+
const signatureCache = /* @__PURE__ */ new Map();
|
|
2213
|
+
async function getFont(family) {
|
|
2214
|
+
let f = fontCache.get(family);
|
|
2215
|
+
if (!f) {
|
|
2216
|
+
const stdName = FONT_MAP[family] || StandardFonts.Helvetica;
|
|
2217
|
+
f = await doc.embedFont(stdName);
|
|
2218
|
+
fontCache.set(family, f);
|
|
2219
|
+
}
|
|
2220
|
+
return f;
|
|
2221
|
+
}
|
|
2222
|
+
async function ensureFonts(fields) {
|
|
2223
|
+
const keys = new Set(fields.map((f) => f.fontFamily || "Helvetica"));
|
|
2224
|
+
for (const k of keys) await getFont(k);
|
|
2225
|
+
}
|
|
2226
|
+
async function embedSource(source) {
|
|
2227
|
+
if (typeof source === "string") {
|
|
2228
|
+
let pages = embeddedPagesByUrl.get(source);
|
|
2229
|
+
if (!pages) {
|
|
2230
|
+
const res = await fetch(source);
|
|
2231
|
+
const bytes = await res.arrayBuffer();
|
|
2232
|
+
const srcDoc2 = await PDFDocument.load(bytes);
|
|
2233
|
+
pages = await Promise.all(
|
|
2234
|
+
srcDoc2.getPages().map((p) => doc.embedPage(p))
|
|
2235
|
+
);
|
|
2236
|
+
embeddedPagesByUrl.set(source, pages);
|
|
2237
|
+
}
|
|
2238
|
+
return pages;
|
|
2239
|
+
}
|
|
2240
|
+
const srcDoc = await PDFDocument.load(source);
|
|
2241
|
+
return Promise.all(srcDoc.getPages().map((p) => doc.embedPage(p)));
|
|
2242
|
+
}
|
|
2243
|
+
async function getSignature(dataUrl) {
|
|
2244
|
+
let img = signatureCache.get(dataUrl);
|
|
2245
|
+
if (!img) {
|
|
2246
|
+
const b64 = dataUrl.split(",")[1] ?? "";
|
|
2247
|
+
const pngBytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
2248
|
+
img = await doc.embedPng(pngBytes);
|
|
2249
|
+
signatureCache.set(dataUrl, img);
|
|
2250
|
+
}
|
|
2251
|
+
return img;
|
|
2252
|
+
}
|
|
2253
|
+
return {
|
|
2254
|
+
doc,
|
|
2255
|
+
async addRecord(opts) {
|
|
2256
|
+
const pageSize = opts.pageSize ?? defaults.pageSize;
|
|
2257
|
+
let fields = opts.resolveFormulas ? resolveAllFormulas(opts.fields, opts.customTransforms) : opts.fields;
|
|
2258
|
+
if (opts.calibration) {
|
|
2259
|
+
fields = applyCalibration(
|
|
2260
|
+
fields,
|
|
2261
|
+
opts.calibration,
|
|
2262
|
+
pageSize ?? US_LETTER
|
|
2263
|
+
);
|
|
2264
|
+
}
|
|
2265
|
+
await ensureFonts(fields);
|
|
2266
|
+
let sourcePages = [];
|
|
2267
|
+
let pageCount;
|
|
2268
|
+
if (opts.pdfSource !== null) {
|
|
2269
|
+
sourcePages = await embedSource(opts.pdfSource);
|
|
2270
|
+
pageCount = sourcePages.length;
|
|
2271
|
+
} else {
|
|
2272
|
+
pageCount = opts.pageCount ?? 1;
|
|
2273
|
+
}
|
|
2274
|
+
const newPages = [];
|
|
2275
|
+
for (let i = 0; i < pageCount; i++) {
|
|
2276
|
+
const size = pageSize ? pageSize : sourcePages[i] ? [sourcePages[i].width, sourcePages[i].height] : US_LETTER;
|
|
2277
|
+
const page = doc.addPage(size);
|
|
2278
|
+
newPages.push(page);
|
|
2279
|
+
if (sourcePages[i]) {
|
|
2280
|
+
page.drawPage(sourcePages[i], {
|
|
2281
|
+
x: 0,
|
|
2282
|
+
y: 0,
|
|
2283
|
+
width: size[0],
|
|
2284
|
+
height: size[1]
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
await renderFieldsOnPages(newPages, fields, getFont, getSignature);
|
|
2289
|
+
},
|
|
2290
|
+
async save() {
|
|
2291
|
+
return doc.save();
|
|
2292
|
+
}
|
|
2293
|
+
};
|
|
2098
2294
|
}
|
|
2099
2295
|
function downloadPdf(bytes, filename) {
|
|
2100
2296
|
const blob = new Blob([bytes.slice().buffer], { type: "application/pdf" });
|
|
@@ -2206,95 +2402,6 @@ function FieldNavigator({
|
|
|
2206
2402
|
] });
|
|
2207
2403
|
}
|
|
2208
2404
|
|
|
2209
|
-
// src/utils/formulaResolver.ts
|
|
2210
|
-
var BUILTIN_TRANSFORMS = {
|
|
2211
|
-
// Date transforms (expects a parseable date string)
|
|
2212
|
-
month: (v) => {
|
|
2213
|
-
const d = new Date(v);
|
|
2214
|
-
return isNaN(d.getTime()) ? "" : String(d.getMonth() + 1);
|
|
2215
|
-
},
|
|
2216
|
-
month2: (v) => {
|
|
2217
|
-
const d = new Date(v);
|
|
2218
|
-
return isNaN(d.getTime()) ? "" : String(d.getMonth() + 1).padStart(2, "0");
|
|
2219
|
-
},
|
|
2220
|
-
monthname: (v) => {
|
|
2221
|
-
const d = new Date(v);
|
|
2222
|
-
return isNaN(d.getTime()) ? "" : d.toLocaleString("en", { month: "long" });
|
|
2223
|
-
},
|
|
2224
|
-
monthshort: (v) => {
|
|
2225
|
-
const d = new Date(v);
|
|
2226
|
-
return isNaN(d.getTime()) ? "" : d.toLocaleString("en", { month: "short" });
|
|
2227
|
-
},
|
|
2228
|
-
day: (v) => {
|
|
2229
|
-
const d = new Date(v);
|
|
2230
|
-
return isNaN(d.getTime()) ? "" : String(d.getDate());
|
|
2231
|
-
},
|
|
2232
|
-
day2: (v) => {
|
|
2233
|
-
const d = new Date(v);
|
|
2234
|
-
return isNaN(d.getTime()) ? "" : String(d.getDate()).padStart(2, "0");
|
|
2235
|
-
},
|
|
2236
|
-
year: (v) => {
|
|
2237
|
-
const d = new Date(v);
|
|
2238
|
-
return isNaN(d.getTime()) ? "" : String(d.getFullYear());
|
|
2239
|
-
},
|
|
2240
|
-
year2: (v) => {
|
|
2241
|
-
const d = new Date(v);
|
|
2242
|
-
return isNaN(d.getTime()) ? "" : String(d.getFullYear()).slice(-2);
|
|
2243
|
-
},
|
|
2244
|
-
// String transforms
|
|
2245
|
-
upper: (v) => v.toUpperCase(),
|
|
2246
|
-
lower: (v) => v.toLowerCase(),
|
|
2247
|
-
trim: (v) => v.trim(),
|
|
2248
|
-
first: (v) => v.split(/\s+/)[0] || "",
|
|
2249
|
-
last: (v) => {
|
|
2250
|
-
const parts = v.split(/\s+/);
|
|
2251
|
-
return parts[parts.length - 1] || "";
|
|
2252
|
-
},
|
|
2253
|
-
initials: (v) => v.split(/\s+/).map((w) => w[0] || "").join("").toUpperCase(),
|
|
2254
|
-
// Numeric / substring
|
|
2255
|
-
last4: (v) => v.slice(-4),
|
|
2256
|
-
last2: (v) => v.slice(-2),
|
|
2257
|
-
first4: (v) => v.slice(0, 4),
|
|
2258
|
-
first2: (v) => v.slice(0, 2),
|
|
2259
|
-
digits: (v) => v.replace(/\D/g, ""),
|
|
2260
|
-
number: (v) => {
|
|
2261
|
-
const n = parseFloat(v);
|
|
2262
|
-
return isNaN(n) ? "" : String(n);
|
|
2263
|
-
},
|
|
2264
|
-
currency: (v) => {
|
|
2265
|
-
const n = parseFloat(v.replace(/[^0-9.-]/g, ""));
|
|
2266
|
-
return isNaN(n) ? "" : `$${n.toFixed(2)}`;
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
var FORMULA_RE = /\{\{(.+?)\}\}/g;
|
|
2270
|
-
var PIPE_RE = /^(.+?)\s*\|\s*(.+)$/;
|
|
2271
|
-
function resolveFormula(formula, fields, customTransforms) {
|
|
2272
|
-
const transforms = { ...BUILTIN_TRANSFORMS, ...customTransforms };
|
|
2273
|
-
return formula.replace(FORMULA_RE, (_match, expr) => {
|
|
2274
|
-
const pipeMatch = expr.match(PIPE_RE);
|
|
2275
|
-
const sourceLabel = (pipeMatch ? pipeMatch[1] : expr).trim();
|
|
2276
|
-
const transformName = pipeMatch ? pipeMatch[2].trim() : null;
|
|
2277
|
-
const sourceField = fields.find((f) => f.label.toLowerCase() === sourceLabel.toLowerCase()) || fields.find((f) => f.id === sourceLabel);
|
|
2278
|
-
if (!sourceField) return "";
|
|
2279
|
-
const rawValue = sourceField.value || "";
|
|
2280
|
-
if (!transformName) return rawValue;
|
|
2281
|
-
const fn = transforms[transformName];
|
|
2282
|
-
if (!fn) return rawValue;
|
|
2283
|
-
try {
|
|
2284
|
-
return fn(rawValue);
|
|
2285
|
-
} catch {
|
|
2286
|
-
return rawValue;
|
|
2287
|
-
}
|
|
2288
|
-
});
|
|
2289
|
-
}
|
|
2290
|
-
function resolveAllFormulas(fields, customTransforms) {
|
|
2291
|
-
return fields.map((f) => {
|
|
2292
|
-
if (!f.formula) return f;
|
|
2293
|
-
const computed = resolveFormula(f.formula, fields, customTransforms);
|
|
2294
|
-
return computed !== f.value ? { ...f, value: computed } : f;
|
|
2295
|
-
});
|
|
2296
|
-
}
|
|
2297
|
-
|
|
2298
2405
|
// src/components/pdf-builder/SignerView.tsx
|
|
2299
2406
|
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2300
2407
|
function SignerView({
|
|
@@ -2512,7 +2619,7 @@ function SignerView({
|
|
|
2512
2619
|
let pdfBytes;
|
|
2513
2620
|
if (includeAuditTrail) {
|
|
2514
2621
|
const { PDFDocument: PDFDocument2, StandardFonts: StandardFonts2, rgb: rgb2 } = await import("pdf-lib");
|
|
2515
|
-
const basePdf = await generateFilledPdf(pdfSource, finalFields);
|
|
2622
|
+
const basePdf = await generateFilledPdf({ pdfSource, fields: finalFields });
|
|
2516
2623
|
const pdfDoc = await PDFDocument2.load(basePdf);
|
|
2517
2624
|
const font = await pdfDoc.embedFont(StandardFonts2.Helvetica);
|
|
2518
2625
|
const boldFont = await pdfDoc.embedFont(StandardFonts2.HelveticaBold);
|
|
@@ -2529,7 +2636,7 @@ function SignerView({
|
|
|
2529
2636
|
}
|
|
2530
2637
|
pdfBytes = await pdfDoc.save();
|
|
2531
2638
|
} else {
|
|
2532
|
-
pdfBytes = await generateFilledPdf(pdfSource, finalFields);
|
|
2639
|
+
pdfBytes = await generateFilledPdf({ pdfSource, fields: finalFields });
|
|
2533
2640
|
}
|
|
2534
2641
|
const blob = new Blob([pdfBytes.slice().buffer], { type: "application/pdf" });
|
|
2535
2642
|
if (onExport && exportFormat) {
|
|
@@ -2851,7 +2958,9 @@ function SignerRoleSelector({
|
|
|
2851
2958
|
] });
|
|
2852
2959
|
}
|
|
2853
2960
|
export {
|
|
2961
|
+
A4,
|
|
2854
2962
|
BUILTIN_TRANSFORMS,
|
|
2963
|
+
DEFAULT_CALIBRATION,
|
|
2855
2964
|
DEFAULT_SIGNER_ROLES,
|
|
2856
2965
|
DesignerView,
|
|
2857
2966
|
FIELD_DEFAULTS,
|
|
@@ -2863,7 +2972,11 @@ export {
|
|
|
2863
2972
|
SignatureCanvas,
|
|
2864
2973
|
SignerRoleSelector,
|
|
2865
2974
|
SignerView,
|
|
2975
|
+
US_LEGAL,
|
|
2976
|
+
US_LETTER,
|
|
2977
|
+
applyCalibration,
|
|
2866
2978
|
createField,
|
|
2979
|
+
createPdfBuilder,
|
|
2867
2980
|
downloadPdf,
|
|
2868
2981
|
generateFilledPdf,
|
|
2869
2982
|
generateId,
|