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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xfinitypros/sdk

v0.2.5

Published

Official Xfinity Pros Group API SDK

Readme

@xfinitypros/sdk

The official TypeScript/JavaScript SDK for the Xfinity Pros Group (XPG) API.

This library provides a strongly typed, cross-platform client for web applications, server components, desktop clients (Tauri/Electron), and mobile platforms to communicate securely with api.xfinitypros.com.

🔒 Security Notice: @xfinitypros/sdk is purely a client communication layer over HTTPS. It never contains direct database connections (PostgreSQL/Drizzle), database credentials, session secrets, or API keys for third-party providers. All security boundaries and business logic are owned and enforced by the XPG API.

For desktop applications, the SDK supports short-lived access tokens, long-lived refresh tokens, authorization codes, and pluggable secure token storage.


Installation

npm install @xfinitypros/sdk

or with yarn / pnpm / bun:

pnpm add @xfinitypros/sdk
# or
yarn add @xfinitypros/sdk
# or
bun add @xfinitypros/sdk

Quick Start

Basic Client Creation

import { XPGClient } from "@xfinitypros/sdk";

const xpg = new XPGClient();

The client defaults to:

https://api.xfinitypros.com

Environment Configuration

Production

import { XPGClient } from "@xfinitypros/sdk";

export const xpg = new XPGClient({
  baseUrl: process.env.NEXT_PUBLIC_XPG_API_URL ?? "https://api.xfinitypros.com",
});

Local Development

import { XPGClient } from "@xfinitypros/sdk";

const xpg = new XPGClient({
  baseUrl: "http://localhost:4000",
});

Authentication

XPG authentication separates user authentication from application authorization.

The main components are:

auth.xfinitypros.com
        │
        │ User authentication
        ▼
api.xfinitypros.com
        │
        │ Authorization Code
        ▼
Application
        │
        │ /auth/exchange
        ▼
Access Token + Refresh Token

The API owns:

  • User accounts
  • Password verification
  • User status
  • Sessions
  • Authorization codes
  • Access tokens
  • Refresh tokens
  • Authorization
  • Authentication business logic

auth.xfinitypros.com provides the user-facing authentication experience.

The SDK provides the client communication layer.


Authentication Flow

There are two important stages:

Stage 1 — Authenticate the user

The authentication application sends the user's credentials to:

POST /auth/login

The API verifies the credentials.

When the request is part of an authorization flow, the API creates a short-lived authorization code.

Stage 2 — Exchange the authorization code

The application receives the authorization code and sends it to:

POST /auth/exchange

The API validates the code and creates/returns an authenticated session with:

  • Access token
  • Refresh token
  • Session information
  • User information

The access and refresh tokens are not returned directly from the normal browser login flow.


Desktop Authentication

Desktop applications such as Tauri should normally authenticate through:

auth.xfinitypros.com

The desktop application should not collect or store the user's password.

The recommended flow is:

Tauri Application
       │
       │ Open browser
       ▼
auth.xfinitypros.com/authorize
       │
       │ User logs in
       ▼
api.xfinitypros.com/auth/login
       │
       │ Authentication succeeds
       ▼
Authorization Code Created
       │
       │ Redirect
       ▼
xpg-content://auth/callback?code=abc123
       │
       ▼
Tauri Application
       │
       │ /auth/exchange
       ▼
api.xfinitypros.com
       │
       ▼
Access Token + Refresh Token
       │
       ├── Access Token → Memory
       │
       └── Refresh Token → Secure OS Storage

Authorization Requests

A desktop application can start authentication by opening the XPG authentication application.

For example:

https://auth.xfinitypros.com/authorize?client_id=xpg-content&redirect_uri=xpg-content://auth/callback

The authorization request identifies:

  • client_id — the application requesting authentication
  • redirect_uri — where the authorization code should be returned

The authorization server should validate that the client_id and redirect_uri combination is registered and allowed.


Login

The authentication application can use:

const result = await xpg.auth.login({
  email,
  password,
  clientId: "xpg-content",
  redirectUri: "xpg-content://auth/callback",
});

The API validates the credentials.

