@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.mjs CHANGED
@@ -1462,6 +1462,425 @@ var AccountResource = class {
1462
1462
  }
1463
1463
  };
1464
1464
 
1465
+ // src/resources/verify.ts
1466
+ var VerifyResource = class {
1467
+ http;
1468
+ constructor(http) {
1469
+ this.http = http;
1470
+ }
1471
+ /**
1472
+ * Send an OTP verification code
1473
+ *
1474
+ * @param request - Verification request details
1475
+ * @returns The created verification with ID and expiry
1476
+ *
1477
+ * @example
1478
+ * ```typescript
1479
+ * // Basic usage
1480
+ * const verification = await sendly.verify.send({
1481
+ * to: '+15551234567'
1482
+ * });
1483
+ *
1484
+ * // With custom options
1485
+ * const verification = await sendly.verify.send({
1486
+ * to: '+15551234567',
1487
+ * appName: 'MyApp',
1488
+ * codeLength: 8,
1489
+ * timeoutSecs: 600
1490
+ * });
1491
+ *
1492
+ * // In sandbox mode, the code is returned for testing
1493
+ * if (verification.sandboxCode) {
1494
+ * console.log('Test code:', verification.sandboxCode);
1495
+ * }
1496
+ * ```
1497
+ */
1498
+ async send(request) {
1499
+ validatePhoneNumber(request.to);
1500
+ const response = await this.http.request({
1501
+ method: "POST",
1502
+ path: "/verify",
1503
+ body: {
1504
+ to: request.to,
1505
+ ...request.templateId && { template_id: request.templateId },
1506
+ ...request.profileId && { profile_id: request.profileId },
1507
+ ...request.appName && { app_name: request.appName },
1508
+ ...request.timeoutSecs && { timeout_secs: request.timeoutSecs },
1509
+ ...request.codeLength && { code_length: request.codeLength }
1510
+ }
1511
+ });
1512
+ return {
1513
+ id: response.id,
1514
+ status: response.status,
1515
+ phone: response.phone,
1516
+ expiresAt: response.expires_at,
1517
+ sandbox: response.sandbox,
1518
+ sandboxCode: response.sandbox_code,
1519
+ message: response.message
1520
+ };
1521
+ }
1522
+ /**
1523
+ * Resend an OTP verification code
1524
+ *
1525
+ * @param id - Verification ID
1526
+ * @returns Updated verification with new expiry
1527
+ *
1528
+ * @example
1529
+ * ```typescript
1530
+ * // Resend when delivery failed or code expired
1531
+ * const result = await sendly.verify.resend('ver_xxx');
1532
+ * console.log('New code expires at:', result.expiresAt);
1533
+ * ```
1534
+ */
1535
+ async resend(id) {
1536
+ const response = await this.http.request({
1537
+ method: "POST",
1538
+ path: `/verify/${id}/resend`
1539
+ });
1540
+ return {
1541
+ id: response.id,
1542
+ status: response.status,
1543
+ phone: response.phone,
1544
+ expiresAt: response.expires_at,
1545
+ sandbox: response.sandbox,
1546
+ sandboxCode: response.sandbox_code,
1547
+ message: response.message
1548
+ };
1549
+ }
1550
+ /**
1551
+ * Check/verify an OTP code
1552
+ *
1553
+ * @param id - Verification ID
1554
+ * @param request - The code to verify
1555
+ * @returns Verification result
1556
+ *
1557
+ * @example
1558
+ * ```typescript
1559
+ * const result = await sendly.verify.check('ver_xxx', {
1560
+ * code: '123456'
1561
+ * });
1562
+ *
1563
+ * if (result.status === 'verified') {
1564
+ * // User is verified
1565
+ * } else if (result.remainingAttempts !== undefined) {
1566
+ * console.log(`Wrong code. ${result.remainingAttempts} attempts remaining`);
1567
+ * }
1568
+ * ```
1569
+ */
1570
+ async check(id, request) {
1571
+ const response = await this.http.request({
1572
+ method: "POST",
1573
+ path: `/verify/${id}/check`,
1574
+ body: { code: request.code }
1575
+ });
1576
+ return {
1577
+ id: response.id,
1578
+ status: response.status,
1579
+ phone: response.phone,
1580
+ verifiedAt: response.verified_at,
1581
+ remainingAttempts: response.remaining_attempts
1582
+ };
1583
+ }
1584
+ /**
1585
+ * Get a verification by ID
1586
+ *
1587
+ * @param id - Verification ID
1588
+ * @returns The verification record
1589
+ *
1590
+ * @example
1591
+ * ```typescript
1592
+ * const verification = await sendly.verify.get('ver_xxx');
1593
+ * console.log(verification.status); // 'pending', 'verified', 'expired', etc.
1594
+ * ```
1595
+ */
1596
+ async get(id) {
1597
+ const response = await this.http.request({
1598
+ method: "GET",
1599
+ path: `/verify/${id}`
1600
+ });
1601
+ return {
1602
+ id: response.id,
1603
+ status: response.status,
1604
+ phone: response.phone,
1605
+ deliveryStatus: response.delivery_status,
1606
+ attempts: response.attempts,
1607
+ maxAttempts: response.max_attempts,
1608
+ expiresAt: response.expires_at,
1609
+ verifiedAt: response.verified_at,
1610
+ createdAt: response.created_at,
1611
+ sandbox: response.sandbox,
1612
+ appName: response.app_name,
1613
+ templateId: response.template_id,
1614
+ profileId: response.profile_id
1615
+ };
1616
+ }
1617
+ /**
1618
+ * List recent verifications
1619
+ *
1620
+ * @param options - Filter and pagination options
1621
+ * @returns List of verifications
1622
+ *
1623
+ * @example
1624
+ * ```typescript
1625
+ * // List recent verifications
1626
+ * const { verifications } = await sendly.verify.list({ limit: 10 });
1627
+ *
1628
+ * // Filter by status
1629
+ * const { verifications } = await sendly.verify.list({
1630
+ * status: 'verified'
1631
+ * });
1632
+ * ```
1633
+ */
1634
+ async list(options = {}) {
1635
+ const response = await this.http.request({
1636
+ method: "GET",
1637
+ path: "/verify",
1638
+ query: {
1639
+ ...options.limit && { limit: options.limit },
1640
+ ...options.status && { status: options.status }
1641
+ }
1642
+ });
1643
+ return {
1644
+ verifications: response.verifications.map((v) => ({
1645
+ id: v.id,
1646
+ status: v.status,
1647
+ phone: v.phone,
1648
+ deliveryStatus: v.delivery_status,
1649
+ attempts: v.attempts,
1650
+ maxAttempts: v.max_attempts,
1651
+ expiresAt: v.expires_at,
1652
+ verifiedAt: v.verified_at,
1653
+ createdAt: v.created_at,
1654
+ sandbox: v.sandbox,
1655
+ appName: v.app_name,
1656
+ templateId: v.template_id,
1657
+ profileId: v.profile_id
1658
+ })),
1659
+ pagination: {
1660
+ limit: response.pagination.limit,
1661
+ hasMore: response.pagination.has_more
1662
+ }
1663
+ };
1664
+ }
1665
+ };
1666
+
1667
+ // src/resources/templates.ts
1668
+ var TemplatesResource = class {
1669
+ http;
1670
+ constructor(http) {
1671
+ this.http = http;
1672
+ }
1673
+ /**
1674
+ * List all templates (presets + custom)
1675
+ *
1676
+ * @returns List of templates
1677
+ *
1678
+ * @example
1679
+ * ```typescript
1680
+ * const { templates } = await sendly.templates.list();
1681
+ * templates.forEach(t => {
1682
+ * console.log(`${t.name}: ${t.isPreset ? 'preset' : t.status}`);
1683
+ * });
1684
+ * ```
1685
+ */
1686
+ async list() {
1687
+ const response = await this.http.request({
1688
+ method: "GET",
1689
+ path: "/templates"
1690
+ });
1691
+ return {
1692
+ templates: response.templates.map((t) => this.transformTemplate(t))
1693
+ };
1694
+ }
1695
+ /**
1696
+ * List preset templates only (no auth required)
1697
+ *
1698
+ * @returns List of preset templates
1699
+ *
1700
+ * @example
1701
+ * ```typescript
1702
+ * const { templates } = await sendly.templates.presets();
1703
+ * // Returns: otp, 2fa, login, signup, reset, generic
1704
+ * ```
1705
+ */
1706
+ async presets() {
1707
+ const response = await this.http.request({
1708
+ method: "GET",
1709
+ path: "/templates/presets"
1710
+ });
1711
+ return {
1712
+ templates: response.templates.map((t) => this.transformTemplate(t))
1713
+ };
1714
+ }
1715
+ /**
1716
+ * Get a template by ID
1717
+ *
1718
+ * @param id - Template ID
1719
+ * @returns The template
1720
+ *
1721
+ * @example
1722
+ * ```typescript
1723
+ * const template = await sendly.templates.get('tpl_preset_otp');
1724
+ * console.log(template.text); // "Your {{app_name}} code is {{code}}"
1725
+ * ```
1726
+ */
1727
+ async get(id) {
1728
+ const response = await this.http.request({
1729
+ method: "GET",
1730
+ path: `/templates/${id}`
1731
+ });
1732
+ return this.transformTemplate(response);
1733
+ }
1734
+ /**
1735
+ * Create a new template
1736
+ *
1737
+ * @param request - Template details
1738
+ * @returns The created template (as draft)
1739
+ *
1740
+ * @example
1741
+ * ```typescript
1742
+ * const template = await sendly.templates.create({
1743
+ * name: 'Password Reset',
1744
+ * text: '{{app_name}}: Your password reset code is {{code}}. Valid for 10 minutes.'
1745
+ * });
1746
+ *
1747
+ * // Template is created as draft, publish when ready
1748
+ * await sendly.templates.publish(template.id);
1749
+ * ```
1750
+ */
1751
+ async create(request) {
1752
+ const response = await this.http.request({
1753
+ method: "POST",
1754
+ path: "/templates",
1755
+ body: {
1756
+ name: request.name,
1757
+ text: request.text
1758
+ }
1759
+ });
1760
+ return this.transformTemplate(response);
1761
+ }
1762
+ /**
1763
+ * Update a template
1764
+ *
1765
+ * Note: Updating a published template creates a new draft version.
1766
+ *
1767
+ * @param id - Template ID
1768
+ * @param request - Fields to update
1769
+ * @returns The updated template
1770
+ *
1771
+ * @example
1772
+ * ```typescript
1773
+ * const template = await sendly.templates.update('tpl_xxx', {
1774
+ * text: 'New message text with {{code}}'
1775
+ * });
1776
+ * ```
1777
+ */
1778
+ async update(id, request) {
1779
+ const response = await this.http.request({
1780
+ method: "PATCH",
1781
+ path: `/templates/${id}`,
1782
+ body: {
1783
+ ...request.name && { name: request.name },
1784
+ ...request.text && { text: request.text }
1785
+ }
1786
+ });
1787
+ return this.transformTemplate(response);
1788
+ }
1789
+ /**
1790
+ * Publish a draft template
1791
+ *
1792
+ * Published templates are locked and can be used with the Verify API.
1793
+ *
1794
+ * @param id - Template ID
1795
+ * @returns The published template
1796
+ *
1797
+ * @example
1798
+ * ```typescript
1799
+ * const template = await sendly.templates.publish('tpl_xxx');
1800
+ * console.log(template.status); // 'published'
1801
+ * ```
1802
+ */
1803
+ async publish(id) {
1804
+ const response = await this.http.request({
1805
+ method: "POST",
1806
+ path: `/templates/${id}/publish`
1807
+ });
1808
+ return this.transformTemplate(response);
1809
+ }
1810
+ /**
1811
+ * Preview a template with sample values
1812
+ *
1813
+ * @param id - Template ID
1814
+ * @param variables - Optional custom variable values
1815
+ * @returns Template with interpolated preview text
1816
+ *
1817
+ * @example
1818
+ * ```typescript
1819
+ * const preview = await sendly.templates.preview('tpl_preset_otp', {
1820
+ * app_name: 'MyApp',
1821
+ * code: '123456'
1822
+ * });
1823
+ * console.log(preview.previewText);
1824
+ * // "Your MyApp code is 123456"
1825
+ * ```
1826
+ */
1827
+ async preview(id, variables) {
1828
+ const response = await this.http.request({
1829
+ method: "POST",
1830
+ path: `/templates/${id}/preview`,
1831
+ body: variables ? { variables } : {}
1832
+ });
1833
+ return {
1834
+ id: response.id,
1835
+ name: response.name,
1836
+ originalText: response.original_text,
1837
+ previewText: response.preview_text,
1838
+ variables: response.variables.map((v) => ({
1839
+ key: v.key,
1840
+ type: v.type,
1841
+ fallback: v.fallback
1842
+ }))
1843
+ };
1844
+ }
1845
+ /**
1846
+ * Delete a template
1847
+ *
1848
+ * Note: Preset templates cannot be deleted.
1849
+ *
1850
+ * @param id - Template ID
1851
+ *
1852
+ * @example
1853
+ * ```typescript
1854
+ * await sendly.templates.delete('tpl_xxx');
1855
+ * ```
1856
+ */
1857
+ async delete(id) {
1858
+ await this.http.request({
1859
+ method: "DELETE",
1860
+ path: `/templates/${id}`
1861
+ });
1862
+ }
1863
+ transformTemplate(t) {
1864
+ return {
1865
+ id: t.id,
1866
+ name: t.name,
1867
+ text: t.text,
1868
+ variables: t.variables.map((v) => ({
1869
+ key: v.key,
1870
+ type: v.type,
1871
+ fallback: v.fallback
1872
+ })),
1873
+ isPreset: t.is_preset,
1874
+ presetSlug: t.preset_slug,
1875
+ status: t.status,
1876
+ version: t.version,
1877
+ publishedAt: t.published_at,
1878
+ createdAt: t.created_at,
1879
+ updatedAt: t.updated_at
1880
+ };
1881
+ }
1882
+ };
1883
+
1465
1884
  // src/client.ts
