@eldev/zoey-client-node
v3.12.0
Published
A client library for working with the Zoey API.
Downloads
89
Readme
Zoey Client for Node.js
Features
- Minimal dependencies (
zodas peer dependency) - Built as both CommonJS and ESM
- Fully type-safe
- Tested on MacOS and Ubuntu 20.04
Coming Soon
- Mock client for testing
Requirements
- Node 18+ (uses native Fetch API)
- Zod 4.0.0+ (peer dependency)
Installation
Install the package with:
npm install @eldev/zoey-client-nodeConfiguration
Pass the OAuth 1.0a credentials and site URL (see Zoey REST docs for instructions) as a ZoeyClientConfig object to the ZoeyClient.
You can optionally set a timeout for the request, but be aware some requests (like converting cart to checkout) can take 10+ seconds.
import { ZoeyClient } from "zoey-client-node";
import type { ZoeyClientConfig } from "zoey-client-node/types";
const configOptions: ZoeyClientConfig = {
baseUrl: "https://zoey-site-url.com/api/rest",
// timeout: 15_000
apiKey: "zoey_api_key_2342344235"
}
const zoey = new ZoeyClient(configOptions); // Throws ZoeyError with type: 'configuration'Basic Usage
Resource methods return either data or throw a ZoeyError.
You can also access the embedded HttpClient that has 3 methods: request, requestWithSchema, requestWithPagination.
Each takes a RequestOptions object.
requestWithSchema additionally takes a schema.
requestWithPagination also takes a PaginationOptions to control the amount of results and a transformFn to parse the page results.
requestWithPagination returns an AsyncIterableIterator that can be consumed with a for await loop.
const Account = z.object({ id: z.string() });
type Account = z.infer<typeof accountSchema>;
const requestOptions: RequestOptions = {
path: "/accounts/account"
queryParams: { id: "500" },
timeout: 5_000, // override default/initialized timeout
method: "GET", // defaults to GET
// body: some_body_object
};
// Raw request
await zoey.client.request(requestOptions); // => unknown
// Parsed request
await zoey.client.requestWithSchema(
requestOptions,
schema: Account,
); // => Account
// Pagination
const paginationOptions: PaginationOptions = {
maxResults: 50,
orderBy: 'created_at'
orderDir: 'DESC'
}
const transformFn = (data: unknown) => z.array(Account).parse(data); // Parses list page into array
const iter = zoey.client.requestWithPagination(
requestOptions,
transformFn,
paginationOptions
)
// Iterate through each record and lazily fetch next page
for await (const account of iter) {
doSomething(account)
};
// Resource methods
// Get single records are explicitly named as they can use different identifiers
await zoey.accounts.getByAccountNumber("account_number_here") // Account
const listOpts: ZoeyListOptions = { maxResults: 50, orderBy: 'created_at', orderDir: 'DESC' }
const iter = zoey.accounts.list(listOpts)
for await (const account of iter) {} // Lazily fetch each page as you loop through
const all = Array.fromAsync(iter) // Loop through all and collect into array
Errors
ZoeyError extends Error and always includes a message property and a type property.
Based on the type code there may be other properties like the URL path, full response body, etc.
| Error Code | Description |
| --------------------- | ----------------------------------------------------------------------------------------- |
| configuration | An invalid ZoeyClientConfig object passed to the client constructor. |
| connection | There was an issue connecting to the Zoey API server. This is an error thrown by fetch. |
| invalid_return_type | The return type from the Zoey API did not match the schema. |
| bad_json | The response body could not be parsed and threw a SyntaxError. |
| timeout | The fetch request threw a TimeoutError due to AbortSignal.timeout() |
| bad_request | The API returned a 400 status. |
| authentication | The API returned a 401 status. |
| permission | The API returned a 403 status. |
| not_found | The API returned a 404 status. |
| too_many_requests | The API returned a 429 status. |
| api_error | The API returned 500 or any other not specified status. |
| unknown | The fetch request threw something that was not an instance of Error. |
Todo:
- Add live e2e tests that record data for msw