For an authorization flow, the API creates a short-lived authorization code and returns information similar to:

{
  user: {
    id: "usr_123",
    email: "[email protected]",
    name: "Jane Doe"
  },
  code: "abc123",
  redirectUri: "xpg-content://auth/callback",
  expiresAt: "2026-08-12T15:30:00.000Z"
}

The authentication application then redirects the browser:

window.location.href = `${result.redirectUri}?code=${encodeURIComponent(result.code)}`;

The authorization code is:

  • Short-lived
  • Single-use
  • Associated with the user
  • Associated with the client
  • Associated with the redirect URI

The API stores a hash of the authorization code rather than the raw code.


Authorization Code Exchange

After authentication, the desktop application receives:

xpg-content://auth/callback?code=abc123

The application extracts the authorization code and exchanges it:

const result = await xpg.auth.exchangeCode({
  code: "abc123",
  clientId: "xpg-content",
});

The SDK sends:

POST /auth/exchange

with:

{
  "code": "abc123",
  "clientId": "xpg-content"
}

The API validates and consumes the authorization code.

If successful, it returns:

{
  user: {
    id: "usr_123",
    email: "[email protected]",
    name: "Jane Doe"
  },

  session: {
    id: "sess_123",
    clientId: "xpg-content",
    deviceName: "My Desktop",
    expiresAt: "..."
  },

  accessToken: "...",
  refreshToken: "..."
}

The SDK automatically stores the returned tokens:

Authorization Code
        │
        ▼
/auth/exchange
        │
        ▼
Access Token + Refresh Token
        │
        ▼
XPGClient.setTokens()
        │
        ▼
XPGTokenStorage

Authorization codes should only be used once.


Tauri Deep-Link Authentication

Tauri applications can register a custom URI scheme such as:

xpg-content://

The authentication application redirects to:

xpg-content://auth/callback?code=abc123

The Tauri application receives the deep-link URL and extracts:

code=abc123

It can then call:

const result = await xpg.auth.exchangeCode({
  code,
  clientId: "xpg-content",
});

After the exchange succeeds, the application has an authenticated XPG session.

The application should then store the refresh token using secure platform storage.


Token Management

The SDK distinguishes between:

  • Access token — short-lived credential used for API requests.
  • Refresh token — longer-lived credential used to obtain new access tokens.
  • Authorization code — short-lived, single-use credential used to establish an application session.
  • Token storage — application-provided storage for securely persisting tokens.

The SDK keeps the active access token in memory and can optionally persist both tokens through an XPGTokenStorage implementation.


XPGTokenStorage

The SDK provides an interface rather than deciding where tokens should be stored.

export interface XPGTokenStorage {
  getAccessToken(): Promise<string | null>;
  getRefreshToken(): Promise<string | null>;

  setTokens(tokens: {
    accessToken: string;
    refreshToken: string;
  }): Promise<void>;

  clear(): Promise<void>;
}

This allows each platform to use an appropriate storage mechanism.

Desktop applications

For Tauri/Electron applications, implement this interface using secure OS credential/keychain storage.

Do not store refresh tokens in:

  • localStorage
  • plain JSON files
  • normal browser storage
  • source code
  • environment variables shipped with the application

The refresh token should be treated as a sensitive credential.


Creating a Client with Token Storage

import { XPGClient } from "@xfinitypros/sdk";
import { secureTokenStorage } from "./token-storage";

export const xpg = new XPGClient({
  baseUrl: "https://api.xfinitypros.com",
  tokenStorage: secureTokenStorage,
});

The SDK automatically persists tokens when an authentication method returns an access token and refresh token.


Direct Login

Direct email/password login is available for applications that are intentionally designed to use that flow.

const result = await xpg.auth.login({
  email: "[email protected]",
  password: "securepassword",
});

This authenticates the user with the API.

For authorization-based applications, provide the client and redirect information:

const result = await xpg.auth.login({
  email: "[email protected]",
  password: "securepassword",
  clientId: "xpg-content",
  redirectUri: "xpg-content://auth/callback",
});

When clientId and redirectUri are provided, the API creates an authorization code.

