@stack0/sdk 0.4.0 → 0.5.2

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/dist/index.js CHANGED
@@ -79,14 +79,644 @@ var HttpClient = class {
79
79
  }
80
80
  };
81
81
 
82
+ // src/mail/audiences.ts
83
+ var Audiences = class {
84
+ constructor(http) {
85
+ this.http = http;
86
+ }
87
+ /**
88
+ * List all audiences
89
+ */
90
+ async list(request = {}) {
91
+ const params = new URLSearchParams();
92
+ if (request.environment) params.set("environment", request.environment);
93
+ if (request.limit) params.set("limit", request.limit.toString());
94
+ if (request.offset) params.set("offset", request.offset.toString());
95
+ if (request.search) params.set("search", request.search);
96
+ const query = params.toString();
97
+ return this.http.get(`/mail/audiences${query ? `?${query}` : ""}`);
98
+ }
99
+ /**
100
+ * Get an audience by ID
101
+ */
102
+ async get(id) {
103
+ return this.http.get(`/mail/audiences/${id}`);
104
+ }
105
+ /**
106
+ * Create a new audience
107
+ */
108
+ async create(request) {
109
+ return this.http.post("/mail/audiences", request);
110
+ }
111
+ /**
112
+ * Update an audience
113
+ */
114
+ async update(request) {
115
+ const { id, ...data } = request;
116
+ return this.http.put(`/mail/audiences/${id}`, data);
117
+ }
118
+ /**
119
+ * Delete an audience
120
+ */
121
+ async delete(id) {
122
+ return this.http.delete(`/mail/audiences/${id}`);
123
+ }
124
+ /**
125
+ * List contacts in an audience
126
+ */
127
+ async listContacts(request) {
128
+ const { id, ...params } = request;
129
+ const searchParams = new URLSearchParams();
130
+ if (params.environment) searchParams.set("environment", params.environment);
131
+ if (params.limit) searchParams.set("limit", params.limit.toString());
132
+ if (params.offset) searchParams.set("offset", params.offset.toString());
133
+ if (params.search) searchParams.set("search", params.search);
134
+ if (params.status) searchParams.set("status", params.status);
135
+ const query = searchParams.toString();
136
+ return this.http.get(`/mail/audiences/${id}/contacts${query ? `?${query}` : ""}`);
137
+ }
138
+ /**
139
+ * Add contacts to an audience
140
+ */
141
+ async addContacts(request) {
142
+ const { id, contactIds } = request;
143
+ return this.http.post(`/mail/audiences/${id}/contacts`, { contactIds });
144
+ }
145
+ /**
146
+ * Remove contacts from an audience
147
+ */
148
+ async removeContacts(request) {
149
+ const { id, contactIds } = request;
150
+ return this.http.deleteWithBody(`/mail/audiences/${id}/contacts`, {
151
+ contactIds
152
+ });
153
+ }
154
+ };
155
+
156
+ // src/mail/campaigns.ts
157
+ var Campaigns = class {
158
+ constructor(http) {
159
+ this.http = http;
160
+ }
161
+ /**
162
+ * List all campaigns
163
+ */
164
+ async list(request = {}) {
165
+ const params = new URLSearchParams();
166
+ if (request.environment) params.set("environment", request.environment);
167
+ if (request.limit) params.set("limit", request.limit.toString());
168
+ if (request.offset) params.set("offset", request.offset.toString());
169
+ if (request.search) params.set("search", request.search);
170
+ if (request.status) params.set("status", request.status);
171
+ const query = params.toString();
172
+ return this.http.get(`/mail/campaigns${query ? `?${query}` : ""}`);
173
+ }
174
+ /**
175
+ * Get a campaign by ID
176
+ */
177
+ async get(id) {
178
+ return this.http.get(`/mail/campaigns/${id}`);
179
+ }
180
+ /**
181
+ * Create a new campaign
182
+ */
183
+ async create(request) {
184
+ return this.http.post("/mail/campaigns", request);
185
+ }
186
+ /**
187
+ * Update a campaign
188
+ */
189
+ async update(request) {
190
+ const { id, ...data } = request;
191
+ return this.http.put(`/mail/campaigns/${id}`, data);
192
+ }
193
+ /**
194
+ * Delete a campaign
195
+ */
196
+ async delete(id) {
197
+ return this.http.delete(`/mail/campaigns/${id}`);
198
+ }
199
+ /**
200
+ * Send a campaign
201
+ */
202
+ async send(request) {
203
+ const { id, ...data } = request;
204
+ return this.http.post(`/mail/campaigns/${id}/send`, data);
205
+ }
206
+ /**
207
+ * Pause a sending campaign
208
+ */
209
+ async pause(id) {
210
+ return this.http.post(`/mail/campaigns/${id}/pause`, {});
211
+ }
212
+ /**
213
+ * Cancel a campaign
214
+ */
215
+ async cancel(id) {
216
+ return this.http.post(`/mail/campaigns/${id}/cancel`, {});
217
+ }
218
+ /**
219
+ * Duplicate a campaign
220
+ */
221
+ async duplicate(id) {
222
+ return this.http.post(`/mail/campaigns/${id}/duplicate`, {});
223
+ }
224
+ /**
225
+ * Get campaign statistics
226
+ */
227
+ async getStats(id) {
228
+ return this.http.get(`/mail/campaigns/${id}/stats`);
229
+ }
230
+ };
231
+
232
+ // src/mail/contacts.ts
233
+ var Contacts = class {
234
+ constructor(http) {
235
+ this.http = http;
236
+ }
237
+ /**
238
+ * List all contacts
239
+ */
240
+ async list(request = {}) {
241
+ const params = new URLSearchParams();
242
+ if (request.environment) params.set("environment", request.environment);
243
+ if (request.limit) params.set("limit", request.limit.toString());
244
+ if (request.offset) params.set("offset", request.offset.toString());
245
+ if (request.search) params.set("search", request.search);
246
+ if (request.status) params.set("status", request.status);
247
+ const query = params.toString();
248
+ return this.http.get(`/mail/contacts${query ? `?${query}` : ""}`);
249
+ }
250
+ /**
251
+ * Get a contact by ID
252
+ */
253
+ async get(id) {
254
+ return this.http.get(`/mail/contacts/${id}`);
255
+ }
256
+ /**
257
+ * Create a new contact
258
+ */
259
+ async create(request) {
260
+ return this.http.post("/mail/contacts", request);
261
+ }
262
+ /**
263
+ * Update a contact
264
+ */
265
+ async update(request) {
266
+ const { id, ...data } = request;
267
+ return this.http.put(`/mail/contacts/${id}`, data);
268
+ }
269
+ /**
270
+ * Delete a contact
271
+ */
272
+ async delete(id) {
273
+ return this.http.delete(`/mail/contacts/${id}`);
274
+ }
275
+ /**
276
+ * Import contacts in bulk
277
+ */
278
+ async import(request) {
279
+ return this.http.post("/mail/contacts/import", request);
280
+ }
281
+ };
282
+
283
+ // src/mail/domains.ts
284
+ var Domains = class {
285
+ constructor(http) {
286
+ this.http = http;
287
+ }
288
+ /**
289
+ * List all domains for the organization
290
+ */
291
+ async list(request) {
292
+ const params = new URLSearchParams();
293
+ params.set("projectSlug", request.projectSlug);
294
+ if (request.environment) params.set("environment", request.environment);
295
+ return this.http.get(`/mail/domains?${params.toString()}`);
296
+ }
297
+ /**
298
+ * Add a new domain
299
+ */
300
+ async add(request) {
301
+ return this.http.post("/mail/domains", request);
302
+ }
303
+ /**
304
+ * Get DNS records for a domain
305
+ */
306
+ async getDnsRecords(domainId) {
307
+ return this.http.get(`/mail/domains/${domainId}/dns`);
308
+ }
309
+ /**
310
+ * Verify a domain
311
+ */
312
+ async verify(domainId) {
313
+ return this.http.post(`/mail/domains/${domainId}/verify`, {});
314
+ }
315
+ /**
316
+ * Delete a domain
317
+ */
318
+ async delete(domainId) {
319
+ return this.http.delete(`/mail/domains/${domainId}`);
320
+ }
321
+ /**
322
+ * Set a domain as the default
323
+ */
324
+ async setDefault(domainId) {
325
+ return this.http.post(`/mail/domains/${domainId}/default`, {});
326
+ }
327
+ };
328
+
329
+ // src/mail/events.ts
330
+ var Events = class {
331
+ constructor(http) {
332
+ this.http = http;
333
+ }
334
+ // ============================================================================
335
+ // EVENT DEFINITIONS
336
+ // ============================================================================
337
+ /**
338
+ * List all event definitions
339
+ */
340
+ async list(request = {}) {
341
+ const params = new URLSearchParams();
342
+ if (request.projectSlug) params.set("projectSlug", request.projectSlug);
343
+ if (request.environment) params.set("environment", request.environment);
344
+ if (request.limit) params.set("limit", request.limit.toString());
345
+ if (request.offset) params.set("offset", request.offset.toString());
346
+ if (request.search) params.set("search", request.search);
347
+ const query = params.toString();
348
+ return this.http.get(`/mail/events${query ? `?${query}` : ""}`);
349
+ }
350
+ /**
351
+ * Get an event definition by ID
352
+ */
353
+ async get(id) {
354
+ return this.http.get(`/mail/events/${id}`);
355
+ }
356
+ /**
357
+ * Create a new event definition
358
+ */
359
+ async create(request) {
360
+ return this.http.post("/mail/events", request);
361
+ }
362
+ /**
363
+ * Update an event definition
364
+ */
365
+ async update(request) {
366
+ const { id, ...data } = request;
367
+ return this.http.put(`/mail/events/${id}`, data);
368
+ }
369
+ /**
370
+ * Delete an event definition
371
+ */
372
+ async delete(id) {
373
+ return this.http.delete(`/mail/events/${id}`);
374
+ }
375
+ // ============================================================================
376
+ // EVENT TRACKING
377
+ // ============================================================================
378
+ /**
379
+ * Track a single event
380
+ * This can trigger email sequences configured to listen for this event
381
+ */
382
+ async track(request) {
383
+ return this.http.post("/mail/events/track", request);
384
+ }
385
+ /**
386
+ * Track multiple events in a batch (max 100)
387
+ */
388
+ async trackBatch(request) {
389
+ return this.http.post("/mail/events/track/batch", request);
390
+ }
391
+ // ============================================================================
392
+ // EVENT OCCURRENCES
393
+ // ============================================================================
394
+ /**
395
+ * List event occurrences
396
+ */
397
+ async listOccurrences(request = {}) {
398
+ const params = new URLSearchParams();
399
+ if (request.eventId) params.set("eventId", request.eventId);
400
+ if (request.contactId) params.set("contactId", request.contactId);
401
+ if (request.limit) params.set("limit", request.limit.toString());
402
+ if (request.offset) params.set("offset", request.offset.toString());
403
+ if (request.startDate) {
404
+ params.set("startDate", request.startDate instanceof Date ? request.startDate.toISOString() : request.startDate);
405
+ }
406
+ if (request.endDate) {
407
+ params.set("endDate", request.endDate instanceof Date ? request.endDate.toISOString() : request.endDate);
408
+ }
409
+ const query = params.toString();
410
+ return this.http.get(`/mail/events/occurrences${query ? `?${query}` : ""}`);
411
+ }
412
+ // ============================================================================
413
+ // ANALYTICS
414
+ // ============================================================================
415
+ /**
416
+ * Get analytics for an event
417
+ */
418
+ async getAnalytics(id) {
419
+ return this.http.get(`/mail/events/analytics/${id}`);
420
+ }
421
+ };
422
+
423
+ // src/mail/sequences.ts
424
+ var Sequences = class {
425
+ constructor(http) {
426
+ this.http = http;
427
+ }
428
+ // ============================================================================
429
+ // SEQUENCE CRUD
430
+ // ============================================================================
431
+ /**
432
+ * List all sequences
433
+ */
434
+ async list(request = {}) {
435
+ const params = new URLSearchParams();
436
+ if (request.environment) params.set("environment", request.environment);
437
+ if (request.limit) params.set("limit", request.limit.toString());
438
+ if (request.offset) params.set("offset", request.offset.toString());
439
+ if (request.search) params.set("search", request.search);
440
+ if (request.status) params.set("status", request.status);
441
+ if (request.triggerType) params.set("triggerType", request.triggerType);
442
+ const query = params.toString();
443
+ return this.http.get(`/mail/sequences${query ? `?${query}` : ""}`);
444
+ }
445
+ /**
446
+ * Get a sequence by ID with all nodes and connections
447
+ */
448
+ async get(id) {
449
+ return this.http.get(`/mail/sequences/${id}`);
450
+ }
451
+ /**
452
+ * Create a new sequence
453
+ */
454
+ async create(request) {
455
+ return this.http.post("/mail/sequences", request);
456
+ }
457
+ /**
458
+ * Update a sequence
459
+ */
460
+ async update(request) {
461
+ const { id, ...data } = request;
462
+ return this.http.put(`/mail/sequences/${id}`, data);
463
+ }
464
+ /**
465
+ * Delete a sequence
466
+ */
467
+ async delete(id) {
468
+ return this.http.delete(`/mail/sequences/${id}`);
469
+ }
470
+ // ============================================================================
471
+ // SEQUENCE LIFECYCLE
472
+ // ============================================================================
473
+ /**
474
+ * Publish (activate) a sequence
475
+ */
476
+ async publish(id) {
477
+ return this.http.post(`/mail/sequences/${id}/publish`, {});
478
+ }
479
+ /**
480
+ * Pause an active sequence
481
+ */
482
+ async pause(id) {
483
+ return this.http.post(`/mail/sequences/${id}/pause`, {});
484
+ }
485
+ /**
486
+ * Resume a paused sequence
487
+ */
488
+ async resume(id) {
489
+ return this.http.post(`/mail/sequences/${id}/resume`, {});
490
+ }
491
+ /**
492
+ * Archive a sequence
493
+ */
494
+ async archive(id) {
495
+ return this.http.post(`/mail/sequences/${id}/archive`, {});
496
+ }
497
+ /**
498
+ * Duplicate a sequence
499
+ */
500
+ async duplicate(id, name) {
501
+ return this.http.post(`/mail/sequences/${id}/duplicate`, { name });
502
+ }
503
+ // ============================================================================
504
+ // NODE MANAGEMENT
505
+ // ============================================================================
506
+ /**
507
+ * Create a new node in a sequence
508
+ */
509
+ async createNode(request) {
510
+ const { id, ...data } = request;
511
+ return this.http.post(`/mail/sequences/${id}/nodes`, data);
512
+ }
513
+ /**
514
+ * Update a node
515
+ */
516
+ async updateNode(request) {
517
+ const { id, nodeId, ...data } = request;
518
+ return this.http.put(`/mail/sequences/${id}/nodes/${nodeId}`, data);
519
+ }
520
+ /**
521
+ * Update node position (for visual editor)
522
+ */
523
+ async updateNodePosition(request) {
524
+ const { id, nodeId, positionX, positionY } = request;
525
+ return this.http.put(`/mail/sequences/${id}/nodes/${nodeId}/position`, { positionX, positionY });
526
+ }
527
+ /**
528
+ * Delete a node
529
+ */
530
+ async deleteNode(sequenceId, nodeId) {
531
+ return this.http.delete(`/mail/sequences/${sequenceId}/nodes/${nodeId}`);
532
+ }
533
+ // ============================================================================
534
+ // NODE CONFIGURATIONS
535
+ // ============================================================================
536
+ /**
537
+ * Set email node content
538
+ */
539
+ async setNodeEmail(sequenceId, request) {
540
+ const { nodeId, ...data } = request;
541
+ return this.http.put(`/mail/sequences/${sequenceId}/nodes/${nodeId}/email`, data);
542
+ }
543
+ /**
544
+ * Set timer node configuration
545
+ */
546
+ async setNodeTimer(sequenceId, request) {
547
+ const { nodeId, ...data } = request;
548
+ return this.http.put(`/mail/sequences/${sequenceId}/nodes/${nodeId}/timer`, data);
549
+ }
550
+ /**
551
+ * Set filter node configuration
552
+ */
553
+ async setNodeFilter(sequenceId, request) {
554
+ const { nodeId, ...data } = request;
555
+ return this.http.put(`/mail/sequences/${sequenceId}/nodes/${nodeId}/filter`, data);
556
+ }
557
+ /**
558
+ * Set branch node configuration
559
+ */
560
+ async setNodeBranch(sequenceId, request) {
561
+ const { nodeId, ...data } = request;
562
+ return this.http.put(`/mail/sequences/${sequenceId}/nodes/${nodeId}/branch`, data);
563
+ }
564
+ /**
565
+ * Set experiment node configuration
566
+ */
567
+ async setNodeExperiment(sequenceId, request) {
568
+ const { nodeId, ...data } = request;
569
+ return this.http.put(`/mail/sequences/${sequenceId}/nodes/${nodeId}/experiment`, data);
570
+ }
571
+ // ============================================================================
572
+ // CONNECTIONS
573
+ // ============================================================================
574
+ /**
575
+ * Create a connection between nodes
576
+ */
577
+ async createConnection(request) {
578
+ const { id, ...data } = request;
579
+ return this.http.post(`/mail/sequences/${id}/connections`, data);
580
+ }
581
+ /**
582
+ * Delete a connection
583
+ */
584
+ async deleteConnection(sequenceId, connectionId) {
585
+ return this.http.delete(`/mail/sequences/${sequenceId}/connections/${connectionId}`);
586
+ }
587
+ // ============================================================================
588
+ // SEQUENCE ENTRIES (CONTACTS IN SEQUENCE)
589
+ // ============================================================================
590
+ /**
591
+ * List contacts in a sequence
592
+ */
593
+ async listEntries(request) {
594
+ const { id, ...params } = request;
595
+ const searchParams = new URLSearchParams();
596
+ if (params.limit) searchParams.set("limit", params.limit.toString());
597
+ if (params.offset) searchParams.set("offset", params.offset.toString());
598
+ if (params.status) searchParams.set("status", params.status);
599
+ const query = searchParams.toString();
600
+ return this.http.get(`/mail/sequences/${id}/entries${query ? `?${query}` : ""}`);
601
+ }
602
+ /**
603
+ * Add a contact to a sequence
604
+ */
605
+ async addContact(request) {
606
+ const { id, contactId } = request;
607
+ return this.http.post(`/mail/sequences/${id}/add-contact`, { contactId });
608
+ }
609
+ /**
610
+ * Remove a contact from a sequence
611
+ */
612
+ async removeContact(request) {
613
+ const { id, entryId, reason } = request;
614
+ return this.http.post(`/mail/sequences/${id}/remove-contact`, {
615
+ entryId,
616
+ reason
617
+ });
618
+ }
619
+ // ============================================================================
620
+ // ANALYTICS
621
+ // ============================================================================
622
+ /**
623
+ * Get sequence analytics
624
+ */
625
+ async getAnalytics(id) {
626
+ return this.http.get(`/mail/sequences/${id}/analytics`);
627
+ }
628
+ };
629
+
630
+ // src/mail/templates.ts
631
+ var Templates = class {
632
+ constructor(http) {
633
+ this.http = http;
634
+ }
635
+ /**
636
+ * List all templates
637
+ */
638
+ async list(request = {}) {
639
+ const params = new URLSearchParams();
640
+ if (request.environment) params.set("environment", request.environment);
641
+ if (request.limit) params.set("limit", request.limit.toString());
642
+ if (request.offset) params.set("offset", request.offset.toString());
643
+ if (request.isActive !== void 0) params.set("isActive", request.isActive.toString());
644
+ if (request.search) params.set("search", request.search);
645
+ const query = params.toString();
646
+ return this.http.get(`/mail/templates${query ? `?${query}` : ""}`);
647
+ }
648
+ /**
649
+ * Get a template by ID
650
+ */
651
+ async get(id) {
652
+ return this.http.get(`/mail/templates/${id}`);
653
+ }
654
+ /**
655
+ * Get a template by slug
656
+ */
657
+ async getBySlug(slug) {
658
+ return this.http.get(`/mail/templates/slug/${slug}`);
659
+ }
660
+ /**
661
+ * Create a new template
662
+ */
663
+ async create(request) {
664
+ return this.http.post("/mail/templates", request);
665
+ }
666
+ /**
667
+ * Update a template
668
+ */
669
+ async update(request) {
670
+ const { id, ...data } = request;
671
+ return this.http.put(`/mail/templates/${id}`, data);
672
+ }
673
+ /**
674
+ * Delete a template
675
+ */
676
+ async delete(id) {
677
+ return this.http.delete(`/mail/templates/${id}`);
678
+ }
679
+ /**
680
+ * Preview a template with variables
681
+ */
682
+ async preview(request) {
683
+ const { id, variables } = request;
684
+ return this.http.post(`/mail/templates/${id}/preview`, { variables });
685
+ }
686
+ };
687
+
82
688
  // src/mail/client.ts
