@sendly/node 3.8.1 → 3.9.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,397 @@ 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
+ * Check/verify an OTP code
1584
+ *
1585
+ * @param id - Verification ID
1586
+ * @param request - The code to verify
1587
+ * @returns Verification result
1588
+ *
1589
+ * @example
1590
+ * ```typescript
1591
+ * const result = await sendly.verify.check('ver_xxx', {
1592
+ * code: '123456'
1593
+ * });
1594
+ *
1595
+ * if (result.status === 'verified') {
1596
+ * // User is verified
1597
+ * } else if (result.remainingAttempts !== undefined) {
1598
+ * console.log(`Wrong code. ${result.remainingAttempts} attempts remaining`);
1599
+ * }
1600
+ * ```
1601
+ */
1602
+ async check(id, request) {
1603
+ const response = await this.http.request({
1604
+ method: "POST",
1605
+ path: `/verify/${id}/check`,
1606
+ body: { code: request.code }
1607
+ });
1608
+ return {
1609
+ id: response.id,
1610
+ status: response.status,
1611
+ phone: response.phone,
1612
+ verifiedAt: response.verified_at,
1613
+ remainingAttempts: response.remaining_attempts
1614
+ };
1615
+ }
1616
+ /**
1617
+ * Get a verification by ID
1618
+ *
1619
+ * @param id - Verification ID
1620
+ * @returns The verification record
1621
+ *
1622
+ * @example
1623
+ * ```typescript
1624
+ * const verification = await sendly.verify.get('ver_xxx');
1625
+ * console.log(verification.status); // 'pending', 'verified', 'expired', etc.
1626
+ * ```
1627
+ */
1628
+ async get(id) {
1629
+ const response = await this.http.request({
1630
+ method: "GET",
1631
+ path: `/verify/${id}`
1632
+ });
1633
+ return {
1634
+ id: response.id,
1635
+ status: response.status,
1636
+ phone: response.phone,
1637
+ deliveryStatus: response.delivery_status,
1638
+ attempts: response.attempts,
1639
+ maxAttempts: response.max_attempts,
1640
+ expiresAt: response.expires_at,
1641
+ verifiedAt: response.verified_at,
1642
+ createdAt: response.created_at,
1643
+ sandbox: response.sandbox,
1644
+ appName: response.app_name,
1645
+ templateId: response.template_id,
1646
+ profileId: response.profile_id
1647
+ };
1648
+ }
1649
+ /**
1650
+ * List recent verifications
1651
+ *
1652
+ * @param options - Filter and pagination options
1653
+ * @returns List of verifications
1654
+ *
1655
+ * @example
1656
+ * ```typescript
1657
+ * // List recent verifications
1658
+ * const { verifications } = await sendly.verify.list({ limit: 10 });
1659
+ *
1660
+ * // Filter by status
1661
+ * const { verifications } = await sendly.verify.list({
1662
+ * status: 'verified'
1663
+ * });
1664
+ * ```
1665
+ */
1666
+ async list(options = {}) {
1667
+ const response = await this.http.request({
1668
+ method: "GET",
1669
+ path: "/verify",
1670
+ query: {
1671
+ ...options.limit && { limit: options.limit },
1672
+ ...options.status && { status: options.status }
1673
+ }
1674
+ });
1675
+ return {
1676
+ verifications: response.verifications.map((v) => ({
1677
+ id: v.id,
1678
+ status: v.status,
1679
+ phone: v.phone,
1680
+ deliveryStatus: v.delivery_status,
1681
+ attempts: v.attempts,
1682
+ maxAttempts: v.max_attempts,
1683
+ expiresAt: v.expires_at,
1684
+ verifiedAt: v.verified_at,
1685
+ createdAt: v.created_at,
1686
+ sandbox: v.sandbox,
1687
+ appName: v.app_name,
1688
+ templateId: v.template_id,
1689
+ profileId: v.profile_id
1690
+ })),
1691
+ pagination: {
1692
+ limit: response.pagination.limit,
1693
+ hasMore: response.pagination.has_more
1694
+ }
1695
+ };
1696
+ }
1697
+ };
1698
+
1699
+ // src/resources/templates.ts
1700
+ var TemplatesResource = class {
1701
+ http;
1702
+ constructor(http) {
1703
+ this.http = http;
1704
+ }
1705
+ /**
1706
+ * List all templates (presets + custom)
1707
+ *
1708
+ * @returns List of templates
1709
+ *
1710
+ * @example
1711
+ * ```typescript
1712
+ * const { templates } = await sendly.templates.list();
1713
+ * templates.forEach(t => {
1714
+ * console.log(`${t.name}: ${t.isPreset ? 'preset' : t.status}`);
1715
+ * });
1716
+ * ```
1717
+ */
1718
+ async list() {
1719
+ const response = await this.http.request({
1720
+ method: "GET",
1721
+ path: "/templates"
1722
+ });
1723
+ return {
1724
+ templates: response.templates.map((t) => this.transformTemplate(t))
1725
+ };
1726
+ }
1727
+ /**
1728
+ * List preset templates only (no auth required)
1729
+ *
1730
+ * @returns List of preset templates
1731
+ *
1732
+ * @example
1733
+ * ```typescript
1734
+ * const { templates } = await sendly.templates.presets();
1735
+ * // Returns: otp, 2fa, login, signup, reset, generic
1736
+ * ```
1737
+ */
1738
+ async presets() {
1739
+ const response = await this.http.request({
1740
+ method: "GET",
1741
+ path: "/templates/presets"
1742
+ });
1743
+ return {
1744
+ templates: response.templates.map((t) => this.transformTemplate(t))
1745
+ };
1746
+ }
1747
+ /**
1748
+ * Get a template by ID
1749
+ *
1750
+ * @param id - Template ID
1751
+ * @returns The template
1752
+ *
1753
+ * @example
1754
+ * ```typescript
1755
+ * const template = await sendly.templates.get('tpl_preset_otp');
1756
+ * console.log(template.text); // "Your {{app_name}} code is {{code}}"
1757
+ * ```
1758
+ */
1759
+ async get(id) {
1760
+ const response = await this.http.request({
1761
+ method: "GET",
1762
+ path: `/templates/${id}`
1763
+ });
1764
+ return this.transformTemplate(response);
1765
+ }
1766
+ /**
1767
+ * Create a new template
1768
+ *
1769
+ * @param request - Template details
1770
+ * @returns The created template (as draft)
1771
+ *
1772
+ * @example
1773
+ * ```typescript
1774
+ * const template = await sendly.templates.create({
1775
+ * name: 'Password Reset',
1776
+ * text: '{{app_name}}: Your password reset code is {{code}}. Valid for 10 minutes.'
1777
+ * });
1778
+ *
1779
+ * // Template is created as draft, publish when ready
1780
+ * await sendly.templates.publish(template.id);
1781
+ * ```
1782
+ */
1783
+ async create(request) {
1784
+ const response = await this.http.request({
1785
+ method: "POST",
1786
+ path: "/templates",
1787
+ body: {
1788
+ name: request.name,
1789
+ text: request.text
1790
+ }
1791
+ });
1792
+ return this.transformTemplate(response);
1793
+ }
1794
+ /**
1795
+ * Update a template
1796
+ *
1797
+ * Note: Updating a published template creates a new draft version.
1798
+ *
1799
+ * @param id - Template ID
1800
+ * @param request - Fields to update
1801
+ * @returns The updated template
1802
+ *
1803
+ * @example
1804
+ * ```typescript
1805
+ * const template = await sendly.templates.update('tpl_xxx', {
1806
+ * text: 'New message text with {{code}}'
1807
+ * });
1808
+ * ```
1809
+ */
1810
+ async update(id, request) {
1811
+ const response = await this.http.request({
1812
+ method: "PATCH",
1813
+ path: `/templates/${id}`,
1814
+ body: {
1815
+ ...request.name && { name: request.name },
1816
+ ...request.text && { text: request.text }
1817
+ }
1818
+ });
1819
+ return this.transformTemplate(response);
1820
+ }
1821
+ /**
1822
+ * Publish a draft template
1823
+ *
1824
+ * Published templates are locked and can be used with the Verify API.
1825
+ *
1826
+ * @param id - Template ID
1827
+ * @returns The published template
1828
+ *
1829
+ * @example
1830
+ * ```typescript
1831
+ * const template = await sendly.templates.publish('tpl_xxx');
1832
+ * console.log(template.status); // 'published'
1833
+ * ```
1834
+ */
1835
+ async publish(id) {
1836
+ const response = await this.http.request({
1837
+ method: "POST",
1838
+ path: `/templates/${id}/publish`
1839
+ });
1840
+ return this.transformTemplate(response);
1841
+ }
1842
+ /**
1843
+ * Preview a template with sample values
1844
+ *
1845
+ * @param id - Template ID
1846
+ * @param variables - Optional custom variable values
1847
+ * @returns Template with interpolated preview text
1848
+ *
1849
+ * @example
1850
+ * ```typescript
1851
+ * const preview = await sendly.templates.preview('tpl_preset_otp', {
1852
+ * app_name: 'MyApp',
1853
+ * code: '123456'
1854
+ * });
1855
+ * console.log(preview.previewText);
1856
+ * // "Your MyApp code is 123456"
1857
+ * ```
1858
+ */
1859
+ async preview(id, variables) {
1860
+ const response = await this.http.request({
1861
+ method: "POST",
1862
+ path: `/templates/${id}/preview`,
1863
+ body: variables ? { variables } : {}
1864
+ });
1865
+ return {
1866
+ id: response.id,
1867
+ name: response.name,
1868
+ originalText: response.original_text,
1869
+ previewText: response.preview_text,
1870
+ variables: response.variables.map((v) => ({
1871
+ key: v.key,
1872
+ type: v.type,
1873
+ fallback: v.fallback
1874
+ }))
1875
+ };
1876
+ }
1877
+ /**
1878
+ * Delete a template
1879
+ *
1880
+ * Note: Preset templates cannot be deleted.
1881
+ *
1882
+ * @param id - Template ID
1883
+ *
1884
+ * @example
1885
+ * ```typescript
1886
+ * await sendly.templates.delete('tpl_xxx');
1887
+ * ```
1888
+ */
1889
+ async delete(id) {
1890
+ await this.http.request({
1891
+ method: "DELETE",
1892
+ path: `/templates/${id}`
1893
+ });
1894
+ }
1895
+ transformTemplate(t) {
1896
+ return {
1897
+ id: t.id,
1898
+ name: t.name,
1899
+ text: t.text,
1900
+ variables: t.variables.map((v) => ({
1901
+ key: v.key,
1902
+ type: v.type,
1903
+ fallback: v.fallback
1904
+ })),
1905
+ isPreset: t.is_preset,
1906
+ presetSlug: t.preset_slug,
1907
+ status: t.status,
1908
+ version: t.version,
1909
+ publishedAt: t.published_at,
1910
+ createdAt: t.created_at,
1911
+ updatedAt: t.updated_at
1912
+ };
1913
+ }
1914
+ };
1915
+
1525
1916
  // src/client.ts
