Skip to Content

@stesura/esign

E-signature fields: an inline esign_field node that marks where a signer signs or fills in, a manifest of the fields for the PDF or DOCX you send, and adapters that turn the manifest into DocuSign, Acrobat Sign and Dropbox Sign field definitions. Framework-free; the editor UI is in @stesura/esign-react. See the package list for how it fits with the other packages.

Schema

Add the node with stesuraSchema(withEsign()); it composes with other with* helpers.

withEsign

Merges the esign node and grant into stesuraSchema props; composes with other with* helpers: stesuraSchema(withEsign(withAutomation())).

Parameters:
NameTypeDefault
propsSchemaProps
Returns:
{ nodes: { [x: string]: StesuraNodeSpec; }; globalAttributes: { nodes: { hidden: { esign_field: true; }; }; definitions?: Record<string, GlobalAttributeDefinition>; }; marks?: Record<...>; }

ESIGN_KINDS

const ESIGN_KINDS: readonly ["signature", "initials", "date", "name", "title", "company", "text", "checkbox"]

The field kinds every supported provider has.

isEsignKind

Whether value is one of ESIGN_KINDS.

Parameters:
NameTypeDefault
valueunknown
Returns:
boolean

readEsignField

The field’s attrs, validated: attrs are unvalidated on the JSON/collab path, so every reader goes through here. A missing or invalid size falls back to the kind’s default.

Parameters:
NameTypeDefault
nodeNode
Returns:
EsignFieldAttrs

EsignKind

type EsignKind = "signature" | "initials" | "date" | "name" | "title" | "company" | "text" | "checkbox";

A field kind: one of ESIGN_KINDS.

EsignFieldAttrs

A field’s attrs, validated: what readEsignField returns.

NameTypeDefault
idstring | null
kind"date" | "name" | "title" | "text" | "checkbox" | "signature" | "initials" | "company"
signerstring

Signer role, normalised; "" when unassigned.

requiredboolean
widthnumber

pt

heightnumber

pt

style"none" | "line" | "box"

EsignStyle

type EsignStyle = "line" | "box" | "none";

What prints for a field: a bottom border (line), a full border (box), or nothing.

EsignResize

type EsignResize = "both" | "width" | "none";

Which sides a field’s box can be dragged on.

Commands

insertEsignField

Inserts a field at the cursor, sized by the kind’s defaults unless overridden. Refused in code blocks and where inline content can’t go.

Parameters:
NameTypeDefault
__0InsertEsignFieldOptions
Returns:
Command

InsertEsignFieldOptions

Options of insertEsignField: the kind, and optionally the signer, size and style.

NameTypeDefault
kind"date" | "name" | "title" | "text" | "checkbox" | "signature" | "initials" | "company"
signerstring
heightnumber

pt

requiredboolean
widthnumber

pt

style"none" | "line" | "box"

updateEsignField

Updates field id. A kind change without a size takes the new kind’s default size. Undoable; false when the field is missing or nothing changes (compared against the validated attrs, so unset sizes don’t count as a change).

Parameters:
NameTypeDefault
idstring
updatePartial<Omit<EsignFieldAttrs, "id">>
Returns:
Command

EsignFieldUpdate

The attrs updateEsignField changes; every attr but id.

NameTypeDefault
kind"date" | "name" | "title" | "text" | "checkbox" | "signature" | "initials" | "company"
heightnumber

pt

requiredboolean
widthnumber

pt

style"none" | "line" | "box"
signerstring

Signer role, normalised; "" when unassigned.

resizeEsignField

What the resize frame commits: the field at pos resized within its kind’s policy (one-line kinds keep their height, checkboxes never resize).

Parameters:
NameTypeDefault
posnumber
sizeSize
Returns:
Command

renameSigner

Reassigns every field of role from to to in one undoable transaction. False when no field changes or to is already a role: a rename never merges two roles (updateEsignField reassigns a single field).

Parameters:
NameTypeDefault
fromstring
tostring
Returns:
Command

findEsignField

The field with id id and its position.

Parameters:
NameTypeDefault
docNode
idstring
Returns:
{ node: Node; pos: number; } | null

signerRoles

Roles already in doc, normalised.

Parameters:
NameTypeDefault
docNode
Returns:
Set<string>

Reading and validating

collectEsignFields

Every field in document order, with its validated attrs.

Parameters:
NameTypeDefault
docNode
Returns:
EsignFieldInfo[]

EsignFieldInfo

A field as collectEsignFields returns it: validated attrs, position and visibility.

NameTypeDefault
idstring | null
kind"date" | "name" | "title" | "text" | "checkbox" | "signature" | "initials" | "company"
signerstring

Signer role, normalised; "" when unassigned.

requiredboolean
widthnumber

pt

heightnumber

pt

style"none" | "line" | "box"
posnumber
hiddenboolean

The field or one of its ancestors is hidden.

collectSigners

Visible fields by signer role, roles in order of first appearance (a stable index for colouring). Unassigned fields are left out.

