@sendly/node 3.8.2 → 3.10.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
@@ -1522,6 +1522,425 @@ var AccountResource = class {
1522
1522
  }
1523
1523
  };
1524
1524
 
1525
+ // src/resources/verify.ts
1526
+ var VerifyResource = class {
1527
+ http;
1528
+ constructor(http) {
1529
+ this.http = http;
1530
+ }
1531
+ /**
1532
+ * Send an OTP verification code
1533
+ *
1534
+ * @param request - Verification request details
1535
+ * @returns The created verification with ID and expiry
1536
+ *
1537
+ * @example
1538
+ * ```typescript
1539
+ * // Basic usage
1540
+ * const verification = await sendly.verify.send({
1541
+ * to: '+15551234567'
1542
+ * });
1543
+ *
1544
+ * // With custom options
1545
+ * const verification = await sendly.verify.send({
1546
+ * to: '+15551234567',
1547
+ * appName: 'MyApp',
1548
+ * codeLength: 8,
1549
+ * timeoutSecs: 600
1550
+ * });
1551
+ *
1552
+ * // In sandbox mode, the code is returned for testing
1553
+ * if (verification.sandboxCode) {
1554
+ * console.log('Test code:', verification.sandboxCode);
1555
+ * }
1556
+ * ```
1557
+ */
1558
+ async send(request) {
1559
+ validatePhoneNumber(request.to);
1560
+ const response = await this.http.request({
1561
+ method: "POST",
1562
+ path: "/verify",
1563
+ body: {
1564
+ to: request.to,
1565
+ ...request.templateId && { template_id: request.templateId },
1566
+ ...request.profileId && { profile_id: request.profileId },
1567
+ ...request.appName && { app_name: request.appName },
1568
+ ...request.timeoutSecs && { timeout_secs: request.timeoutSecs },
1569
+ ...request.codeLength && { code_length: request.codeLength }
1570
+ }
1571
+ });
1572
+ return {
1573
+ id: response.id,
1574
+ status: response.status,
1575
+ phone: response.phone,
1576
+ expiresAt: response.expires_at,
1577
+ sandbox: response.sandbox,
1578
+ sandboxCode: response.sandbox_code,
1579
+ message: response.message
1580
+ };
1581
+ }
1582
+ /**
1583
+ * Resend an OTP verification code
1584
+ *
1585
+ * @param id - Verification ID
1586
+ * @returns Updated verification with new expiry
1587
+ *
1588
+ * @example
1589
+ * ```typescript
1590
+ * // Resend when delivery failed or code expired
1591
+ * const result = await sendly.verify.resend('ver_xxx');
1592
+ * console.log('New code expires at:', result.expiresAt);
1593
+ * ```
1594
+ */
1595
+ async resend(id) {
1596
+ const response = await this.http.request({
1597
+ method: "POST",
1598
+ path: `/verify/${id}/resend`
1599
+ });
1600
+ return {
1601
+ id: response.id,
1602
+ status: response.status,
1603
+ phone: response.phone,
1604
+ expiresAt: response.expires_at,
1605
+ sandbox: response.sandbox,
1606
+ sandboxCode: response.sandbox_code,
1607
+ message: response.message
1608
+ };
1609
+ }
1610
+ /**
1611
+ * Check/verify an OTP code
1612
+ *
1613
+ * @param id - Verification ID
1614
+ * @param request - The code to verify
1615
+ * @returns Verification result
1616
+ *
1617
+ * @example
1618
+ * ```typescript
1619
+ * const result = await sendly.verify.check('ver_xxx', {
1620
+ * code: '123456'
1621
+ * });
1622
+ *
1623
+ * if (result.status === 'verified') {
1624
+ * // User is verified
1625
+ * } else if (result.remainingAttempts !== undefined) {
1626
+ * console.log(`Wrong code. ${result.remainingAttempts} attempts remaining`);
1627
+ * }
1628
+ * ```
1629
+ */
1630
+ async check(id, request) {
1631
+ const response = await this.http.request({
1632
+ method: "POST",
1633
+ path: `/verify/${id}/check`,
1634
+ body: { code: request.code }
1635
+ });
1636
+ return {
1637
+ id: response.id,
1638
+ status: response.status,
1639
+ phone: response.phone,
1640
+ verifiedAt: response.verified_at,
1641
+ remainingAttempts: response.remaining_attempts
1642
+ };
1643
+ }
1644
+ /**
1645
+ * Get a verification by ID
1646
+ *
1647
+ * @param id - Verification ID
1648
+ * @returns The verification record
1649
+ *
1650
+ * @example
1651
+ * ```typescript
1652
+ * const verification = await sendly.verify.get('ver_xxx');
1653
+ * console.log(verification.status); // 'pending', 'verified', 'expired', etc.
1654
+ * ```
1655
+ */
1656
+ async get(id) {
1657
+ const response = await this.http.request({
1658
+ method: "GET",
1659
+ path: `/verify/${id}`
1660
+ });
1661
+ return {
1662
+ id: response.id,
1663
+ status: response.status,
1664
+ phone: response.phone,
1665
+ deliveryStatus: response.delivery_status,
1666
+ attempts: response.attempts,
1667
+ maxAttempts: response.max_attempts,
1668
+ expiresAt: response.expires_at,
1669
+ verifiedAt: response.verified_at,
1670
+ createdAt: response.created_at,
1671
+ sandbox: response.sandbox,
1672
+ appName: response.app_name,
1673
+ templateId: response.template_id,
1674
+ profileId: response.profile_id
1675
+ };
1676
+ }
1677
+ /**
1678
+ * List recent verifications
1679
+ *
1680
+ * @param options - Filter and pagination options
1681
+ * @returns List of verifications
1682
+ *
1683
+ * @example
1684
+ * ```typescript
1685
+ * // List recent verifications
1686
+ * const { verifications } = await sendly.verify.list({ limit: 10 });
1687
+ *
1688
+ * // Filter by status
1689
+ * const { verifications } = await sendly.verify.list({
1690
+ * status: 'verified'
1691
+ * });
1692
+ * ```
1693
+ */
1694
+ async list(options = {}) {
1695
+ const response = await this.http.request({
1696
+ method: "GET",
1697
+ path: "/verify",
1698
+ query: {
1699
+ ...options.limit && { limit: options.limit },
1700
+ ...options.status && { status: options.status }
1701
+ }
1702
+ });
1703
+ return {
1704
+ verifications: response.verifications.map((v) => ({
1705
+ id: v.id,
1706
+ status: v.status,
1707
+ phone: v.phone,
1708
+ deliveryStatus: v.delivery_status,
1709
+ attempts: v.attempts,
1710
+ maxAttempts: v.max_attempts,
1711
+ expiresAt: v.expires_at,
1712
+ verifiedAt: v.verified_at,
1713
+ createdAt: v.created_at,
1714
+ sandbox: v.sandbox,
1715
+ appName: v.app_name,
1716
+ templateId: v.template_id,
1717
+ profileId: v.profile_id
1718
+ })),
1719
+ pagination: {
1720
+ limit: response.pagination.limit,
1721
+ hasMore: response.pagination.has_more
1722
+ }
1723
+ };
1724
+ }
1725
+ };
1726
+
1727
+ // src/resources/templates.ts
1728
+ var TemplatesResource = class {
1729
+ http;
1730
+ constructor(http) {
1731
+ this.http = http;
1732
+ }
1733
+ /**
1734
+ * List all templates (presets + custom)
1735
+ *
1736
+ * @returns List of templates
1737
+ *
1738
+ * @example
1739
+ * ```typescript
1740
+ * const { templates } = await sendly.templates.list();
1741
+ * templates.forEach(t => {
1742
+ * console.log(`${t.name}: ${t.isPreset ? 'preset' : t.status}`);
1743
+ * });
1744
+ * ```
1745
+ */
1746
+ async list() {
1747
+ const response = await this.http.request({
1748
+ method: "GET",
1749
+ path: "/templates"
1750
+ });
1751
+ return {
1752
+ templates: response.templates.map((t) => this.transformTemplate(t))
1753
+ };
1754
+ }
1755
+ /**
1756
+ * List preset templates only (no auth required)
1757
+ *
1758
+ * @returns List of preset templates
1759
+ *
1760
+ * @example
1761
+ * ```typescript
1762
+ * const { templates } = await sendly.templates.presets();
1763
+ * // Returns: otp, 2fa, login, signup, reset, generic
1764
+ * ```
1765
+ */
1766
+ async presets() {
1767
+ const response = await this.http.request({
1768
+ method: "GET",
1769
+ path: "/templates/presets"
1770
+ });
1771
+ return {
1772
+ templates: response.templates.map((t) => this.transformTemplate(t))
1773
+ };
1774
+ }
1775
+ /**
1776
+ * Get a template by ID
1777
+ *
1778
+ * @param id - Template ID
1779
+ * @returns The template
1780
+ *
1781
+ * @example
1782
+ * ```typescript
1783
+ * const template = await sendly.templates.get('tpl_preset_otp');
1784
+ * console.log(template.text); // "Your {{app_name}} code is {{code}}"
1785
+ * ```
1786
+ */
1787
+ async get(id) {
1788
+ const response = await this.http.request({
1789
+ method: "GET",
1790
+ path: `/templates/${id}`
1791
+ });
1792
+ return this.transformTemplate(response);
1793
+ }
1794
+ /**
1795
+ * Create a new template
1796
+ *
1797
+ * @param request - Template details
1798
+ * @returns The created template (as draft)
1799
+ *
1800
+ * @example
1801
+ * ```typescript
1802
+ * const template = await sendly.templates.create({
1803
+ * name: 'Password Reset',
1804
+ * text: '{{app_name}}: Your password reset code is {{code}}. Valid for 10 minutes.'
1805
+ * });
1806
+ *
1807
+ * // Template is created as draft, publish when ready
1808
+ * await sendly.templates.publish(template.id);
1809
+ * ```
1810
+ */
1811
+ async create(request) {
1812
+ const response = await this.http.request({
1813
+ method: "POST",
1814
+ path: "/templates",
1815
+ body: {
1816
+ name: request.name,
1817
+ text: request.text
1818
+ }
1819
+ });
1820
+ return this.transformTemplate(response);
1821
+ }
1822
+ /**
1823
+ * Update a template
1824
+ *
1825
+ * Note: Updating a published template creates a new draft version.
1826
+ *
1827
+ * @param id - Template ID
1828
+ * @param request - Fields to update
1829
+ * @returns The updated template
1830
+ *
1831
+ * @example
1832
+ * ```typescript
1833
+ * const template = await sendly.templates.update('tpl_xxx', {
1834
+ * text: 'New message text with {{code}}'
1835
+ * });
1836
+ * ```
1837
+ */
1838
+ async update(id, request) {
1839
+ const response = await this.http.request({
1840
+ method: "PATCH",
1841
+ path: `/templates/${id}`,
1842
+ body: {
1843
+ ...request.name && { name: request.name },
1844
+ ...request.text && { text: request.text }
1845
+ }
1846
+ });
1847
+ return this.transformTemplate(response);
1848
+ }
1849
+ /**
1850
+ * Publish a draft template
1851
+ *
1852
+ * Published templates are locked and can be used with the Verify API.
1853
+ *
1854
+ * @param id - Template ID
1855
+ * @returns The published template
1856
+ *
1857
+ * @example
1858
+ * ```typescript
1859
+ * const template = await sendly.templates.publish('tpl_xxx');
1860
+ * console.log(template.status); // 'published'
1861
+ * ```
1862
+ */
1863
+ async publish(id) {
1864
+ const response = await this.http.request({
1865
+ method: "POST",
1866
+ path: `/templates/${id}/publish`
1867
+ });
1868
+ return this.transformTemplate(response);
1869
+ }
1870
+ /**
1871
+ * Preview a template with sample values
1872
+ *
1873
+ * @param id - Template ID
1874
+ * @param variables - Optional custom variable values
1875
+ * @returns Template with interpolated preview text
1876
+ *
1877
+ * @example
1878
+ * ```typescript
1879
+ * const preview = await sendly.templates.preview('tpl_preset_otp', {
1880
+ * app_name: 'MyApp',
1881
+ * code: '123456'
1882
+ * });
1883
+ * console.log(preview.previewText);
1884
+ * // "Your MyApp code is 123456"
1885
+ * ```
1886
+ */
1887
+ async preview(id, variables) {
1888
+ const response = await this.http.request({
1889
+ method: "POST",
1890
+ path: `/templates/${id}/preview`,
1891
+ body: variables ? { variables } : {}
1892
+ });
1893
+ return {
1894
+ id: response.id,
1895
+ name: response.name,
1896
+ originalText: response.original_text,
1897
+ previewText: response.preview_text,
1898
+ variables: response.variables.map((v) => ({
1899
+ key: v.key,
1900
+ type: v.type,
1901
+ fallback: v.fallback
1902
+ }))
1903
+ };
1904
+ }
1905
+ /**
1906
+ * Delete a template
1907
+ *
1908
+ * Note: Preset templates cannot be deleted.
1909
+ *
1910
+ * @param id - Template ID
1911
+ *
1912
+ * @example
1913
+ * ```typescript
1914
+ * await sendly.templates.delete('tpl_xxx');
1915
+ * ```
1916
+ */
1917
+ async delete(id) {
1918
+ await this.http.request({
1919
+ method: "DELETE",
1920
+ path: `/templates/${id}`
1921
+ });
1922
+ }
1923
+ transformTemplate(t) {
1924
+ return {
1925
+ id: t.id,
1926
+ name: t.name,
1927
+ text: t.text,
1928
+ variables: t.variables.map((v) => ({
1929
+ key: v.key,
1930
+ type: v.type,
1931
+ fallback: v.fallback
1932
+ })),
1933
+ isPreset: t.is_preset,
1934
+ presetSlug: t.preset_slug,
1935
+ status: t.status,
1936
+ version: t.version,
1937
+ publishedAt: t.published_at,
1938
+ createdAt: t.created_at,
1939
+ updatedAt: t.updated_at
1940
+ };
1941
+ }
1942
+ };
1943
+
1525
1944
  // src/client.ts
