🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@sendly/node

Package Overview
Dependencies
Maintainers
1
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sendly/node - npm Package Compare versions

Comparing version
3.8.2
to
3.9.0
+434
-0
dist/index.js

@@ -1525,2 +1525,393 @@ "use strict";

// src/resources/verify.ts
var VerifyResource = class {
http;
constructor(http) {
this.http = http;
}
/**
* Send an OTP verification code
*
* @param request - Verification request details
* @returns The created verification with ID and expiry
*
* @example
* ```typescript
* // Basic usage
* const verification = await sendly.verify.send({
* to: '+15551234567'
* });
*
* // With custom options
* const verification = await sendly.verify.send({
* to: '+15551234567',
* appName: 'MyApp',
* codeLength: 8,
* timeoutSecs: 600
* });
*
* // In sandbox mode, the code is returned for testing
* if (verification.sandboxCode) {
* console.log('Test code:', verification.sandboxCode);
* }
* ```
*/
async send(request) {
validatePhoneNumber(request.to);
const response = await this.http.request({
method: "POST",
path: "/verify",
body: {
to: request.to,
...request.templateId && { template_id: request.templateId },
...request.profileId && { profile_id: request.profileId },
...request.appName && { app_name: request.appName },
...request.timeoutSecs && { timeout_secs: request.timeoutSecs },
...request.codeLength && { code_length: request.codeLength }
}
});
return {
id: response.id,
status: response.status,
phone: response.phone,
expiresAt: response.expires_at,
sandbox: response.sandbox,
sandboxCode: response.sandbox_code,
message: response.message
};
}
/**
* Check/verify an OTP code
*
* @param id - Verification ID
* @param request - The code to verify
* @returns Verification result
*
* @example
* ```typescript
* const result = await sendly.verify.check('ver_xxx', {
* code: '123456'
* });
*
* if (result.status === 'verified') {
* // User is verified
* } else if (result.remainingAttempts !== undefined) {
* console.log(`Wrong code. ${result.remainingAttempts} attempts remaining`);
* }
* ```
*/
async check(id, request) {
const response = await this.http.request({
method: "POST",
path: `/verify/${id}/check`,
body: { code: request.code }
});
return {
id: response.id,
status: response.status,
phone: response.phone,
verifiedAt: response.verified_at,
remainingAttempts: response.remaining_attempts
};
}
/**
* Get a verification by ID
*
* @param id - Verification ID
* @returns The verification record
*
* @example
* ```typescript
* const verification = await sendly.verify.get('ver_xxx');
* console.log(verification.status); // 'pending', 'verified', 'expired', etc.
* ```
*/
async get(id) {
const response = await this.http.request({
method: "GET",
path: `/verify/${id}`
});
return {
id: response.id,
status: response.status,
phone: response.phone,
deliveryStatus: response.delivery_status,
attempts: response.attempts,
maxAttempts: response.max_attempts,
expiresAt: response.expires_at,
verifiedAt: response.verified_at,
createdAt: response.created_at,
sandbox: response.sandbox,
appName: response.app_name,
templateId: response.template_id,
profileId: response.profile_id
};
}
/**
* List recent verifications
*
* @param options - Filter and pagination options
* @returns List of verifications
*
* @example
* ```typescript
* // List recent verifications
* const { verifications } = await sendly.verify.list({ limit: 10 });
*
* // Filter by status
* const { verifications } = await sendly.verify.list({
* status: 'verified'
* });
* ```
*/
async list(options = {}) {
const response = await this.http.request({
method: "GET",
path: "/verify",
query: {
...options.limit && { limit: options.limit },
...options.status && { status: options.status }
}
});
return {
verifications: response.verifications.map((v) => ({
id: v.id,
status: v.status,
phone: v.phone,
deliveryStatus: v.delivery_status,
attempts: v.attempts,
maxAttempts: v.max_attempts,
expiresAt: v.expires_at,
verifiedAt: v.verified_at,
createdAt: v.created_at,
sandbox: v.sandbox,
appName: v.app_name,
templateId: v.template_id,
profileId: v.profile_id
})),
pagination: {
limit: response.pagination.limit,
hasMore: response.pagination.has_more
}
};
}
};
// src/resources/templates.ts
var TemplatesResource = class {
http;
constructor(http) {
this.http = http;
}
/**
* List all templates (presets + custom)
*
* @returns List of templates
*
* @example
* ```typescript
* const { templates } = await sendly.templates.list();
* templates.forEach(t => {
* console.log(`${t.name}: ${t.isPreset ? 'preset' : t.status}`);
* });
* ```
*/
async list() {
const response = await this.http.request({
method: "GET",
path: "/templates"
});
return {
templates: response.templates.map((t) => this.transformTemplate(t))
};
}
/**
* List preset templates only (no auth required)
*
* @returns List of preset templates
*
* @example
* ```typescript
* const { templates } = await sendly.templates.presets();
* // Returns: otp, 2fa, login, signup, reset, generic
* ```
*/
async presets() {
const response = await this.http.request({
method: "GET",
path: "/templates/presets"
});
return {
templates: response.templates.map((t) => this.transformTemplate(t))
};
}
/**
* Get a template by ID
*
* @param id - Template ID
* @returns The template
*
* @example
* ```typescript
* const template = await sendly.templates.get('tpl_preset_otp');
* console.log(template.text); // "Your {{app_name}} code is {{code}}"
* ```
*/
async get(id) {
const response = await this.http.request({
method: "GET",
path: `/templates/${id}`
});
return this.transformTemplate(response);
}
/**
* Create a new template
*
* @param request - Template details
* @returns The created template (as draft)
*
* @example
* ```typescript
* const template = await sendly.templates.create({
* name: 'Password Reset',
* text: '{{app_name}}: Your password reset code is {{code}}. Valid for 10 minutes.'
* });
*
* // Template is created as draft, publish when ready
* await sendly.templates.publish(template.id);
* ```
*/
async create(request) {
const response = await this.http.request({
method: "POST",
path: "/templates",
body: {
name: request.name,
text: request.text
}
});
return this.transformTemplate(response);
}
/**
* Update a template
*
* Note: Updating a published template creates a new draft version.
*
* @param id - Template ID
* @param request - Fields to update
* @returns The updated template
*
* @example
* ```typescript
* const template = await sendly.templates.update('tpl_xxx', {
* text: 'New message text with {{code}}'
* });
* ```
*/
async update(id, request) {
const response = await this.http.request({
method: "PATCH",
path: `/templates/${id}`,
body: {
...request.name && { name: request.name },
...request.text && { text: request.text }
}
});
return this.transformTemplate(response);
}
/**
* Publish a draft template
*
* Published templates are locked and can be used with the Verify API.
*
* @param id - Template ID
* @returns The published template
*
* @example
* ```typescript
* const template = await sendly.templates.publish('tpl_xxx');
* console.log(template.status); // 'published'
* ```
*/
async publish(id) {
const response = await this.http.request({
method: "POST",
path: `/templates/${id}/publish`
});
return this.transformTemplate(response);
}
/**
* Preview a template with sample values
*
* @param id - Template ID
* @param variables - Optional custom variable values
* @returns Template with interpolated preview text
*
* @example
* ```typescript
* const preview = await sendly.templates.preview('tpl_preset_otp', {
* app_name: 'MyApp',
* code: '123456'
* });
* console.log(preview.previewText);
* // "Your MyApp code is 123456"
* ```
*/
async preview(id, variables) {
const response = await this.http.request({
method: "POST",
path: `/templates/${id}/preview`,
body: variables ? { variables } : {}
});
return {
id: response.id,
name: response.name,
originalText: response.original_text,
previewText: response.preview_text,
variables: response.variables.map((v) => ({
key: v.key,
type: v.type,
fallback: v.fallback
}))
};
}
/**
* Delete a template
*
* Note: Preset templates cannot be deleted.
*
* @param id - Template ID
*
* @example
* ```typescript
* await sendly.templates.delete('tpl_xxx');
* ```
*/
async delete(id) {
await this.http.request({
method: "DELETE",
path: `/templates/${id}`
});
}
transformTemplate(t) {
return {
id: t.id,
name: t.name,
text: t.text,
variables: t.variables.map((v) => ({
key: v.key,
type: v.type,
fallback: v.fallback
})),
isPreset: t.is_preset,
presetSlug: t.preset_slug,
status: t.status,
version: t.version,
publishedAt: t.published_at,
createdAt: t.created_at,
updatedAt: t.updated_at
};
}
};
// src/client.ts

