@bubblelab/bubble-core 0.1.267 → 0.1.269

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.
Files changed (154) hide show
  1. package/dist/bubble-bundle.d.ts +127 -127
  2. package/dist/bubbles/service-bubble/agi-inc.d.ts +20 -20
  3. package/dist/bubbles/service-bubble/ai-agent.d.ts +74 -74
  4. package/dist/bubbles/service-bubble/airtable.d.ts +76 -76
  5. package/dist/bubbles/service-bubble/apify/actors/app-rankings-scraper.d.ts +6 -6
  6. package/dist/bubbles/service-bubble/apify/actors/instagram-hashtag-scraper.d.ts +2 -2
  7. package/dist/bubbles/service-bubble/apify/actors/instagram-scraper.d.ts +8 -8
  8. package/dist/bubbles/service-bubble/apify/actors/linkedin-jobs-scraper.d.ts +2 -2
  9. package/dist/bubbles/service-bubble/apify/actors/linkedin-posts-search.d.ts +22 -22
  10. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.d.ts +38 -38
  11. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-posts.d.ts +52 -52
  12. package/dist/bubbles/service-bubble/apify/actors/tiktok-scraper.d.ts +6 -6
  13. package/dist/bubbles/service-bubble/apify/actors/twitter-scraper.d.ts +12 -12
  14. package/dist/bubbles/service-bubble/apify/actors/youtube-scraper.d.ts +12 -12
  15. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.d.ts +132 -132
  16. package/dist/bubbles/service-bubble/apify/apify.d.ts +18 -18
  17. package/dist/bubbles/service-bubble/asana/asana.d.ts +1 -1
  18. package/dist/bubbles/service-bubble/asana/asana.schema.d.ts +1 -1
  19. package/dist/bubbles/service-bubble/ashby/ashby.d.ts +16 -16
  20. package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +22 -22
  21. package/dist/bubbles/service-bubble/assembled/assembled.d.ts +6 -6
  22. package/dist/bubbles/service-bubble/assembled/assembled.schema.d.ts +6 -6
  23. package/dist/bubbles/service-bubble/attio/attio.d.ts +6 -6
  24. package/dist/bubbles/service-bubble/attio/attio.schema.d.ts +6 -6
  25. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +1 -1
  26. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +1 -1
  27. package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +4 -4
  28. package/dist/bubbles/service-bubble/crustdata/crustdata.schema.d.ts +8 -8
  29. package/dist/bubbles/service-bubble/discord/discord.d.ts +12 -12
  30. package/dist/bubbles/service-bubble/discord/discord.schema.d.ts +12 -12
  31. package/dist/bubbles/service-bubble/firecrawl.d.ts +330 -330
  32. package/dist/bubbles/service-bubble/followupboss.d.ts +4 -4
  33. package/dist/bubbles/service-bubble/github.d.ts +60 -60
  34. package/dist/bubbles/service-bubble/gmail.d.ts +164 -164
  35. package/dist/bubbles/service-bubble/google-calendar.d.ts +6 -6
  36. package/dist/bubbles/service-bubble/google-drive.d.ts +4 -4
  37. package/dist/bubbles/service-bubble/http.d.ts +6 -6
  38. package/dist/bubbles/service-bubble/hubspot/hubspot.d.ts +2 -2
  39. package/dist/bubbles/service-bubble/hubspot/hubspot.schema.d.ts +2 -2
  40. package/dist/bubbles/service-bubble/insforge-db.d.ts +8 -8
  41. package/dist/bubbles/service-bubble/jira/jira.d.ts +30 -30
  42. package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +36 -36
  43. package/dist/bubbles/service-bubble/notion/notion.d.ts +168 -168
  44. package/dist/bubbles/service-bubble/notion/property-schemas.d.ts +16 -16
  45. package/dist/bubbles/service-bubble/postgresql.d.ts +8 -8
  46. package/dist/bubbles/service-bubble/posthog/posthog.d.ts +10 -10
  47. package/dist/bubbles/service-bubble/posthog/posthog.schema.d.ts +14 -14
  48. package/dist/bubbles/service-bubble/resend.d.ts +4 -4
  49. package/dist/bubbles/service-bubble/slack/slack.d.ts +388 -388
  50. package/dist/bubbles/service-bubble/snowflake/snowflake.d.ts +4 -4
  51. package/dist/bubbles/service-bubble/snowflake/snowflake.schema.d.ts +4 -4
  52. package/dist/bubbles/service-bubble/stripe/stripe.d.ts +24 -24
  53. package/dist/bubbles/service-bubble/stripe/stripe.schema.d.ts +28 -28
  54. package/dist/bubbles/service-bubble/xero/xero.d.ts +2 -2
  55. package/dist/bubbles/service-bubble/xero/xero.schema.d.ts +2 -2
  56. package/dist/bubbles/service-bubble/zendesk/zendesk.d.ts +20 -20
  57. package/dist/bubbles/service-bubble/zendesk/zendesk.schema.d.ts +20 -20
  58. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +6 -6
  59. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.schema.d.ts +8 -8
  60. package/dist/bubbles/tool-bubble/app-rankings-tool.d.ts +8 -8
  61. package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
  62. package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +4 -4
  63. package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +20 -20
  64. package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +384 -384
  65. package/dist/bubbles/tool-bubble/people-search-tool.d.ts +44 -44
  66. package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +10 -10
  67. package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +4 -4
  68. package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +4 -4
  69. package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +60 -60
  70. package/dist/bubbles/tool-bubble/twitter-tool.d.ts +134 -134
  71. package/dist/bubbles/tool-bubble/yc-scraper-tool.d.ts +8 -8
  72. package/dist/bubbles/tool-bubble/youtube-tool.d.ts +20 -20
  73. package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +12 -12
  74. package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +8 -8
  75. package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +2 -2
  76. package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +34 -34
  77. package/dist/bubbles.json +1 -1
  78. package/package.json +2 -2
  79. package/dist/bubble-trigger/index.d.ts +0 -2
  80. package/dist/bubble-trigger/index.d.ts.map +0 -1
  81. package/dist/bubble-trigger/index.js +0 -2
  82. package/dist/bubble-trigger/index.js.map +0 -1
  83. package/dist/bubble-trigger/types.d.ts +0 -87
  84. package/dist/bubble-trigger/types.d.ts.map +0 -1
  85. package/dist/bubble-trigger/types.js +0 -14
  86. package/dist/bubble-trigger/types.js.map +0 -1
  87. package/dist/bubbles/service-bubble/docusign/docusign.d.ts +0 -1101
  88. package/dist/bubbles/service-bubble/docusign/docusign.d.ts.map +0 -1
  89. package/dist/bubbles/service-bubble/docusign/docusign.js +0 -730
  90. package/dist/bubbles/service-bubble/docusign/docusign.js.map +0 -1
  91. package/dist/bubbles/service-bubble/docusign/docusign.schema.d.ts +0 -1035
  92. package/dist/bubbles/service-bubble/docusign/docusign.schema.d.ts.map +0 -1
  93. package/dist/bubbles/service-bubble/docusign/docusign.schema.js +0 -304
  94. package/dist/bubbles/service-bubble/docusign/docusign.schema.js.map +0 -1
  95. package/dist/bubbles/service-bubble/docusign/index.d.ts +0 -4
  96. package/dist/bubbles/service-bubble/docusign/index.d.ts.map +0 -1
  97. package/dist/bubbles/service-bubble/docusign/index.js +0 -3
  98. package/dist/bubbles/service-bubble/docusign/index.js.map +0 -1
  99. package/dist/bubbles/service-bubble/google-sheets.d.ts +0 -1811
  100. package/dist/bubbles/service-bubble/google-sheets.d.ts.map +0 -1
  101. package/dist/bubbles/service-bubble/google-sheets.js +0 -904
  102. package/dist/bubbles/service-bubble/google-sheets.js.map +0 -1
  103. package/dist/bubbles/service-bubble/looker/index.d.ts +0 -3
  104. package/dist/bubbles/service-bubble/looker/index.d.ts.map +0 -1
  105. package/dist/bubbles/service-bubble/looker/index.js +0 -3
  106. package/dist/bubbles/service-bubble/looker/index.js.map +0 -1
  107. package/dist/bubbles/service-bubble/looker/looker.d.ts +0 -768
  108. package/dist/bubbles/service-bubble/looker/looker.d.ts.map +0 -1
  109. package/dist/bubbles/service-bubble/looker/looker.js +0 -319
  110. package/dist/bubbles/service-bubble/looker/looker.js.map +0 -1
  111. package/dist/bubbles/service-bubble/looker/looker.schema.d.ts +0 -735
  112. package/dist/bubbles/service-bubble/looker/looker.schema.d.ts.map +0 -1
  113. package/dist/bubbles/service-bubble/looker/looker.schema.js +0 -264
  114. package/dist/bubbles/service-bubble/looker/looker.schema.js.map +0 -1
  115. package/dist/bubbles/service-bubble/pylon/index.d.ts +0 -3
  116. package/dist/bubbles/service-bubble/pylon/index.d.ts.map +0 -1
  117. package/dist/bubbles/service-bubble/pylon/index.js +0 -3
  118. package/dist/bubbles/service-bubble/pylon/index.js.map +0 -1
  119. package/dist/bubbles/service-bubble/pylon/pylon.d.ts +0 -435
  120. package/dist/bubbles/service-bubble/pylon/pylon.d.ts.map +0 -1
  121. package/dist/bubbles/service-bubble/pylon/pylon.js +0 -375
  122. package/dist/bubbles/service-bubble/pylon/pylon.js.map +0 -1
  123. package/dist/bubbles/service-bubble/pylon/pylon.schema.d.ts +0 -408
  124. package/dist/bubbles/service-bubble/pylon/pylon.schema.d.ts.map +0 -1
  125. package/dist/bubbles/service-bubble/pylon/pylon.schema.js +0 -249
  126. package/dist/bubbles/service-bubble/pylon/pylon.schema.js.map +0 -1
  127. package/dist/bubbles/service-bubble/slack.d.ts +0 -5869
  128. package/dist/bubbles/service-bubble/slack.d.ts.map +0 -1
  129. package/dist/bubbles/service-bubble/slack.js +0 -1536
  130. package/dist/bubbles/service-bubble/slack.js.map +0 -1
  131. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.d.ts +0 -3
  132. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.d.ts.map +0 -1
  133. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.js +0 -3
  134. package/dist/bubbles/tool-bubble/linkedin-connection-tool/index.js.map +0 -1
  135. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts +0 -160
  136. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts.map +0 -1
  137. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.js +0 -706
  138. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.js.map +0 -1
  139. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts +0 -93
  140. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.d.ts.map +0 -1
  141. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js +0 -50
  142. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.schema.js.map +0 -1
  143. package/dist/bubbles/workflow-bubble/bubbleflow-generator.workflow.d.ts +0 -114
  144. package/dist/bubbles/workflow-bubble/bubbleflow-generator.workflow.d.ts.map +0 -1
  145. package/dist/bubbles/workflow-bubble/bubbleflow-generator.workflow.js +0 -777
  146. package/dist/bubbles/workflow-bubble/bubbleflow-generator.workflow.js.map +0 -1
  147. package/dist/types/ai-models.d.ts +0 -4
  148. package/dist/types/ai-models.d.ts.map +0 -1
  149. package/dist/types/ai-models.js +0 -16
  150. package/dist/types/ai-models.js.map +0 -1
  151. package/dist/utils/param-helper.d.ts +0 -2
  152. package/dist/utils/param-helper.d.ts.map +0 -1
  153. package/dist/utils/param-helper.js +0 -5
  154. package/dist/utils/param-helper.js.map +0 -1
