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

@voltade/wess-sdk

v1.1.1

Published

A comprehensive TypeScript SDK for the WESS Open API with built-in error handling and resource-based architecture

Readme

@voltade/wess-sdk

A comprehensive, type-safe TypeScript SDK for the WESS Open API with built-in error handling and resource-based architecture.

License: MIT GitHub Package

Features

  • Type-safe: Full TypeScript support with exported types and Zod schemas
  • Resource-based architecture: Organized by API domain (user, branches, customers)
  • Error handling: Specific error classes for different failure scenarios
  • Zero dependencies: Uses native fetch API (Node.js 18+)
  • Configurable: Environment variables or programmatic configuration

Installation

Note: This package is published to GitHub Packages (not npm) as a private package.

npm install @voltade/wess-sdk
# or
yarn add @voltade/wess-sdk
# or
pnpm add @voltade/wess-sdk

Quick Start

import { WessClient } from "@voltade/wess-sdk";

const client = new WessClient({
  baseUrl: "https://your-wess-api.com/api",
  bearerToken: "your-bearer-token",
});

// Get current user
const user = await client.user.get();

// List all branches
const branches = await client.branches.list();

// Create an appointment
const appointment = await client.branches.createOnlineAppointment(branchId, {
  date: "2024-12-15 10:00:00",
  items: [
    { product_id: 1718, unit: 1 },
    { product_id: 5523, unit: 1 },
  ],
  customer_id: 123,
});

Configuration

Environment Variables

WESS_BASE_URL=https://your-wess-api.com/api
WESS_BEARER_TOKEN=your-bearer-token

Client Options

interface WessClientConfig {
  baseUrl: string; // Base URL for the WESS API
  bearerToken: string; // Bearer token for authentication
  timeout?: number; // Request timeout in milliseconds (default: 30000)
  headers?: Record<string, string>; // Custom headers for all requests
}

Method Reference

Quick lookup table for all SDK methods.

UserResource

| Method | HTTP | Endpoint | Returns | | ------- | ---- | ---------- | -------------- | | get() | GET | /v1/user | UserResponse |

BranchesResource

| Method | HTTP | Endpoint | Returns | | --------------------------------------------------------------- | ----- | ----------------------------------------------------------------------------- | ------------------------------- | | list() | GET | /v1/branches | Branch[] | | get(branchId) | GET | /v1/branches/:branch | Branch | | getCustomer(branchId, customerId) | GET | /v1/branches/:branch/customers/:customer | Customer | | getOnlineAppointmentServices(branchId) | GET | /v1/branches/:branch/online-appointments/services | OnlineAppointmentService[] | | getOnlineAppointmentEmployees(branchId, params) | GET | /v1/branches/:branch/online-appointments/employees | OnlineAppointmentEmployee[] | | getOnlineAppointmentTimeSlots(branchId, params) | GET | /v1/branches/:branch/online-appointments/time-slots | OnlineAppointmentTimeSlot[] | | createOnlineAppointment(branchId, params, options?) | POST | /v1/branches/:branch/online-appointments | OnlineAppointmentSaleTicket | | cancelOnlineAppointment(branchId, saleTicketId, params) | PATCH | /v1/branches/:branch/online-appointments/:saleTicketId/cancel | OnlineAppointmentSaleTicket | | getCustomerUpcomingAppointments(branchId, customerId, params) | GET | /v1/branches/:branch/customers/:customer/appointments/upcoming-appointments | OnlineAppointmentSaleTicket[] |

CustomersResource

| Method | HTTP | Endpoint | Returns | | ---------------------------------- | ---- | ----------------------------------------- | ------------ | | searchByPhoneNumber(phoneNumber) | GET | /v1/customers/phone-number/:phoneNumber | Customer[] |


API Reference

User Resource

client.user.get()

Get the current authenticated user.

const response = await client.user.get();
// Returns: { code: number, data: User }

Returns: UserResponse


Branches Resource

client.branches.list()

List all branches.

const branches = await client.branches.list();

Returns: Branch[]


client.branches.get(branchId)

Get a single branch by ID.

const branch = await client.branches.get(4630);

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID |

Returns: Branch


client.branches.getCustomer(branchId, customerId)

Get a customer from a specific branch.

const customer = await client.branches.getCustomer(4630, 123);
// or by customer code
const customer = await client.branches.getCustomer(4630, "CUST001");

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | customerId | number \| string | Yes | The customer ID or customer code |

Returns: Customer