@@ -1582,2 +1973,43 @@ var DEFAULT_BASE_URL2 = "https://sendly.live/api/v1";

account;
/**
* Verify API resource - OTP verification
*
* @example
* ```typescript
* // Send an OTP
* const verification = await sendly.verify.send({
* to: '+15551234567',
* appName: 'MyApp'
* });
*
* // Check the OTP (user enters code)
* const result = await sendly.verify.check(verification.id, {
* code: '123456'
* });
*
* if (result.status === 'verified') {
* console.log('Phone verified!');
* }
* ```
*/
verify;
/**
* Templates API resource - SMS template management
*
* @example
* ```typescript
* // List preset templates
* const { templates } = await sendly.templates.presets();
*
* // Create a custom template
* const template = await sendly.templates.create({
* name: 'My OTP',
* text: 'Your {{app_name}} code is {{code}}'
* });
*
* // Publish for use
* await sendly.templates.publish(template.id);
* ```
*/
templates;
http;

@@ -1615,2 +2047,4 @@ config;

this.account = new AccountResource(this.http);
this.verify = new VerifyResource(this.http);
this.templates = new TemplatesResource(this.http);
}

@@ -1617,0 +2051,0 @@ /**

@@ -1465,2 +1465,393 @@ // src/errors.ts

// src/resources/verify.ts
var VerifyResource = class {
http;
constructor(http) {
this.http = http;
}
/**
* Send an OTP verification code
*
* @param request - Verification request details
* @returns The created verification with ID and expiry
*
* @example
* ```typescript
* // Basic usage
* const verification = await sendly.verify.send({
* to: '+15551234567'
* });
*
* // With custom options
* const verification = await sendly.verify.send({
* to: '+15551234567',
* appName: 'MyApp',
* codeLength: 8,
* timeoutSecs: 600
* });
*
* // In sandbox mode, the code is returned for testing
* if (verification.sandboxCode) {
* console.log('Test code:', verification.sandboxCode);
* }
* ```
*/
async send(request) {
validatePhoneNumber(request.to);
const response = await this.http.request({
method: "POST",
path: "/verify",
body: {
to: request.to,
...request.templateId && { template_id: request.templateId },
...request.profileId && { profile_id: request.profileId },
...request.appName && { app_name: request.appName },
...request.timeoutSecs && { timeout_secs: request.timeoutSecs },
...request.codeLength && { code_length: request.codeLength }
}
});
return {
id: response.id,
status: response.status,
phone: response.phone,
expiresAt: response.expires_at,
sandbox: response.sandbox,
sandboxCode: response.sandbox_code,
message: response.message
};
}
/**
* Check/verify an OTP code
*
* @param id - Verification ID
* @param request - The code to verify
* @returns Verification result
*
* @example
* ```typescript
* const result = await sendly.verify.check('ver_xxx', {
* code: '123456'
* });
*
* if (result.status === 'verified') {
* // User is verified
* } else if (result.remainingAttempts !== undefined) {
* console.log(`Wrong code. ${result.remainingAttempts} attempts remaining`);
* }
* ```
*/
async check(id, request) {
const response = await this.http.request({
method: "POST",
path: `/verify/${id}/check`,
body: { code: request.code }
});
return {
id: response.id,
status: response.status,
phone: response.phone,
verifiedAt: response.verified_at,
remainingAttempts: response.remaining_attempts
};
}
/**
* Get a verification by ID
*
* @param id - Verification ID
* @returns The verification record
*
* @example
* ```typescript
* const verification = await sendly.verify.get('ver_xxx');
* console.log(verification.status); // 'pending', 'verified', 'expired', etc.
* ```
*/
async get(id) {
const response = await this.http.request({
method: "GET",
path: `/verify/${id}`
});
return {
id: response.id,
status: response.status,
phone: response.phone,
deliveryStatus: response.delivery_status,
attempts: response.attempts,
maxAttempts: response.max_attempts,
expiresAt: response.expires_at,
verifiedAt: response.verified_at,
createdAt: response.created_at,
sandbox: response.sandbox,
appName: response.app_name,
templateId: response.template_id,
profileId: response.profile_id
};
}
/**
* List recent verifications
*
* @param options - Filter and pagination options
* @returns List of verifications
*
* @example
* ```typescript
* // List recent verifications
* const { verifications } = await sendly.verify.list({ limit: 10 });
*
* // Filter by status
* const { verifications } = await sendly.verify.list({
* status: 'verified'
* });
* ```
*/
async list(options = {}) {
const response = await this.http.request({
method: "GET",
path: "/verify",
query: {
...options.limit && { limit: options.limit },
...options.status && { status: options.status }
}
});
return {
verifications: response.verifications.map((v) => ({
id: v.id,
status: v.status,
phone: v.phone,
deliveryStatus: v.delivery_status,
attempts: v.attempts,
maxAttempts: v.max_attempts,
expiresAt: v.expires_at,
verifiedAt: v.verified_at,
createdAt: v.created_at,
sandbox: v.sandbox,
appName: v.app_name,
templateId: v.template_id,
profileId: v.profile_id
})),
pagination: {
limit: response.pagination.limit,
hasMore: response.pagination.has_more
}
};
}
};
// src/resources/templates.ts
var TemplatesResource = class {
http;
constructor(http) {
this.http = http;
}
/**
* List all templates (presets + custom)
*
* @returns List of templates
*
* @example
* ```typescript
* const { templates } = await sendly.templates.list();
* templates.forEach(t => {
* console.log(`${t.name}: ${t.isPreset ? 'preset' : t.status}`);
* });
* ```
*/
async list() {
const response = await this.http.request({
method: "GET",
path: "/templates"
});
return {
templates: response.templates.map((t) => this.transformTemplate(t))
};
}
/**
* List preset templates only (no auth required)
*
* @returns List of preset templates
*
* @example
* ```typescript
* const { templates } = await sendly.templates.presets();
* // Returns: otp, 2fa, login, signup, reset, generic
* ```
*/
async presets() {
const response = await this.http.request({
method: "GET",
path: "/templates/presets"
});
return {
templates: response.templates.map((t) => this.transformTemplate(t))
};
}
/**
* Get a template by ID
*
* @param id - Template ID
* @returns The template
*
* @example
* ```typescript
* const template = await sendly.templates.get('tpl_preset_otp');
* console.log(template.text); // "Your {{app_name}} code is {{code}}"
* ```
*/
async get(id) {
const response = await this.http.request({
method: "GET",
path: `/templates/${id}`
});
return this.transformTemplate(response);
}
/**
* Create a new template
*
* @param request - Template details
* @returns The created template (as draft)
*
* @example
* ```typescript
* const template = await sendly.templates.create({
* name: 'Password Reset',
* text: '{{app_name}}: Your password reset code is {{code}}. Valid for 10 minutes.'
* });
*
* // Template is created as draft, publish when ready
* await sendly.templates.publish(template.id);
* ```
*/
async create(request) {
const response = await this.http.request({
method: "POST",
path: "/templates",
body: {
name: request.name,
text: request.text
}
});
return this.transformTemplate(response);
}
/**
* Update a template
*
* Note: Updating a published template creates a new draft version.
*
* @param id - Template ID
* @param request - Fields to update
* @returns The updated template
*
* @example
* ```typescript
* const template = await sendly.templates.update('tpl_xxx', {
* text: 'New message text with {{code}}'
* });
* ```
*/
async update(id, request) {
const response = await this.http.request({
method: "PATCH",
path: `/templates/${id}`,
body: {
...request.name && { name: request.name },
...request.text && { text: request.text }
}
});
return this.transformTemplate(response);
}
/**
* Publish a draft template
*
* Published templates are locked and can be used with the Verify API.
*
* @param id - Template ID
* @returns The published template
*
* @example
* ```typescript
* const template = await sendly.templates.publish('tpl_xxx');
* console.log(template.status); // 'published'
* ```
*/
async publish(id) {
const response = await this.http.request({
method: "POST",
path: `/templates/${id}/publish`
});
return this.transformTemplate(response);
}
/**
* Preview a template with sample values
*
* @param id - Template ID
* @param variables - Optional custom variable values
* @returns Template with interpolated preview text
*
* @example
* ```typescript
* const preview = await sendly.templates.preview('tpl_preset_otp', {
* app_name: 'MyApp',
* code: '123456'
* });
* console.log(preview.previewText);
* // "Your MyApp code is 123456"
* ```
*/
async preview(id, variables) {
const response = await this.http.request({
method: "POST",
path: `/templates/${id}/preview`,
body: variables ? { variables } : {}
});
return {
id: response.id,
name: response.name,
originalText: response.original_text,
previewText: response.preview_text,
variables: response.variables.map((v) => ({
key: v.key,
type: v.type,
fallback: v.fallback
}))
};
}
/**
* Delete a template
*
* Note: Preset templates cannot be deleted.
*
* @param id - Template ID
*
* @example
* ```typescript
* await sendly.templates.delete('tpl_xxx');
* ```
*/
async delete(id) {
await this.http.request({
method: "DELETE",
path: `/templates/${id}`
});
}
transformTemplate(t) {
return {
id: t.id,
name: t.name,
text: t.text,
variables: t.variables.map((v) => ({
key: v.key,
type: v.type,
fallback: v.fallback
})),
isPreset: t.is_preset,
presetSlug: t.preset_slug,
status: t.status,
version: t.version,
publishedAt: t.published_at,
createdAt: t.created_at,
updatedAt: t.updated_at
};
}
};
// src/client.ts

