@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.
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
fetchAPI (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-sdkQuick 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-tokenClient 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, deleteRequirements
- 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 typesPublishing (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, andrepo - 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 publishLicense
MIT (c) Voltade
Support
For issues and questions, please file an issue on GitHub.