Parameters:
NameTypeDefault
fieldsreadonly EsignFieldInfo[]
Returns:
Map<string, EsignFieldInfo[]>

esignDiagnostics

Problems that would block or weaken a send. Visible fields only; not stored.

Parameters:
NameTypeDefault
fieldsreadonly EsignFieldInfo[]
Returns:
EsignDiagnostic[]

EsignDiagnostic

One problem esignDiagnostics found, about a field (id) or a role (signer).

NameTypeDefault
codeEsignDiagnosticCode
severity"error" | "warning"
idstring | null

The field it is about; null for a role-level diagnostic.

signerstring | null
messagestring

EsignDiagnosticCode

type EsignDiagnosticCode = | "unassigned-signer" | "missing-id" | "duplicate-id" | "signer-without-signature";

What esignDiagnostics found: a field without a signer, without an id, sharing an id, or a signer with no signature field (a warning).

Manifest

Build the manifest from the document you rendered, with the field boxes the PDF export measured.

buildManifest

Joins the document’s fields with what the PDF render measured, by id.

Build fields from the document that was rendered (for an automation document, the materialized one): hidden content never gets a box, so ids from the editor document would not match. Hidden, unassigned and id-less fields are left out; a field the render did not place keeps its anchor and is reported. Without measured (DOCX output) every field is anchor-only.

Parameters:
NameTypeDefault
fieldsreadonly EsignFieldInfo[]
measuredPdfFieldPlacements
Returns:
{ manifest: EsignManifest; warnings: EsignManifestWarning[]; }

EsignManifest

The fields to send to a provider, built by buildManifest. Units are pt, origin each page’s top-left corner.

NameTypeDefault
fieldsEsignManifestField[]
signersstring[]

Roles in order of first appearance.

pages{ width: number; height: number; }[]

Every page of the PDF, pt; absent without measurement.

units"pt"
origin"top-left"

EsignManifestField

One field of the EsignManifest: its role, size and anchor, and its box when measured.

NameTypeDefault
idstring
kind"date" | "name" | "title" | "text" | "checkbox" | "signature" | "initials" | "company"
signerstring
requiredboolean
widthnumber

The field’s own size, pt: what anchor-placed fields are sized by.

heightnumber
anchorstring

Always present: providers that place by text search use it.

placementEsignPlacement

Absent for DOCX output or when measurement failed.

EsignPlacement

A field’s box: pt, origin its page’s top-left corner, page 1-based.

NameTypeDefault
pagenumber
xnumber
ynumber
widthnumber
heightnumber

EsignManifestWarning

One buildManifest warning; id is null for a field without one.

NameTypeDefault
codeEsignManifestWarningCode
idstring | null
messagestring

EsignManifestWarningCode

type EsignManifestWarningCode = | "unassigned-signer" | "missing-id" | "duplicate-id" | "unplaced-field";

Why buildManifest warned: a field left out, or one the render did not place.

Provider adapters

docusignEnvelopeTabs

The manifest as DocuSign tabs, per signer: set each signers[].tabs of the envelope definition to its entry. Fields whose role has no recipient are skipped.

Parameters:
NameTypeDefault
manifestEsignManifest
optionsDocusignOptions
Returns:
{ signers: { role: string; recipientId: string; tabs: DocusignTabs; }[]; skipped: AdapterSkip[]; }

DocusignOptions

Options of docusignEnvelopeTabs.

NameTypeDefault
documentIdstring
recipientsReadonly<Record<string, { recipientId: string; }>>

Each role’s recipientId in the envelope’s recipients.signers.

placement"auto" | "anchor"

auto (default): coordinates when the manifest has them, else the anchor. anchor: anchors only, e.g. when the uploaded document is the DOCX.

DocusignTabs

A DocuSign recipient’s tabs, one collection per tab type.

NameTypeDefault
signHereTabsDocusignTab[]
initialHereTabsDocusignTab[]
dateSignedTabsDocusignTab[]
fullNameTabsDocusignTab[]
titleTabsDocusignTab[]
companyTabsDocusignTab[]
textTabsDocusignTab[]
checkboxTabsDocusignTab[]

DocusignTab

One DocuSign tab (eSignature REST v2.1). Every value is a string, as the API types them; positions are whole points from the page’s top-left.

NameTypeDefault
documentIdstring
recipientIdstring
tabLabelstring

The field id: same-type tabs sharing a label share their value.

pageNumberstring
xPositionstring
yPositionstring
anchorStringstring
anchorUnits"pixels"
anchorXOffsetstring
anchorYOffsetstring
anchorIgnoreIfNotPresent"false"
anchorMatchWholeWord"true"
anchorCaseSensitive"true"
widthstring

Not on sign-here tabs, which DocuSign sizes itself.

heightstring
optional"true" | "false"

Sign-here and initial-here tabs.

required"true" | "false"

Title, company, text and checkbox tabs.

adobeSignFormFields

The manifest as the body of PUT /agreements/{id}/formFields ({ fields }), for an agreement created in AUTHORING state. Coordinates only: fields without a placement are skipped (see adobeSignFormFieldGenerators).

