@planescrm/sdk 0.4.0 → 0.55.0
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/README.md +423 -12
- package/dist/index.d.mts +3669 -183
- package/dist/index.d.ts +3669 -183
- package/dist/index.js +1737 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1685 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -13
package/dist/index.mjs
CHANGED
|
@@ -200,6 +200,9 @@ var HttpClient = class {
|
|
|
200
200
|
if (response.status === 204) {
|
|
201
201
|
return void 0;
|
|
202
202
|
}
|
|
203
|
+
if (options.responseType === "arrayBuffer") {
|
|
204
|
+
return await response.arrayBuffer();
|
|
205
|
+
}
|
|
203
206
|
return await response.json();
|
|
204
207
|
}
|
|
205
208
|
if (response.status === 429 && this.retryOnRateLimit && attempt < this.maxRetries) {
|
|
@@ -355,11 +358,13 @@ var HttpClient = class {
|
|
|
355
358
|
};
|
|
356
359
|
|
|
357
360
|
// src/resources/base-resource.ts
|
|
358
|
-
var
|
|
361
|
+
var ApiResource = class {
|
|
359
362
|
constructor(http2, basePath) {
|
|
360
363
|
this.http = http2;
|
|
361
364
|
this.basePath = basePath;
|
|
362
365
|
}
|
|
366
|
+
};
|
|
367
|
+
var BaseResource = class extends ApiResource {
|
|
363
368
|
/**
|
|
364
369
|
* List entities with optional filters and pagination.
|
|
365
370
|
*/
|
|
@@ -410,11 +415,46 @@ var BaseResource = class {
|
|
|
410
415
|
}
|
|
411
416
|
};
|
|
412
417
|
|
|
418
|
+
// src/resources/query-params.ts
|
|
419
|
+
function toQueryParams(params) {
|
|
420
|
+
const out = {};
|
|
421
|
+
if (!params) return out;
|
|
422
|
+
for (const [key, value] of Object.entries(params)) {
|
|
423
|
+
if (value === void 0 || value === null) continue;
|
|
424
|
+
if (Array.isArray(value)) {
|
|
425
|
+
if (value.length === 0) continue;
|
|
426
|
+
out[key] = value.map(String).join(",");
|
|
427
|
+
} else {
|
|
428
|
+
out[key] = value;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return out;
|
|
432
|
+
}
|
|
433
|
+
|
|
413
434
|
// src/resources/opportunities.ts
|
|
414
435
|
var OpportunityResource = class extends BaseResource {
|
|
415
436
|
constructor(http2) {
|
|
416
437
|
super(http2, "/opportunities");
|
|
417
438
|
}
|
|
439
|
+
/**
|
|
440
|
+
* List opportunities. `tag_ids` is ANY-of and travels as one comma-separated
|
|
441
|
+
* query value (`?tag_ids=a,b`), which is what the API's filter schema parses.
|
|
442
|
+
*/
|
|
443
|
+
async list(params) {
|
|
444
|
+
return this.http.request({
|
|
445
|
+
method: "GET",
|
|
446
|
+
path: this.basePath,
|
|
447
|
+
params: toQueryParams(params)
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/** PUT /opportunities/{id} — partial update; stage moves go through workflow transitions. */
|
|
451
|
+
async update(id, data) {
|
|
452
|
+
return this.http.request({
|
|
453
|
+
method: "PUT",
|
|
454
|
+
path: `${this.basePath}/${id}`,
|
|
455
|
+
body: data
|
|
456
|
+
});
|
|
457
|
+
}
|
|
418
458
|
};
|
|
419
459
|
|
|
420
460
|
// src/resources/customers.ts
|
|
@@ -422,19 +462,125 @@ var CustomerResource = class extends BaseResource {
|
|
|
422
462
|
constructor(http2) {
|
|
423
463
|
super(http2, "/customers");
|
|
424
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Update a customer. The API route is `PUT /customers/{id}` (not PATCH like
|
|
467
|
+
* the other resources), so this overrides the base verb; the body is still a
|
|
468
|
+
* partial — send only the fields to change. See `UpdateCustomerDto.address`
|
|
469
|
+
* for how a service address resolves to a property.
|
|
470
|
+
*/
|
|
471
|
+
async update(id, data) {
|
|
472
|
+
return this.http.request({
|
|
473
|
+
method: "PUT",
|
|
474
|
+
path: `/customers/${id}`,
|
|
475
|
+
body: data
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* List customers. `tag_ids` is ANY-of and travels as one comma-separated
|
|
480
|
+
* query value (`?tag_ids=a,b`), which is what the API's filter schema parses.
|
|
481
|
+
*/
|
|
482
|
+
async list(params) {
|
|
483
|
+
return this.http.request({
|
|
484
|
+
method: "GET",
|
|
485
|
+
path: this.basePath,
|
|
486
|
+
params: toQueryParams(params)
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Fold a duplicate company (`loserId`) into a survivor (`winnerId`).
|
|
491
|
+
*
|
|
492
|
+
* Everything hanging off the loser moves to the winner, the winner's empty
|
|
493
|
+
* fields are filled from the loser, and the loser is soft-deleted with a
|
|
494
|
+
* resolvable pointer — `GET /customers/{loserId}` afterwards returns the
|
|
495
|
+
* winner's detail with a `mergedFrom` pointer, so a stored loser id keeps
|
|
496
|
+
* working. Irreversible; requires admin scope.
|
|
497
|
+
*/
|
|
498
|
+
async merge(winnerId, loserId) {
|
|
499
|
+
return this.http.request({
|
|
500
|
+
method: "POST",
|
|
501
|
+
path: `/customers/${winnerId}/merge/${loserId}`
|
|
502
|
+
});
|
|
503
|
+
}
|
|
425
504
|
};
|
|
426
505
|
|
|
427
506
|
// src/resources/properties.ts
|
|
428
|
-
var PropertyResource = class extends
|
|
507
|
+
var PropertyResource = class extends ApiResource {
|
|
429
508
|
constructor(http2) {
|
|
430
509
|
super(http2, "/properties");
|
|
431
510
|
}
|
|
511
|
+
/** GET /customers/{customerId}/properties — paginated (`page`, `limit` ≤ 100). */
|
|
512
|
+
async list(customerId, params) {
|
|
513
|
+
return this.http.request({
|
|
514
|
+
method: "GET",
|
|
515
|
+
path: `/customers/${customerId}/properties`,
|
|
516
|
+
params: toQueryParams(params)
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
/** GET /properties/{id} — one property, without naming its customer. */
|
|
520
|
+
async get(id) {
|
|
521
|
+
return this.http.request({
|
|
522
|
+
method: "GET",
|
|
523
|
+
path: `${this.basePath}/${id}`
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
/** POST /customers/{customerId}/properties — the property inherits the customer's org path. */
|
|
527
|
+
async create(customerId, data) {
|
|
528
|
+
return this.http.request({
|
|
529
|
+
method: "POST",
|
|
530
|
+
path: `/customers/${customerId}/properties`,
|
|
531
|
+
body: data
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
/** PUT /customers/{customerId}/properties/{id} — partial update. */
|
|
535
|
+
async update(customerId, id, data) {
|
|
536
|
+
return this.http.request({
|
|
537
|
+
method: "PUT",
|
|
538
|
+
path: `/customers/${customerId}/properties/${id}`,
|
|
539
|
+
body: data
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
/** DELETE /customers/{customerId}/properties/{id} — soft delete (204). */
|
|
543
|
+
async delete(customerId, id) {
|
|
544
|
+
await this.http.request({
|
|
545
|
+
method: "DELETE",
|
|
546
|
+
path: `/customers/${customerId}/properties/${id}`
|
|
547
|
+
});
|
|
548
|
+
}
|
|
432
549
|
};
|
|
433
550
|
|
|
434
551
|
// src/resources/calendar-events.ts
|
|
435
552
|
var CalendarEventResource = class extends BaseResource {
|
|
436
553
|
constructor(http2) {
|
|
437
|
-
super(http2, "/
|
|
554
|
+
super(http2, "/events");
|
|
555
|
+
}
|
|
556
|
+
async list(params) {
|
|
557
|
+
return super.list(params);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* PATCH /events/:id. For an occurrence of a recurring event, `editMode`
|
|
561
|
+
* picks which occurrences change (`this` when omitted — the server's
|
|
562
|
+
* default); it is ignored for one-time events.
|
|
563
|
+
*/
|
|
564
|
+
async update(id, data, options = {}) {
|
|
565
|
+
return this.http.request({
|
|
566
|
+
method: "PATCH",
|
|
567
|
+
path: `${this.basePath}/${id}`,
|
|
568
|
+
params: { recurrence_edit_mode: options.editMode },
|
|
569
|
+
body: data
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* POST /events/:id/complete — marks the event completed and runs its "on
|
|
574
|
+
* complete" transition, best-effort. The event is completed even when the
|
|
575
|
+
* transition can't run; `workflow_trigger` says whether it fired, was
|
|
576
|
+
* skipped (none set) or failed (with a reason).
|
|
577
|
+
*/
|
|
578
|
+
async complete(id, body = {}) {
|
|
579
|
+
return this.http.request({
|
|
580
|
+
method: "POST",
|
|
581
|
+
path: `${this.basePath}/${id}/complete`,
|
|
582
|
+
body
|
|
583
|
+
});
|
|
438
584
|
}
|
|
439
585
|
};
|
|
440
586
|
|
|
@@ -446,30 +592,219 @@ var ContractResource = class extends BaseResource {
|
|
|
446
592
|
};
|
|
447
593
|
|
|
448
594
|
// src/resources/jobs.ts
|
|
449
|
-
var JobResource = class extends
|
|
595
|
+
var JobResource = class extends ApiResource {
|
|
450
596
|
constructor(http2) {
|
|
451
597
|
super(http2, "/jobs");
|
|
452
598
|
}
|
|
599
|
+
/** The jobs under one opportunity — the same route as `listForOpportunity()`. */
|
|
600
|
+
async list(opportunityId, params) {
|
|
601
|
+
return this.listForOpportunity(opportunityId, params);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* List the jobs under one opportunity — `GET /opportunities/{opportunityId}/jobs`,
|
|
605
|
+
* the API's job list route. Default order is `created_at` desc;
|
|
606
|
+
* `sort_by: 'recent'` puts the calling user's most recently opened jobs first.
|
|
607
|
+
*/
|
|
608
|
+
async listForOpportunity(opportunityId, params) {
|
|
609
|
+
return this.http.request({
|
|
610
|
+
method: "GET",
|
|
611
|
+
path: `/opportunities/${opportunityId}/jobs`,
|
|
612
|
+
params: toQueryParams(params)
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
/** GET /opportunities/{opportunityId}/jobs/{id} */
|
|
616
|
+
async get(opportunityId, id) {
|
|
617
|
+
return this.http.request({
|
|
618
|
+
method: "GET",
|
|
619
|
+
path: `/opportunities/${opportunityId}/jobs/${id}`
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* POST /opportunities/{opportunityId}/jobs — 422 WORKFLOW_NOT_CONFIGURED when
|
|
624
|
+
* the trade has no published job workflow (check `getTradeCoverage()` first).
|
|
625
|
+
*/
|
|
626
|
+
async create(opportunityId, data) {
|
|
627
|
+
return this.http.request({
|
|
628
|
+
method: "POST",
|
|
629
|
+
path: `/opportunities/${opportunityId}/jobs`,
|
|
630
|
+
body: data
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
/** PUT /opportunities/{opportunityId}/jobs/{id} — partial update (status, notes). */
|
|
634
|
+
async update(opportunityId, id, data) {
|
|
635
|
+
return this.http.request({
|
|
636
|
+
method: "PUT",
|
|
637
|
+
path: `/opportunities/${opportunityId}/jobs/${id}`,
|
|
638
|
+
body: data
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
/** DELETE /opportunities/{opportunityId}/jobs/{id} — soft delete (204). */
|
|
642
|
+
async delete(opportunityId, id) {
|
|
643
|
+
await this.http.request({
|
|
644
|
+
method: "DELETE",
|
|
645
|
+
path: `/opportunities/${opportunityId}/jobs/${id}`
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* GET /jobs/trade-coverage — every active trade with whether a job can be
|
|
650
|
+
* created under it (a published job workflow resolves: the trade's own or the
|
|
651
|
+
* generic one). Check before creating a job to avoid a 422
|
|
652
|
+
* WORKFLOW_NOT_CONFIGURED. Readable by any role that can create jobs (403
|
|
653
|
+
* otherwise); carries no workflow details.
|
|
654
|
+
*/
|
|
655
|
+
async getTradeCoverage() {
|
|
656
|
+
return this.http.request({
|
|
657
|
+
method: "GET",
|
|
658
|
+
path: "/jobs/trade-coverage"
|
|
659
|
+
});
|
|
660
|
+
}
|
|
453
661
|
};
|
|
454
662
|
|
|
455
663
|
// src/resources/estimates.ts
|
|
456
|
-
var EstimateResource = class extends
|
|
664
|
+
var EstimateResource = class extends ApiResource {
|
|
457
665
|
constructor(http2) {
|
|
458
666
|
super(http2, "/estimates");
|
|
459
667
|
}
|
|
668
|
+
/** GET /jobs/{jobId}/estimates — newest first, paginated (`page`, `limit` ≤ 100). */
|
|
669
|
+
async list(jobId, params) {
|
|
670
|
+
return this.http.request({
|
|
671
|
+
method: "GET",
|
|
672
|
+
path: `/jobs/${jobId}/estimates`,
|
|
673
|
+
params: toQueryParams(params)
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Every estimate across all of one opportunity's jobs, in one request —
|
|
678
|
+
* `GET /opportunities/{opportunityId}/estimates`. Newest first; each row
|
|
679
|
+
* carries its `jobId`. Paginated with `page` / `limit` (max 100).
|
|
680
|
+
*/
|
|
681
|
+
async listForOpportunity(opportunityId, params) {
|
|
682
|
+
return this.http.request({
|
|
683
|
+
method: "GET",
|
|
684
|
+
path: `/opportunities/${opportunityId}/estimates`,
|
|
685
|
+
params: toQueryParams(params)
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
/** GET /jobs/{jobId}/estimates/{id} — the estimate with its line items. */
|
|
689
|
+
async get(jobId, id) {
|
|
690
|
+
return this.http.request({
|
|
691
|
+
method: "GET",
|
|
692
|
+
path: `/jobs/${jobId}/estimates/${id}`
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
/** POST /jobs/{jobId}/estimates — optionally cloned from an estimate template. */
|
|
696
|
+
async create(jobId, data) {
|
|
697
|
+
return this.http.request({
|
|
698
|
+
method: "POST",
|
|
699
|
+
path: `/jobs/${jobId}/estimates`,
|
|
700
|
+
body: data
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
/** PUT /jobs/{jobId}/estimates/{id} — partial update (measurements, notes, discount, tax). */
|
|
704
|
+
async update(jobId, id, data) {
|
|
705
|
+
return this.http.request({
|
|
706
|
+
method: "PUT",
|
|
707
|
+
path: `/jobs/${jobId}/estimates/${id}`,
|
|
708
|
+
body: data
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
/** DELETE /jobs/{jobId}/estimates/{id} — soft delete (204). */
|
|
712
|
+
async delete(jobId, id) {
|
|
713
|
+
await this.http.request({
|
|
714
|
+
method: "DELETE",
|
|
715
|
+
path: `/jobs/${jobId}/estimates/${id}`
|
|
716
|
+
});
|
|
717
|
+
}
|
|
460
718
|
};
|
|
461
719
|
|
|
462
720
|
// src/resources/invoices.ts
|
|
463
721
|
var InvoiceResource = class extends BaseResource {
|
|
464
722
|
constructor(http2) {
|
|
465
|
-
super(http2, "/invoices");
|
|
723
|
+
super(http2, "/admin/invoices");
|
|
724
|
+
}
|
|
725
|
+
/** List invoices, newest first. Each row carries the customer's `customerName`. */
|
|
726
|
+
async list(params) {
|
|
727
|
+
return this.http.request({
|
|
728
|
+
method: "GET",
|
|
729
|
+
path: this.basePath,
|
|
730
|
+
params
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* GET /admin/invoices/:id — the invoice with its line items, payments
|
|
735
|
+
* (including any `needs_review` payment) and `payLink` state.
|
|
736
|
+
*/
|
|
737
|
+
async get(id) {
|
|
738
|
+
return this.http.request({
|
|
739
|
+
method: "GET",
|
|
740
|
+
path: `${this.basePath}/${id}`
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* POST /admin/invoices/:id/pay-link — issue a fresh durable pay link for a
|
|
745
|
+
* `sent` or `partially_paid` invoice (Send Invoice grant) and return its URL,
|
|
746
|
+
* e.g. to share by text. Rotates: the previously emailed link stops working.
|
|
747
|
+
* Any other status → 409 `INVOICE_NOT_PAYABLE`.
|
|
748
|
+
*/
|
|
749
|
+
async createPayLink(id) {
|
|
750
|
+
return this.http.request({
|
|
751
|
+
method: "POST",
|
|
752
|
+
path: `${this.basePath}/${id}/pay-link`
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* GET /admin/invoices/:id/pdf — the invoice PDF bytes (Read Invoice grant).
|
|
757
|
+
* A sent invoice returns the copy stored when it was sent; a draft renders on
|
|
758
|
+
* demand with a DRAFT watermark.
|
|
759
|
+
*/
|
|
760
|
+
async downloadPdf(id) {
|
|
761
|
+
return this.http.request({
|
|
762
|
+
method: "GET",
|
|
763
|
+
path: `${this.basePath}/${id}/pdf`,
|
|
764
|
+
headers: { Accept: "application/pdf" },
|
|
765
|
+
responseType: "arrayBuffer"
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* GET /admin/invoices/overdue — sent / partially paid invoices with a balance
|
|
770
|
+
* past their due date, most overdue first, each with `daysOverdue` and the
|
|
771
|
+
* last overdue offset reached (E56-F8-S2). Read Invoice.
|
|
772
|
+
*/
|
|
773
|
+
async listOverdue(params) {
|
|
774
|
+
return this.http.request({
|
|
775
|
+
method: "GET",
|
|
776
|
+
path: `${this.basePath}/overdue`,
|
|
777
|
+
params
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
/** GET /admin/invoices/overdue/summary — `{ count, total }` of every overdue invoice. Read Invoice. */
|
|
781
|
+
async overdueSummary() {
|
|
782
|
+
return this.http.request({
|
|
783
|
+
method: "GET",
|
|
784
|
+
path: `${this.basePath}/overdue/summary`
|
|
785
|
+
});
|
|
466
786
|
}
|
|
467
787
|
};
|
|
468
788
|
|
|
469
789
|
// src/resources/inventory.ts
|
|
470
790
|
var InventoryResource = class extends BaseResource {
|
|
471
791
|
constructor(http2) {
|
|
472
|
-
super(http2, "/inventory/items");
|
|
792
|
+
super(http2, "/admin/inventory/items");
|
|
793
|
+
}
|
|
794
|
+
async list(params) {
|
|
795
|
+
return this.http.request({
|
|
796
|
+
method: "GET",
|
|
797
|
+
path: this.basePath,
|
|
798
|
+
params: toQueryParams(params)
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
/** PUT /admin/inventory/items/{id} — partial update. */
|
|
802
|
+
async update(id, data) {
|
|
803
|
+
return this.http.request({
|
|
804
|
+
method: "PUT",
|
|
805
|
+
path: `${this.basePath}/${id}`,
|
|
806
|
+
body: data
|
|
807
|
+
});
|
|
473
808
|
}
|
|
474
809
|
};
|
|
475
810
|
|
|
@@ -505,6 +840,20 @@ var ContactResource = class extends BaseResource {
|
|
|
505
840
|
constructor(http2) {
|
|
506
841
|
super(http2, "/contacts");
|
|
507
842
|
}
|
|
843
|
+
/**
|
|
844
|
+
* List contacts. Typed against the real filter schema (customer_id /
|
|
845
|
+
* property_id / q / sort_by / sort_order / page / limit / include) — the base
|
|
846
|
+
* `list` would accept any key and let a typo reach the server as a 400.
|
|
847
|
+
* `include: ['channels', 'links']` attaches each row's channels and active
|
|
848
|
+
* links in the same response.
|
|
849
|
+
*/
|
|
850
|
+
async list(params) {
|
|
851
|
+
return this.http.request({
|
|
852
|
+
method: "GET",
|
|
853
|
+
path: this.basePath,
|
|
854
|
+
params: toQueryParams(params)
|
|
855
|
+
});
|
|
856
|
+
}
|
|
508
857
|
async merge(winnerId, loserId) {
|
|
509
858
|
return this.http.request({
|
|
510
859
|
method: "POST",
|
|
@@ -544,64 +893,1051 @@ var ActivityResource = class {
|
|
|
544
893
|
}
|
|
545
894
|
};
|
|
546
895
|
|
|
547
|
-
// src/resources/
|
|
548
|
-
var
|
|
896
|
+
// src/resources/communications.ts
|
|
897
|
+
var CommunicationsResource = class {
|
|
549
898
|
constructor(http2) {
|
|
550
|
-
|
|
899
|
+
this.http = http2;
|
|
551
900
|
}
|
|
552
|
-
|
|
553
|
-
async setEntityTags(entityType, entityId, data) {
|
|
901
|
+
async log(data) {
|
|
554
902
|
return this.http.request({
|
|
555
|
-
method: "
|
|
556
|
-
path:
|
|
903
|
+
method: "POST",
|
|
904
|
+
path: "/communications",
|
|
557
905
|
body: data
|
|
558
906
|
});
|
|
559
907
|
}
|
|
560
|
-
async
|
|
908
|
+
async list(params) {
|
|
561
909
|
return this.http.request({
|
|
562
910
|
method: "GET",
|
|
563
|
-
path:
|
|
911
|
+
path: "/communications",
|
|
912
|
+
params
|
|
564
913
|
});
|
|
565
914
|
}
|
|
566
|
-
async
|
|
915
|
+
async get(id) {
|
|
567
916
|
return this.http.request({
|
|
568
917
|
method: "GET",
|
|
569
|
-
path: `/
|
|
570
|
-
|
|
918
|
+
path: `/communications/${id}`
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
async link(id, data) {
|
|
922
|
+
return this.http.request({
|
|
923
|
+
method: "POST",
|
|
924
|
+
path: `/communications/${id}/link`,
|
|
925
|
+
body: data
|
|
571
926
|
});
|
|
572
927
|
}
|
|
573
928
|
};
|
|
574
929
|
|
|
575
|
-
// src/
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return false;
|
|
930
|
+
// src/resources/conversations.ts
|
|
931
|
+
var ConversationsResource = class {
|
|
932
|
+
constructor(http2) {
|
|
933
|
+
this.http = http2;
|
|
580
934
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
return false;
|
|
935
|
+
async log(data) {
|
|
936
|
+
return this.http.request({ method: "POST", path: "/conversations", body: data });
|
|
584
937
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
return false;
|
|
938
|
+
async list(params) {
|
|
939
|
+
return this.http.request({ method: "GET", path: "/conversations", params });
|
|
588
940
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if (receivedBuf.length !== expectedBuf.length) {
|
|
593
|
-
return false;
|
|
941
|
+
/** The review queue: `list()` pinned to `match_status: 'needs_review'`. */
|
|
942
|
+
async reviewQueue(params) {
|
|
943
|
+
return this.list({ ...params, match_status: "needs_review" });
|
|
594
944
|
}
|
|
595
|
-
|
|
596
|
-
}
|
|
597
|
-
function parseWebhookEvent(body, signature, secret) {
|
|
598
|
-
if (!verifyWebhookSignature(body, signature, secret)) {
|
|
599
|
-
throw new WebhookVerificationError();
|
|
945
|
+
async get(id) {
|
|
946
|
+
return this.http.request({ method: "GET", path: `/conversations/${encodeURIComponent(id)}` });
|
|
600
947
|
}
|
|
601
|
-
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
|
|
948
|
+
async update(id, data) {
|
|
949
|
+
return this.http.request({ method: "PATCH", path: `/conversations/${encodeURIComponent(id)}`, body: data });
|
|
950
|
+
}
|
|
951
|
+
async delete(id) {
|
|
952
|
+
await this.http.request({ method: "DELETE", path: `/conversations/${encodeURIComponent(id)}` });
|
|
953
|
+
}
|
|
954
|
+
async link(id, data) {
|
|
955
|
+
return this.http.request({ method: "POST", path: `/conversations/${encodeURIComponent(id)}/links`, body: data });
|
|
956
|
+
}
|
|
957
|
+
async unlink(id, linkId) {
|
|
958
|
+
return this.http.request({
|
|
959
|
+
method: "DELETE",
|
|
960
|
+
path: `/conversations/${encodeURIComponent(id)}/links/${encodeURIComponent(linkId)}`
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
async resolve(id, data) {
|
|
964
|
+
return this.http.request({ method: "POST", path: `/conversations/${encodeURIComponent(id)}/resolve`, body: data });
|
|
965
|
+
}
|
|
966
|
+
async getInternalDomains() {
|
|
967
|
+
return this.http.request({ method: "GET", path: "/conversations/settings/internal-domains" });
|
|
968
|
+
}
|
|
969
|
+
/** Requires an admin: the server checks `Update` on `Subject.Tenant` (tenant-wide matching config), not `Subject.Conversation`. */
|
|
970
|
+
async setInternalDomains(data) {
|
|
971
|
+
return this.http.request({ method: "PUT", path: "/conversations/settings/internal-domains", body: data });
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* E57-F2-S4 — disconnect the CALLER's own Circleback connection (Update
|
|
975
|
+
* Conversation). Another user's connection id is a 404. Connecting is the
|
|
976
|
+
* interactive browser OAuth flow (Settings → Conversations), not an SDK call.
|
|
977
|
+
*/
|
|
978
|
+
async disconnectCircleback(data) {
|
|
979
|
+
return this.http.request({
|
|
980
|
+
method: "POST",
|
|
981
|
+
path: "/conversations/sources/circleback/disconnect",
|
|
982
|
+
body: data
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* E57-F2-S8 — pull one company's meetings from every active teammate's
|
|
987
|
+
* connected source (Update Conversation). 202, runs in the background.
|
|
988
|
+
* 404 for a company you can't see; 409 `NO_SOURCES` when nobody has one.
|
|
989
|
+
*/
|
|
990
|
+
async pull(data) {
|
|
991
|
+
return this.http.request({ method: "POST", path: "/conversations/pull", body: data });
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* E57-F2-S9 — whether a Pull has finished: pass the `job_ids` `pull()`
|
|
995
|
+
* returned (1–50). Update Conversation, like `pull()`. 404
|
|
996
|
+
* `PULL_NOT_FOUND` when none of them is readable (expired after ~2h,
|
|
997
|
+
* unknown) — treat that as settled.
|
|
998
|
+
*/
|
|
999
|
+
async getPullStatus(jobIds) {
|
|
1000
|
+
return this.http.request({
|
|
1001
|
+
method: "GET",
|
|
1002
|
+
path: "/conversations/pull/status",
|
|
1003
|
+
params: { job_ids: jobIds.join(",") }
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
/** E57-F2-S8 — sync the caller's OWN Circleback connection now (deduplicated). 409 `NO_CONNECTION` when they have none. */
|
|
1007
|
+
async syncNow() {
|
|
1008
|
+
return this.http.request({ method: "POST", path: "/conversations/sources/circleback/sync-now" });
|
|
1009
|
+
}
|
|
1010
|
+
/** E57-F2-S8 — the caller's own connection, `has_sources`, and (admins only) the roster. */
|
|
1011
|
+
async syncStatus() {
|
|
1012
|
+
return this.http.request({ method: "GET", path: "/conversations/sync-status" });
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* E57-F4-S1 — a synced meeting's transcript, fetched live from the meeting
|
|
1016
|
+
* recorder (never stored by Planes; the response is `Cache-Control:
|
|
1017
|
+
* no-store`). Read Conversation, plus the tenant's transcript-access rule:
|
|
1018
|
+
* 403 `TRANSCRIPT_OWNER_ONLY` under `owner` for a non-owner; 409
|
|
1019
|
+
* `TRANSCRIPT_SOURCE_UNAVAILABLE` (`owner_name` says who must reconnect) or
|
|
1020
|
+
* `TRANSCRIPT_NOT_AVAILABLE` (not a synced meeting); 404 when you can't see
|
|
1021
|
+
* the conversation. `segments: []` = no transcript yet.
|
|
1022
|
+
*/
|
|
1023
|
+
async getTranscript(id) {
|
|
1024
|
+
return this.http.request({
|
|
1025
|
+
method: "GET",
|
|
1026
|
+
path: `/conversations/${encodeURIComponent(id)}/transcript`
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
/** E57-F4-S1 — who can view transcripts: `owner` (default) or `viewers`. Read Conversation. */
|
|
1030
|
+
async getTranscriptAccess() {
|
|
1031
|
+
return this.http.request({ method: "GET", path: "/conversations/settings/transcript-access" });
|
|
1032
|
+
}
|
|
1033
|
+
/** E57-F4-S1 — requires an admin: the server checks `Update` on `Subject.Tenant`. */
|
|
1034
|
+
async setTranscriptAccess(value) {
|
|
1035
|
+
return this.http.request({
|
|
1036
|
+
method: "PUT",
|
|
1037
|
+
path: "/conversations/settings/transcript-access",
|
|
1038
|
+
body: { transcript_access: value }
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
// src/resources/gmail.ts
|
|
1044
|
+
var GmailResource = class {
|
|
1045
|
+
constructor(http2) {
|
|
1046
|
+
this.http = http2;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Send an email RIGHT NOW from the connected user's real Gmail address.
|
|
1050
|
+
* Hits `POST /admin/integrations/google/gmail/send` — final per Task 4
|
|
1051
|
+
* (`apps/api/src/modules/integrations/google/google-connection.controller.ts`).
|
|
1052
|
+
*/
|
|
1053
|
+
async send(data) {
|
|
1054
|
+
return this.http.request({
|
|
1055
|
+
method: "POST",
|
|
1056
|
+
path: "/admin/integrations/google/gmail/send",
|
|
1057
|
+
body: data
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
// src/resources/documents.ts
|
|
1063
|
+
var DocumentsResource = class {
|
|
1064
|
+
constructor(http2) {
|
|
1065
|
+
this.http = http2;
|
|
1066
|
+
}
|
|
1067
|
+
/** Attach an external (link-only) document — e.g. a Google Drive link — to a record. */
|
|
1068
|
+
async attachExternal(data) {
|
|
1069
|
+
return this.http.request({
|
|
1070
|
+
method: "POST",
|
|
1071
|
+
path: "/documents/external",
|
|
1072
|
+
body: data
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
/** Documents filed directly on one record (uploaded + external), newest first. */
|
|
1076
|
+
async listForEntity(entityType, entityId) {
|
|
1077
|
+
return this.http.request({
|
|
1078
|
+
method: "GET",
|
|
1079
|
+
path: `/${entityType}/${entityId}/documents`
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
// src/resources/tags.ts
|
|
1085
|
+
var TagResource = class extends ApiResource {
|
|
1086
|
+
constructor(http2) {
|
|
1087
|
+
super(http2, "/tags");
|
|
1088
|
+
}
|
|
1089
|
+
/** GET /tags */
|
|
1090
|
+
async list(params) {
|
|
1091
|
+
return this.http.request({
|
|
1092
|
+
method: "GET",
|
|
1093
|
+
path: this.basePath,
|
|
1094
|
+
params
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
/** POST /tags — 409 on a case-insensitive duplicate name. */
|
|
1098
|
+
async create(data) {
|
|
1099
|
+
return this.http.request({ method: "POST", path: this.basePath, body: data });
|
|
1100
|
+
}
|
|
1101
|
+
/** PATCH /tags/:id — rename / recolor; 409 on a case-insensitive duplicate name. */
|
|
1102
|
+
async update(id, data) {
|
|
1103
|
+
return this.http.request({ method: "PATCH", path: `${this.basePath}/${id}`, body: data });
|
|
1104
|
+
}
|
|
1105
|
+
/** DELETE /tags/:id — cascades the tag off every record. */
|
|
1106
|
+
async delete(id) {
|
|
1107
|
+
await this.http.request({ method: "DELETE", path: `${this.basePath}/${id}` });
|
|
1108
|
+
}
|
|
1109
|
+
/** `TagsService.setEntityTags()` returns the final tag set wrapped in `{ tags }`. */
|
|
1110
|
+
async setEntityTags(entityType, entityId, data) {
|
|
1111
|
+
return this.http.request({
|
|
1112
|
+
method: "PUT",
|
|
1113
|
+
path: `/entities/${entityType}/${entityId}/tags`,
|
|
1114
|
+
body: data
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
async getEntityTags(entityType, entityId) {
|
|
1118
|
+
return this.http.request({
|
|
1119
|
+
method: "GET",
|
|
1120
|
+
path: `/entities/${entityType}/${entityId}/tags`
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
async getEntities(tagId, params) {
|
|
1124
|
+
return this.http.request({
|
|
1125
|
+
method: "GET",
|
|
1126
|
+
path: `/tags/${tagId}/entities`,
|
|
1127
|
+
params
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
// src/resources/tasks.ts
|
|
1133
|
+
var TaskResource = class extends ApiResource {
|
|
1134
|
+
constructor(http2) {
|
|
1135
|
+
super(http2, "/tasks");
|
|
1136
|
+
}
|
|
1137
|
+
async list(params) {
|
|
1138
|
+
return this.http.request({
|
|
1139
|
+
method: "GET",
|
|
1140
|
+
path: this.basePath,
|
|
1141
|
+
params
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
/** GET /tasks/:id */
|
|
1145
|
+
async get(id) {
|
|
1146
|
+
return this.http.request({ method: "GET", path: `${this.basePath}/${id}` });
|
|
1147
|
+
}
|
|
1148
|
+
/** POST /tasks */
|
|
1149
|
+
async create(data) {
|
|
1150
|
+
return this.http.request({ method: "POST", path: this.basePath, body: data });
|
|
1151
|
+
}
|
|
1152
|
+
/** PATCH /tasks/:id — non-terminal fields only; terminal status changes use the action methods. */
|
|
1153
|
+
async update(id, data) {
|
|
1154
|
+
return this.http.request({ method: "PATCH", path: `${this.basePath}/${id}`, body: data });
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* POST /tasks/:id/complete — fires the linked workflow transition (best-effort).
|
|
1158
|
+
* The task always completes; `workflow_trigger` says whether the next step ran.
|
|
1159
|
+
*/
|
|
1160
|
+
async complete(id) {
|
|
1161
|
+
return this.http.request({ method: "POST", path: `${this.basePath}/${id}/complete` });
|
|
1162
|
+
}
|
|
1163
|
+
/** POST /tasks/:id/cancel */
|
|
1164
|
+
async cancel(id) {
|
|
1165
|
+
return this.http.request({ method: "POST", path: `${this.basePath}/${id}/cancel` });
|
|
1166
|
+
}
|
|
1167
|
+
/** POST /tasks/:id/reopen — the sanctioned resurrect of a completed/cancelled task. */
|
|
1168
|
+
async reopen(id) {
|
|
1169
|
+
return this.http.request({ method: "POST", path: `${this.basePath}/${id}/reopen` });
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
// src/resources/record-views.ts
|
|
1174
|
+
var RecordViewsResource = class {
|
|
1175
|
+
constructor(http2) {
|
|
1176
|
+
this.http = http2;
|
|
1177
|
+
this.basePath = "/record-views";
|
|
1178
|
+
}
|
|
1179
|
+
/** POST /record-views — record that the calling user opened this record. Resolves on 204. */
|
|
1180
|
+
async touch(input) {
|
|
1181
|
+
await this.http.request({ method: "POST", path: this.basePath, body: input });
|
|
1182
|
+
}
|
|
1183
|
+
/** GET /record-views/recent — the calling user's most recently viewed records, newest first. */
|
|
1184
|
+
async recent(params) {
|
|
1185
|
+
return this.http.request({
|
|
1186
|
+
method: "GET",
|
|
1187
|
+
path: `${this.basePath}/recent`,
|
|
1188
|
+
params: toQueryParams(params)
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
// src/resources/modules.ts
|
|
1194
|
+
var ModulesResource = class {
|
|
1195
|
+
constructor(http2) {
|
|
1196
|
+
this.http = http2;
|
|
1197
|
+
this.basePath = "/modules";
|
|
1198
|
+
}
|
|
1199
|
+
/** GET /modules — one entry per registered module key, in canonical order. */
|
|
1200
|
+
async list() {
|
|
1201
|
+
const res = await this.http.request({
|
|
1202
|
+
method: "GET",
|
|
1203
|
+
path: this.basePath
|
|
1204
|
+
});
|
|
1205
|
+
return res.data;
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// src/resources/plan.ts
|
|
1210
|
+
var PlanResource = class {
|
|
1211
|
+
constructor(http2) {
|
|
1212
|
+
this.http = http2;
|
|
1213
|
+
this.basePath = "/plan";
|
|
1214
|
+
}
|
|
1215
|
+
/** GET /plan — plan, billing status and the plan's ceiling. */
|
|
1216
|
+
async get() {
|
|
1217
|
+
const res = await this.http.request({
|
|
1218
|
+
method: "GET",
|
|
1219
|
+
path: this.basePath
|
|
1220
|
+
});
|
|
1221
|
+
return res.data;
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
// src/resources/me.ts
|
|
1226
|
+
var MeResource = class {
|
|
1227
|
+
constructor(http2) {
|
|
1228
|
+
this.http = http2;
|
|
1229
|
+
this.basePath = "/me";
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* GET /me/abilities — the caller's effective ability: for an API key, the key
|
|
1233
|
+
* role intersected with its acting agent's live role (`actingRole`).
|
|
1234
|
+
*/
|
|
1235
|
+
async abilities() {
|
|
1236
|
+
return this.http.request({
|
|
1237
|
+
method: "GET",
|
|
1238
|
+
path: `${this.basePath}/abilities`
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
// src/resources/roles.ts
|
|
1244
|
+
var RolesResource = class {
|
|
1245
|
+
constructor(http2) {
|
|
1246
|
+
this.http = http2;
|
|
1247
|
+
this.basePath = "/roles";
|
|
1248
|
+
}
|
|
1249
|
+
/** GET /roles — every role (not `system_agent`) with user and change counts. */
|
|
1250
|
+
async list() {
|
|
1251
|
+
return this.http.request({ method: "GET", path: this.basePath });
|
|
1252
|
+
}
|
|
1253
|
+
/** GET /roles/:key — one role's permission matrix, summary and grant version. */
|
|
1254
|
+
async get(key) {
|
|
1255
|
+
return this.http.request({
|
|
1256
|
+
method: "GET",
|
|
1257
|
+
path: `${this.basePath}/${encodeURIComponent(key)}`
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* PUT /roles/:key/grants — sparse per-cell changes, all validated before any
|
|
1262
|
+
* is written. 422 `GRANT_REQUIRED` / `GRANT_NOT_DELEGABLE` for locked cells,
|
|
1263
|
+
* `CONFIRMATION_REQUIRED` when a money action is granted without
|
|
1264
|
+
* `confirm: true` + `reason`, `ROLE_NOT_TUNABLE` for admin; 409
|
|
1265
|
+
* `ROLE_VERSION_CONFLICT` on a stale `baseVersion`. Returns the updated role.
|
|
1266
|
+
*/
|
|
1267
|
+
async updateGrants(key, body) {
|
|
1268
|
+
return this.http.request({
|
|
1269
|
+
method: "PUT",
|
|
1270
|
+
path: `${this.basePath}/${encodeURIComponent(key)}/grants`,
|
|
1271
|
+
body
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
/** DELETE /roles/:key/grants — back to the Planes defaults. Returns the reset role. */
|
|
1275
|
+
async reset(key) {
|
|
1276
|
+
return this.http.request({
|
|
1277
|
+
method: "DELETE",
|
|
1278
|
+
path: `${this.basePath}/${encodeURIComponent(key)}/grants`
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
/** GET /roles/history — the change log, newest first; page with `cursor`. */
|
|
1282
|
+
async history(params) {
|
|
1283
|
+
return this.http.request({
|
|
1284
|
+
method: "GET",
|
|
1285
|
+
path: `${this.basePath}/history`,
|
|
1286
|
+
...params ? { params } : {}
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
// src/resources/invoice-settings.ts
|
|
1292
|
+
var InvoiceSettingsResource = class {
|
|
1293
|
+
constructor(http2) {
|
|
1294
|
+
this.http = http2;
|
|
1295
|
+
this.basePath = "/admin/invoice-settings";
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* GET /admin/invoice-settings/offline-instructions — the plain-text
|
|
1299
|
+
* instructions shown on the pay page when online payment is unavailable,
|
|
1300
|
+
* or null when none are set.
|
|
1301
|
+
*/
|
|
1302
|
+
async getOfflineInstructions() {
|
|
1303
|
+
const res = await this.http.request({
|
|
1304
|
+
method: "GET",
|
|
1305
|
+
path: `${this.basePath}/offline-instructions`
|
|
1306
|
+
});
|
|
1307
|
+
return res.instructions;
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* PUT /admin/invoice-settings/offline-instructions — store plain text
|
|
1311
|
+
* (trimmed, at most 2,000 characters); null or blank clears it. Returns the
|
|
1312
|
+
* stored value.
|
|
1313
|
+
*/
|
|
1314
|
+
async setOfflineInstructions(text) {
|
|
1315
|
+
const body = { instructions: text };
|
|
1316
|
+
const res = await this.http.request({
|
|
1317
|
+
method: "PUT",
|
|
1318
|
+
path: `${this.basePath}/offline-instructions`,
|
|
1319
|
+
body
|
|
1320
|
+
});
|
|
1321
|
+
return res.instructions;
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* GET /admin/invoice-settings/overdue-offsets — the days after the due date
|
|
1325
|
+
* at which `invoice.overdue` fires, ascending (default `[3, 7, 14]`).
|
|
1326
|
+
*/
|
|
1327
|
+
async getOverdueOffsets() {
|
|
1328
|
+
const res = await this.http.request({
|
|
1329
|
+
method: "GET",
|
|
1330
|
+
path: `${this.basePath}/overdue-offsets`
|
|
1331
|
+
});
|
|
1332
|
+
return res.offsets;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* PUT /admin/invoice-settings/overdue-offsets — replace the offsets: 1 to 5
|
|
1336
|
+
* unique whole days, each 1–90. Returns them sorted ascending. Admin only.
|
|
1337
|
+
*/
|
|
1338
|
+
async setOverdueOffsets(offsets) {
|
|
1339
|
+
const body = { offsets };
|
|
1340
|
+
const res = await this.http.request({
|
|
1341
|
+
method: "PUT",
|
|
1342
|
+
path: `${this.basePath}/overdue-offsets`,
|
|
1343
|
+
body
|
|
1344
|
+
});
|
|
1345
|
+
return res.offsets;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* GET /admin/invoice-settings/attach-pdf — whether invoice emails carry the
|
|
1349
|
+
* invoice PDF (on unless an admin turned it off).
|
|
1350
|
+
*/
|
|
1351
|
+
async getAttachPdf() {
|
|
1352
|
+
const res = await this.http.request({
|
|
1353
|
+
method: "GET",
|
|
1354
|
+
path: `${this.basePath}/attach-pdf`
|
|
1355
|
+
});
|
|
1356
|
+
return res.enabled;
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* PUT /admin/invoice-settings/attach-pdf — turn the PDF attachment on
|
|
1360
|
+
* invoice emails on or off. Returns the stored value.
|
|
1361
|
+
*/
|
|
1362
|
+
async setAttachPdf(enabled) {
|
|
1363
|
+
const body = { enabled };
|
|
1364
|
+
const res = await this.http.request({
|
|
1365
|
+
method: "PUT",
|
|
1366
|
+
path: `${this.basePath}/attach-pdf`,
|
|
1367
|
+
body
|
|
1368
|
+
});
|
|
1369
|
+
return res.enabled;
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
|
|
1373
|
+
// src/resources/invoice-reminders.ts
|
|
1374
|
+
var InvoiceRemindersResource = class {
|
|
1375
|
+
constructor(http2) {
|
|
1376
|
+
this.http = http2;
|
|
1377
|
+
this.basePath = "/admin/invoice-reminders";
|
|
1378
|
+
}
|
|
1379
|
+
/** GET /admin/invoice-reminders — the rules, ascending by offset, and the overdue offsets. */
|
|
1380
|
+
async list() {
|
|
1381
|
+
return this.http.request({
|
|
1382
|
+
method: "GET",
|
|
1383
|
+
path: this.basePath
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* PUT /admin/invoice-reminders — replace the WHOLE rule set (a rule left out
|
|
1388
|
+
* is deleted): up to 5 rules at unique offsets. Templates may use only
|
|
1389
|
+
* `{{customerName}}`, `{{invoiceNumber}}`, `{{amountDue}}`, `{{total}}`,
|
|
1390
|
+
* `{{dueDate}}`, `{{daysOverdue}}` and `{{companyName}}`; any other is a 422
|
|
1391
|
+
* `REMINDER_TEMPLATE_INVALID` listing each one. Returns the stored set.
|
|
1392
|
+
*/
|
|
1393
|
+
async update(rules) {
|
|
1394
|
+
return this.http.request({
|
|
1395
|
+
method: "PUT",
|
|
1396
|
+
path: this.basePath,
|
|
1397
|
+
body: { rules }
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* POST /admin/invoice-reminders/preview — render a subject and body exactly
|
|
1402
|
+
* as the reminder email would, against an invoice or a sample. Sends nothing.
|
|
1403
|
+
*/
|
|
1404
|
+
async preview(params) {
|
|
1405
|
+
return this.http.request({
|
|
1406
|
+
method: "POST",
|
|
1407
|
+
path: `${this.basePath}/preview`,
|
|
1408
|
+
body: params
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
// src/resources/contact-sequences.ts
|
|
1414
|
+
var ContactSequencesResource = class {
|
|
1415
|
+
constructor(http2) {
|
|
1416
|
+
this.http = http2;
|
|
1417
|
+
this.basePath = "/contact-sequences";
|
|
1418
|
+
}
|
|
1419
|
+
/** GET /contact-sequences — `{ data, meta: { total } }`, name-sorted, max 100. */
|
|
1420
|
+
async list() {
|
|
1421
|
+
return this.http.request({
|
|
1422
|
+
method: "GET",
|
|
1423
|
+
path: this.basePath
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
|
|
1428
|
+
// src/resources/enrollments.ts
|
|
1429
|
+
var EnrollmentsResource = class {
|
|
1430
|
+
constructor(http2) {
|
|
1431
|
+
this.http = http2;
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* POST /contacts/:id/enrollments — `{ workflow_id }`. 409 if the contact is
|
|
1435
|
+
* already active in the sequence; 422 if the sequence has no published version.
|
|
1436
|
+
*/
|
|
1437
|
+
async enroll(contactId, workflowId) {
|
|
1438
|
+
return this.http.request({
|
|
1439
|
+
method: "POST",
|
|
1440
|
+
path: `/contacts/${contactId}/enrollments`,
|
|
1441
|
+
body: { workflow_id: workflowId }
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
/** GET /contacts/:id/enrollments — a bare array, newest first; optional `status` filter. */
|
|
1445
|
+
async list(contactId, params) {
|
|
1446
|
+
return this.http.request({
|
|
1447
|
+
method: "GET",
|
|
1448
|
+
path: `/contacts/${contactId}/enrollments`,
|
|
1449
|
+
...params ? { params } : {}
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* POST /enrollments/:id/exit — no body; the exit reason is recorded as
|
|
1454
|
+
* `'manual'`. Idempotent: an already-ended enrollment is returned unchanged.
|
|
1455
|
+
*/
|
|
1456
|
+
async exit(enrollmentId) {
|
|
1457
|
+
return this.http.request({
|
|
1458
|
+
method: "POST",
|
|
1459
|
+
path: `/enrollments/${enrollmentId}/exit`
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1464
|
+
// src/resources/workflow-event-rules.ts
|
|
1465
|
+
var WorkflowEventRulesResource = class {
|
|
1466
|
+
constructor(http2, workflowId) {
|
|
1467
|
+
this.http = http2;
|
|
1468
|
+
this.workflowId = workflowId;
|
|
1469
|
+
}
|
|
1470
|
+
// Each request spells its path out in full (no computed base path) so the
|
|
1471
|
+
// API's SDK route-parity audit (sdk-route-parity-audit.spec.ts) can read it.
|
|
1472
|
+
/** GET — a bare array of the workflow's live rules, newest first. 404 `WORKFLOW_NOT_FOUND`. */
|
|
1473
|
+
async list() {
|
|
1474
|
+
return this.http.request({
|
|
1475
|
+
method: "GET",
|
|
1476
|
+
path: `/admin/workflows/${encodeURIComponent(this.workflowId)}/event-rules`
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* POST — add a rule (201). `when` defaults to `{}` and `enabled` to true; use
|
|
1481
|
+
* `when: {}` for the creation types in `WORKFLOW_EVENT_RULE_MATCH_ALL_EVENT_TYPES`.
|
|
1482
|
+
* 400 `VALIDATION_FAILED` for a bad body; 404 `WORKFLOW_NOT_FOUND`.
|
|
1483
|
+
*/
|
|
1484
|
+
async create(input) {
|
|
1485
|
+
return this.http.request({
|
|
1486
|
+
method: "POST",
|
|
1487
|
+
path: `/admin/workflows/${encodeURIComponent(this.workflowId)}/event-rules`,
|
|
1488
|
+
body: input
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
/** PATCH /:id — only the fields sent change (at least one). 404 `EVENT_RULE_NOT_FOUND`. */
|
|
1492
|
+
async update(ruleId, input) {
|
|
1493
|
+
return this.http.request({
|
|
1494
|
+
method: "PATCH",
|
|
1495
|
+
path: `/admin/workflows/${encodeURIComponent(this.workflowId)}/event-rules/${encodeURIComponent(ruleId)}`,
|
|
1496
|
+
body: input
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
/** DELETE /:id — soft delete; returns `{ id }` (200). 404 `EVENT_RULE_NOT_FOUND`. */
|
|
1500
|
+
async delete(ruleId) {
|
|
1501
|
+
return this.http.request({
|
|
1502
|
+
method: "DELETE",
|
|
1503
|
+
path: `/admin/workflows/${encodeURIComponent(this.workflowId)}/event-rules/${encodeURIComponent(ruleId)}`
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
|
|
1508
|
+
// src/resources/workflows.ts
|
|
1509
|
+
var WorkflowsResource = class {
|
|
1510
|
+
constructor(http2) {
|
|
1511
|
+
this.http = http2;
|
|
1512
|
+
this.basePath = "/workflows";
|
|
1513
|
+
this.adminPath = "/admin/workflows";
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* GET /workflows/:id/stages — the ordered stages of one workflow version. Pass
|
|
1517
|
+
* a record's instance `workflowId` (e.g. from `GET /opportunities/:id/workflow`)
|
|
1518
|
+
* to get the stages of the version that record is pinned to, even an archived
|
|
1519
|
+
* one. 404 for an unknown or draft id; 403 if the caller cannot read the
|
|
1520
|
+
* workflow's record type.
|
|
1521
|
+
*/
|
|
1522
|
+
async getStages(workflowId) {
|
|
1523
|
+
return this.http.request({
|
|
1524
|
+
method: "GET",
|
|
1525
|
+
path: `${this.basePath}/${encodeURIComponent(workflowId)}/stages`
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* GET /workflows/transitions — transition summaries of every published
|
|
1530
|
+
* workflow, or with `workflowId` of that one version (published or archived;
|
|
1531
|
+
* an unknown, draft or other-tenant id returns an empty list). Each summary
|
|
1532
|
+
* carries `workflow_id`, `workflow_version`, `lineage_workflow_id` and
|
|
1533
|
+
* `automatic_only`. Only pipelines whose record type the caller can read
|
|
1534
|
+
* are listed; an unreadable `workflowId` returns an empty list, not 403.
|
|
1535
|
+
*/
|
|
1536
|
+
async listTransitions(params = {}) {
|
|
1537
|
+
const query = {};
|
|
1538
|
+
if (params.entityTypes && params.entityTypes.length > 0) query["entity_types"] = params.entityTypes.join(",");
|
|
1539
|
+
if (params.workflowId) query["workflow_id"] = params.workflowId;
|
|
1540
|
+
return this.http.request({
|
|
1541
|
+
method: "GET",
|
|
1542
|
+
path: `${this.basePath}/transitions`,
|
|
1543
|
+
params: query
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* POST /admin/workflows/:wid/transitions — add a transition to a draft
|
|
1548
|
+
* workflow. Pass `automaticOnly: true` for an edge only automation should
|
|
1549
|
+
* fire (e.g. an event rule advancing on "contract sent").
|
|
1550
|
+
*/
|
|
1551
|
+
async createTransition(workflowId, input) {
|
|
1552
|
+
return this.http.request({
|
|
1553
|
+
method: "POST",
|
|
1554
|
+
path: `${this.adminPath}/${encodeURIComponent(workflowId)}/transitions`,
|
|
1555
|
+
body: input
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* The event rules of one workflow (`/admin/workflows/:wid/event-rules`) —
|
|
1560
|
+
* "advance automatically when…". Any version's id works; rules are keyed by
|
|
1561
|
+
* the lineage root.
|
|
1562
|
+
*/
|
|
1563
|
+
eventRules(workflowId) {
|
|
1564
|
+
return new WorkflowEventRulesResource(this.http, workflowId);
|
|
1565
|
+
}
|
|
1566
|
+
/** PUT /admin/workflows/:wid/transitions/:tid — update a draft workflow's transition. */
|
|
1567
|
+
async updateTransition(workflowId, transitionId, input) {
|
|
1568
|
+
return this.http.request({
|
|
1569
|
+
method: "PUT",
|
|
1570
|
+
path: `${this.adminPath}/${encodeURIComponent(workflowId)}/transitions/${encodeURIComponent(transitionId)}`,
|
|
1571
|
+
body: input
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
|
|
1576
|
+
// src/resources/service-schedules.ts
|
|
1577
|
+
var ServiceSchedulesResource = class {
|
|
1578
|
+
constructor(http2) {
|
|
1579
|
+
this.http = http2;
|
|
1580
|
+
this.basePath = "/service-schedules";
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* POST /service-schedules/conflicts/preview — before booking people, see
|
|
1584
|
+
* who is already on another event (`conflicts`) and who would be outside
|
|
1585
|
+
* their working hours (`working_hours`). Read-only and warn-only: nothing
|
|
1586
|
+
* is ever blocked. Give exactly one of `windows` (single booking) or
|
|
1587
|
+
* `schedule` (a cadence). 400 on invalid input, INVALID_RECURRENCE_RULE,
|
|
1588
|
+
* INVALID_TIMEZONE or TOO_MANY_WINDOWS (> 400).
|
|
1589
|
+
*/
|
|
1590
|
+
async previewConflicts(request) {
|
|
1591
|
+
return this.http.request({
|
|
1592
|
+
method: "POST",
|
|
1593
|
+
path: `${this.basePath}/conflicts/preview`,
|
|
1594
|
+
body: request
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
// src/resources/billing-schedules.ts
|
|
1600
|
+
var BillingScheduleResource = class extends BaseResource {
|
|
1601
|
+
constructor(http2) {
|
|
1602
|
+
super(http2, "/admin/billing-schedules");
|
|
1603
|
+
}
|
|
1604
|
+
/** GET /admin/billing-schedules — list rows (no lines; `line_count` and `next_amount` instead). */
|
|
1605
|
+
async list(params) {
|
|
1606
|
+
return this.http.request({
|
|
1607
|
+
method: "GET",
|
|
1608
|
+
path: this.basePath,
|
|
1609
|
+
params: toQueryParams(params)
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
/** GET /admin/billing-schedules/:id — the schedule with its lines and next 3 periods. */
|
|
1613
|
+
async get(id) {
|
|
1614
|
+
return this.http.request({
|
|
1615
|
+
method: "GET",
|
|
1616
|
+
path: `${this.basePath}/${encodeURIComponent(id)}`
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* POST /admin/billing-schedules. `timezone` defaults to the tenant's. A
|
|
1621
|
+
* backdated `start_date` needs `backfill` ('skip' | 'draft'), else 400
|
|
1622
|
+
* `BACKFILL_REQUIRED`; `collection: 'autopay'` without a platform-managed
|
|
1623
|
+
* Stripe connection and a saved default card is 422 `AUTOPAY_UNAVAILABLE`
|
|
1624
|
+
* (`reason` `no_connect` | `no_saved_method`).
|
|
1625
|
+
*/
|
|
1626
|
+
async create(data) {
|
|
1627
|
+
return this.http.request({
|
|
1628
|
+
method: "POST",
|
|
1629
|
+
path: this.basePath,
|
|
1630
|
+
body: data
|
|
1631
|
+
});
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
* PATCH /admin/billing-schedules/:id — partial. `lines` replaces every line
|
|
1635
|
+
* from `effective_from` (default: the next period not yet invoiced) as a new
|
|
1636
|
+
* line version. 409 `CADENCE_LOCKED`; 422 `EFFECTIVE_DATE_IN_GENERATED_PERIOD`
|
|
1637
|
+
* for a date inside an invoiced period.
|
|
1638
|
+
*/
|
|
1639
|
+
async update(id, data) {
|
|
1640
|
+
return this.http.request({
|
|
1641
|
+
method: "PATCH",
|
|
1642
|
+
path: `${this.basePath}/${encodeURIComponent(id)}`,
|
|
1643
|
+
body: data
|
|
1644
|
+
});
|
|
1645
|
+
}
|
|
1646
|
+
/** DELETE /admin/billing-schedules/:id — only a schedule that never invoiced (else 409 `SCHEDULE_HAS_INVOICES`). */
|
|
1647
|
+
async delete(id) {
|
|
1648
|
+
await this.http.request({
|
|
1649
|
+
method: "DELETE",
|
|
1650
|
+
path: `${this.basePath}/${encodeURIComponent(id)}`
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
/** GET /admin/billing-schedules/:id/versions — line version history, newest effective date first. */
|
|
1654
|
+
async listVersions(id) {
|
|
1655
|
+
return this.http.request({
|
|
1656
|
+
method: "GET",
|
|
1657
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/versions`
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* POST /admin/billing-schedules/:id/adjustments — add a one-off amount
|
|
1662
|
+
* (signed; negative is a credit) to the schedule's next generated invoice.
|
|
1663
|
+
* Billed exactly once; no automatic proration. 422 `ADJUSTMENT_INVALID`
|
|
1664
|
+
* (zero, or the next invoice would go below zero) or `SCHEDULE_NOT_ACTIVE`.
|
|
1665
|
+
*/
|
|
1666
|
+
async addAdjustment(id, data) {
|
|
1667
|
+
return this.http.request({
|
|
1668
|
+
method: "POST",
|
|
1669
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/adjustments`,
|
|
1670
|
+
body: data
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
/** GET /admin/billing-schedules/:id/adjustments — oldest first; default pending and consumed. */
|
|
1674
|
+
async listAdjustments(id, params) {
|
|
1675
|
+
return this.http.request({
|
|
1676
|
+
method: "GET",
|
|
1677
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/adjustments`,
|
|
1678
|
+
params: toQueryParams(params)
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* DELETE /admin/billing-schedules/:id/adjustments/:adjustmentId — cancel a
|
|
1683
|
+
* pending adjustment (it never bills). Returns it; 409
|
|
1684
|
+
* `ADJUSTMENT_ALREADY_CONSUMED` once an invoice carries it.
|
|
1685
|
+
*/
|
|
1686
|
+
async cancelAdjustment(id, adjustmentId) {
|
|
1687
|
+
return this.http.request({
|
|
1688
|
+
method: "DELETE",
|
|
1689
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/adjustments/${encodeURIComponent(adjustmentId)}`
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
/** POST /admin/billing-schedules/:id/pause — 409 `INVALID_STATUS_TRANSITION` unless active. */
|
|
1693
|
+
async pause(id) {
|
|
1694
|
+
return this.http.request({
|
|
1695
|
+
method: "POST",
|
|
1696
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/pause`
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
/** POST /admin/billing-schedules/:id/resume — periods that fell due while paused are skipped. */
|
|
1700
|
+
async resume(id) {
|
|
1701
|
+
return this.http.request({
|
|
1702
|
+
method: "POST",
|
|
1703
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/resume`
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
/** POST /admin/billing-schedules/:id/end — no further periods generate. */
|
|
1707
|
+
async end(id) {
|
|
1708
|
+
return this.http.request({
|
|
1709
|
+
method: "POST",
|
|
1710
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/end`
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
/** GET /admin/billing-schedules/:id/preview — the next `count` (1–24, default 6) periods from the first unbilled one. */
|
|
1714
|
+
async preview(id, params) {
|
|
1715
|
+
return this.http.request({
|
|
1716
|
+
method: "GET",
|
|
1717
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/preview`,
|
|
1718
|
+
params: toQueryParams(params)
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
/** GET /admin/billing-schedules/:id/periods — the period ledger, newest first. */
|
|
1722
|
+
async periods(id, params) {
|
|
1723
|
+
return this.http.request({
|
|
1724
|
+
method: "GET",
|
|
1725
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/periods`,
|
|
1726
|
+
params: toQueryParams(params)
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* GET /admin/billing-schedules/periods/needs-review — tenant-wide: needs_review
|
|
1731
|
+
* rows plus failed and stuck (pending over 2h) deliveries.
|
|
1732
|
+
*/
|
|
1733
|
+
async needsReview(params) {
|
|
1734
|
+
return this.http.request({
|
|
1735
|
+
method: "GET",
|
|
1736
|
+
path: `${this.basePath}/periods/needs-review`,
|
|
1737
|
+
params: toQueryParams(params)
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* GET /admin/billing-schedules/autopay-summary — what disconnecting Stripe
|
|
1742
|
+
* would touch: live autopay schedules, the distinct customers on them, and
|
|
1743
|
+
* active saved cards on the current Stripe connection. On disconnect, autopay
|
|
1744
|
+
* schedules that can no longer charge switch to emailed pay links.
|
|
1745
|
+
*/
|
|
1746
|
+
async autopaySummary() {
|
|
1747
|
+
return this.http.request({
|
|
1748
|
+
method: "GET",
|
|
1749
|
+
path: `${this.basePath}/autopay-summary`
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* POST /admin/billing-schedules/:id/generate-now — bill the current due
|
|
1754
|
+
* period now. Idempotent (`already_generated`); 409 `NOTHING_DUE` or
|
|
1755
|
+
* `SCHEDULE_NOT_ACTIVE`.
|
|
1756
|
+
*/
|
|
1757
|
+
async generateNow(id) {
|
|
1758
|
+
return this.http.request({
|
|
1759
|
+
method: "POST",
|
|
1760
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/generate-now`
|
|
1761
|
+
});
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* POST /admin/billing-schedules/:id/periods/:periodStart/skip — skip one
|
|
1765
|
+
* period (`periodStart` is `YYYY-MM-DD`). Returns the skipped ledger row;
|
|
1766
|
+
* 400 `NOT_A_PERIOD`, 409 `PERIOD_ALREADY_INVOICED`.
|
|
1767
|
+
*/
|
|
1768
|
+
async skipPeriod(id, periodStart, data = {}) {
|
|
1769
|
+
return this.http.request({
|
|
1770
|
+
method: "POST",
|
|
1771
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/periods/${encodeURIComponent(periodStart)}/skip`,
|
|
1772
|
+
body: data
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* POST /admin/billing-schedules/:id/periods/:periodStart/regenerate — re-bill
|
|
1777
|
+
* a period whose invoice was voided (new draft on the same ledger row).
|
|
1778
|
+
* 409 `INVOICE_NOT_VOID` or `CHECKOUT_IN_FLIGHT`.
|
|
1779
|
+
*/
|
|
1780
|
+
async regeneratePeriod(id, periodStart) {
|
|
1781
|
+
return this.http.request({
|
|
1782
|
+
method: "POST",
|
|
1783
|
+
path: `${this.basePath}/${encodeURIComponent(id)}/periods/${encodeURIComponent(periodStart)}/regenerate`
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1788
|
+
// src/resources/custom-fields.ts
|
|
1789
|
+
var CustomFieldsResource = class {
|
|
1790
|
+
constructor(http2) {
|
|
1791
|
+
this.http = http2;
|
|
1792
|
+
}
|
|
1793
|
+
/** List definitions, optionally narrowed to one entity type. */
|
|
1794
|
+
async list(params) {
|
|
1795
|
+
return this.http.request({
|
|
1796
|
+
method: "GET",
|
|
1797
|
+
path: "/custom-fields",
|
|
1798
|
+
params
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
};
|
|
1802
|
+
|
|
1803
|
+
// src/resources/ortto.ts
|
|
1804
|
+
var OrttoResource = class {
|
|
1805
|
+
constructor(http2) {
|
|
1806
|
+
this.http = http2;
|
|
1807
|
+
this.basePath = "/admin/integrations/ortto";
|
|
1808
|
+
}
|
|
1809
|
+
/** GET /admin/integrations/ortto/mappings — live mappings with their list names. */
|
|
1810
|
+
async listMappings() {
|
|
1811
|
+
const res = await this.http.request({
|
|
1812
|
+
method: "GET",
|
|
1813
|
+
path: `${this.basePath}/mappings`
|
|
1814
|
+
});
|
|
1815
|
+
return res.data;
|
|
1816
|
+
}
|
|
1817
|
+
/** GET /admin/integrations/ortto/audiences — the connected account's audiences (cached 60 s). */
|
|
1818
|
+
async listAudiences(params) {
|
|
1819
|
+
const res = await this.http.request({
|
|
1820
|
+
method: "GET",
|
|
1821
|
+
path: `${this.basePath}/audiences`,
|
|
1822
|
+
params
|
|
1823
|
+
});
|
|
1824
|
+
return res.data;
|
|
1825
|
+
}
|
|
1826
|
+
/** POST /admin/integrations/ortto/mappings — 409 when the list already has a mapping. */
|
|
1827
|
+
async createMapping(data) {
|
|
1828
|
+
const res = await this.http.request({
|
|
1829
|
+
method: "POST",
|
|
1830
|
+
path: `${this.basePath}/mappings`,
|
|
1831
|
+
body: data
|
|
1832
|
+
});
|
|
1833
|
+
return res.data;
|
|
1834
|
+
}
|
|
1835
|
+
/** PATCH /admin/integrations/ortto/mappings/:id — `ortto_tag` and/or `create_unmatched`. */
|
|
1836
|
+
async updateMapping(id, data) {
|
|
1837
|
+
const res = await this.http.request({
|
|
1838
|
+
method: "PATCH",
|
|
1839
|
+
path: `${this.basePath}/mappings/${id}`,
|
|
1840
|
+
body: data
|
|
1841
|
+
});
|
|
1842
|
+
return res.data;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* DELETE /admin/integrations/ortto/mappings/:id (204). A pull list becomes
|
|
1846
|
+
* editable again and keeps its members; a push tag is NOT removed from Ortto.
|
|
1847
|
+
*/
|
|
1848
|
+
async deleteMapping(id) {
|
|
1849
|
+
await this.http.request({
|
|
1850
|
+
method: "DELETE",
|
|
1851
|
+
path: `${this.basePath}/mappings/${id}`
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* POST /admin/integrations/ortto/sync (202) — queue a sync for one mapping or
|
|
1856
|
+
* the whole connection. Never calls Ortto in-request.
|
|
1857
|
+
*/
|
|
1858
|
+
async sync(data = {}) {
|
|
1859
|
+
const res = await this.http.request({
|
|
1860
|
+
method: "POST",
|
|
1861
|
+
path: `${this.basePath}/sync`,
|
|
1862
|
+
body: data
|
|
1863
|
+
});
|
|
1864
|
+
return res.data;
|
|
1865
|
+
}
|
|
1866
|
+
/** GET /admin/integrations/ortto/sync-status — 404 when Ortto is not connected. */
|
|
1867
|
+
async syncStatus() {
|
|
1868
|
+
const res = await this.http.request({
|
|
1869
|
+
method: "GET",
|
|
1870
|
+
path: `${this.basePath}/sync-status`
|
|
1871
|
+
});
|
|
1872
|
+
return res.data;
|
|
1873
|
+
}
|
|
1874
|
+
};
|
|
1875
|
+
|
|
1876
|
+
// src/webhooks.ts
|
|
1877
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
1878
|
+
var WEBHOOK_EVENT_TYPES = [
|
|
1879
|
+
"created",
|
|
1880
|
+
"updated",
|
|
1881
|
+
"deleted",
|
|
1882
|
+
"status_changed",
|
|
1883
|
+
"entity.tagged",
|
|
1884
|
+
"entity.untagged",
|
|
1885
|
+
"list.member_added",
|
|
1886
|
+
"list.member_removed",
|
|
1887
|
+
"entity.assigned",
|
|
1888
|
+
"entity.unassigned",
|
|
1889
|
+
"team.member_added",
|
|
1890
|
+
"team.member_removed",
|
|
1891
|
+
"task.created",
|
|
1892
|
+
"task.updated",
|
|
1893
|
+
"task.completed",
|
|
1894
|
+
"task.cancelled",
|
|
1895
|
+
"comment.created",
|
|
1896
|
+
"conversation.created",
|
|
1897
|
+
"conversation.matched",
|
|
1898
|
+
"conversation.deleted",
|
|
1899
|
+
"customer.merged",
|
|
1900
|
+
"workflow.instance_moved",
|
|
1901
|
+
"consent.changed",
|
|
1902
|
+
"billing_schedule.period_generated",
|
|
1903
|
+
"billing_schedule.period_needs_review",
|
|
1904
|
+
"billing_schedule.period_delivered",
|
|
1905
|
+
"billing_schedule.period_delivery_failed",
|
|
1906
|
+
"payment.on_void_invoice",
|
|
1907
|
+
"invoice.overdue",
|
|
1908
|
+
"integration_connection.deactivated",
|
|
1909
|
+
"customer_payment_method.invalidated",
|
|
1910
|
+
"invoice.autopay_succeeded",
|
|
1911
|
+
"invoice.autopay_failed"
|
|
1912
|
+
];
|
|
1913
|
+
function verifyWebhookSignature(payload, signature, secret) {
|
|
1914
|
+
if (!signature || !secret || !payload) {
|
|
1915
|
+
return false;
|
|
1916
|
+
}
|
|
1917
|
+
const prefix = "sha256=";
|
|
1918
|
+
if (!signature.startsWith(prefix)) {
|
|
1919
|
+
return false;
|
|
1920
|
+
}
|
|
1921
|
+
const receivedHex = signature.slice(prefix.length);
|
|
1922
|
+
if (!receivedHex) {
|
|
1923
|
+
return false;
|
|
1924
|
+
}
|
|
1925
|
+
const expectedHmac = createHmac("sha256", secret).update(payload).digest("hex");
|
|
1926
|
+
const receivedBuf = Buffer.from(receivedHex, "hex");
|
|
1927
|
+
const expectedBuf = Buffer.from(expectedHmac, "hex");
|
|
1928
|
+
if (receivedBuf.length !== expectedBuf.length) {
|
|
1929
|
+
return false;
|
|
1930
|
+
}
|
|
1931
|
+
return timingSafeEqual(receivedBuf, expectedBuf);
|
|
1932
|
+
}
|
|
1933
|
+
function parseWebhookEvent(body, signature, secret) {
|
|
1934
|
+
if (!verifyWebhookSignature(body, signature, secret)) {
|
|
1935
|
+
throw new WebhookVerificationError();
|
|
1936
|
+
}
|
|
1937
|
+
return JSON.parse(body);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
// src/webhook-router.ts
|
|
605
1941
|
var WebhookRouter = class {
|
|
606
1942
|
constructor() {
|
|
607
1943
|
/** pattern (composite key / entity wildcard / '*') → registered handlers. */
|
|
@@ -743,12 +2079,142 @@ var PlanesClient = class {
|
|
|
743
2079
|
}
|
|
744
2080
|
return this._activities;
|
|
745
2081
|
}
|
|
2082
|
+
get communications() {
|
|
2083
|
+
if (!this._communications) {
|
|
2084
|
+
this._communications = new CommunicationsResource(this.http);
|
|
2085
|
+
}
|
|
2086
|
+
return this._communications;
|
|
2087
|
+
}
|
|
2088
|
+
/** Logged meetings — manual + provider-synced, with company matching (E55). */
|
|
2089
|
+
get conversations() {
|
|
2090
|
+
if (!this._conversations) {
|
|
2091
|
+
this._conversations = new ConversationsResource(this.http);
|
|
2092
|
+
}
|
|
2093
|
+
return this._conversations;
|
|
2094
|
+
}
|
|
2095
|
+
get gmail() {
|
|
2096
|
+
if (!this._gmail) {
|
|
2097
|
+
this._gmail = new GmailResource(this.http);
|
|
2098
|
+
}
|
|
2099
|
+
return this._gmail;
|
|
2100
|
+
}
|
|
2101
|
+
get documents() {
|
|
2102
|
+
if (!this._documents) {
|
|
2103
|
+
this._documents = new DocumentsResource(this.http);
|
|
2104
|
+
}
|
|
2105
|
+
return this._documents;
|
|
2106
|
+
}
|
|
746
2107
|
get tags() {
|
|
747
2108
|
if (!this._tags) {
|
|
748
2109
|
this._tags = new TagResource(this.http);
|
|
749
2110
|
}
|
|
750
2111
|
return this._tags;
|
|
751
2112
|
}
|
|
2113
|
+
get tasks() {
|
|
2114
|
+
if (!this._tasks) {
|
|
2115
|
+
this._tasks = new TaskResource(this.http);
|
|
2116
|
+
}
|
|
2117
|
+
return this._tasks;
|
|
2118
|
+
}
|
|
2119
|
+
/** Record views — the "recently viewed" beacon + read (E41-F7). */
|
|
2120
|
+
get recordViews() {
|
|
2121
|
+
if (!this._recordViews) {
|
|
2122
|
+
this._recordViews = new RecordViewsResource(this.http);
|
|
2123
|
+
}
|
|
2124
|
+
return this._recordViews;
|
|
2125
|
+
}
|
|
2126
|
+
/** Module status — which modules are active for the caller's tenant (E51-F1-S1). */
|
|
2127
|
+
get modules() {
|
|
2128
|
+
if (!this._modules) {
|
|
2129
|
+
this._modules = new ModulesResource(this.http);
|
|
2130
|
+
}
|
|
2131
|
+
return this._modules;
|
|
2132
|
+
}
|
|
2133
|
+
/** The tenant's plan, billing status and plan ceiling — `plan.get()` (E54-F1-S2). */
|
|
2134
|
+
get plan() {
|
|
2135
|
+
if (!this._plan) {
|
|
2136
|
+
this._plan = new PlanResource(this.http);
|
|
2137
|
+
}
|
|
2138
|
+
return this._plan;
|
|
2139
|
+
}
|
|
2140
|
+
/** The authenticated caller — `me.abilities()` (E52-F1-S3). */
|
|
2141
|
+
get me() {
|
|
2142
|
+
if (!this._me) {
|
|
2143
|
+
this._me = new MeResource(this.http);
|
|
2144
|
+
}
|
|
2145
|
+
return this._me;
|
|
2146
|
+
}
|
|
2147
|
+
/** Settings → Roles, admin only — `roles.list/get/updateGrants/reset/history` (E52-F2-S5). */
|
|
2148
|
+
get roles() {
|
|
2149
|
+
if (!this._roles) {
|
|
2150
|
+
this._roles = new RolesResource(this.http);
|
|
2151
|
+
}
|
|
2152
|
+
return this._roles;
|
|
2153
|
+
}
|
|
2154
|
+
/** Invoice settings — `invoiceSettings.getOfflineInstructions/setOfflineInstructions` (E56-F5-S4). */
|
|
2155
|
+
get invoiceSettings() {
|
|
2156
|
+
if (!this._invoiceSettings) {
|
|
2157
|
+
this._invoiceSettings = new InvoiceSettingsResource(this.http);
|
|
2158
|
+
}
|
|
2159
|
+
return this._invoiceSettings;
|
|
2160
|
+
}
|
|
2161
|
+
/** Payment reminder settings, admin only — `invoiceReminders.list/update/preview` (E56-F8-S6). */
|
|
2162
|
+
get invoiceReminders() {
|
|
2163
|
+
if (!this._invoiceReminders) {
|
|
2164
|
+
this._invoiceReminders = new InvoiceRemindersResource(this.http);
|
|
2165
|
+
}
|
|
2166
|
+
return this._invoiceReminders;
|
|
2167
|
+
}
|
|
2168
|
+
/** Published sequences a contact can be enrolled in (E51-F2-S6). */
|
|
2169
|
+
get contactSequences() {
|
|
2170
|
+
if (!this._contactSequences) {
|
|
2171
|
+
this._contactSequences = new ContactSequencesResource(this.http);
|
|
2172
|
+
}
|
|
2173
|
+
return this._contactSequences;
|
|
2174
|
+
}
|
|
2175
|
+
/** Enroll a contact in a sequence, list its enrollments, exit one (E51-F2-S8). */
|
|
2176
|
+
get enrollments() {
|
|
2177
|
+
if (!this._enrollments) {
|
|
2178
|
+
this._enrollments = new EnrollmentsResource(this.http);
|
|
2179
|
+
}
|
|
2180
|
+
return this._enrollments;
|
|
2181
|
+
}
|
|
2182
|
+
/** Tenant-readable workflow reads — a workflow version's ordered stages. */
|
|
2183
|
+
get workflows() {
|
|
2184
|
+
if (!this._workflows) {
|
|
2185
|
+
this._workflows = new WorkflowsResource(this.http);
|
|
2186
|
+
}
|
|
2187
|
+
return this._workflows;
|
|
2188
|
+
}
|
|
2189
|
+
get serviceSchedules() {
|
|
2190
|
+
if (!this._serviceSchedules) {
|
|
2191
|
+
this._serviceSchedules = new ServiceSchedulesResource(this.http);
|
|
2192
|
+
}
|
|
2193
|
+
return this._serviceSchedules;
|
|
2194
|
+
}
|
|
2195
|
+
/**
|
|
2196
|
+
* Recurring billing schedules (E56-F3) — CRUD, pause/resume/end, preview,
|
|
2197
|
+
* the period ledger, Needs review, generate-now, skip and regenerate.
|
|
2198
|
+
*/
|
|
2199
|
+
get billingSchedules() {
|
|
2200
|
+
if (!this._billingSchedules) {
|
|
2201
|
+
this._billingSchedules = new BillingScheduleResource(this.http);
|
|
2202
|
+
}
|
|
2203
|
+
return this._billingSchedules;
|
|
2204
|
+
}
|
|
2205
|
+
get customFields() {
|
|
2206
|
+
if (!this._customFields) {
|
|
2207
|
+
this._customFields = new CustomFieldsResource(this.http);
|
|
2208
|
+
}
|
|
2209
|
+
return this._customFields;
|
|
2210
|
+
}
|
|
2211
|
+
/** Ortto connector — list mappings, audiences, manual sync, sync status (E53). Admin-only. */
|
|
2212
|
+
get ortto() {
|
|
2213
|
+
if (!this._ortto) {
|
|
2214
|
+
this._ortto = new OrttoResource(this.http);
|
|
2215
|
+
}
|
|
2216
|
+
return this._ortto;
|
|
2217
|
+
}
|
|
752
2218
|
/**
|
|
753
2219
|
* Ergonomic webhook event router — `client.webhooks.on(pattern, handler)`
|
|
754
2220
|
* plus `client.webhooks.process({ body, signature, secret })`. Auth-independent
|
|
@@ -763,6 +2229,129 @@ var PlanesClient = class {
|
|
|
763
2229
|
}
|
|
764
2230
|
};
|
|
765
2231
|
|
|
2232
|
+
// src/types/billing-schedule-types.ts
|
|
2233
|
+
var BILLING_CADENCES = ["weekly", "every_n_weeks", "monthly", "quarterly", "annually"];
|
|
2234
|
+
var BILLING_SCHEDULE_STATUSES = ["active", "paused", "ended"];
|
|
2235
|
+
var BILL_TIMINGS = ["in_advance", "in_arrears"];
|
|
2236
|
+
var BILLING_DELIVERY_MODES = ["auto_send", "draft_for_review"];
|
|
2237
|
+
var BILLING_COLLECTION_MODES = ["send_link", "autopay"];
|
|
2238
|
+
var AUTOPAY_UNAVAILABLE_REASONS = ["no_connect", "no_saved_method"];
|
|
2239
|
+
var BILLING_AUTOPAY_STATUSES = [
|
|
2240
|
+
"not_applicable",
|
|
2241
|
+
"scheduled",
|
|
2242
|
+
"submitted",
|
|
2243
|
+
"succeeded",
|
|
2244
|
+
"failed",
|
|
2245
|
+
"auth_required",
|
|
2246
|
+
"retry_scheduled",
|
|
2247
|
+
"abandoned"
|
|
2248
|
+
];
|
|
2249
|
+
var BILLING_BACKFILL_MODES = ["skip", "draft"];
|
|
2250
|
+
var BILLING_PERIOD_STATUSES = ["generated", "skipped", "needs_review", "failed", "voided"];
|
|
2251
|
+
var BILLING_PREVIEW_PERIOD_STATUSES = [...BILLING_PERIOD_STATUSES, "upcoming"];
|
|
2252
|
+
var BILLING_DELIVERY_STATUSES = ["pending", "sent", "failed", "not_applicable"];
|
|
2253
|
+
var BILLING_ADJUSTMENT_STATUSES = ["pending", "consumed", "cancelled"];
|
|
2254
|
+
var BILLING_ADJUSTMENT_TARGETS = ["next_invoice"];
|
|
2255
|
+
|
|
2256
|
+
// src/types/contact-types.ts
|
|
2257
|
+
var CONTACT_SORT_KEYS = ["name", "created_at", "recent"];
|
|
2258
|
+
var CONTACT_LIST_INCLUDES = ["channels", "links"];
|
|
2259
|
+
|
|
2260
|
+
// src/types/customer-types.ts
|
|
2261
|
+
var CUSTOMER_SORT_KEYS = ["created_at", "last_name", "first_name", "email", "phone", "source", "recent"];
|
|
2262
|
+
|
|
2263
|
+
// src/types/opportunity-types.ts
|
|
2264
|
+
var OPPORTUNITY_SORT_KEYS = ["created_at", "total", "title", "customer_name", "stage", "priority", "recent"];
|
|
2265
|
+
var OPPORTUNITY_STATES = ["open", "closed", "won", "lost"];
|
|
2266
|
+
|
|
2267
|
+
// src/types/job-types.ts
|
|
2268
|
+
var JOB_SORT_KEYS = ["created_at", "recent"];
|
|
2269
|
+
|
|
2270
|
+
// src/types/estimate-types.ts
|
|
2271
|
+
var ESTIMATE_STATUSES = ["draft", "sent", "approved", "rejected"];
|
|
2272
|
+
|
|
2273
|
+
// src/types/record-view-types.ts
|
|
2274
|
+
var RECORD_VIEW_ENTITY_TYPES = ["customer", "contact", "opportunity", "job"];
|
|
2275
|
+
|
|
2276
|
+
// src/types/module-types.ts
|
|
2277
|
+
var MODULE_KEYS = [
|
|
2278
|
+
"estimates",
|
|
2279
|
+
"contracts",
|
|
2280
|
+
"inventory",
|
|
2281
|
+
"production",
|
|
2282
|
+
"production_scheduling",
|
|
2283
|
+
"calendar",
|
|
2284
|
+
"service-schedules",
|
|
2285
|
+
"marketplace",
|
|
2286
|
+
"invoicing",
|
|
2287
|
+
"knocks",
|
|
2288
|
+
"accounting",
|
|
2289
|
+
"contacts",
|
|
2290
|
+
"tasks",
|
|
2291
|
+
"comments",
|
|
2292
|
+
"conversations"
|
|
2293
|
+
];
|
|
2294
|
+
|
|
2295
|
+
// src/types/plan-types.ts
|
|
2296
|
+
var PLAN_KEYS = ["solo", "sales", "business", "operations", "legacy", "internal"];
|
|
2297
|
+
var BILLING_STATUSES = [
|
|
2298
|
+
"trialing",
|
|
2299
|
+
"active",
|
|
2300
|
+
"past_due",
|
|
2301
|
+
"unpaid",
|
|
2302
|
+
"paused",
|
|
2303
|
+
"canceled",
|
|
2304
|
+
"comped"
|
|
2305
|
+
];
|
|
2306
|
+
var PLAN_SOURCES = ["stripe", "manual"];
|
|
2307
|
+
var BILLING_INTERVALS = ["month", "year"];
|
|
2308
|
+
var FEATURE_KEYS = [
|
|
2309
|
+
"calendar",
|
|
2310
|
+
"estimates",
|
|
2311
|
+
"contracts",
|
|
2312
|
+
"service_dispatch",
|
|
2313
|
+
"production_scheduling",
|
|
2314
|
+
"sub_management",
|
|
2315
|
+
"reports",
|
|
2316
|
+
"open_api",
|
|
2317
|
+
"workflow_builder",
|
|
2318
|
+
"integrations.quickbooks",
|
|
2319
|
+
"integrations.stripe",
|
|
2320
|
+
"integrations.hover",
|
|
2321
|
+
"integrations.ortto",
|
|
2322
|
+
"communications.marketing",
|
|
2323
|
+
"ai.scheduling",
|
|
2324
|
+
"ai.content_assist",
|
|
2325
|
+
"ai.documents",
|
|
2326
|
+
"ai.search",
|
|
2327
|
+
"inventory_management",
|
|
2328
|
+
"workflow_execution",
|
|
2329
|
+
"marketplace"
|
|
2330
|
+
];
|
|
2331
|
+
|
|
2332
|
+
// src/types/me-types.ts
|
|
2333
|
+
var AGENT_ROLES = [
|
|
2334
|
+
"admin",
|
|
2335
|
+
"sales",
|
|
2336
|
+
"service",
|
|
2337
|
+
"production",
|
|
2338
|
+
"sub",
|
|
2339
|
+
"readonly",
|
|
2340
|
+
"system_agent"
|
|
2341
|
+
];
|
|
2342
|
+
|
|
2343
|
+
// src/types/workflow-event-rule-types.ts
|
|
2344
|
+
var WORKFLOW_EVENT_RULE_EVENT_TYPES = [
|
|
2345
|
+
"contract.status_changed",
|
|
2346
|
+
"invoice.status_changed",
|
|
2347
|
+
"calendar_event.status_changed",
|
|
2348
|
+
/** "An event is booked": one-off events and recurring series masters. */
|
|
2349
|
+
"calendar_event.created"
|
|
2350
|
+
];
|
|
2351
|
+
var WORKFLOW_EVENT_RULE_MATCH_ALL_EVENT_TYPES = [
|
|
2352
|
+
"calendar_event.created"
|
|
2353
|
+
];
|
|
2354
|
+
|
|
766
2355
|
// src/agent.ts
|
|
767
2356
|
import * as http from "http";
|
|
768
2357
|
function createActionServer(handlerMap, options) {
|
|
@@ -918,38 +2507,90 @@ function readBody(req) {
|
|
|
918
2507
|
});
|
|
919
2508
|
}
|
|
920
2509
|
export {
|
|
2510
|
+
AGENT_ROLES,
|
|
2511
|
+
AUTOPAY_UNAVAILABLE_REASONS,
|
|
921
2512
|
ActivityResource,
|
|
922
2513
|
AgentApp,
|
|
2514
|
+
ApiResource,
|
|
923
2515
|
AuthenticationError,
|
|
924
2516
|
AuthorizationError,
|
|
2517
|
+
BILLING_ADJUSTMENT_STATUSES,
|
|
2518
|
+
BILLING_ADJUSTMENT_TARGETS,
|
|
2519
|
+
BILLING_AUTOPAY_STATUSES,
|
|
2520
|
+
BILLING_BACKFILL_MODES,
|
|
2521
|
+
BILLING_CADENCES,
|
|
2522
|
+
BILLING_COLLECTION_MODES,
|
|
2523
|
+
BILLING_DELIVERY_MODES,
|
|
2524
|
+
BILLING_DELIVERY_STATUSES,
|
|
2525
|
+
BILLING_INTERVALS,
|
|
2526
|
+
BILLING_PERIOD_STATUSES,
|
|
2527
|
+
BILLING_PREVIEW_PERIOD_STATUSES,
|
|
2528
|
+
BILLING_SCHEDULE_STATUSES,
|
|
2529
|
+
BILLING_STATUSES,
|
|
2530
|
+
BILL_TIMINGS,
|
|
925
2531
|
BaseResource,
|
|
2532
|
+
BillingScheduleResource,
|
|
2533
|
+
CONTACT_LIST_INCLUDES,
|
|
2534
|
+
CONTACT_SORT_KEYS,
|
|
2535
|
+
CUSTOMER_SORT_KEYS,
|
|
926
2536
|
CalendarEventResource,
|
|
2537
|
+
CommunicationsResource,
|
|
927
2538
|
ContactChannelResource,
|
|
928
2539
|
ContactResource,
|
|
2540
|
+
ContactSequencesResource,
|
|
929
2541
|
ContractResource,
|
|
2542
|
+
ConversationsResource,
|
|
2543
|
+
CustomFieldsResource,
|
|
930
2544
|
CustomerResource,
|
|
931
2545
|
DEFAULT_BASE_URL,
|
|
932
2546
|
DEFAULT_MAX_RETRIES,
|
|
933
2547
|
DEFAULT_TIMEOUT,
|
|
934
2548
|
DEFAULT_TOKEN_REFRESH_SKEW_MS,
|
|
2549
|
+
DocumentsResource,
|
|
2550
|
+
ESTIMATE_STATUSES,
|
|
2551
|
+
EnrollmentsResource,
|
|
935
2552
|
EstimateResource,
|
|
2553
|
+
FEATURE_KEYS,
|
|
2554
|
+
GmailResource,
|
|
936
2555
|
InventoryResource,
|
|
2556
|
+
InvoiceRemindersResource,
|
|
937
2557
|
InvoiceResource,
|
|
2558
|
+
InvoiceSettingsResource,
|
|
2559
|
+
JOB_SORT_KEYS,
|
|
938
2560
|
JobResource,
|
|
2561
|
+
MODULE_KEYS,
|
|
2562
|
+
MeResource,
|
|
939
2563
|
MemoryTokenStorage,
|
|
2564
|
+
ModulesResource,
|
|
940
2565
|
NotFoundError,
|
|
941
2566
|
OAuthError,
|
|
2567
|
+
OPPORTUNITY_SORT_KEYS,
|
|
2568
|
+
OPPORTUNITY_STATES,
|
|
942
2569
|
OpportunityResource,
|
|
2570
|
+
OrttoResource,
|
|
2571
|
+
PLAN_KEYS,
|
|
2572
|
+
PLAN_SOURCES,
|
|
2573
|
+
PlanResource,
|
|
943
2574
|
Planes,
|
|
944
2575
|
PlanesClient,
|
|
945
2576
|
PlanesError,
|
|
946
2577
|
PropertyResource,
|
|
2578
|
+
RECORD_VIEW_ENTITY_TYPES,
|
|
947
2579
|
RateLimitError,
|
|
2580
|
+
RecordViewsResource,
|
|
2581
|
+
RolesResource,
|
|
948
2582
|
ServerError,
|
|
2583
|
+
ServiceSchedulesResource,
|
|
949
2584
|
TagResource,
|
|
2585
|
+
TaskResource,
|
|
950
2586
|
ValidationError,
|
|
2587
|
+
WEBHOOK_EVENT_TYPES,
|
|
2588
|
+
WORKFLOW_EVENT_RULE_EVENT_TYPES,
|
|
2589
|
+
WORKFLOW_EVENT_RULE_MATCH_ALL_EVENT_TYPES,
|
|
951
2590
|
WebhookRouter,
|
|
952
2591
|
WebhookVerificationError,
|
|
2592
|
+
WorkflowEventRulesResource,
|
|
2593
|
+
WorkflowsResource,
|
|
953
2594
|
buildAuthorizeUrl,
|
|
954
2595
|
clientCredentialsGrant,
|
|
955
2596
|
createAgentApp,
|