client.branches.getOnlineAppointmentServices(branchId)

Get services available for online appointments.

const services = await client.branches.getOnlineAppointmentServices(4630);

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID |

Returns: OnlineAppointmentService[]


client.branches.getOnlineAppointmentEmployees(branchId, params)

Get employees available for online appointments, filtered by product IDs.

const employees = await client.branches.getOnlineAppointmentEmployees(4630, {
  product_ids: [1718, 5523],
});

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | params.product_ids | number[] | Yes | Array of product IDs to filter employees |

Returns: OnlineAppointmentEmployee[]


client.branches.getOnlineAppointmentTimeSlots(branchId, params)

Get available time slots for online appointments.

const timeSlots = await client.branches.getOnlineAppointmentTimeSlots(4630, {
  product_ids: [1718],
  date: "2024-12-15",
});

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | params.product_ids | number[] | Yes | Array of product IDs | | params.date | string | Yes | Date in YYYY-MM-DD format |

Returns: OnlineAppointmentTimeSlot[]


client.branches.createOnlineAppointment(branchId, params, options?)

Create an online appointment.

const appointment = await client.branches.createOnlineAppointment(
  4630,
  {
    date: "2024-12-15 10:00:00",
    items: [
      { product_id: 1718, unit: 1 },
      { product_id: 5523, unit: 2 },
    ],
    customer_id: 123,
    employee_id: 456, // optional
    remark: "Notes here", // optional
  },
  {
    idempotencyKey: "unique-request-key", // optional, prevents duplicate submissions
  }
);

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | params.date | string | Yes | Appointment date (ISO8601 or Y-m-d H:i:s format) | | params.items | { product_id: number, unit: number }[] | Yes | Array of items with product ID and quantity | | params.customer_id | number | Yes | The customer ID | | params.employee_id | number \| null | No | The employee ID (optional) | | params.remark | string | No | Appointment notes | | options.idempotencyKey | string | No | Idempotency key to prevent duplicates |

Returns: OnlineAppointmentSaleTicket


client.branches.cancelOnlineAppointment(branchId, saleTicketId, params)

Cancel an online appointment.

const cancelled = await client.branches.cancelOnlineAppointment(4630, 789, {
  customer_id: 123,
});

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | saleTicketId | number | Yes | The sale ticket ID to cancel | | params.customer_id | number | Yes | The customer ID |

Returns: OnlineAppointmentSaleTicket


client.branches.getCustomerUpcomingAppointments(branchId, customerId, params)

Get upcoming appointments for a customer within a date range.

const appointments = await client.branches.getCustomerUpcomingAppointments(
  4630,
  123,
  {
    from: "2024-12-01 00:00:00",
    to: "2024-12-31 23:59:59",
  }
);

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | branchId | number | Yes | The branch ID | | customerId | number | Yes | The customer ID | | params.from | string | Yes | Start date (ISO8601 or Y-m-d H:i:s format) | | params.to | string | Yes | End date (ISO8601 or Y-m-d H:i:s format) |

Returns: OnlineAppointmentSaleTicket[]

Note: Only returns appointments with statuses: OPEN, CONFIRMED, REQUEST, BOOKING_CONFIRMED.


Customers Resource

client.customers.searchByPhoneNumber(phoneNumber)

Search customers by phone number.

const customers = await client.customers.searchByPhoneNumber("+60123456789");

Parameters: | Name | Type | Required | Description | |------|------|----------|-------------| | phoneNumber | string | Yes | The phone number to search for |

Returns: Customer[]


Error Handling

The SDK provides specific error classes for different failure scenarios:

import {
  WessError,
  WessAuthenticationError,
  WessNotFoundError,
  WessValidationError,
  WessRateLimitError,
  WessNetworkError,
  WessTimeoutError,
} from "@voltade/wess-sdk";

try {
  const branch = await client.branches.get(99999);
} catch (error) {
  if (error instanceof WessAuthenticationError) {
    // 401 - Invalid or expired token
  } else if (error instanceof WessNotFoundError) {
    // 404 - Resource not found
  } else if (error instanceof WessValidationError) {
    // 422 - Validation failed
    console.error("Errors:", error.errors);
  } else if (error instanceof WessRateLimitError) {
    // 429 - Too many requests
  } else if (error instanceof WessNetworkError) {
    // Network connectivity issues
  } else if (error instanceof WessTimeoutError) {
    // Request timeout
  } else if (error instanceof WessError) {
    // Generic API error
    console.error(`API error (${error.statusCode}):`, error.message);
  }
}