top is taken as the field’s top edge measured up from the page bottom. The API reference does not say which edge: check one real agreement first.

Parameters:
NameTypeDefault
manifestEsignManifest
__1{ participantSetIds: Readonly<Record<string, string>>; }
Returns:
{ fields: AdobeSignFormField[]; skipped: AdapterSkip[]; }

adobeSignFormFieldGenerators

The manifest as formFieldGenerators for POST /agreements: every field placed by its anchor text, so it works for PDF and DOCX uploads alike.

Parameters:
NameTypeDefault
manifestEsignManifest
__1{ participantSetNames: Readonly<Record<string, string>>; }
Returns:
{ generators: AdobeSignFormFieldGenerator[]; skipped: AdapterSkip[]; }

AdobeSignFormField

Acrobat Sign REST v6 FormField. Locations are points with a bottom-left origin.

NameTypeDefault
inputTypeAdobeSignInputType
contentTypeAdobeSignContentType
namestring
assigneestring

The participant set id.

requiredboolean
locations{ pageNumber: number; left: number; top: number; width: number; height: number; }[]

AdobeSignFormFieldGenerator

Acrobat Sign REST v6 FormFieldGenerator placing one field by its anchor text.

NameTypeDefault
formFieldNamePrefixstring
participantSetNamestring

Matches a participantSetsInfo[].name of the agreement.

generatorType"ANCHOR_TEXT"
anchorTextInfo{ anchorText: string; anchoredFormFieldLocation: { offsetX: number; offsetY: number; width: number; height: number; }; }
formFieldDescriptionFieldTypes & { required: boolean; }
linkedfalse

AdobeSignInputType

type AdobeSignInputType = "SIGNATURE" | "TEXT_FIELD" | "CHECKBOX";

An Acrobat Sign form field’s inputType.

AdobeSignContentType

type AdobeSignContentType = | "SIGNATURE" | "SIGNER_INITIALS" | "SIGNATURE_DATE" | "SIGNER_NAME" | "SIGNER_TITLE" | "SIGNER_COMPANY" | "DATA";

An Acrobat Sign form field’s contentType.

dropboxSignFormFields

The manifest as form_fields_per_document. Coordinates only (Dropbox Sign has no anchor-string placement): fields without a placement are skipped.

Values are whole points (72 dpi, top-left), as the API reference states. The help centre describes sizes in an 80 dpi system and pages rescaled to US Letter: verify against one real request, A4 especially.

Parameters:
NameTypeDefault
manifestEsignManifest
__1{ signers: Readonly<Record<string, number>>; documentIndex?: number; }
Returns:
{ fields: DropboxSignFormField[]; skipped: AdapterSkip[]; }

DropboxSignFormField

Dropbox Sign API v3 form_fields_per_document entry, page coordinate system.

NameTypeDefault
document_indexnumber
api_idstring

The field id; unique across the request’s documents.

namestring
typeDropboxSignFieldType
requiredboolean
signernumber

0-based signer index.

pagenumber
xnumber
ynumber
widthnumber
heightnumber
auto_fill_type"name" | "title" | "company"
is_checkedboolean

DropboxSignFieldType

type DropboxSignFieldType = "signature" | "initials" | "date_signed" | "text" | "checkbox";

A Dropbox Sign form field’s type.

AdapterSkip

A manifest field an adapter could not express.

NameTypeDefault
idstring
reason"no-recipient" | "no-placement"

no-recipient: its role has no recipient; no-placement: the provider needs coordinates.

Export

esignDocx

DOCX export of the field: a bordered (or underlined) box sized like the field, preceded by its anchor token as 1pt white text. One-way: importing the file gives plain text. With automationDocx, spread both nodes and keep its transformDoc.

NameTypeDefault
nodesNodeSerializer

Handlers merged over the defaults (same name replaces).

transformDoc(doc: Node) => Node

Rewrites the document before anything reads it (preload, pre-passes, rendering), e.g. to resolve content that must not reach Word. Same schema.

preloadExtra(doc: Node) => Promise<Map<string, Buffer<ArrayBufferLike>>>

Bytes added to the image preload pass, keyed as handlers will ask for them through state.options.getImageBuffer. Runs alongside preloadImages.

traceDocxExportTrace

Filled with where the export’s time and bytes went (createExportTrace()).

lastModifiedBystring

The saving user’s name, stamped as cp:lastModifiedBy as Word does on save.

removeDocumentPropertiesboolean

Leaves the document’s properties (title, author, custom properties) out of the file, as Word’s Inspect Document → “Document Properties” does: kept otherwise, they reach whoever receives it (SEC-98).

redactionReasonsRedactionTaxonomy

Labels and colors of redaction reasons (the host’s taxonomy), for the content controls’ titles and boxes.

esignMarkdown

Markdown serialization of the field as {{esign|kind|signer}} text. One-way: parsing gives the text back, not a field.

NameTypeDefault
fenceHandlersReadonly<Record<string, FenceHandler>>
nodeHandlersReadonly<Record<string, PmNodeHandler>>
Last updated on