@@ -1522,2 +1913,43 @@ var DEFAULT_BASE_URL2 = "https://sendly.live/api/v1";

account;
/**
* Verify API resource - OTP verification
*
* @example
* ```typescript
* // Send an OTP
* const verification = await sendly.verify.send({
* to: '+15551234567',
* appName: 'MyApp'
* });
*
* // Check the OTP (user enters code)
* const result = await sendly.verify.check(verification.id, {
* code: '123456'
* });
*
* if (result.status === 'verified') {
* console.log('Phone verified!');
* }
* ```
*/
verify;
/**
* Templates API resource - SMS template management
*
* @example
* ```typescript
* // List preset templates
* const { templates } = await sendly.templates.presets();
*
* // Create a custom template
* const template = await sendly.templates.create({
* name: 'My OTP',
* text: 'Your {{app_name}} code is {{code}}'
* });
*
* // Publish for use
* await sendly.templates.publish(template.id);
* ```
*/
templates;
http;

@@ -1555,2 +1987,4 @@ config;

this.account = new AccountResource(this.http);
this.verify = new VerifyResource(this.http);
this.templates = new TemplatesResource(this.http);
}

@@ -1557,0 +1991,0 @@ /**

+1
-1
{
"name": "@sendly/node",
"version": "3.8.2",
"version": "3.9.0",
"description": "Official Sendly Node.js SDK for SMS messaging",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display