@signiphi/pdf-signer 0.2.0-beta.16 → 0.2.0-beta.18

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.
@@ -584,13 +584,20 @@ function extractFieldValue(field, fieldType) {
584
584
  try {
585
585
  switch (fieldType) {
586
586
  case "text":
587
+ case "date":
587
588
  return field.getText?.() || "";
588
589
  case "checkbox":
589
590
  return field.isChecked?.() ? "true" : "false";
590
591
  case "dropdown":
591
- case "optionlist":
592
+ case "optionlist": {
593
+ const selected = field.getSelected?.();
594
+ return Array.isArray(selected) ? selected[0] || "" : String(selected || "");
595
+ }
592
596
  case "radiogroup":
593
- return field.getSelected?.()?.[0] || "";
597
+ case "radio": {
598
+ const radioSelected = field.getSelected?.();
599
+ return radioSelected ? String(radioSelected) : "";
600
+ }
594
601
  default:
595
602
  return "";
596
603
  }
@@ -903,7 +910,7 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
903
910
  const fieldInfo = extractedFormFields?.find((f) => f.name === fieldName);
904
911
  if (fieldInfo && hasDrawableLabel(fieldInfo)) {
905
912
  const labelFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
906
- const labelFontSize = Math.min(12, height * 0.6);
913
+ const labelFontSize = Math.min(10, height * 0.4);
907
914
  const labelX = x;
908
915
  const labelY = y + height + 5;
909
916
  page.drawText(fieldInfo.label, {
@@ -948,7 +955,7 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
948
955
  console.log("[FLATTEN] After pattern matching in fieldPageMap:", foundInitialsFields);
949
956
  if (extractedFormFields && extractedFormFields.length > 0) {
950
957
  foundInitialsFields = foundInitialsFields.filter((fieldName) => {
951
- const fieldInfo = extractedFormFields.find((f) => f.name === fieldName);
958
+ const fieldInfo = extractedFormFields.find((f) => f.name === fieldName) || extractedFormFields.find((f) => f.name === fieldName.replace(/_initials$/i, "")) || extractedFormFields.find((f) => fieldName.startsWith(f.name));
952
959
  if (!fieldInfo) return false;
953
960
  const isActualInitialsField = fieldInfo.type === "initials" || fieldName.toLowerCase().includes("initials");
954
961
  if (!isActualInitialsField) return false;
@@ -977,9 +984,9 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
977
984
  const y = fieldPosition.y;
978
985
  const height = Math.max(fieldPosition.height, 20);
979
986
  const fontSize = Math.min(height * 0.7, 14);
980
- const fieldInfo = extractedFormFields?.find((f) => f.name === fieldName);
987
+ const fieldInfo = extractedFormFields?.find((f) => f.name === fieldName) || extractedFormFields?.find((f) => f.name === fieldName.replace(/_initials$/i, "")) || extractedFormFields?.find((f) => fieldName.startsWith(f.name)) || extractedFormFields?.find((f) => f.fieldId && fieldName.includes(f.fieldId)) || extractedFormFields?.find((f) => f.type === "initials" && f.name !== "initials_field_main");
981
988
  if (fieldInfo && hasDrawableLabel(fieldInfo)) {
982
- const labelFontSize = Math.min(12, height * 0.6);
989
+ const labelFontSize = Math.min(10, height * 0.4);
983
990
  const labelX = x;
984
991
  const labelY = y + height + 5;
985
992
  page.drawText(fieldInfo.label, {
@@ -1060,7 +1067,7 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
1060
1067
  if (!result) continue;
1061
1068
  const { rect, page } = result;
1062
1069
  if (fieldInfo && hasDrawableLabel(fieldInfo)) {
1063
- const labelFontSize = Math.min(12, rect.height * 0.6);
1070
+ const labelFontSize = Math.min(10, rect.height * 0.4);
1064
1071
  const labelX = rect.x + rect.width + 5;
1065
1072
  const labelY = rect.y + (rect.height - labelFontSize) / 2;
1066
1073
  page.drawText(fieldInfo.label, {
@@ -1174,11 +1181,12 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
1174
1181
  if (i === 0 && fieldInfo && hasDrawableLabel(fieldInfo)) {
1175
1182
  const groupLabelKey = `${pageIndex}-${fieldName}-grouplabel`;
1176
1183
  if (!drawnGroupLabels.has(groupLabelKey)) {
1184
+ const labelFontSize = Math.min(10, rect.height * 0.4);
1177
1185
  const labelY = rect.y + rect.height + 3;
1178
1186
  page.drawText(fieldInfo.label, {
1179
1187
  x: rect.x,
1180
1188
  y: labelY,
1181
- size: 9,
1189
+ size: labelFontSize,
1182
1190
  font: labelFont,
1183
1191
  color: rgb(0, 0, 0)
1184
1192
  });
@@ -1230,7 +1238,7 @@ async function fillPdfWithSignatures(pdfBytes, signatures, formFieldValues = {},
1230
1238
  if (!result) continue;
1231
1239
  const { rect, page } = result;
1232
1240
  if (fieldInfo && hasDrawableLabel(fieldInfo)) {
1233
- const labelFontSize = Math.min(12, rect.height * 0.6);
1241
+ const labelFontSize = Math.min(10, rect.height * 0.4);
1234
1242
  const labelX = rect.x;
1235
1243
  const labelY = rect.y + rect.height + 5;
1236
1244
  page.drawText(fieldInfo.label, {
@@ -1530,6 +1538,13 @@ async function extractVisibleFormFields(pdfBytes, currentSignerEmail) {
1530
1538
  logger.warn("Error extracting options for field:", error);
1531
1539
  }
1532
1540
  }
1541
+ try {
1542
+ const currentValue = extractFieldValue(f, esignField.type);
1543
+ if (currentValue) {
1544
+ esignField.defaultValue = currentValue;
1545
+ }
1546
+ } catch {
1547
+ }
1533
1548
  visibleFields.push(esignField);
1534
1549
  }
1535
1550
  }
@@ -2309,6 +2324,7 @@ ${cssRules.join("\n")}`;
2309
2324
  }
2310
2325
  }
2311
2326
  logger.info(`[RADIO DETECT] Found ${Object.keys(radioGroups).length} radio groups:`, Object.keys(radioGroups));
2327
+ const processedRadioFieldNames = new Set(Object.keys(radioGroups));
2312
2328
  for (const [fieldName, radioButtons] of Object.entries(radioGroups)) {
2313
2329
  const selectedRadio = radioButtons.find(
2314
2330
  (rb) => rb.data && typeof rb.data === "object" && rb.data.value === true
@@ -2334,7 +2350,7 @@ ${cssRules.join("\n")}`;
2334
2350
  }
2335
2351
  for (const [id, data] of Object.entries(storedData)) {
2336
2352
  const fieldName = idToNameMap[id];
2337
- if (fieldName && values[fieldName]) {
2353
+ if (fieldName && (fieldName in values || processedRadioFieldNames.has(fieldName))) {
2338
2354
  continue;
2339
2355
  }
2340
2356
  if (fieldName) {
@@ -2351,13 +2367,13 @@ ${cssRules.join("\n")}`;
2351
2367
  } else if (data !== void 0 && data !== null) {
2352
2368
  extractedValue = String(data);
2353
2369
  }
2354
- if (extractedValue !== void 0 && extractedValue !== "") {
2370
+ if (extractedValue !== void 0) {
2355
2371
  values[fieldName] = extractedValue;
2356
2372
  }
2357
2373
  }
2358
2374
  }
2359
2375
  for (const [name, fields] of Object.entries(fieldObjects)) {
2360
- if (!values[name]) {
2376
+ if (!(name in values)) {
2361
2377
  const fieldArray = fields;
2362
2378
  const field = fieldArray[0];
2363
2379
  if (field && field.value !== void 0 && field.value !== null) {
@@ -5102,12 +5118,22 @@ function RadioGroupRenderer({
5102
5118
  className = ""
5103
5119
  }) {
5104
5120
  const options = field.options || [];
5121
+ const [localValue, setLocalValue] = React9.useState(value);
5122
+ React9.useEffect(() => {
5123
+ if (value && value !== localValue) {
5124
+ setLocalValue(value);
5125
+ }
5126
+ }, [value]);
5127
+ const handleChange = (newValue) => {
5128
+ setLocalValue(newValue);
5129
+ onChange(newValue);
5130
+ };
5105
5131
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
5106
5132
  /* @__PURE__ */ jsxRuntime.jsx(
5107
5133
  RadioGroup,
5108
5134
  {
5109
- value,
5110
- onValueChange: onChange,
5135
+ value: localValue,
5136
+ onValueChange: handleChange,
5111
5137
  required: field.required,
5112
5138
  className: "",
5113
5139
  children: options.map((option) => {
@@ -5116,7 +5142,7 @@ function RadioGroupRenderer({
5116
5142
  "div",
5117
5143
  {
5118
5144
  className: "flex items-center space-x-3 p-3 -ml-3 -mr-3 rounded-lg hover:bg-muted/50 cursor-pointer transition-colors duration-200",
5119
- onClick: () => onChange(option),
5145
+ onClick: () => handleChange(option),
5120
5146
  children: [
5121
5147
  /* @__PURE__ */ jsxRuntime.jsx(
5122
5148
  RadioGroupItem,
@@ -7349,11 +7375,12 @@ async function drawFieldLabelsOnPdf(pdfDoc, fieldsToLabel, rgb) {
7349
7375
  if (page) {
7350
7376
  const groupLabelKey = `${pageIndex}-${field.name}-grouplabel`;
7351
7377
  if (!drawnOnce.has(groupLabelKey)) {
7378
+ const radioLabelFontSize = Math.min(10, firstRect.height * 0.4);
7352
7379
  const labelY = firstRect.y + firstRect.height + 5;
7353
7380
  page.drawText(field.label, {
7354
7381
  x: firstRect.x,
7355
7382
  y: labelY,
7356
- size: 9,
7383
+ size: radioLabelFontSize,
7357
7384
  font: labelFont,
7358
7385
  color: rgb(0, 0, 0)
7359
7386
  });
@@ -7403,11 +7430,12 @@ async function drawFieldLabelsOnPdf(pdfDoc, fieldsToLabel, rgb) {
7403
7430
  const key = `${pageIndex}-${field.name}`;
7404
7431
  if (!drawnOnce.has(key)) {
7405
7432
  if (hasDrawableLabel(field)) {
7433
+ const labelFontSize = Math.min(10, rect.height * 0.4);
7406
7434
  if (field.type === "checkbox" /* CHECKBOX */) {
7407
7435
  page.drawText(field.label, {
7408
7436
  x: rect.x + rect.width + 5,
7409
- y: rect.y + rect.height * 0.2,
7410
- size: 10,
7437
+ y: rect.y + (rect.height - labelFontSize) / 2,
7438
+ size: labelFontSize,
7411
7439
  font: labelFont,
7412
7440
  color: rgb(0, 0, 0)
7413
7441
  });
@@ -7416,9 +7444,9 @@ async function drawFieldLabelsOnPdf(pdfDoc, fieldsToLabel, rgb) {
7416
7444
  page.drawText(field.label, {
7417
7445
  x: rect.x,
7418
7446
  y: labelY,
7419
- size: 9,
7447
+ size: labelFontSize,
7420
7448
  font: labelFont,
7421
- color: rgb(0.3, 0.3, 0.3)
7449
+ color: rgb(0, 0, 0)
7422
7450
  });
7423
7451
  }
7424
7452
  drawnOnce.add(key);
@@ -7736,6 +7764,20 @@ function usePdfViewer(multiSignerContext) {
7736
7764
  }
7737
7765
  function useFormFields(fields = []) {
7738
7766
  const [fieldValues, setFieldValues] = React9.useState({});
7767
+ const seededFieldsRef = React9.useRef(/* @__PURE__ */ new Set());
7768
+ React9.useEffect(() => {
7769
+ if (fields.length === 0) return;
7770
+ const defaults = {};
7771
+ for (const field of fields) {
7772
+ if (field.defaultValue && field.defaultValue.trim() && !seededFieldsRef.current.has(field.id)) {
7773
+ defaults[field.id] = field.defaultValue;
7774
+ seededFieldsRef.current.add(field.id);
7775
+ }
7776
+ }
7777
+ if (Object.keys(defaults).length > 0) {
7778
+ setFieldValues((prev) => ({ ...defaults, ...prev }));
7779
+ }
7780
+ }, [fields]);
7739
7781
  const [errors, setErrors] = React9.useState([]);
7740
7782
  const [touched, setTouched] = React9.useState({});
7741
7783
  const updateField = React9.useCallback((fieldId, value) => {
@@ -8351,7 +8393,7 @@ function SubmissionForm({
8351
8393
  getFieldError,
8352
8394
  isFieldTouched,
8353
8395
  clearFields
8354
- } = useFormFields();
8396
+ } = useFormFields(extractedFields);
8355
8397
  const {
8356
8398
  signatures,
8357
8399
  setSignature: setSignatureOriginal,
@@ -9006,6 +9048,9 @@ function SubmissionForm({
9006
9048
  }
9007
9049
  }
9008
9050
  }
9051
+ if (field.type === "radio" && (normalizedPdfValue === "true" || normalizedPdfValue === "false")) {
9052
+ normalizedPdfValue = void 0;
9053
+ }
9009
9054
  if (field.type === "date" && pdfValue) {
9010
9055
  const validation = parseAndValidateDate(pdfValue);
9011
9056
  if (!validation.isValid) {
@@ -9019,8 +9064,12 @@ function SubmissionForm({
9019
9064
  normalizedPdfValue = validation.isoString;
9020
9065
  }
9021
9066
  }
9022
- if (normalizedPdfValue && normalizedPdfValue !== currentReactValue) {
9067
+ const isUnresolvedRadioIndex = field.type === "radio" && normalizedPdfValue?.includes("__RADIO_OPTION_INDEX_");
9068
+ const pdfFieldReported = field.id in pdfValues;
9069
+ if (normalizedPdfValue && normalizedPdfValue !== currentReactValue && !isUnresolvedRadioIndex) {
9023
9070
  setFieldValue(field.id, normalizedPdfValue);
9071
+ } else if (pdfFieldReported && !normalizedPdfValue && currentReactValue) {
9072
+ setFieldValue(field.id, "");
9024
9073
  }
9025
9074
  }
9026
9075
  if (invalidDates.length > 0) {
@@ -9132,6 +9181,15 @@ function SubmissionForm({
9132
9181
  setFieldValue(currentDateField.id, dateValue);
9133
9182
  try {
9134
9183
  await setFormFieldValues({ [currentDateField.id]: dateValue });
9184
+ const pdfApp = viewerRef.current?.getPDFViewerApplication?.();
9185
+ const pdfDocument = pdfApp?.pdfDocument;
9186
+ if (pdfDocument?.annotationStorage && typeof pdfDocument.getFieldObjects === "function") {
9187
+ const fieldObjects = await pdfDocument.getFieldObjects() || {};
9188
+ const widgets = fieldObjects[currentDateField.id];
9189
+ if (widgets?.[0]?.id) {
9190
+ pdfDocument.annotationStorage.setValue(widgets[0].id, { value: dateValue });
9191
+ }
9192
+ }
9135
9193
  logger.info(`[DATE SELECT] Updated PDF field ${currentDateField.id}`);
9136
9194
  } catch (error) {
9137
9195
  logger.error(`[DATE SELECT] Failed to update PDF field:`, error);
@@ -9639,6 +9697,11 @@ function SubmissionForm({
9639
9697
  const currentSignatures = signaturesRef.current;
9640
9698
  const pdfFieldValues = await getFormFieldValues();
9641
9699
  const allFieldValues = { ...pdfFieldValues, ...currentFieldValues };
9700
+ for (const [fieldId, pdfVal] of Object.entries(pdfFieldValues)) {
9701
+ if (pdfVal === "") {
9702
+ allFieldValues[fieldId] = "";
9703
+ }
9704
+ }
9642
9705
  console.log("[VALIDATION] === MERGING SIGNATURES INTO allFieldValues ===");
9643
9706
  console.log("[VALIDATION] currentSignatures:", currentSignatures);
9644
9707
  for (const [fieldId, signatureValue] of Object.entries(currentSignatures)) {
@@ -9803,6 +9866,11 @@ function SubmissionForm({
9803
9866
  const currentFieldValues = fieldValuesRef.current;
9804
9867
  const currentSignatures = signaturesRef.current;
9805
9868
  const finalFieldValues = { ...pdfFieldValues, ...currentFieldValues };
9869
+ for (const [fieldId, pdfVal] of Object.entries(pdfFieldValues)) {
9870
+ if (pdfVal === "") {
9871
+ finalFieldValues[fieldId] = "";
9872
+ }
9873
+ }
9806
9874
  console.log("[SUBMIT] === MERGING SIGNATURES INTO finalFieldValues FOR FLATTENING ===");
9807
9875
  console.log("[SUBMIT] currentSignatures:", currentSignatures);
9808
9876
  for (const [fieldId, signatureValue] of Object.entries(currentSignatures)) {