@xenterprises/fastify-xsignwell 1.1.1 → 1.2.1
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/LICENSE +100 -0
- package/README.md +137 -302
- package/index.d.ts +164 -0
- package/package.json +35 -32
- package/src/apiRequest.js +49 -0
- package/src/services/bulkSend.js +67 -94
- package/src/services/documents.js +118 -105
- package/src/services/templates.js +64 -95
- package/src/services/webhooks.js +49 -83
- package/src/xSignwell.js +20 -27
- package/.gitlab-ci.yml +0 -45
package/LICENSE
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 X Enterprises LLC. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are the
|
|
6
|
+
exclusive property of X Enterprises LLC, a Washington limited liability
|
|
7
|
+
company ("X Enterprises"). The Software is distributed through public
|
|
8
|
+
package registries (including npm) for operational convenience only; such
|
|
9
|
+
distribution does not grant any rights beyond those expressly stated below.
|
|
10
|
+
|
|
11
|
+
TERMS AND CONDITIONS
|
|
12
|
+
|
|
13
|
+
1. OWNERSHIP
|
|
14
|
+
All rights, title, and interest in and to the Software, including all
|
|
15
|
+
intellectual property rights, are and shall remain the exclusive property
|
|
16
|
+
of X Enterprises. No rights are granted except as expressly set forth in
|
|
17
|
+
this License.
|
|
18
|
+
|
|
19
|
+
2. PERMITTED USE
|
|
20
|
+
Subject to the restrictions in Section 3, you are permitted to download,
|
|
21
|
+
install, and execute the Software solely as a dependency of:
|
|
22
|
+
|
|
23
|
+
(a) software developed, owned, or operated by X Enterprises;
|
|
24
|
+
|
|
25
|
+
(b) software that X Enterprises has developed, delivered, or licensed to
|
|
26
|
+
a third party ("Client") under a written engagement agreement with
|
|
27
|
+
X Enterprises, when such use is performed by or on behalf of that
|
|
28
|
+
Client; or
|
|
29
|
+
|
|
30
|
+
(c) end-user access to, or consumption of, a product or service described
|
|
31
|
+
in (a) or (b), provided that such access does not involve
|
|
32
|
+
redistribution, modification, or separate use of the Software.
|
|
33
|
+
|
|
34
|
+
Permitted Use includes automated installation and execution by continuous
|
|
35
|
+
integration systems, container builds, hosting platforms, and similar
|
|
36
|
+
infrastructure, to the extent necessary to support (a), (b), or (c).
|
|
37
|
+
|
|
38
|
+
3. RESTRICTIONS
|
|
39
|
+
Except as expressly permitted in Section 2, and without the prior written
|
|
40
|
+
consent of X Enterprises, you may not:
|
|
41
|
+
|
|
42
|
+
(a) copy, modify, adapt, translate, or create derivative works of the
|
|
43
|
+
Software for any purpose outside the scope of Section 2;
|
|
44
|
+
|
|
45
|
+
(b) redistribute, republish, sublicense, sell, lease, rent, or otherwise
|
|
46
|
+
transfer the Software, in whole or in part, whether standalone or
|
|
47
|
+
bundled with other software;
|
|
48
|
+
|
|
49
|
+
(c) reverse engineer, decompile, disassemble, or attempt to derive the
|
|
50
|
+
source code or underlying ideas, algorithms, structure, or
|
|
51
|
+
organization of the Software, except to the extent such activity is
|
|
52
|
+
expressly permitted by applicable law notwithstanding this
|
|
53
|
+
restriction;
|
|
54
|
+
|
|
55
|
+
(d) use the Software, in whole or in part, to develop, operate, or
|
|
56
|
+
provide any product or service that competes with or substitutes for
|
|
57
|
+
any X Enterprises product or service;
|
|
58
|
+
|
|
59
|
+
(e) remove, obscure, or alter any copyright, trademark, license, or other
|
|
60
|
+
proprietary notice contained in or on the Software; or
|
|
61
|
+
|
|
62
|
+
(f) use the Software in violation of any applicable law or regulation.
|
|
63
|
+
|
|
64
|
+
4. NO WARRANTY
|
|
65
|
+
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
66
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
67
|
+
FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
68
|
+
X ENTERPRISES BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
|
|
69
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT
|
|
70
|
+
OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
71
|
+
THE SOFTWARE.
|
|
72
|
+
|
|
73
|
+
5. LIMITATION OF LIABILITY
|
|
74
|
+
IN NO EVENT SHALL X ENTERPRISES BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
|
|
75
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
76
|
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
77
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
78
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
79
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
80
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
81
|
+
|
|
82
|
+
6. GOVERNING LAW
|
|
83
|
+
This License shall be governed by and construed in accordance with the
|
|
84
|
+
laws of the State of Washington, United States, without regard to its
|
|
85
|
+
conflict of law provisions. Exclusive jurisdiction for any dispute
|
|
86
|
+
arising out of this License shall lie in the state or federal courts
|
|
87
|
+
located in King County, Washington.
|
|
88
|
+
|
|
89
|
+
7. TERMINATION
|
|
90
|
+
This License is effective until terminated. Your rights under this
|
|
91
|
+
License will terminate automatically and without notice if you fail to
|
|
92
|
+
comply with any term herein. Upon termination, you must cease all use of
|
|
93
|
+
the Software and destroy all copies in your possession or control.
|
|
94
|
+
Sections 1, 3, 4, 5, 6, and 7 survive termination.
|
|
95
|
+
|
|
96
|
+
For licensing inquiries, contact: legal@x.enterprises
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
X Enterprises LLC
|
|
100
|
+
Bothell, Washington, United States
|
package/README.md
CHANGED
|
@@ -1,333 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @xenterprises/fastify-xsignwell
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Fastify plugin for [SignWell](https://www.signwell.com/) e-signature API integration — document creation, templates, bulk sending, webhooks, and embedded signing.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- **Document Management**: Create, send, and track documents for signing
|
|
8
|
-
- **Template Support**: Create and manage reusable document templates
|
|
9
|
-
- **Embedded Signing**: Get URLs for embedded signing experiences
|
|
10
|
-
- **Bulk Send**: Send documents to multiple recipients at once
|
|
11
|
-
- **Webhooks**: Register and manage webhook callbacks for document events
|
|
12
|
-
- **Test Mode**: Built-in support for SignWell's test mode
|
|
13
|
-
|
|
14
|
-
## Installation
|
|
5
|
+
## Install
|
|
15
6
|
|
|
16
7
|
```bash
|
|
17
|
-
npm install xsignwell
|
|
8
|
+
npm install @xenterprises/fastify-xsignwell
|
|
18
9
|
```
|
|
19
10
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
### Environment Variables
|
|
23
|
-
|
|
24
|
-
| Variable | Description | Required |
|
|
25
|
-
|----------|-------------|----------|
|
|
26
|
-
| `SIGNWELL_API_KEY` | SignWell API key | Yes |
|
|
27
|
-
| `SIGNWELL_TEST_MODE` | Enable test mode | No |
|
|
28
|
-
|
|
29
|
-
### Plugin Registration
|
|
11
|
+
## Quick Start
|
|
30
12
|
|
|
31
13
|
```javascript
|
|
32
|
-
import Fastify from
|
|
33
|
-
import xSignwell from
|
|
14
|
+
import Fastify from "fastify";
|
|
15
|
+
import xSignwell from "@xenterprises/fastify-xsignwell";
|
|
34
16
|
|
|
35
17
|
const fastify = Fastify();
|
|
36
18
|
|
|
37
19
|
await fastify.register(xSignwell, {
|
|
38
20
|
apiKey: process.env.SIGNWELL_API_KEY,
|
|
39
|
-
testMode: process.env.NODE_ENV !==
|
|
40
|
-
});
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Usage
|
|
44
|
-
|
|
45
|
-
### Documents
|
|
46
|
-
|
|
47
|
-
#### Create a Document
|
|
48
|
-
|
|
49
|
-
```javascript
|
|
50
|
-
const document = await fastify.xsignwell.documents.create({
|
|
51
|
-
name: 'Employment Agreement',
|
|
52
|
-
recipients: [
|
|
53
|
-
{
|
|
54
|
-
id: 'signer_1',
|
|
55
|
-
name: 'John Doe',
|
|
56
|
-
email: 'john@example.com',
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
files: [
|
|
60
|
-
{
|
|
61
|
-
name: 'agreement.pdf',
|
|
62
|
-
url: 'https://example.com/agreement.pdf',
|
|
63
|
-
// OR use base64:
|
|
64
|
-
// base64: 'JVBERi0xLjQK...',
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
subject: 'Please sign your employment agreement',
|
|
68
|
-
message: 'Hi John, please review and sign the attached agreement.',
|
|
69
|
-
});
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
#### Create from Template
|
|
73
|
-
|
|
74
|
-
```javascript
|
|
75
|
-
const document = await fastify.xsignwell.documents.createFromTemplate(
|
|
76
|
-
'template_id_here',
|
|
77
|
-
{
|
|
78
|
-
recipients: [
|
|
79
|
-
{
|
|
80
|
-
id: 'signer_1', // Must match template recipient ID
|
|
81
|
-
name: 'John Doe',
|
|
82
|
-
email: 'john@example.com',
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
fields: {
|
|
86
|
-
employee_name: 'John Doe',
|
|
87
|
-
start_date: '2025-02-01',
|
|
88
|
-
salary: '$75,000',
|
|
89
|
-
},
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
#### Get Document Status
|
|
95
|
-
|
|
96
|
-
```javascript
|
|
97
|
-
const document = await fastify.xsignwell.documents.get('document_id');
|
|
98
|
-
console.log(document.status); // 'pending', 'completed', etc.
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
#### Send a Document
|
|
102
|
-
|
|
103
|
-
```javascript
|
|
104
|
-
await fastify.xsignwell.documents.send('document_id');
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
#### Send Reminder
|
|
108
|
-
|
|
109
|
-
```javascript
|
|
110
|
-
await fastify.xsignwell.documents.remind('document_id');
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
#### Get Completed PDF
|
|
114
|
-
|
|
115
|
-
```javascript
|
|
116
|
-
const pdf = await fastify.xsignwell.documents.getCompletedPdf('document_id');
|
|
117
|
-
// pdf.file_url contains the download URL
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
#### Get Embedded Signing URL
|
|
121
|
-
|
|
122
|
-
```javascript
|
|
123
|
-
const { url, recipient } = await fastify.xsignwell.documents.getEmbeddedSigningUrl(
|
|
124
|
-
'document_id',
|
|
125
|
-
'recipient_id'
|
|
126
|
-
);
|
|
127
|
-
// Redirect user to `url` for signing
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
#### Delete Document
|
|
131
|
-
|
|
132
|
-
```javascript
|
|
133
|
-
await fastify.xsignwell.documents.remove('document_id');
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Templates
|
|
137
|
-
|
|
138
|
-
#### Get Template
|
|
139
|
-
|
|
140
|
-
```javascript
|
|
141
|
-
const template = await fastify.xsignwell.templates.get('template_id');
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
#### List Templates
|
|
145
|
-
|
|
146
|
-
```javascript
|
|
147
|
-
const templates = await fastify.xsignwell.templates.list({
|
|
148
|
-
page: 1,
|
|
149
|
-
limit: 20,
|
|
150
|
-
});
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### Create Template
|
|
154
|
-
|
|
155
|
-
```javascript
|
|
156
|
-
const template = await fastify.xsignwell.templates.create({
|
|
157
|
-
name: 'NDA Template',
|
|
158
|
-
files: [
|
|
159
|
-
{
|
|
160
|
-
name: 'nda.pdf',
|
|
161
|
-
url: 'https://example.com/nda.pdf',
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
recipients: [
|
|
165
|
-
{ id: 'signer_1', name: 'Signer' },
|
|
166
|
-
{ id: 'signer_2', name: 'Counter-Signer' },
|
|
167
|
-
],
|
|
168
|
-
});
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
#### Update Template
|
|
172
|
-
|
|
173
|
-
```javascript
|
|
174
|
-
await fastify.xsignwell.templates.update('template_id', {
|
|
175
|
-
name: 'Updated NDA Template',
|
|
176
|
-
subject: 'New subject line',
|
|
177
|
-
});
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### Delete Template
|
|
181
|
-
|
|
182
|
-
```javascript
|
|
183
|
-
await fastify.xsignwell.templates.remove('template_id');
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
#### Get Template Fields
|
|
187
|
-
|
|
188
|
-
```javascript
|
|
189
|
-
const fields = await fastify.xsignwell.templates.getFields('template_id');
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Bulk Send
|
|
193
|
-
|
|
194
|
-
#### Create Bulk Send
|
|
195
|
-
|
|
196
|
-
```javascript
|
|
197
|
-
const bulkSend = await fastify.xsignwell.bulkSend.create({
|
|
198
|
-
templateId: 'template_id',
|
|
199
|
-
recipients: [
|
|
200
|
-
{
|
|
201
|
-
email: 'john@example.com',
|
|
202
|
-
name: 'John Doe',
|
|
203
|
-
// Field values for this recipient
|
|
204
|
-
employee_name: 'John Doe',
|
|
205
|
-
start_date: '2025-02-01',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
email: 'jane@example.com',
|
|
209
|
-
name: 'Jane Smith',
|
|
210
|
-
employee_name: 'Jane Smith',
|
|
211
|
-
start_date: '2025-02-15',
|
|
212
|
-
},
|
|
213
|
-
],
|
|
214
|
-
});
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### List Bulk Sends
|
|
218
|
-
|
|
219
|
-
```javascript
|
|
220
|
-
const bulkSends = await fastify.xsignwell.bulkSend.list();
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
#### Get Bulk Send Documents
|
|
224
|
-
|
|
225
|
-
```javascript
|
|
226
|
-
const documents = await fastify.xsignwell.bulkSend.getDocuments('bulk_send_id');
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
#### Get CSV Template
|
|
230
|
-
|
|
231
|
-
```javascript
|
|
232
|
-
const csvTemplate = await fastify.xsignwell.bulkSend.getCsvTemplate('template_id');
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### Webhooks
|
|
236
|
-
|
|
237
|
-
#### List Webhooks
|
|
238
|
-
|
|
239
|
-
```javascript
|
|
240
|
-
const webhooks = await fastify.xsignwell.webhooks.list();
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
#### Create Webhook
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
const webhook = await fastify.xsignwell.webhooks.create({
|
|
247
|
-
callbackUrl: 'https://your-api.com/webhooks/signwell',
|
|
248
|
-
event: 'document.completed', // Optional: subscribe to specific event
|
|
21
|
+
testMode: process.env.NODE_ENV !== "production",
|
|
249
22
|
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
#### Delete Webhook
|
|
253
23
|
|
|
254
|
-
|
|
255
|
-
await fastify.xsignwell.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```javascript
|
|
261
|
-
fastify.post('/webhooks/signwell', async (request, reply) => {
|
|
262
|
-
const event = fastify.xsignwell.webhooks.parseEvent(request.body);
|
|
263
|
-
|
|
264
|
-
switch (event.event) {
|
|
265
|
-
case 'document.completed':
|
|
266
|
-
console.log(`Document ${event.documentId} completed`);
|
|
267
|
-
// Download the completed PDF
|
|
268
|
-
const pdf = await fastify.xsignwell.documents.getCompletedPdf(event.documentId);
|
|
269
|
-
break;
|
|
270
|
-
|
|
271
|
-
case 'document.signed':
|
|
272
|
-
console.log(`Document ${event.documentId} signed by ${event.recipient?.email}`);
|
|
273
|
-
break;
|
|
274
|
-
|
|
275
|
-
case 'document.declined':
|
|
276
|
-
console.log(`Document ${event.documentId} was declined`);
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return { received: true };
|
|
24
|
+
// Create and send a document
|
|
25
|
+
const doc = await fastify.xsignwell.documents.create({
|
|
26
|
+
name: "Employment Agreement",
|
|
27
|
+
recipients: [{ email: "john@example.com", name: "John Doe" }],
|
|
28
|
+
files: [{ name: "agreement.pdf", url: "https://example.com/agreement.pdf" }],
|
|
281
29
|
});
|
|
282
30
|
```
|
|
283
31
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
```javascript
|
|
287
|
-
const events = fastify.xsignwell.webhooks.events;
|
|
288
|
-
// {
|
|
289
|
-
// DOCUMENT_COMPLETED: 'document.completed',
|
|
290
|
-
// DOCUMENT_SENT: 'document.sent',
|
|
291
|
-
// DOCUMENT_VIEWED: 'document.viewed',
|
|
292
|
-
// DOCUMENT_SIGNED: 'document.signed',
|
|
293
|
-
// DOCUMENT_DECLINED: 'document.declined',
|
|
294
|
-
// DOCUMENT_EXPIRED: 'document.expired',
|
|
295
|
-
// DOCUMENT_VOIDED: 'document.voided',
|
|
296
|
-
// RECIPIENT_COMPLETED: 'recipient.completed',
|
|
297
|
-
// RECIPIENT_VIEWED: 'recipient.viewed',
|
|
298
|
-
// RECIPIENT_SIGNED: 'recipient.signed',
|
|
299
|
-
// RECIPIENT_DECLINED: 'recipient.declined',
|
|
300
|
-
// }
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Account Info
|
|
32
|
+
## Options
|
|
304
33
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
34
|
+
| Name | Type | Default | Required | Description |
|
|
35
|
+
|------|------|---------|----------|-------------|
|
|
36
|
+
| `apiKey` | `string` | — | Yes | SignWell API key |
|
|
37
|
+
| `baseUrl` | `string` | `https://www.signwell.com/api/v1` | No | API base URL |
|
|
38
|
+
| `testMode` | `boolean` | `false` | No | Enable test mode (documents won't actually send) |
|
|
39
|
+
| `active` | `boolean` | `true` | No | Set `false` to disable the plugin entirely |
|
|
309
40
|
|
|
310
|
-
##
|
|
41
|
+
## Environment Variables
|
|
311
42
|
|
|
312
|
-
|
|
43
|
+
| Name | Required | Description |
|
|
44
|
+
|------|----------|-------------|
|
|
45
|
+
| `SIGNWELL_API_KEY` | Yes | SignWell API key |
|
|
46
|
+
| `SIGNWELL_TEST_MODE` | No | Set `"true"` to enable test mode |
|
|
313
47
|
|
|
314
|
-
|
|
48
|
+
## Decorated Properties
|
|
315
49
|
|
|
316
50
|
| Decorator | Description |
|
|
317
51
|
|-----------|-------------|
|
|
52
|
+
| `fastify.xsignwell.config` | Plugin configuration object |
|
|
318
53
|
| `fastify.xsignwell.documents` | Document management methods |
|
|
319
54
|
| `fastify.xsignwell.templates` | Template management methods |
|
|
320
55
|
| `fastify.xsignwell.bulkSend` | Bulk send methods |
|
|
321
56
|
| `fastify.xsignwell.webhooks` | Webhook management methods |
|
|
322
|
-
| `fastify.xsignwell.me` | Get account info |
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
57
|
+
| `fastify.xsignwell.me()` | Get current account info |
|
|
58
|
+
|
|
59
|
+
### `documents`
|
|
60
|
+
|
|
61
|
+
| Method | Description |
|
|
62
|
+
|--------|-------------|
|
|
63
|
+
| `create(params)` | Create a new document for signing |
|
|
64
|
+
| `createFromTemplate(templateId, params)` | Create a document from a template |
|
|
65
|
+
| `get(documentId)` | Get document details by ID |
|
|
66
|
+
| `list(params?)` | List documents (page, limit) |
|
|
67
|
+
| `send(documentId, params?)` | Send a draft document |
|
|
68
|
+
| `remind(documentId)` | Send reminder to unsigned recipients |
|
|
69
|
+
| `remove(documentId)` | Delete a document |
|
|
70
|
+
| `getCompletedPdf(documentId)` | Get download URL for completed PDF |
|
|
71
|
+
| `getEmbeddedSigningUrl(documentId, recipientId)` | Get embedded signing URL |
|
|
72
|
+
| `getAuditTrail(documentId)` | Get document audit trail |
|
|
73
|
+
|
|
74
|
+
### `templates`
|
|
75
|
+
|
|
76
|
+
| Method | Description |
|
|
77
|
+
|--------|-------------|
|
|
78
|
+
| `get(templateId)` | Get template by ID |
|
|
79
|
+
| `create(params)` | Create a new template |
|
|
80
|
+
| `update(templateId, params)` | Update an existing template |
|
|
81
|
+
| `remove(templateId)` | Delete a template |
|
|
82
|
+
| `list(params?)` | List all templates (page, limit) |
|
|
83
|
+
| `getFields(templateId)` | Get template field definitions |
|
|
84
|
+
| `getRecipients(templateId)` | Get template recipient placeholders |
|
|
85
|
+
|
|
86
|
+
### `bulkSend`
|
|
87
|
+
|
|
88
|
+
| Method | Description |
|
|
89
|
+
|--------|-------------|
|
|
90
|
+
| `get(bulkSendId)` | Get bulk send by ID |
|
|
91
|
+
| `list(params?)` | List all bulk sends (page, limit) |
|
|
92
|
+
| `create(params)` | Create a bulk send from a template |
|
|
93
|
+
| `getCsvTemplate(templateId)` | Get CSV template for bulk upload |
|
|
94
|
+
| `validateCsv(templateId, csvContent)` | Validate CSV before sending |
|
|
95
|
+
| `getDocuments(bulkSendId, params?)` | Get documents from a bulk send |
|
|
96
|
+
|
|
97
|
+
### `webhooks`
|
|
98
|
+
|
|
99
|
+
| Method | Description |
|
|
100
|
+
|--------|-------------|
|
|
101
|
+
| `list()` | List all webhooks |
|
|
102
|
+
| `create(params)` | Create a new webhook |
|
|
103
|
+
| `remove(webhookId)` | Delete a webhook |
|
|
104
|
+
| `events` | Event type constants (see below) |
|
|
105
|
+
| `verifySignature(payload, signature, secret)` | Verify webhook HMAC-SHA256 signature |
|
|
106
|
+
| `parseEvent(payload)` | Parse webhook payload into structured event |
|
|
107
|
+
|
|
108
|
+
#### Webhook Event Constants
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_COMPLETED // "document.completed"
|
|
112
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_SENT // "document.sent"
|
|
113
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_VIEWED // "document.viewed"
|
|
114
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_SIGNED // "document.signed"
|
|
115
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_DECLINED // "document.declined"
|
|
116
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_EXPIRED // "document.expired"
|
|
117
|
+
fastify.xsignwell.webhooks.events.DOCUMENT_VOIDED // "document.voided"
|
|
118
|
+
fastify.xsignwell.webhooks.events.RECIPIENT_COMPLETED // "recipient.completed"
|
|
119
|
+
fastify.xsignwell.webhooks.events.RECIPIENT_VIEWED // "recipient.viewed"
|
|
120
|
+
fastify.xsignwell.webhooks.events.RECIPIENT_SIGNED // "recipient.signed"
|
|
121
|
+
fastify.xsignwell.webhooks.events.RECIPIENT_DECLINED // "recipient.declined"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Error Reference
|
|
125
|
+
|
|
126
|
+
All errors thrown by the plugin are prefixed with `[xSignwell]`.
|
|
127
|
+
|
|
128
|
+
| Error | When |
|
|
129
|
+
|-------|------|
|
|
130
|
+
| `[xSignwell] apiKey is required` | Plugin registered without `apiKey` option |
|
|
131
|
+
| `[xSignwell] apiKey must be a string` | `apiKey` is not a string |
|
|
132
|
+
| `[xSignwell] baseUrl must be a string` | `baseUrl` is not a string |
|
|
133
|
+
| `[xSignwell] testMode must be a boolean` | `testMode` is not a boolean |
|
|
134
|
+
| `[xSignwell] documents.create: name (string) is required` | `create()` called without `name` |
|
|
135
|
+
| `[xSignwell] documents.create: recipients (non-empty array) is required` | `create()` missing recipients |
|
|
136
|
+
| `[xSignwell] documents.create: each recipient must have an email` | Recipient without email field |
|
|
137
|
+
| `[xSignwell] <service>.<method>: <param> is required` | Any method called with missing required param |
|
|
138
|
+
| `[xSignwell] Recipient <id> not found in document <id>` | `getEmbeddedSigningUrl` can't find recipient |
|
|
139
|
+
| `[xSignwell] API error: <status>` | SignWell API returned a non-2xx response |
|
|
140
|
+
| `[xSignwell] Network error calling <endpoint>: <message>` | Network/connection failure |
|
|
141
|
+
|
|
142
|
+
API errors include `statusCode` and `signwellError` properties on the Error object for programmatic handling:
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
try {
|
|
146
|
+
await fastify.xsignwell.documents.get("bad_id");
|
|
147
|
+
} catch (err) {
|
|
148
|
+
console.log(err.statusCode); // 404
|
|
149
|
+
console.log(err.signwellError); // { message: "Document not found" }
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## How It Works
|
|
154
|
+
|
|
155
|
+
The plugin registers a single `xsignwell` decorator on the Fastify instance. On startup it validates options (apiKey type, baseUrl type, testMode type) and builds a config object. Four service modules (documents, templates, webhooks, bulkSend) attach their methods to sub-objects on the decorator.
|
|
156
|
+
|
|
157
|
+
All API calls go through a shared `apiRequest` helper that:
|
|
158
|
+
1. Adds the `X-Api-Key` header from config
|
|
159
|
+
2. Parses JSON responses (handles empty bodies for DELETE)
|
|
160
|
+
3. On non-2xx responses, attaches `statusCode` and `signwellError` to the thrown Error
|
|
161
|
+
4. On network failures, wraps with `[xSignwell] Network error` message
|
|
162
|
+
|
|
163
|
+
The plugin uses `fastify-plugin` with `fastify >=5.0.0` constraint so the decorator is visible across all scopes. The `testMode` config flag is passed as `test_mode` in document/bulk-send creation payloads so SignWell won't actually deliver signing emails.
|
|
331
164
|
|
|
332
165
|
## Testing
|
|
333
166
|
|
|
@@ -335,6 +168,8 @@ SignWell API has the following rate limits:
|
|
|
335
168
|
npm test
|
|
336
169
|
```
|
|
337
170
|
|
|
171
|
+
82 tests covering plugin registration, startup validation, all document/template/webhook/bulk-send methods (happy path + input validation + error propagation), webhook signature verification, and network error handling.
|
|
172
|
+
|
|
338
173
|
## License
|
|
339
174
|
|
|
340
|
-
|
|
175
|
+
UNLICENSED
|