1526
1945
  var DEFAULT_BASE_URL2 = "https://sendly.live/api/v1";
1527
1946
  var DEFAULT_TIMEOUT2 = 3e4;
@@ -1578,6 +1997,47 @@ var Sendly = class {
1578
1997
  * ```
1579
1998
  */
1580
1999
  account;
2000
+ /**
2001
+ * Verify API resource - OTP verification
2002
+ *
2003
+ * @example
2004
+ * ```typescript
2005
+ * // Send an OTP
2006
+ * const verification = await sendly.verify.send({
2007
+ * to: '+15551234567',
2008
+ * appName: 'MyApp'
2009
+ * });
2010
+ *
2011
+ * // Check the OTP (user enters code)
2012
+ * const result = await sendly.verify.check(verification.id, {
2013
+ * code: '123456'
2014
+ * });
2015
+ *
2016
+ * if (result.status === 'verified') {
2017
+ * console.log('Phone verified!');
2018
+ * }
2019
+ * ```
2020
+ */
2021
+ verify;
2022
+ /**
2023
+ * Templates API resource - SMS template management
2024
+ *
2025
+ * @example
2026
+ * ```typescript
2027
+ * // List preset templates
2028
+ * const { templates } = await sendly.templates.presets();
2029
+ *
2030
+ * // Create a custom template
2031
+ * const template = await sendly.templates.create({
2032
+ * name: 'My OTP',
2033
+ * text: 'Your {{app_name}} code is {{code}}'
2034
+ * });
2035
+ *
2036
+ * // Publish for use
2037
+ * await sendly.templates.publish(template.id);
2038
+ * ```
2039
+ */
2040
+ templates;
1581
2041
  http;
1582
2042
  config;
1583
2043
  /**
@@ -1610,6 +2070,8 @@ var Sendly = class {
1610
2070
  this.messages = new MessagesResource(this.http);
1611
2071
  this.webhooks = new WebhooksResource(this.http);
1612
2072
  this.account = new AccountResource(this.http);
2073
+ this.verify = new VerifyResource(this.http);
2074
+ this.templates = new TemplatesResource(this.http);
1613
2075
  }
1614
2076
  /**
1615
2077
  * Check if the client is using a test API key