1466
1885
  var DEFAULT_BASE_URL2 = "https://sendly.live/api/v1";
1467
1886
  var DEFAULT_TIMEOUT2 = 3e4;
@@ -1518,6 +1937,47 @@ var Sendly = class {
1518
1937
  * ```
1519
1938
  */
1520
1939
  account;
1940
+ /**
1941
+ * Verify API resource - OTP verification
1942
+ *
1943
+ * @example
1944
+ * ```typescript
1945
+ * // Send an OTP
1946
+ * const verification = await sendly.verify.send({
1947
+ * to: '+15551234567',
1948
+ * appName: 'MyApp'
1949
+ * });
1950
+ *
1951
+ * // Check the OTP (user enters code)
1952
+ * const result = await sendly.verify.check(verification.id, {
1953
+ * code: '123456'
1954
+ * });
1955
+ *
1956
+ * if (result.status === 'verified') {
1957
+ * console.log('Phone verified!');
1958
+ * }
1959
+ * ```
1960
+ */
1961
+ verify;
1962
+ /**
1963
+ * Templates API resource - SMS template management
1964
+ *
1965
+ * @example
1966
+ * ```typescript
1967
+ * // List preset templates
1968
+ * const { templates } = await sendly.templates.presets();
1969
+ *
1970
+ * // Create a custom template
1971
+ * const template = await sendly.templates.create({
1972
+ * name: 'My OTP',
1973
+ * text: 'Your {{app_name}} code is {{code}}'
1974
+ * });
1975
+ *
1976
+ * // Publish for use
1977
+ * await sendly.templates.publish(template.id);
1978
+ * ```
1979
+ */
1980
+ templates;
1521
1981
  http;
1522
1982
  config;
1523
1983
  /**
@@ -1550,6 +2010,8 @@ var Sendly = class {
1550
2010
  this.messages = new MessagesResource(this.http);
1551
2011
  this.webhooks = new WebhooksResource(this.http);
1552
2012
  this.account = new AccountResource(this.http);
2013
+ this.verify = new VerifyResource(this.http);
2014
+ this.templates = new TemplatesResource(this.http);
1553
2015
  }
1554
2016
  /**
1555
2017
  * Check if the client is using a test API key
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendly/node",
3
- "version": "3.8.2",
3
+ "version": "3.10.0",
4
4
  "description": "Official Sendly Node.js SDK for SMS messaging",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",