@wokuapp/sdk 0.3.0 → 0.5.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/dist/index.js CHANGED
@@ -20,8 +20,23 @@ var Media = class {
20
20
  }
21
21
  };
22
22
 
23
+ // src/resources/follow-ups.ts
24
+ var FollowUps = class {
25
+ constructor(client) {
26
+ this.client = client;
27
+ }
28
+ async get(id, opts) {
29
+ const result = await this.client.request(
30
+ "get",
31
+ `/v1/follow-ups/${encodeURIComponent(id)}`,
32
+ opts
33
+ );
34
+ return result.data;
35
+ }
36
+ };
37
+
23
38
  // package.json
24
- var version = "0.3.0";
39
+ var version = "0.5.0";
25
40
 
26
41
  // src/core/errors.ts
27
42
  var WokuError = class extends Error {
@@ -368,7 +383,8 @@ var WokuClient = class {
368
383
  headers,
369
384
  bodyText,
370
385
  timeout,
371
- args.signal
386
+ args.signal,
387
+ args.binary
372
388
  );
373
389
  if (status >= 200 && status < 300) {
374
390
  return body;
@@ -485,7 +501,7 @@ var WokuClient = class {
485
501
  }
486
502
  return headers;
487
503
  }
488
- async send(url, method, headers, body, timeout, signal) {
504
+ async send(url, method, headers, body, timeout, signal, binary) {
489
505
  if (signal?.aborted)
490
506
  throw new WokuConnectionError("Request aborted", { code: "aborted" });
491
507
  const controller = new AbortController();
@@ -506,6 +522,20 @@ var WokuClient = class {
506
522
  body,
507
523
  signal: controller.signal
508
524
  });
525
+ if (binary && response.status >= 200 && response.status < 300) {
526
+ if (!response.arrayBuffer) {
527
+ throw new WokuError(
528
+ "The fetch implementation cannot read binary responses.",
529
+ { code: "config_error" }
530
+ );
531
+ }
532
+ return {
533
+ status: response.status,
534
+ body: new Uint8Array(await response.arrayBuffer()),
535
+ requestId: requestIdFrom(response.headers),
536
+ retryAfterSeconds: retryAfterFromHeaders(response.headers)
537
+ };
538
+ }
509
539
  const text = await response.text();
510
540
  return {
511
541
  status: response.status,
@@ -704,6 +734,14 @@ var NpsTools = class {
704
734
  }
705
735
  );
706
736
  }
737
+ /** Move the tool into a folder, or to the root with `folderId: null`. */
738
+ move(id, body, opts) {
739
+ return this.client.request(
740
+ "patch",
741
+ `/v1/nps-tools/${encodeURIComponent(id)}/move`,
742
+ { ...opts, body }
743
+ );
744
+ }
707
745
  delete(id, opts) {
708
746
  return this.client.request(
709
747
  "delete",
@@ -743,6 +781,14 @@ var CsatTools = class {
743
781
  }
744
782
  );
745
783
  }
784
+ /** Move the tool into a folder, or to the root with `folderId: null`. */
785
+ move(id, body, opts) {
786
+ return this.client.request(
787
+ "patch",
788
+ `/v1/csat-tools/${encodeURIComponent(id)}/move`,
789
+ { ...opts, body }
790
+ );
791
+ }
746
792
  delete(id, opts) {
747
793
  return this.client.request(
748
794
  "delete",
@@ -782,6 +828,14 @@ var CesTools = class {
782
828
  }
783
829
  );
784
830
  }
831
+ /** Move the tool into a folder, or to the root with `folderId: null`. */
832
+ move(id, body, opts) {
833
+ return this.client.request(
834
+ "patch",
835
+ `/v1/ces-tools/${encodeURIComponent(id)}/move`,
836
+ { ...opts, body }
837
+ );
838
+ }
785
839
  delete(id, opts) {
786
840
  return this.client.request(
787
841
  "delete",
@@ -999,9 +1053,11 @@ var Flows = class {
999
1053
  constructor(client) {
1000
1054
  this.client = client;
1001
1055
  }
1056
+ /** List the flows of the company, with their ordered `steps`. */
1002
1057
  list(params, opts) {
1003
1058
  return this.client.getPage("/v1/flows", params, opts);
1004
1059
  }
1060
+ /** The data of a flow: ordered steps with their tools, wokus and branding. */
1005
1061
  get(id, opts) {
1006
1062
  return this.client.request(
1007
1063
  "get",
@@ -1009,6 +1065,33 @@ var Flows = class {
1009
1065
  opts
1010
1066
  );
1011
1067
  }
1068
+ /**
1069
+ * Create a flow from 1 to 20 ordered steps (each tool once, all of your
1070
+ * company). Flows live outside folders.
1071
+ */
1072
+ create(body, opts) {
1073
+ return this.client.request("post", "/v1/flows", {
1074
+ ...opts,
1075
+ body,
1076
+ idempotent: true
1077
+ });
1078
+ }
1079
+ /** Rename a flow or replace its full ordered list of steps. */
1080
+ update(id, body, opts) {
1081
+ return this.client.request(
1082
+ "patch",
1083
+ `/v1/flows/${encodeURIComponent(id)}`,
1084
+ { ...opts, body }
1085
+ );
1086
+ }
1087
+ /** Delete a flow. Its tools and their responses stay. */
1088
+ delete(id, opts) {
1089
+ return this.client.request(
1090
+ "delete",
1091
+ `/v1/flows/${encodeURIComponent(id)}`,
1092
+ opts
1093
+ );
1094
+ }
1012
1095
  };
1013
1096
 
1014
1097
  // src/resources/action-plans.ts
@@ -1506,6 +1589,240 @@ var Quarantines = class {
1506
1589
  }
1507
1590
  };
1508
1591
 
1592
+ // src/resources/folders.ts
1593
+ var Folders = class {
1594
+ constructor(client) {
1595
+ this.client = client;
1596
+ }
1597
+ /** Every folder of the company, or the direct subfolders of `parentFolderId`. */
1598
+ list(params, opts) {
1599
+ return this.client.request("get", "/v1/folders", {
1600
+ ...opts,
1601
+ query: { ...params, ...opts?.query }
1602
+ });
1603
+ }
1604
+ get(id, opts) {
1605
+ return this.client.request(
1606
+ "get",
1607
+ `/v1/folders/${encodeURIComponent(id)}`,
1608
+ opts
1609
+ );
1610
+ }
1611
+ create(body, opts) {
1612
+ return this.client.request("post", "/v1/folders", {
1613
+ ...opts,
1614
+ body,
1615
+ idempotent: true
1616
+ });
1617
+ }
1618
+ /**
1619
+ * Rename or recolor a folder (`color: null` clears the color) and/or replace
1620
+ * its WhatsApp alert recipients (`whatsappAlertRecipients`, `[]` clears them).
1621
+ */
1622
+ update(id, body, opts) {
1623
+ return this.client.request(
1624
+ "patch",
1625
+ `/v1/folders/${encodeURIComponent(id)}`,
1626
+ { ...opts, body }
1627
+ );
1628
+ }
1629
+ /**
1630
+ * Move a folder under another folder, or to the root with
1631
+ * `parentFolderId: null`. A folder cannot move into its own subtree.
1632
+ */
1633
+ move(id, body, opts) {
1634
+ return this.client.request(
1635
+ "patch",
1636
+ `/v1/folders/${encodeURIComponent(id)}/move`,
1637
+ { ...opts, body }
1638
+ );
1639
+ }
1640
+ /**
1641
+ * Delete a folder. Nothing inside is deleted: subfolders, wokus and tools
1642
+ * move up to the parent folder (or the root).
1643
+ */
1644
+ delete(id, opts) {
1645
+ return this.client.request(
1646
+ "delete",
1647
+ `/v1/folders/${encodeURIComponent(id)}`,
1648
+ opts
1649
+ );
1650
+ }
1651
+ /**
1652
+ * AI report over every woku, NPS, CSAT and CES tool of the folder and its
1653
+ * subfolders. Scales differ per type, so there is no rating distribution.
1654
+ */
1655
+ report(id, params, opts) {
1656
+ return this.client.request(
1657
+ "get",
1658
+ `/v1/folders/${encodeURIComponent(id)}/report`,
1659
+ { ...opts, query: { ...params, ...opts?.query } }
1660
+ );
1661
+ }
1662
+ /**
1663
+ * Per-tool figures of the woku, NPS, CSAT and CES tools of the folder and its
1664
+ * subfolders for a period against the one before it, with the daily sums and
1665
+ * the histogram of scores. `days` is 7, 30 (default) or 90, or 0 for the whole
1666
+ * history (every `previous` window is then empty). The period is the last
1667
+ * `days` calendar days in UTC, today included. Scales are never mixed across
1668
+ * types.
1669
+ */
1670
+ metrics(id, params, opts) {
1671
+ return this.client.request(
1672
+ "get",
1673
+ `/v1/folders/${encodeURIComponent(id)}/metrics`,
1674
+ { ...opts, query: { ...params, ...opts?.query } }
1675
+ );
1676
+ }
1677
+ /** CSV text with one row per response of every tool of the folder subtree. */
1678
+ csv(id, opts) {
1679
+ return this.client.request(
1680
+ "get",
1681
+ `/v1/folders/${encodeURIComponent(id)}/csv`,
1682
+ opts
1683
+ );
1684
+ }
1685
+ /**
1686
+ * PDF of the folder report (every woku, NPS, CSAT and CES tool of the folder
1687
+ * and its subfolders) with a breakdown per type on each native scale.
1688
+ * Returns the file bytes: write them to disk or send them as is.
1689
+ */
1690
+ pdf(id, params, opts) {
1691
+ return this.client.request(
1692
+ "get",
1693
+ `/v1/folders/${encodeURIComponent(id)}/pdf`,
1694
+ {
1695
+ ...opts,
1696
+ headers: { Accept: "application/pdf", ...opts?.headers },
1697
+ query: { ...params, ...opts?.query },
1698
+ binary: true
1699
+ }
1700
+ );
1701
+ }
1702
+ };
1703
+
1704
+ // src/resources/tools.ts
1705
+ var ToolsPage = class {
1706
+ constructor(response, fetchNext, fetchMoreFolders = () => Promise.reject(new RangeError("No more folders"))) {
1707
+ this.fetchNext = fetchNext;
1708
+ this.fetchMoreFolders = fetchMoreFolders;
1709
+ this.folders = response.folders;
1710
+ this.tools = response.tools;
1711
+ this.nextCursor = response.nextCursor;
1712
+ this.foldersNextCursor = response.foldersNextCursor ?? null;
1713
+ this.facets = response.facets;
1714
+ }
1715
+ hasMoreFolders() {
1716
+ return this.foldersNextCursor !== null;
1717
+ }
1718
+ /** The next page of folders ("see more"): a page with those folders and no tools. */
1719
+ getMoreFolders() {
1720
+ if (this.foldersNextCursor === null)
1721
+ throw new RangeError("No more folders");
1722
+ return this.fetchMoreFolders(this.foldersNextCursor);
1723
+ }
1724
+ hasNextPage() {
1725
+ return this.nextCursor !== null;
1726
+ }
1727
+ getNextPage() {
1728
+ if (this.nextCursor === null) throw new RangeError("No next page");
1729
+ return this.fetchNext(this.nextCursor);
1730
+ }
1731
+ async *iterPages() {
1732
+ yield this;
1733
+ if (this.hasNextPage()) yield* (await this.getNextPage()).iterPages();
1734
+ }
1735
+ async *[Symbol.asyncIterator]() {
1736
+ for await (const page of this.iterPages()) {
1737
+ for (const tool of page.tools) yield tool;
1738
+ }
1739
+ }
1740
+ };
1741
+ var Tools = class {
1742
+ constructor(client) {
1743
+ this.client = client;
1744
+ }
1745
+ /**
1746
+ * List one folder level (or search the company). Folders and tools of every
1747
+ * type come together; the first page also carries the folders and facets.
1748
+ */
1749
+ async list(params, opts) {
1750
+ const fetchPage = async (cursor, foldersCursor) => {
1751
+ const response = await this.client.request(
1752
+ "get",
1753
+ "/v1/tools",
1754
+ {
1755
+ ...opts,
1756
+ query: {
1757
+ ...params,
1758
+ types: params?.types?.join(","),
1759
+ ...cursor ? { cursor } : {},
1760
+ ...foldersCursor ? { foldersCursor } : {},
1761
+ ...opts?.query
1762
+ }
1763
+ }
1764
+ );
1765
+ return new ToolsPage(
1766
+ response,
1767
+ fetchPage,
1768
+ (next) => fetchPage(void 0, next)
1769
+ );
1770
+ };
1771
+ return fetchPage();
1772
+ }
1773
+ /**
1774
+ * Headline figures per type (woku stars, NPS score, CSAT satisfied %, CES
1775
+ * mean) for the company or one folder and its subfolders, in a period.
1776
+ * A type that fails reports `{ error: true }`; the others stay valid.
1777
+ */
1778
+ stats(params, opts) {
1779
+ return this.client.request("get", "/v1/tools/stats", {
1780
+ ...opts,
1781
+ query: { ...params, ...opts?.query }
1782
+ });
1783
+ }
1784
+ /**
1785
+ * Move up to 200 items of mixed types (`woku`, `nps`, `csat`, `ces`,
1786
+ * `folder`) into a folder, or to the root with `folderId: null`. Idempotent;
1787
+ * nothing moves if one item or the destination is not found.
1788
+ */
1789
+ move(body, opts) {
1790
+ return this.client.request("post", "/v1/tools/move", {
1791
+ ...opts,
1792
+ body
1793
+ });
1794
+ }
1795
+ };
1796
+
1797
+ // src/resources/journey-folders.ts
1798
+ var JourneyFolders = class {
1799
+ constructor(client) {
1800
+ this.client = client;
1801
+ }
1802
+ /** Whether the organization is on, running, and how much is still without a folder. */
1803
+ status(opts) {
1804
+ return this.client.request(
1805
+ "get",
1806
+ "/v1/journey-folders",
1807
+ opts
1808
+ );
1809
+ }
1810
+ /**
1811
+ * Switch the organization on and run the one-off pass in the background: tools
1812
+ * of existing journeys without a folder move into their moment folder, and
1813
+ * tools journeys create from now on are placed there. Tools that already have
1814
+ * a folder are never touched. Rejects with a conflict (409) while a pass is
1815
+ * already running; poll {@link status} for progress.
1816
+ */
1817
+ organize(opts) {
1818
+ return this.client.request(
1819
+ "post",
1820
+ "/v1/journey-folders/organize",
1821
+ opts
1822
+ );
1823
+ }
1824
+ };
1825
+
1509
1826
  // src/woku.ts
1510
1827
  var Woku = class {
1511
1828
  constructor(options) {
@@ -1525,15 +1842,19 @@ var Woku = class {
1525
1842
  this.actionPlans = new ActionPlans(this.client);
1526
1843
  this.actionPlanGroups = new ActionPlanGroups(this.client);
1527
1844
  this.tickets = new Tickets(this.client);
1845
+ this.followUps = new FollowUps(this.client);
1528
1846
  this.ticketDestinations = new TicketDestinations(this.client);
1529
1847
  this.dispatches = new Dispatches(this.client);
1530
1848
  this.reports = new Reports(this.client);
1531
1849
  this.company = new Company(this.client);
1532
1850
  this.journeys = new Journeys(this.client);
1851
+ this.folders = new Folders(this.client);
1852
+ this.tools = new Tools(this.client);
1853
+ this.journeyFolders = new JourneyFolders(this.client);
1533
1854
  this.quarantines = new Quarantines(this.client);
1534
1855
  }
1535
1856
  };
1536
1857
 
1537
- export { AuthenticationError, BadRequestError, ConflictError, InternalServerError, Journeys, Media, NotFoundError, Page, PayloadTooLargeError, PermissionDeniedError, RateLimitError, UnprocessableEntityError, Woku, WokuAPIError, WokuClient, WokuConnectionError, WokuError, WokuTimeoutError };
1858
+ export { AuthenticationError, BadRequestError, ConflictError, Folders, FollowUps, InternalServerError, JourneyFolders, Journeys, Media, NotFoundError, Page, PayloadTooLargeError, PermissionDeniedError, RateLimitError, Tools, ToolsPage, UnprocessableEntityError, Woku, WokuAPIError, WokuClient, WokuConnectionError, WokuError, WokuTimeoutError };
1538
1859
  //# sourceMappingURL=index.js.map
1539
1860
  //# sourceMappingURL=index.js.map