fix(eoi): v1 field placement uses percent coords, not absolute points
Documenso 2.x's v1-compat POST /documents/{id}/fields expects percent
coordinates (0-100), same as v2 — but placeFields multiplied by a hardcoded
A4 page size, so 39.6% became ~237 and was read as 237%, placing the EOI
signature fields far off-page. Send percent straight through (matches
template-native fields, which render correctly). Drop the now-dead
getPageDimensions/DEFAULT_PAGE_DIMENSIONS A4 fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1291,8 +1291,6 @@ export interface DocumensoPageDimensions {
|
||||
height: number;
|
||||
}
|
||||
|
||||
const DEFAULT_PAGE_DIMENSIONS: DocumensoPageDimensions = { width: 595, height: 842 }; // A4 pt
|
||||
|
||||
const pageDimensionCache = new Map<string, DocumensoPageDimensions>();
|
||||
|
||||
/** Test seam - clears the page-dimension memoization. */
|
||||
@@ -1300,18 +1298,6 @@ export function __resetDocumensoCachesForTests(): void {
|
||||
pageDimensionCache.clear();
|
||||
}
|
||||
|
||||
async function getPageDimensions(docId: string, portId?: string): Promise<DocumensoPageDimensions> {
|
||||
const cached = pageDimensionCache.get(docId);
|
||||
if (cached) return cached;
|
||||
// v1 doesn't expose page dimensions cleanly via the public API; the auto-
|
||||
// placement use case is footer-anchored signature fields, where a default A4
|
||||
// page rendered by Documenso is a safe assumption. Real page dims can be
|
||||
// wired in a follow-up by parsing the document/document-data endpoints.
|
||||
void portId;
|
||||
pageDimensionCache.set(docId, DEFAULT_PAGE_DIMENSIONS);
|
||||
return DEFAULT_PAGE_DIMENSIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Place one or more fields on a Documenso document. Coordinates are PERCENT
|
||||
* (0-100) and converted to pixels for v1 internally.
|
||||
@@ -1374,16 +1360,19 @@ export async function placeFields(
|
||||
return;
|
||||
}
|
||||
|
||||
const dims = await getPageDimensions(docId, portId);
|
||||
for (const f of fields) {
|
||||
const body = {
|
||||
recipientId: typeof f.recipientId === 'string' ? Number(f.recipientId) : f.recipientId,
|
||||
type: f.type,
|
||||
pageNumber: f.pageNumber,
|
||||
pageX: Math.round((f.pageX / 100) * dims.width),
|
||||
pageY: Math.round((f.pageY / 100) * dims.height),
|
||||
pageWidth: Math.round((f.pageWidth / 100) * dims.width),
|
||||
pageHeight: Math.round((f.pageHeight / 100) * dims.height),
|
||||
// Documenso 2.x's v1-compat /fields endpoint expects PERCENT coords
|
||||
// (0-100), the same as v2 — NOT absolute points. (Confirmed live:
|
||||
// absolute values like 237 were read as 237% and placed fields far
|
||||
// off-page.) Send the percent values straight through.
|
||||
pageX: f.pageX,
|
||||
pageY: f.pageY,
|
||||
pageWidth: f.pageWidth,
|
||||
pageHeight: f.pageHeight,
|
||||
// Pass fieldMeta through on v1 too (Documenso 2.x's v1-compat endpoint
|
||||
// accepts it) so TEXT fields like "Place of Signing" keep their label /
|
||||
// required / placeholder. Older v1 servers ignore unknown keys.
|
||||
|
||||
Reference in New Issue
Block a user