@@ -1,730 +0,0 @@
1
- import { ServiceBubble } from '../../../types/service-bubble-class.js';
2
- import { CredentialType, decodeCredentialPayload, } from '@bubblelab/shared-schemas';
3
- import { DocuSignParamsSchema, DocuSignResultSchema, } from './docusign.schema.js';
4
- /**
5
- * DocuSign Service Bubble
6
- *
7
- * eSignature integration for managing document signing workflows.
8
- *
9
- * Features:
10
- * - Create and send envelopes with documents and signers
11
- * - Create envelopes from pre-built templates
12
- * - Track envelope and recipient signing status
13
- * - Configure automatic reminders and expiration
14
- * - Download signed documents
15
- * - Void and resend envelopes
16
- *
17
- * Use cases:
18
- * - Automate agreement lifecycle (send, track, remind)
19
- * - Savings account agreement workflows
20
- * - Contract management and tracking
21
- * - Bulk envelope status monitoring
22
- */
23
- export class DocuSignBubble extends ServiceBubble {
24
- static type = 'service';
25
- static service = 'docusign';
26
- static authType = 'oauth';
27
- static bubbleName = 'docusign';
28
- static schema = DocuSignParamsSchema;
29
- static resultSchema = DocuSignResultSchema;
30
- static shortDescription = 'DocuSign eSignature integration for document signing workflows';
31
- static longDescription = `
32
- DocuSign eSignature integration for managing document signing workflows.
33
-
34
- Features:
35
- - Create and send envelopes with documents and signers
36
- - Create envelopes from pre-built templates with role mapping
37
- - Track envelope and recipient signing status
38
- - Configure automatic reminders and envelope expiration
39
- - Download signed/completed documents
40
- - Void in-progress envelopes and resend notifications
41
- - List and search envelopes and templates
42
-
43
- Use cases:
44
- - Automate agreement lifecycle (generate, send, track, remind, escalate)
45
- - Savings account agreement workflows
46
- - Contract management and compliance tracking
47
- - Bulk envelope status monitoring for CS agents
48
-
49
- Security Features:
50
- - OAuth 2.0 authentication with DocuSign
51
- - Scoped access permissions
52
- - Secure document handling
53
- `;
54
- static alias = 'docusign';
55
- /**
56
- * DocuSign credential format:
57
- * Base64-encoded JSON: { accessToken, accountId, baseUri }
58
- * The accountId identifies which DocuSign account to access.
59
- * The baseUri is the region-specific API base URL.
60
- */
61
- parseCredentials() {
62
- const { credentials } = this.params;
63
- if (!credentials || typeof credentials !== 'object') {
64
- return null;
65
- }
66
- const docusignCredRaw = credentials[CredentialType.DOCUSIGN_CRED];
67
- if (!docusignCredRaw) {
68
- return null;
69
- }
70
- try {
71
- const parsed = decodeCredentialPayload(docusignCredRaw);
72
- if (parsed.accessToken && parsed.accountId) {
73
- return {
74
- accessToken: parsed.accessToken,
75
- accountId: parsed.accountId,
76
- baseUri: parsed.baseUri
77
- ? `${parsed.baseUri}/restapi`
78
- : 'https://demo.docusign.net/restapi',
79
- };
80
- }
81
- }
82
- catch {
83
- // If decoding fails, treat the raw value as an access token
84
- // In this case, we can't make API calls without accountId
85
- }
86
- return null;
87
- }
88
- constructor(params = {
89
- operation: 'list_envelopes',
90
- }, context) {
91
- super(params, context);
92
- }
93
- async testCredential() {
94
- const creds = this.parseCredentials();
95
- if (!creds) {
96
- throw new Error('DocuSign credentials are required');
97
- }
98
- // Test by calling userinfo endpoint
99
- const response = await fetch('https://account-d.docusign.com/oauth/userinfo', {
100
- headers: { Authorization: `Bearer ${creds.accessToken}` },
101
- });
102
- if (!response.ok) {
103
- const text = await response.text();
104
- throw new Error(`DocuSign token validation failed (${response.status}): ${text}`);
105
- }
106
- return true;
107
- }
108
- async makeDocuSignRequest(endpoint, method = 'GET', body) {
109
- const creds = this.parseCredentials();
110
- if (!creds) {
111
- throw new Error('Invalid DocuSign credentials. Expected base64-encoded JSON with { accessToken, accountId, baseUri }.');
112
- }
113
- const url = `${creds.baseUri}/v2.1/accounts/${creds.accountId}${endpoint}`;
114
- const headers = {
115
- Authorization: `Bearer ${creds.accessToken}`,
116
- 'Content-Type': 'application/json',
117
- };
118
- const response = await fetch(url, {
119
- method,
120
- headers,
121
- body: body ? JSON.stringify(body) : undefined,
122
- });
123
- if (!response.ok) {
124
- const errorText = await response.text();
125
- let errorMessage;
126
- try {
127
- const errorJson = JSON.parse(errorText);
128
- errorMessage = errorJson.message || errorJson.errorCode || errorText;
129
- }
130
- catch {
131
- errorMessage = errorText;
132
- }
133
- throw new Error(`DocuSign API error (${response.status}): ${errorMessage}`);
134
- }
135
- // Some endpoints return no content (204)
136
- if (response.status === 204) {
137
- return {};
138
- }
139
- const contentType = response.headers.get('content-type') || '';
140
- if (contentType.includes('application/json')) {
141
- return response.json();
142
- }
143
- // For binary responses (document downloads)
144
- const buffer = await response.arrayBuffer();
145
- return Buffer.from(buffer).toString('base64');
146
- }
147
- async performAction(context) {
148
- void context;
149
- const { operation } = this.params;
150
- try {
151
- const result = await (async () => {
152
- const parsedParams = this.params;
153
- switch (operation) {
154
- case 'create_envelope':
155
- return await this.createEnvelope(parsedParams);
156
- case 'create_envelope_from_template':
157
- return await this.createEnvelopeFromTemplate(parsedParams);
158
- case 'get_envelope':
159
- return await this.getEnvelope(parsedParams);
160
- case 'list_envelopes':
161
- return await this.listEnvelopes(parsedParams);
162
- case 'get_recipients':
163
- return await this.getRecipients(parsedParams);
164
- case 'list_templates':
165
- return await this.listTemplates(parsedParams);
166
- case 'download_document':
167
- return await this.downloadDocument(parsedParams);
168
- case 'void_envelope':
169
- return await this.voidEnvelope(parsedParams);
170
- case 'resend_envelope':
171
- return await this.resendEnvelope(parsedParams);
172
- case 'bulk_send_from_template':
173
- return await this.bulkSendFromTemplate(parsedParams);
174
- case 'get_signing_url':
175
- return await this.getSigningUrl(parsedParams);
176
- case 'correct_recipient':
177
- return await this.correctRecipient(parsedParams);
178
- default:
179
- throw new Error(`Unsupported operation: ${operation}`);
180
- }
181
- })();
182
- return result;
183
- }
184
- catch (error) {
185
- return {
186
- operation,
187
- success: false,
188
- error: error instanceof Error ? error.message : 'Unknown error occurred',
189
- };
190
- }
191
- }
192
- buildNotificationObject(params) {
193
- const hasReminders = params.reminder_enabled !== undefined;
194
- const hasExpiration = params.expire_enabled !== undefined;
195
- if (!hasReminders && !hasExpiration)
196
- return undefined;
197
- const notification = { useAccountDefaults: 'false' };
198
- if (hasReminders) {
199
- notification.reminders = {
200
- reminderEnabled: String(params.reminder_enabled),
201
- reminderDelay: params.reminder_delay || '3',
202
- reminderFrequency: params.reminder_frequency || '5',
203
- };
204
- }
205
- if (hasExpiration) {
206
- notification.expirations = {
207
- expireEnabled: String(params.expire_enabled),
208
- expireAfter: params.expire_after || '30',
209
- expireWarn: params.expire_warn || '3',
210
- };
211
- }
212
- return notification;
213
- }
214
- /**
215
- * Check if base64 content is a valid PDF (starts with %PDF).
216
- * If not, wrap the decoded text in a minimal valid PDF.
217
- */
218
- ensurePdfContent(base64Content, _fileName) {
219
- // Check if it's already a PDF
220
- try {
221
- const decoded = Buffer.from(base64Content, 'base64').toString('utf-8');
222
- if (decoded.startsWith('%PDF')) {
223
- return { base64: base64Content, extension: 'pdf' };
224
- }
225
- }
226
- catch {
227
- // If decoding fails, assume it's binary PDF data
228
- return { base64: base64Content, extension: 'pdf' };
229
- }
230
- // It's plain text — wrap in a minimal PDF with proper layout
231
- const text = Buffer.from(base64Content, 'base64').toString('utf-8');
232
- const pdf = this.textToMinimalPdf(text);
233
- return {
234
- base64: Buffer.from(pdf).toString('base64'),
235
- extension: 'pdf',
236
- };
237
- }
238
- /**
239
- * Convert plain text to a minimal valid PDF with proper formatting.
240
- * Uses Helvetica 10pt, 72pt margins, 14pt line spacing, with word wrapping.
241
- */
242
- textToMinimalPdf(text) {
243
- const PAGE_WIDTH = 612; // US Letter
244
- const PAGE_HEIGHT = 792;
245
- const MARGIN = 72; // 1 inch
246
- const FONT_SIZE = 10;
247
- const LINE_HEIGHT = 14;
248
- const CHARS_PER_LINE = 85; // Approximate for Helvetica 10pt at this width
249
- const TOP_Y = PAGE_HEIGHT - MARGIN;
250
- const LINES_PER_PAGE = Math.floor((PAGE_HEIGHT - 2 * MARGIN) / LINE_HEIGHT);
251
- // Escape PDF special chars
252
- const escape = (s) => s.replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
253
- // Word-wrap and split into lines
254
- const rawLines = text.split('\n');
255
- const wrappedLines = [];
256
- for (const rawLine of rawLines) {
257
- if (rawLine.length === 0) {
258
- wrappedLines.push('');
259
- continue;
260
- }
261
- const words = rawLine.split(' ');
262
- let current = '';
263
- for (const word of words) {
264
- if (current.length + word.length + 1 > CHARS_PER_LINE) {
265
- wrappedLines.push(current);
266
- current = word;
267
- }
268
- else {
269
- current = current ? current + ' ' + word : word;
270
- }
271
- }
272
- if (current)
273
- wrappedLines.push(current);
274
- }
275
- // Split into pages
276
- const pages = [];
277
- for (let i = 0; i < wrappedLines.length; i += LINES_PER_PAGE) {
278
- pages.push(wrappedLines.slice(i, i + LINES_PER_PAGE));
279
- }
280
- if (pages.length === 0)
281
- pages.push(['']);
282
- // Build PDF objects
283
- const objects = [];
284
- let objNum = 1;
285
- // Catalog
286
- const catalogNum = objNum++;
287
- objects.push(`${catalogNum} 0 obj\n<< /Type /Catalog /Pages ${catalogNum + 1} 0 R >>\nendobj`);
288
- // Pages
289
- const pagesNum = objNum++;
290
- const pageObjNums = [];
291
- for (let i = 0; i < pages.length; i++) {
292
- pageObjNums.push(pagesNum + 1 + i * 2); // page obj numbers
293
- }
294
- objects.push(`${pagesNum} 0 obj\n<< /Type /Pages /Kids [${pageObjNums.map(n => `${n} 0 R`).join(' ')}] /Count ${pages.length} >>\nendobj`);
295
- // Font object number (will be assigned after pages)
296
- const fontObjNum = pagesNum + 1 + pages.length * 2;
297
- // Page + Content objects for each page
298
- for (let p = 0; p < pages.length; p++) {
299
- const pageNum = objNum++;
300
- const contentNum = objNum++;
301
- const lineCommands = pages[p]
302
- .map((line, i) => {
303
- const pos = i === 0 ? `${MARGIN} ${TOP_Y} Td` : `0 -${LINE_HEIGHT} Td`;
304
- return `${pos}\n(${escape(line)}) Tj`;
305
- })
306
- .join('\n');
307
- const stream = `BT\n/F1 ${FONT_SIZE} Tf\n${lineCommands}\nET`;
308
- objects.push(`${pageNum} 0 obj\n<< /Type /Page /Parent ${pagesNum} 0 R /MediaBox [0 0 ${PAGE_WIDTH} ${PAGE_HEIGHT}] /Contents ${contentNum} 0 R /Resources << /Font << /F1 ${fontObjNum} 0 R >> >> >>\nendobj`);
309
- objects.push(`${contentNum} 0 obj\n<< /Length ${stream.length} >>\nstream\n${stream}\nendstream\nendobj`);
310
- }
311
- // Font
312
- objNum++;
313
- objects.push(`${fontObjNum} 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>\nendobj`);
314
- // Build the PDF
315
- const body = objects.join('\n');
316
- const totalObjs = fontObjNum + 1;
317
- // Simplified xref — DocuSign is lenient with xref offsets for programmatic PDFs
318
- let xref = `xref\n0 ${totalObjs}\n0000000000 65535 f \n`;
319
- let offset = 9; // after %PDF-1.4\n
320
- for (const obj of objects) {
321
- xref += `${String(offset).padStart(10, '0')} 00000 n \n`;
322
- offset += obj.length + 1;
323
- }
324
- return `%PDF-1.4\n${body}\n${xref}trailer\n<< /Size ${totalObjs} /Root ${catalogNum} 0 R >>\nstartxref\n${offset}\n%%EOF`;
325
- }
326
- async createEnvelope(params) {
327
- const body = {
328
- emailSubject: params.email_subject,
329
- status: params.status,
330
- documents: params.documents.map((doc, i) => {
331
- const isPdfName = (doc.name || '').toLowerCase().endsWith('.pdf');
332
- // Auto-convert text content to PDF if the file is named .pdf
333
- if (isPdfName) {
334
- const { base64, extension } = this.ensurePdfContent(doc.document_base64, doc.name);
335
- return {
336
- documentId: doc.document_id || String(i + 1),
337
- name: doc.name,
338
- fileExtension: extension,
339
- documentBase64: base64,
340
- };
341
- }
342
- return {
343
- documentId: doc.document_id || String(i + 1),
344
- name: doc.name,
345
- fileExtension: doc.file_extension,
346
- documentBase64: doc.document_base64,
347
- };
348
- }),
349
- recipients: {
350
- signers: params.signers.map((s, i) => {
351
- const signer = {
352
- email: s.email,
353
- name: s.name,
354
- recipientId: s.recipient_id || String(i + 1),
355
- routingOrder: s.routing_order,
356
- };
357
- if (s.tabs) {
358
- signer.tabs = {};
359
- if (s.tabs.sign_here?.length) {
360
- signer.tabs.signHereTabs = s.tabs.sign_here.map(t => ({
361
- documentId: t.document_id,
362
- pageNumber: t.page_number,
363
- xPosition: t.x_position,
364
- yPosition: t.y_position,
365
- }));
366
- }
367
- if (s.tabs.date_signed?.length) {
368
- signer.tabs.dateSignedTabs = s.tabs.date_signed.map(t => ({
369
- documentId: t.document_id,
370
- pageNumber: t.page_number,
371
- xPosition: t.x_position,
372
- yPosition: t.y_position,
373
- }));
374
- }
375
- if (s.tabs.text?.length) {
376
- signer.tabs.textTabs = s.tabs.text.map(t => ({
377
- documentId: t.document_id,
378
- pageNumber: t.page_number,
379
- xPosition: t.x_position,
380
- yPosition: t.y_position,
381
- tabLabel: t.tab_label,
382
- value: t.value,
383
- required: t.required,
384
- }));
385
- }
386
- }
387
- return signer;
388
- }),
389
- },
390
- };
391
- if (params.cc_recipients?.length) {
392
- body.recipients.carbonCopies = params.cc_recipients.map((cc, i) => ({
393
- email: cc.email,
394
- name: cc.name,
395
- recipientId: cc.recipient_id || String(params.signers.length + i + 1),
396
- routingOrder: cc.routing_order,
397
- }));
398
- }
399
- if (params.email_body) {
400
- body.emailBlurb = params.email_body;
401
- }
402
- const notification = this.buildNotificationObject(params);
403
- if (notification) {
404
- body.notification = notification;
405
- }
406
- const response = await this.makeDocuSignRequest('/envelopes', 'POST', body);
407
- return {
408
- operation: 'create_envelope',
409
- success: true,
410
- envelope_id: response.envelopeId,
411
- status: response.status,
412
- status_date_time: response.statusDateTime,
413
- uri: response.uri,
414
- error: '',
415
- };
416
- }
417
- async createEnvelopeFromTemplate(params) {
418
- const body = {
419
- templateId: params.template_id,
420
- status: params.status,
421
- templateRoles: params.signers.map((s, i) => {
422
- const role = {
423
- email: s.email,
424
- name: s.name,
425
- roleName: s.role_name,
426
- recipientId: s.recipient_id || String(i + 1),
427
- };
428
- // Pre-fill template fields if provided
429
- if (params.template_data) {
430
- role.tabs = {
431
- textTabs: Object.entries(params.template_data).map(([label, value]) => ({
432
- tabLabel: label,
433
- value,
434
- })),
435
- };
436
- }
437
- return role;
438
- }),
439
- };
440
- if (params.cc_recipients?.length) {
441
- body.templateRoles.push(...params.cc_recipients.map((cc, i) => ({
442
- email: cc.email,
443
- name: cc.name,
444
- roleName: cc.role_name,
445
- recipientId: cc.recipient_id || String(params.signers.length + i + 1),
446
- })));
447
- }
448
- if (params.email_subject)
449
- body.emailSubject = params.email_subject;
450
- if (params.email_body)
451
- body.emailBlurb = params.email_body;
452
- const notification = this.buildNotificationObject(params);
453
- if (notification)
454
- body.notification = notification;
455
- const response = await this.makeDocuSignRequest('/envelopes', 'POST', body);
456
- return {
457
- operation: 'create_envelope_from_template',
458
- success: true,
459
- envelope_id: response.envelopeId,
460
- status: response.status,
461
- status_date_time: response.statusDateTime,
462
- uri: response.uri,
463
- error: '',
464
- };
465
- }
466
- async getEnvelope(params) {
467
- const response = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}`);
468
- return {
469
- operation: 'get_envelope',
470
- success: true,
471
- envelope_id: response.envelopeId,
472
- status: response.status,
473
- email_subject: response.emailSubject,
474
- sent_date_time: response.sentDateTime,
475
- completed_date_time: response.completedDateTime,
476
- declined_date_time: response.declinedDateTime,
477
- voided_date_time: response.voidedDateTime,
478
- status_changed_date_time: response.statusChangedDateTime,
479
- error: '',
480
- };
481
- }
482
- async listEnvelopes(params) {
483
- const queryParams = new URLSearchParams();
484
- // Default from_date to 30 days ago if not provided
485
- const fromDate = params.from_date || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
486
- queryParams.set('from_date', fromDate);
487
- if (params.to_date)
488
- queryParams.set('to_date', params.to_date);
489
- if (params.status)
490
- queryParams.set('status', params.status);
491
- if (params.search_text)
492
- queryParams.set('search_text', params.search_text);
493
- if (params.count)
494
- queryParams.set('count', params.count);
495
- if (params.start_position)
496
- queryParams.set('start_position', params.start_position);
497
- if (params.order_by)
498
- queryParams.set('order_by', params.order_by);
499
- if (params.order)
500
- queryParams.set('order', params.order);
501
- const response = await this.makeDocuSignRequest(`/envelopes?${queryParams.toString()}`);
502
- const envelopes = (response.envelopes || []).map((env) => ({
503
- envelope_id: env.envelopeId,
504
- status: env.status,
505
- email_subject: env.emailSubject,
506
- sent_date_time: env.sentDateTime,
507
- completed_date_time: env.completedDateTime,
508
- status_changed_date_time: env.statusChangedDateTime,
509
- }));
510
- return {
511
- operation: 'list_envelopes',
512
- success: true,
513
- envelopes,
514
- result_set_size: response.resultSetSize,
515
- total_set_size: response.totalSetSize,
516
- next_uri: response.nextUri,
517
- error: '',
518
- };
519
- }
520
- async getRecipients(params) {
521
- const response = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/recipients`);
522
- const signers = (response.signers || []).map((s) => ({
523
- email: s.email,
524
- name: s.name,
525
- status: s.status,
526
- signed_date_time: s.signedDateTime,
527
- delivered_date_time: s.deliveredDateTime,
528
- declined_date_time: s.declinedDateTime,
529
- decline_reason: s.declinedReason,
530
- recipient_id: s.recipientId,
531
- routing_order: s.routingOrder,
532
- }));
533
- const ccRecipients = (response.carbonCopies || []).map((cc) => ({
534
- email: cc.email,
535
- name: cc.name,
536
- status: cc.status,
537
- recipient_id: cc.recipientId,
538
- }));
539
- return {
540
- operation: 'get_recipients',
541
- success: true,
542
- signers,
543
- cc_recipients: ccRecipients,
544
- error: '',
545
- };
546
- }
547
- async listTemplates(params) {
548
- const queryParams = new URLSearchParams();
549
- if (params.search_text)
550
- queryParams.set('search_text', params.search_text);
551
- if (params.count)
552
- queryParams.set('count', params.count);
553
- const query = queryParams.toString();
554
- const response = await this.makeDocuSignRequest(`/templates${query ? '?' + query : ''}`);
555
- const templates = (response.envelopeTemplates || []).map((t) => ({
556
- template_id: t.templateId,
557
- name: t.name,
558
- description: t.description,
559
- created: t.created,
560
- last_modified: t.lastModified,
561
- }));
562
- return {
563
- operation: 'list_templates',
564
- success: true,
565
- templates,
566
- result_set_size: response.resultSetSize,
567
- total_set_size: response.totalSetSize,
568
- error: '',
569
- };
570
- }
571
- async downloadDocument(params) {
572
- const documentBase64 = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/documents/${params.document_id}`);
573
- return {
574
- operation: 'download_document',
575
- success: true,
576
- document_base64: documentBase64,
577
- document_name: `envelope_${params.envelope_id}_doc_${params.document_id}.pdf`,
578
- error: '',
579
- };
580
- }
581
- async voidEnvelope(params) {
582
- await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}`, 'PUT', {
583
- status: 'voided',
584
- voidedReason: params.void_reason,
585
- });
586
- return {
587
- operation: 'void_envelope',
588
- success: true,
589
- envelope_id: params.envelope_id,
590
- error: '',
591
- };
592
- }
593
- async resendEnvelope(params) {
594
- // First get current recipients, then PUT them back with resend flag
595
- const recipients = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/recipients`);
596
- // Build the recipients payload with only signers who haven't completed
597
- const signers = (recipients.signers || [])
598
- .filter((s) => s.status !== 'completed')
599
- .map((s) => ({
600
- email: s.email,
601
- name: s.name,
602
- recipientId: s.recipientId,
603
- }));
604
- if (signers.length === 0) {
605
- return {
606
- operation: 'resend_envelope',
607
- success: true,
608
- envelope_id: params.envelope_id,
609
- error: 'All recipients have already completed signing.',
610
- };
611
- }
612
- await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/recipients?resend_envelope=true`, 'PUT', { signers });
613
- return {
614
- operation: 'resend_envelope',
615
- success: true,
616
- envelope_id: params.envelope_id,
617
- error: '',
618
- };
619
- }
620
- async bulkSendFromTemplate(params) {
621
- if (!params.recipients || params.recipients.length === 0) {
622
- return {
623
- operation: 'bulk_send_from_template',
624
- success: false,
625
- results: [],
626
- total_sent: 0,
627
- total_failed: 0,
628
- error: 'Recipients array is empty. At least one recipient is required.',
629
- };
630
- }
631
- const results = [];
632
- let totalSent = 0;
633
- let totalFailed = 0;
634
- for (const recipient of params.recipients) {
635
- try {
636
- const body = {
637
- templateId: params.template_id,
638
- status: 'sent',
639
- templateRoles: [
640
- {
641
- email: recipient.email,
642
- name: recipient.name,
643
- roleName: recipient.role_name,
644
- },
645
- ],
646
- };
647
- if (params.email_subject)
648
- body.emailSubject = params.email_subject;
649
- if (params.email_body)
650
- body.emailBlurb = params.email_body;
651
- const response = await this.makeDocuSignRequest('/envelopes', 'POST', body);
652
- results.push({
653
- envelope_id: response.envelopeId,
654
- status: response.status,
655
- recipient_email: recipient.email,
656
- });
657
- totalSent++;
658
- }
659
- catch (error) {
660
- results.push({
661
- recipient_email: recipient.email,
662
- error: error instanceof Error ? error.message : 'Unknown error',
663
- });
664
- totalFailed++;
665
- }
666
- }
667
- return {
668
- operation: 'bulk_send_from_template',
669
- success: totalSent > 0,
670
- results,
671
- total_sent: totalSent,
672
- total_failed: totalFailed,
673
- error: totalFailed > 0 ? `${totalFailed} of ${params.recipients.length} sends failed.` : '',
674
- };
675
- }
676
- async getSigningUrl(params) {
677
- const body = {
678
- returnUrl: params.return_url,
679
- authenticationMethod: 'none',
680
- email: params.signer_email,
681
- userName: params.signer_name,
682
- };
683
- const response = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/views/recipient`, 'POST', body);
684
- return {
685
- operation: 'get_signing_url',
686
- success: true,
687
- signing_url: response.url,
688
- error: '',
689
- };
690
- }
691
- async correctRecipient(params) {
692
- // First, get current recipients to find the recipientId for old_email
693
- const recipients = await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/recipients`);
694
- const signers = recipients.signers || [];
695
- const matchingSigner = signers.find((s) => s.email.toLowerCase() === params.old_email.toLowerCase());
696
- if (!matchingSigner) {
697
- return {
698
- operation: 'correct_recipient',
699
- success: false,
700
- envelope_id: params.envelope_id,
701
- old_email: params.old_email,
702
- new_email: params.new_email,
703
- error: `No recipient found with email "${params.old_email}" on envelope ${params.envelope_id}.`,
704
- };
705
- }
706
- // PUT updated recipient info
707
- await this.makeDocuSignRequest(`/envelopes/${params.envelope_id}/recipients`, 'PUT', {
708
- signers: [
709
- {
710
- recipientId: matchingSigner.recipientId,
711
- email: params.new_email,
712
- name: params.new_name || matchingSigner.name,
713
- },
714
- ],
715
- });
716
- return {
717
- operation: 'correct_recipient',
718
- success: true,
719
- envelope_id: params.envelope_id,
720
- old_email: params.old_email,
721
- new_email: params.new_email,
722
- error: '',
723
- };
724
- }
725
- chooseCredential() {
726
- const creds = this.parseCredentials();
727
- return creds?.accessToken;
728
- }
729
- }
730
- //# sourceMappingURL=docusign.js.map