The login response does not contain the application's access and refresh tokens.

For desktop applications, prefer the browser-based authorization-code flow.


Two-Factor Authentication

If two-factor authentication is required, the authentication application should complete the required verification before creating the authorization code.

The exact two-factor flow is controlled by the XPG authentication service.

Example:

const result = await xpg.auth.verifyTwoFactor({
  userId,
  code: "123456",
});

After successful verification, the authentication flow can continue and create the authorization code for the requesting application.


Current User

Once an application has an access token:

const { user, session } = await xpg.auth.me();

console.log(user);
console.log(session);

The SDK automatically includes:

Authorization: Bearer <access-token>

when an access token is available.


Refreshing an Access Token

Access tokens are intentionally short-lived.

When an access token expires, use the refresh token to obtain a new token pair:

const result = await xpg.auth.refresh({
  refreshToken: "your-refresh-token",
});

The SDK automatically replaces the stored tokens:

Old Access Token
Old Refresh Token
        │
        ▼
/auth/refresh
        │
        ▼
New Access Token
New Refresh Token
        │
        ▼
XPGTokenStorage.setTokens()

Applications should generally avoid manually passing refresh tokens throughout their code.

A secure token storage implementation should provide the refresh token when required.


Logout

const result = await xpg.auth.logout();

console.log(result.status);
// "success"

console.log(result.message);
// "Logged out successfully"

Logout performs two operations:

  1. Sends the logout request to the API so the server-side session can be revoked.
  2. Clears the locally stored access and refresh tokens.
await xpg.auth.logout();

Bearer Token Management

The current access token can be managed directly when necessary.

Set access token

xpg.setAccessToken("access-token");

Get access token

const accessToken = xpg.getAccessToken();

Clear access token

xpg.clearAccessToken();

These methods only manage the in-memory access token.

They do not replace secure refresh-token storage.

For persistent authentication, prefer:

await xpg.setTokens({
  accessToken,
  refreshToken,
});

and provide an XPGTokenStorage implementation.


Users

The xpg.users module provides access to XPG user operations.

List Users

const users = await xpg.users.list();

console.log(users);

The method returns an array of User objects:

const users: User[] = await xpg.users.list();

Each user currently contains:

{
  id: string;
  email: string;
  name: string;
  status: string;
  createdAt: string;
  updatedAt: string;
}

Example:

const users = await xpg.users.list();

for (const user of users) {
  console.log(user.name);
  console.log(user.email);
  console.log(user.status);
}

The underlying API endpoint is:

GET /users

Note: User listing is currently an administrative operation and should be protected by the XPG API's authorization system before being exposed to normal users.


Create User

The SDK can create users through the users module:

const user = await xpg.users.create({
  email: "[email protected]",
  name: "John Doe",
  password: "securepassword",
});

The underlying API endpoint is:

POST /users

The API validates the request and handles password hashing.

The returned user does not contain the user's password or password hash.

Example response:

{
  id: "usr_123",
  email: "[email protected]",
  name: "John Doe",
  status: "active",
  createdAt: "...",
  updatedAt: "..."
}

Note: User creation should be protected by the XPG API's authorization system before being exposed to normal users.


Organizations

The xpg.organizations module provides organization management.

List organizations

const organizations = await xpg.organizations.list();

Get an organization

const organization = await xpg.organizations.get("org_123");

API Requests

All SDK modules use the same authenticated client.

For example:

const users = await xpg.users.list();

If an access token exists, the request automatically contains:

Authorization: Bearer <access-token>

Other API modules follow the same pattern:

const organization = await xpg.organizations.get("org_123");

Error Handling

All API errors are parsed into XPGApiError objects containing status codes and machine-readable error codes.

import { XPGApiError } from "@xfinitypros/sdk";

try {
  await xpg.auth.login({
    email,
    password,
  });
} catch (err) {
  if (err instanceof XPGApiError) {
    console.error("Status:", err.status);
    console.error("Code:", err.code);
    console.error("Message:", err.message);
  }
}

For example:

Status: 401
Code: INVALID_PASSWORD
Message: Invalid password

