npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@appedge/core

v0.1.1

Published

AppEdge core SDK for flexible API data modeling

Readme

AppEdge Node SDK

Installation

npm install appedge-node

Quick Start (Unified Client)

import { AppEdgeClient } from "appedge-node";

const client = new AppEdgeClient({
  appToken: "app_sometoken",
  workerUrl: "https://xyz.appedge.xyz",
  binding,
});

// Data usage (auto-anonymous if not signed in)
const users = client.data.collection("users", userSchema);
await users.create({ name: "Alice", email: "[email protected]" });

// Auth usage (upgrades session)
await client.auth.signInEmailOTP(email, otp);
// All future data/auth calls use this session automatically

Features

  • Automatic anonymous user/session creation
  • Automatic session upgrade on authentication
  • Unified API for both Data and Auth
  • Type-safe schema definitions
  • Silent Network Authentication (SNA) with Twilio Verify

Silent Network Authentication (SNA)

The AppEdge SDK now supports Silent Network Authentication (SNA) using Twilio Verify, providing frictionless phone number verification that happens in the background without requiring user input like OTP codes.

What is SNA?

SNA is a secure authentication method that:

  • Verifies phone number possession in real-time
  • Works silently in the background (2-4 seconds)
  • Requires no user input (no OTP codes to enter)
  • Uses direct carrier connections for verification
  • Is immune to phishing attacks

Setup SNA

First, configure your Twilio credentials:

import { AppEdgeClient, SNAConfig } from "appedge-node";

const snaConfig: SNAConfig = {
  twilioAccountSid: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // Your Twilio Account SID
  twilioAuthToken: "your_auth_token_here",             // Your Twilio Auth Token
  verifyServiceSid: "VAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  // Your Verify Service SID
};

// Option 1: Configure during initialization
const client = new AppEdgeClient({
  appToken: "app_sometoken",
  workerUrl: "https://xyz.appedge.xyz",
  snaConfig: snaConfig
});

// Option 2: Configure after initialization
const client = new AppEdgeClient({
  appToken: "app_sometoken",
  workerUrl: "https://xyz.appedge.xyz"
});
client.configureSNA(snaConfig);

Using SNA

Simple SNA Authentication

try {
  // Complete SNA authentication flow
  const session = await client.auth.signInSNA("+1234567890");
  console.log("User authenticated successfully!", session);
  
  // Session is automatically set on the client
  const currentSession = client.getSession();
} catch (error) {
  console.error("SNA authentication failed:", error);
  // Fallback to SMS OTP or other authentication method
}

Manual SNA Flow (Advanced)

For more control over the SNA process:

try {
  // Step 1: Start SNA verification
  const verification = await client.auth.startSNAVerification("+1234567890");
  console.log("SNA verification started:", verification.sid);
  
  if (verification.sna?.url) {
    console.log("SNA URL:", verification.sna.url);
    
    // In a mobile app, invoke this URL on cellular data:
    // await fetch(verification.sna.url, { method: 'POST' });
    
    // Wait for carrier verification (usually 2-4 seconds)
    await new Promise(resolve => setTimeout(resolve, 4000));
    
    // Step 2: Check verification status
    const result = await client.auth.checkSNAVerification("+1234567890");
    
    if (result.status === 'approved' && result.valid) {
      console.log("Phone number verified successfully!");
    } else {
      console.log("Verification failed:", result.status);
      if (result.sna_attempts_error_codes?.length) {
        console.log("Error codes:", result.sna_attempts_error_codes);
      }
    }
  }
} catch (error) {
  console.error("SNA verification failed:", error);
}

SNA with SMS Fallback

const phoneNumber = "+1234567890";

try {
  // Try SNA first
  const session = await client.auth.signInSNA(phoneNumber);
  console.log("SNA successful:", session);
} catch (snaError) {
  console.log("SNA failed, falling back to SMS OTP");
  
  try {
    // Fallback to SMS OTP
    await client.auth.signInPhoneNumber(phoneNumber);
    console.log("SMS OTP sent. Collect verification code from user.");
    
    const otp = "123456"; // From user input
    const session = await client.auth.verifyPhoneNumber(phoneNumber, otp);
    console.log("SMS verification successful:", session);
  } catch (smsError) {
    console.error("Both SNA and SMS verification failed");
  }
}

Mobile App Integration

For React Native or mobile web apps:

// In your mobile app
const verification = await client.auth.startSNAVerification(phoneNumber);

if (verification.sna?.url) {
  // Show loading indicator
  console.log("Verifying your phone number...");
  
  // Invoke SNA URL on cellular data (not Wi-Fi)
  try {
    await fetch(verification.sna.url, { method: 'POST' });
    
    // Check verification result
    const result = await client.auth.checkSNAVerification(phoneNumber);
    
    if (result.status === 'approved') {
      console.log("Phone verified! User authenticated.");
      // Navigate to authenticated area
    } else {
      console.log("Verification failed. Show SMS fallback.");
    }
  } catch (error) {
    console.log("SNA failed. Show SMS fallback.");
  }
}

SNA Requirements and Limitations

Requirements:

  • Twilio Verify Service with SNA enabled
  • Mobile device with cellular data connection
  • Phone number from supported carrier and country

Limitations:

  • Must use cellular data (not Wi-Fi)
  • Currently available in 9+ countries (US, Canada, UK, Germany, France, Spain, etc.)
  • Takes 2-4 seconds to complete
  • Dual SIM devices may require additional configuration

Error Handling:

  • Always implement SMS fallback for unsupported scenarios
  • Check error codes in verification results
  • Handle network timeouts gracefully

SNA Error Codes

Common SNA error codes:

  • 60500: Phone number mismatch
  • 60540: Carrier identified invalid phone number
  • 60519: Verification check called too early
  • 60001: General SNA failure

For complete error code documentation, see Twilio Verify Error Codes.

Session Management

  • The SDK manages session state for you.
  • When you authenticate (including SNA), the session is upgraded and all future calls use the new session.
  • You can access the current session via client.getSession().

Advanced Usage

  • You can still use Data, Auth, and App directly for advanced scenarios.

Example: Full CRUD

const users = client.data.collection("users", userSchema);
const newUser = await users.create({
  name: "Alice",
  email: "[email protected]",
});
const found = await users.find({ email: "[email protected]" });
await users.update({ id: newUser.id }, { name: "Alice Smith" });
await users.delete({ id: newUser.id });

Example: Authentication

// Sign in/up with email OTP
await client.auth.signInEmailOTP("[email protected]", "123456");

// Or use SNA for frictionless authentication
await client.auth.signInSNA("+1234567890");

// Now all data operations are associated with this authenticated user

Device ID

  • The SDK automatically manages a device ID (persisted in browser, random in Node.js) for anonymous sessions.

Upgrading from Previous Versions

  • Replace direct usage of Data and Auth with the new AppEdgeClient for most use cases.
  • Manual session management is no longer required.
  • Add SNA configuration for frictionless phone verification.