83
689
  var Mail = class {
84
690
  http;
691
+ /** Manage sending domains */
692
+ domains;
693
+ /** Manage email templates */
694
+ templates;
695
+ /** Manage contact audiences/lists */
696
+ audiences;
697
+ /** Manage contacts */
698
+ contacts;
699
+ /** Manage email campaigns */
700
+ campaigns;
701
+ /** Manage automated email sequences */
702
+ sequences;
703
+ /** Track and manage custom events */
704
+ events;
85
705
  constructor(config) {
86
706
  this.http = new HttpClient(config);
707
+ this.domains = new Domains(this.http);
708
+ this.templates = new Templates(this.http);
709
+ this.audiences = new Audiences(this.http);
710
+ this.contacts = new Contacts(this.http);
711
+ this.campaigns = new Campaigns(this.http);
712
+ this.sequences = new Sequences(this.http);
713
+ this.events = new Events(this.http);
87
714
  }
715
+ // ============================================================================
716
+ // TRANSACTIONAL EMAILS
717
+ // ============================================================================
88
718
  /**
89
- * Send an email
719
+ * Send a single email
90
720
  *
91
721
  * @example
92
722
  * ```typescript
@@ -99,11 +729,40 @@ var Mail = class {
99
729
  * ```
100
730
  */
101
731
  async send(request) {
102
- const response = await this.http.post("/mail/send", request);
103
- if (typeof response.createdAt === "string") {
104
- response.createdAt = new Date(response.createdAt);
105
- }
106
- return response;
732
+ return this.http.post("/mail/send", request);
733
+ }
734
+ /**
735
+ * Send multiple emails in a batch (up to 100)
736
+ * Each email can have different content and recipients
737
+ *
738
+ * @example
739
+ * ```typescript
740
+ * const result = await mail.sendBatch({
741
+ * emails: [
742
+ * { from: 'noreply@example.com', to: 'user1@example.com', subject: 'Hello', html: '<p>Hi User 1</p>' },
743
+ * { from: 'noreply@example.com', to: 'user2@example.com', subject: 'Hello', html: '<p>Hi User 2</p>' },
744
+ * ]
745
+ * });
746
+ * ```
747
+ */
748
+ async sendBatch(request) {
749
+ return this.http.post("/mail/send/batch", request);
750
+ }
751
+ /**
752
+ * Send a broadcast email (same content to multiple recipients, up to 1000)
753
+ *
754
+ * @example
755
+ * ```typescript
756
+ * const result = await mail.sendBroadcast({
757
+ * from: 'noreply@example.com',
758
+ * to: ['user1@example.com', 'user2@example.com', 'user3@example.com'],
759
+ * subject: 'Newsletter',
760
+ * html: '<p>Our latest updates...</p>',
761
+ * });
762
+ * ```
763
+ */
764
+ async sendBroadcast(request) {
765
+ return this.http.post("/mail/send/broadcast", request);
107
766
  }
108
767
  /**
109
768
  * Get email details by ID
@@ -115,14 +774,87 @@ var Mail = class {
115
774
  * ```
116
775
  */
117
776
  async get(id) {
118
- const response = await this.http.get(`/mail/${id}`);
119
- const dateFields = ["createdAt", "sentAt", "deliveredAt", "openedAt", "clickedAt", "bouncedAt"];
120
- for (const field of dateFields) {
121
- if (response[field] && typeof response[field] === "string") {
122
- response[field] = new Date(response[field]);
123
- }
777
+ return this.http.get(`/mail/${id}`);
778
+ }
779
+ /**
780
+ * List emails with optional filters
781
+ *
782
+ * @example
783
+ * ```typescript
784
+ * const result = await mail.list({
785
+ * status: 'delivered',
786
+ * limit: 50,
787
+ * });
788
+ * ```
789
+ */
790
+ async list(request = {}) {
791
+ const params = new URLSearchParams();
792
+ if (request.projectSlug) params.set("projectSlug", request.projectSlug);
793
+ if (request.environment) params.set("environment", request.environment);
794
+ if (request.limit) params.set("limit", request.limit.toString());
795
+ if (request.offset) params.set("offset", request.offset.toString());
796
+ if (request.status) params.set("status", request.status);
797
+ if (request.from) params.set("from", request.from);
798
+ if (request.to) params.set("to", request.to);
799
+ if (request.subject) params.set("subject", request.subject);
800
+ if (request.tag) params.set("tag", request.tag);
801
+ if (request.startDate) {
802
+ params.set("startDate", request.startDate instanceof Date ? request.startDate.toISOString() : request.startDate);
124
803
  }
125
- return response;
804
+ if (request.endDate) {
805
+ params.set("endDate", request.endDate instanceof Date ? request.endDate.toISOString() : request.endDate);
806
+ }
807
+ if (request.sortBy) params.set("sortBy", request.sortBy);
808
+ if (request.sortOrder) params.set("sortOrder", request.sortOrder);
809
+ const query = params.toString();
810
+ return this.http.get(`/mail${query ? `?${query}` : ""}`);
811
+ }
812
+ /**
813
+ * Resend a previously sent email
814
+ */
815
+ async resend(id) {
816
+ return this.http.post(`/mail/${id}/resend`, {});
817
+ }
818
+ /**
819
+ * Cancel a scheduled email
820
+ */
821
+ async cancel(id) {
822
+ return this.http.post(`/mail/${id}/cancel`, {});
823
+ }
824
+ // ============================================================================
825
+ // ANALYTICS
826
+ // ============================================================================
827
+ /**
828
+ * Get overall email analytics
829
+ */
830
+ async getAnalytics() {
831
+ return this.http.get("/mail/analytics");
832
+ }
833
+ /**
834
+ * Get time series analytics (daily breakdown)
835
+ */
836
+ async getTimeSeriesAnalytics(request = {}) {
837
+ const params = new URLSearchParams();
838
+ if (request.days) params.set("days", request.days.toString());
839
+ const query = params.toString();
840
+ return this.http.get(`/mail/analytics/timeseries${query ? `?${query}` : ""}`);
841
+ }
842
+ /**
843
+ * Get hourly analytics
844
+ */
845
+ async getHourlyAnalytics() {
846
+ return this.http.get("/mail/analytics/hourly");
847
+ }
848
+ /**
849
+ * List unique senders with their statistics
850
+ */
851
+ async listSenders(request = {}) {
852
+ const params = new URLSearchParams();
853
+ if (request.projectSlug) params.set("projectSlug", request.projectSlug);
854
+ if (request.environment) params.set("environment", request.environment);
855
+ if (request.search) params.set("search", request.search);
856
+ const query = params.toString();
857
+ return this.http.get(`/mail/senders${query ? `?${query}` : ""}`);
126
858
  }
127
859
  };
128
860
 
@@ -603,6 +1335,273 @@ var CDN = class {
603
1335
  }
604
1336
  return job;
605
1337
  }