Error Classes

| Error Class | Status Code | Description | | ------------------------- | ----------- | ------------------------------ | | WessError | Any | Base error class | | WessAuthenticationError | 401 | Invalid or missing credentials | | WessNotFoundError | 404 | Resource not found | | WessValidationError | 422 | Request validation failed | | WessRateLimitError | 429 | Too many requests | | WessNetworkError | - | Network connectivity issues | | WessTimeoutError | - | Request timeout |


TypeScript Types

All types are exported with Zod schemas for runtime validation.

Import Types

import type {
  // Config
  WessClientConfig,
  RequestOptions,

  // User
  User,
  UserResponse,

  // Branch
  Branch,

  // Customer
  Customer,

  // Online Appointments - Services
  OnlineAppointmentService,
  ServiceDetails,

  // Online Appointments - Employees
  OnlineAppointmentEmployee,
  EmployeeProduct,

  // Online Appointments - Time Slots
  OnlineAppointmentTimeSlot,

  // Online Appointments - Sale Ticket (Create/Cancel/Upcoming)
  OnlineAppointmentSaleTicket,
  SaleTicketCustomer,
  SaleTicketItem,

  // Request Parameters
  GetEmployeesParams,
  GetTimeSlotsParams,
  CreateAppointmentParams,
  CreateAppointmentOptions,
  CancelAppointmentParams,
  GetUpcomingAppointmentsParams,

  // Error Responses
  ApiErrorResponse,
  ValidationErrorResponse,
} from "@voltade/wess-sdk";

Import Zod Schemas

import {
  // User
  UserSchema,
  UserResponseSchema,

  // Branch
  BranchSchema,

  // Customer
  CustomerSchema,

  // Online Appointments
  OnlineAppointmentServiceSchema,
  ServiceDetailsSchema,
  OnlineAppointmentEmployeeSchema,
  EmployeeProductSchema,
  OnlineAppointmentTimeSlotSchema,
  OnlineAppointmentSaleTicketSchema,
  SaleTicketCustomerSchema,
  SaleTicketItemSchema,

  // Request Parameters
  GetEmployeesParamsSchema,
  GetTimeSlotsParamsSchema,
  CreateAppointmentParamsSchema,
  CancelAppointmentParamsSchema,
  GetUpcomingAppointmentsParamsSchema,

  // Error Responses
  ApiErrorResponseSchema,
  ValidationErrorResponseSchema,
} from "@voltade/wess-sdk";

Advanced Usage

Direct Resource Access

import { WessClient, BranchesResource } from "@voltade/wess-sdk";

const client = new WessClient({ baseUrl: "...", bearerToken: "..." });

const branches: BranchesResource = client.branches;
const allBranches = await branches.list();

Custom HTTP Client

const httpClient = client.getHttpClient();

// Make custom requests
const response = await httpClient.get("/custom-endpoint", {
  params: { key: "value" },
});

// Available methods: get, post, put, patch, delete

Requirements

  • Node.js >= 18.0.0
  • TypeScript >= 5.0.0

Architecture

@voltade/wess-sdk/
├── index.ts              # Main entry point & WessClient class
├── client.ts             # HTTP client wrapper
├── types.ts              # Re-exports from types/
├── errors.ts             # Error classes
├── resources/
│   ├── index.ts          # Resource exports
│   ├── user.ts           # User resource (1 method)
│   ├── branches.ts       # Branches resource (9 methods)
│   └── customers.ts      # Customers resource (1 method)
└── types/
    ├── index.ts          # Type exports
    ├── config.ts         # Config types
    ├── user.ts           # User types
    ├── branch.ts         # Branch types
    ├── customer.ts       # Customer types
    ├── appointment.ts    # Appointment types
    └── error.ts          # Error response types

Publishing (Maintainers Only)

This package is published exclusively to GitHub Packages.

1. Create a GitHub Personal Access Token

  • Go to https://github.com/settings/tokens/new
  • Name: npm-publish-token
  • Select scopes: write:packages, read:packages, and repo
  • Generate and copy the token

2. Authenticate with GitHub Packages

npm login --registry=https://npm.pkg.github.com
  • Username: voltade
  • Password: Your personal access token
  • Email: Your GitHub email

3. Publish

npm version patch  # or minor, or major
npm publish

License

MIT (c) Voltade

Support

For issues and questions, please file an issue on GitHub.