1526
1917
  var DEFAULT_BASE_URL2 = "https://sendly.live/api/v1";
1527
1918
  var DEFAULT_TIMEOUT2 = 3e4;
@@ -1578,6 +1969,47 @@ var Sendly = class {
1578
1969
  * ```
1579
1970
  */
1580
1971
  account;
1972
+ /**
1973
+ * Verify API resource - OTP verification
1974
+ *
1975
+ * @example
1976
+ * ```typescript
1977
+ * // Send an OTP
1978
+ * const verification = await sendly.verify.send({
1979
+ * to: '+15551234567',
1980
+ * appName: 'MyApp'
1981
+ * });
1982
+ *
1983
+ * // Check the OTP (user enters code)
1984
+ * const result = await sendly.verify.check(verification.id, {
1985
+ * code: '123456'
1986
+ * });
1987
+ *
1988
+ * if (result.status === 'verified') {
1989
+ * console.log('Phone verified!');
1990
+ * }
1991
+ * ```
1992
+ */
1993
+ verify;
1994
+ /**
1995
+ * Templates API resource - SMS template management
1996
+ *
1997
+ * @example
1998
+ * ```typescript
1999
+ * // List preset templates
2000
+ * const { templates } = await sendly.templates.presets();
2001
+ *
2002
+ * // Create a custom template
2003
+ * const template = await sendly.templates.create({
2004
+ * name: 'My OTP',
2005
+ * text: 'Your {{app_name}} code is {{code}}'
2006
+ * });
2007
+ *
2008
+ * // Publish for use
2009
+ * await sendly.templates.publish(template.id);
2010
+ * ```
2011
+ */
2012
+ templates;
1581
2013
  http;
1582
2014
  config;
1583
2015
  /**
@@ -1610,6 +2042,8 @@ var Sendly = class {
1610
2042
  this.messages = new MessagesResource(this.http);
1611
2043
  this.webhooks = new WebhooksResource(this.http);
1612
2044
  this.account = new AccountResource(this.http);
2045
+ this.verify = new VerifyResource(this.http);
2046
+ this.templates = new TemplatesResource(this.http);
1613
2047
  }
1614
2048
  /**
1615
2049
  * Check if the client is using a test API key