1338
+ // ============================================================================
1339
+ // Private Files Methods
1340
+ // ============================================================================
1341
+ /**
1342
+ * Generate a presigned URL for uploading a private file
1343
+ *
1344
+ * Private files are stored securely and can only be accessed through
1345
+ * authorized download links with configurable expiration.
1346
+ *
1347
+ * @example
1348
+ * ```typescript
1349
+ * const { uploadUrl, fileId } = await cdn.getPrivateUploadUrl({
1350
+ * projectSlug: 'my-project',
1351
+ * filename: 'confidential.pdf',
1352
+ * mimeType: 'application/pdf',
1353
+ * size: 1024 * 1024,
1354
+ * });
1355
+ *
1356
+ * // Upload file to the presigned URL
1357
+ * await fetch(uploadUrl, {
1358
+ * method: 'PUT',
1359
+ * body: file,
1360
+ * headers: { 'Content-Type': 'application/pdf' },
1361
+ * });
1362
+ *
1363
+ * // Confirm the upload
1364
+ * const privateFile = await cdn.confirmPrivateUpload(fileId);
1365
+ * ```
1366
+ */
1367
+ async getPrivateUploadUrl(request) {
1368
+ const response = await this.http.post("/cdn/private/upload", request);
1369
+ if (typeof response.expiresAt === "string") {
1370
+ response.expiresAt = new Date(response.expiresAt);
1371
+ }
1372
+ return response;
1373
+ }
1374
+ /**
1375
+ * Confirm that a private file upload has completed
1376
+ */
1377
+ async confirmPrivateUpload(fileId) {
1378
+ const response = await this.http.post(`/cdn/private/upload/${fileId}/confirm`, {});
1379
+ return this.convertPrivateFileDates(response);
1380
+ }
1381
+ /**
1382
+ * Upload a private file directly (handles presigned URL flow automatically)
1383
+ *
1384
+ * @example
1385
+ * ```typescript
1386
+ * const privateFile = await cdn.uploadPrivate({
1387
+ * projectSlug: 'my-project',
1388
+ * file: fileBuffer,
1389
+ * filename: 'confidential.pdf',
1390
+ * mimeType: 'application/pdf',
1391
+ * });
1392
+ * ```
1393
+ */
1394
+ async uploadPrivate(options) {
1395
+ const { projectSlug, file, filename, mimeType, folder, description, metadata } = options;
1396
+ let size;
1397
+ if (file instanceof Blob) {
1398
+ size = file.size;
1399
+ } else if (file instanceof ArrayBuffer) {
1400
+ size = file.byteLength;
1401
+ } else {
1402
+ size = file.length;
1403
+ }
1404
+ const { uploadUrl, fileId } = await this.getPrivateUploadUrl({
1405
+ projectSlug,
1406
+ filename,
1407
+ mimeType,
1408
+ size,
1409
+ folder,
1410
+ description,
1411
+ metadata
1412
+ });
1413
+ const uploadResponse = await fetch(uploadUrl, {
1414
+ method: "PUT",
1415
+ body: file,
1416
+ headers: {
1417
+ "Content-Type": mimeType
1418
+ }
1419
+ });
1420
+ if (!uploadResponse.ok) {
1421
+ throw new Error(`Upload failed: ${uploadResponse.statusText}`);
1422
+ }
1423
+ return this.confirmPrivateUpload(fileId);
1424
+ }
1425
+ /**
1426
+ * Generate a presigned download URL for a private file
1427
+ *
1428
+ * @example
1429
+ * ```typescript
1430
+ * const { downloadUrl, expiresAt } = await cdn.getPrivateDownloadUrl({
1431
+ * fileId: 'file-id',
1432
+ * expiresIn: 86400, // 24 hours
1433
+ * });
1434
+ * ```
1435
+ */
1436
+ async getPrivateDownloadUrl(request) {
1437
+ const response = await this.http.post(
1438
+ `/cdn/private/${request.fileId}/download`,
1439
+ { expiresIn: request.expiresIn }
1440
+ );
1441
+ if (typeof response.expiresAt === "string") {
1442
+ response.expiresAt = new Date(response.expiresAt);
1443
+ }
1444
+ return response;
1445
+ }
1446
+ /**
1447
+ * Get a private file by ID
1448
+ */
1449
+ async getPrivateFile(fileId) {
1450
+ const response = await this.http.get(`/cdn/private/${fileId}`);
1451
+ return this.convertPrivateFileDates(response);
1452
+ }
1453
+ /**
1454
+ * Update a private file's metadata
1455
+ */
1456
+ async updatePrivateFile(request) {
1457
+ const { fileId, ...data } = request;
1458
+ const response = await this.http.patch(`/cdn/private/${fileId}`, data);
1459
+ return this.convertPrivateFileDates(response);
1460
+ }
1461
+ /**
1462
+ * Delete a private file
1463
+ */
1464
+ async deletePrivateFile(fileId) {
1465
+ return this.http.deleteWithBody(`/cdn/private/${fileId}`, { fileId });
1466
+ }
1467
+ /**
1468
+ * Delete multiple private files
1469
+ */
1470
+ async deletePrivateFiles(fileIds) {
1471
+ return this.http.post("/cdn/private/delete", { fileIds });
1472
+ }
1473
+ /**
1474
+ * List private files with filters and pagination
1475
+ *
1476
+ * @example
1477
+ * ```typescript
1478
+ * const { files, total, hasMore } = await cdn.listPrivateFiles({
1479
+ * projectSlug: 'my-project',
1480
+ * limit: 20,
1481
+ * });
1482
+ * ```
1483
+ */
1484
+ async listPrivateFiles(request) {
1485
+ const params = new URLSearchParams();
1486
+ params.set("projectSlug", request.projectSlug);
1487
+ if (request.folder !== void 0) params.set("folder", request.folder ?? "");
1488
+ if (request.status) params.set("status", request.status);
1489
+ if (request.search) params.set("search", request.search);
1490
+ if (request.sortBy) params.set("sortBy", request.sortBy);
1491
+ if (request.sortOrder) params.set("sortOrder", request.sortOrder);
1492
+ if (request.limit) params.set("limit", request.limit.toString());
1493
+ if (request.offset) params.set("offset", request.offset.toString());
1494
+ const response = await this.http.get(`/cdn/private?${params.toString()}`);
1495
+ return {
1496
+ ...response,
1497
+ files: response.files.map((file) => this.convertPrivateFileDates(file))
1498
+ };
1499
+ }
1500
+ convertPrivateFileDates(file) {
1501
+ if (typeof file.createdAt === "string") {
1502
+ file.createdAt = new Date(file.createdAt);
1503
+ }
1504
+ if (file.updatedAt && typeof file.updatedAt === "string") {
1505
+ file.updatedAt = new Date(file.updatedAt);
1506
+ }
1507
+ return file;
1508
+ }
1509
+ // ============================================================================
1510
+ // Download Bundle Methods
1511
+ // ============================================================================
1512
+ /**
1513
+ * Create a download bundle from assets and/or private files
1514
+ *
1515
+ * The bundle will be created asynchronously. Check the status using getBundle().
1516
+ *
1517
+ * @example
1518
+ * ```typescript
1519
+ * const { bundle } = await cdn.createBundle({
1520
+ * projectSlug: 'my-project',
1521
+ * name: 'Project Assets - Dec 2024',
1522
+ * assetIds: ['asset-1', 'asset-2'],
1523
+ * privateFileIds: ['file-1', 'file-2'],
1524
+ * expiresIn: 86400, // 24 hours
1525
+ * });
1526
+ * console.log(`Bundle ${bundle.id} status: ${bundle.status}`);
1527
+ * ```
1528
+ */
1529
+ async createBundle(request) {
1530
+ const response = await this.http.post("/cdn/bundles", request);
1531
+ return {
1532
+ bundle: this.convertBundleDates(response.bundle)
1533
+ };
1534
+ }
1535
+ /**
1536
+ * Get a download bundle by ID
1537
+ */
1538
+ async getBundle(bundleId) {
1539
+ const response = await this.http.get(`/cdn/bundles/${bundleId}`);
1540
+ return this.convertBundleDates(response);
1541
+ }
1542
+ /**
1543
+ * List download bundles with filters and pagination
1544
+ *
1545
+ * @example
1546
+ * ```typescript
1547
+ * const { bundles, total } = await cdn.listBundles({
1548
+ * projectSlug: 'my-project',
1549
+ * status: 'ready',
1550
+ * });
1551
+ * ```
1552
+ */
1553
+ async listBundles(request) {
1554
+ const params = new URLSearchParams();
1555
+ params.set("projectSlug", request.projectSlug);
1556
+ if (request.status) params.set("status", request.status);
1557
+ if (request.search) params.set("search", request.search);
1558
+ if (request.limit) params.set("limit", request.limit.toString());
1559
+ if (request.offset) params.set("offset", request.offset.toString());
1560
+ const response = await this.http.get(`/cdn/bundles?${params.toString()}`);
1561
+ return {
1562
+ ...response,
1563
+ bundles: response.bundles.map((bundle) => this.convertBundleDates(bundle))
1564
+ };
1565
+ }
1566
+ /**
1567
+ * Generate a presigned download URL for a bundle
1568
+ *
1569
+ * @example
1570
+ * ```typescript
1571
+ * const { downloadUrl, expiresAt } = await cdn.getBundleDownloadUrl({
1572
+ * bundleId: 'bundle-id',
1573
+ * expiresIn: 3600, // 1 hour
1574
+ * });
1575
+ * ```
1576
+ */
1577
+ async getBundleDownloadUrl(request) {
1578
+ const response = await this.http.post(
1579
+ `/cdn/bundles/${request.bundleId}/download`,
1580
+ { expiresIn: request.expiresIn }
1581
+ );
1582
+ if (typeof response.expiresAt === "string") {
1583
+ response.expiresAt = new Date(response.expiresAt);
1584
+ }
1585
+ return response;
1586
+ }
1587
+ /**
1588
+ * Delete a download bundle
1589
+ */
1590
+ async deleteBundle(bundleId) {
1591
+ return this.http.deleteWithBody(`/cdn/bundles/${bundleId}`, { bundleId });
1592
+ }
1593
+ convertBundleDates(bundle) {
1594
+ if (typeof bundle.createdAt === "string") {
1595
+ bundle.createdAt = new Date(bundle.createdAt);
1596
+ }
1597
+ if (bundle.completedAt && typeof bundle.completedAt === "string") {
1598
+ bundle.completedAt = new Date(bundle.completedAt);
1599
+ }
1600
+ if (bundle.expiresAt && typeof bundle.expiresAt === "string") {
1601
+ bundle.expiresAt = new Date(bundle.expiresAt);
1602
+ }
1603
+ return bundle;
1604
+ }
606
1605
  };
607
1606
 
608
1607
  // src/screenshots/client.ts
@@ -2647,13 +3646,20 @@ var Stack0 = class {
2647
3646
  };
2648
3647
  var src_default = Stack0;
2649
3648
 
3649
+ exports.Audiences = Audiences;
2650
3650
  exports.CDN = CDN;
3651
+ exports.Campaigns = Campaigns;
3652
+ exports.Contacts = Contacts;
3653
+ exports.Domains = Domains;
3654
+ exports.Events = Events;
2651
3655
  exports.Extraction = Extraction;
2652
3656
  exports.Integrations = Integrations;
2653
3657
  exports.Mail = Mail;
2654
3658
  exports.Marketing = Marketing;
2655
3659
  exports.Screenshots = Screenshots;
3660
+ exports.Sequences = Sequences;
2656
3661
  exports.Stack0 = Stack0;
3662
+ exports.Templates = Templates;
2657
3663
  exports.Webdata = Webdata;
2658
3664
  exports.default = src_default;
2659
3665
  //# sourceMappingURL=index.js.map