Other authentication errors may include:

USER_MISSING
USER_INACTIVE
INVALID_PASSWORD
INVALID_AUTHORIZATION_CODE
INVALID_REFRESH_TOKEN
INVALID_2FA_CODE
USER_ALREADY_EXISTS

Available Modules

The SDK is organized modularly for scalability across XPG applications:

  • xpg.auth — Authentication, authorization codes, sessions and tokens
  • xpg.users — User listing, creation, profiles and user operations
  • xpg.organizations — Organization management
  • xpg.employees — Employee directory and management
  • xpg.tasks — Task management
  • xpg.billing — Invoices and billing operations
  • xpg.accounting — Accounts and ledger operations
  • xpg.ai — XPG AI provider endpoints

Some modules are planned and may not yet be available in the current SDK version.


Browser and Server Compatibility

@xfinitypros/sdk uses the standard Web fetch API and can be used with:

  • Browser applications
  • React
  • Vue
  • Svelte
  • Angular
  • Next.js
  • Next.js Server Components
  • Next.js Server Actions
  • Node.js
  • Bun
  • Tauri
  • Electron
  • React Native

Applications should provide platform-appropriate token storage where persistent authentication is required.


Cookie-Based Authentication

The client supports the standard fetch credentials configuration:

const xpg = new XPGClient({
  credentials: "include",
});

This can be useful for browser-based applications using HTTP cookies.

For example:

await xpg.auth.me();

will make the request with:

credentials: "include";

Cookie authentication is primarily useful in browser environments where the API and frontend are configured for secure cookie-based sessions.

Desktop applications should generally use bearer access tokens with secure refresh-token storage instead.


Security Model

The SDK intentionally does not contain authentication secrets or database access.

Application
    │
    ▼
@xfinitypros/sdk
    │
    │ HTTPS
    ▼
api.xfinitypros.com
    │
    ├── Authentication
    ├── Authorization
    ├── Sessions
    ├── Authorization Codes
    ├── Access Tokens
    ├── Refresh Tokens
    ├── Business Logic
    └── PostgreSQL

The SDK only handles communication with the API and local token management.

Desktop Authentication

The recommended desktop authentication architecture is:

┌──────────────────────┐
│   Tauri Application  │
└──────────┬───────────┘
           │
           │ Open browser
           ▼
┌─────────────────────────────┐
│   auth.xfinitypros.com      │
│                             │
│   Login / Registration      │
│   2FA                       │
└─────────────┬───────────────┘
              │
              │ /auth/login
              ▼
┌─────────────────────────────┐
│   api.xfinitypros.com       │
│                             │
│   Verify credentials        │
│   Create authorization code │
└─────────────┬───────────────┘
              │
              │ redirect
              ▼
┌─────────────────────────────┐
│ xpg-content://auth/callback │
│ ?code=abc123                │
└─────────────┬───────────────┘
              │
              │ Deep-link
              ▼
┌──────────────────────┐
│   Tauri Application  │
└──────────┬───────────┘
           │
           │ /auth/exchange
           ▼
┌─────────────────────────────┐
│   api.xfinitypros.com       │
│                             │
│   Validate authorization    │
│   code                       │
│                             │
│   Create session             │
└─────────────┬───────────────┘
              │
              │
              ▼
       Access Token
       Refresh Token
       Session
              │
       ┌──────┴──────┐
       │             │
       ▼             ▼
    Memory       Secure OS
                 Storage

This architecture means:

  • The desktop application does not collect the user's password.
  • auth.xfinitypros.com provides the login experience.
  • api.xfinitypros.com remains the authority for authentication and sessions.
  • Authorization codes are short-lived and single-use.
  • Access tokens are used for normal API requests.
  • Refresh tokens are stored securely.
  • The SDK does not have direct database access.

Publishing to npm

Make your changes

pnpm run typecheck
pnpm run build

Run tests

pnpm test

Bump the version

npm version patch

Or:

npm version minor

or:

npm version major

Publish

npm publish

You might need to npm login again.

Test your login with:

npm whoami

License

MIT © Xfinity Pros Group