yee-sdk-node
v0.1.3
Published
TypeScript SDK for Yeeflow & YeeOffice
Maintainers
Readme
Yee OpenAPI Node SDK
Production-grade JavaScript/TypeScript SDK for Yee-compatible REST APIs.
Features
- Full TypeScript support with published
.d.ts - ESM + CJS builds (
tsup) fetch-based HTTP transport- API key auth via header
- Built-in token bucket rate limiter (default
10 req/s) - Retries with exponential backoff for transient failures
- Structured errors for HTTP, API, and timeout failures
- Resource-oriented client (
lists,users,workflows, etc.)
Installation
npm install yee-sdk-nodeAuthentication
import { YeeClient } from 'yee-sdk-node';
const client = new YeeClient({
apiKey: process.env.API_KEY,
baseUrl: 'https://api.yeeflow.com/v1',
});Quick Start
import { FilterType, YeeClient } from 'yee-sdk-node';
const client = new YeeClient({ apiKey: 'xxx', baseUrl: 'https://api.yeeflow.com/v1' });
const { data, totalCount } = await client.lists.queryItems({
listId: '1278240778311831552',
filters: [{ field: 'Status', type: FilterType.Equal, value: 'Active' }],
pageIndex: 1,
pageSize: 50,
});Configuration
const client = new YeeClient({
apiKey: 'xxx',
baseUrl: 'https://api.yeeflow.com/v1',
defaultAppId: 41, // use 30 for YeeOffice
timeoutMs: 30_000,
maxRetries: 2,
retry: {
maxRetries: 2,
initialDelayMs: 250,
maxDelayMs: 2000,
retryOnStatuses: [408, 409, 425, 429, 500, 502, 503, 504],
},
rateLimit: {
enabled: true,
requestsPerSecond: 10,
burst: 10,
},
});Error Handling
import { APIConnectionError, APIError, APITimeoutError } from 'yee-sdk-node';
try {
await client.users.get(123);
} catch (err) {
if (err instanceof APIError) {
console.error(err.status, err.code, err.message);
} else if (err instanceof APITimeoutError) {
console.error('request timed out');
} else if (err instanceof APIConnectionError) {
console.error('network error');
}
}Full API Reference
client.lists
get(listId, appId?)getFields(listId, appId?)createItem({ appId, listId, data })createItemsBatch({ appId, listId, items, triggerFlow? })updateItemsBatch({ appId, listId, items, triggerFlow? })deleteItemsBatch({ appId, listId, ids })updateItem({ appId, listId, id, data, rowVersion? })deleteItem({ appId, listId, id })getItem({ appId, listId, id, fields? })queryItems({ appId, listId, fields?, filters?, sorts?, pageIndex?, pageSize? })addItemFile({ appId, listId, id, fieldId, fileName, file, contentType? })addLibraryFile({ appId, listId, fileName, path?, file, contentType? })getLibraryFileContent({ appId, listId, id })
client.users
create(body)getByAccount(account)search({ pageIndex?, pageSize?, searchKey?, orgId?, sorts?, status?, wheres? })get(id)update(id, body)delete(id)enable(id)disable(id)
client.departments
list(parentId?)create(body)update(body)delete(id)
client.locations
list()create(body)get(id)update(id, body)delete(id)
client.groups
list({ keywords?, pageIndex?, pageSize? })create(body)update(id, body)delete(id)addUsers(id, userIds)getUsers(id, { keywords?, pageIndex?, pageSize? })removeUsers(id, userIds)
client.positions
list()create(body)update(id, body)delete(id)assignUsers(id, body)getAssignment({ id, userId?, bindingType?, targetId? })removeUsers(id, body)
client.workflows
startForm({ key, body })getTodoTasks({ assigneeId?, start?, end?, trackingNo?, pageIndex?, pageSize? })getTaskVariables(id)handleTask(id, body)listDelegates({ ownerId?, pageIndex?, pageSize? })createDelegate(body)getDelegate(id)updateDelegate(id, body)deleteDelegate(id)enableDelegate(id)disableDelegate(id)getFormVariables(id)updateFormVariables(id, body)
client.servicePortal
createUser({ portalId, body })searchUsers(portalId, { keywords?, pageIndex?, pageSize? })deleteUser({ portalId, userId })resetUserPassword({ portalId, userId, body })listGroups(portalId)createGroup({ portalId, body })updateGroup({ portalId, id, body })deleteGroup({ portalId, id })getGroupUserCount({ portalId, id })addUsersToGroup({ portalId, id, userIds })removeUsersFromGroup({ portalId, id, userIds })
client.agents
listByApplication({ listId, appId?, pageIndex?, pageSize? })getDefinition(agentId)run(agentId, variables)
client.files
upload({ fileName, file, contentType? })getContent(id)
client.webhooks
create(body)get(id)delete(id)
client.request
Use client.request() for non-standard or newly added endpoints:
const result = await client.request<{ ok: boolean }>({
method: 'GET',
path: '/custom/path',
query: { q: 'a' },
});Development
npm install
npm run lint
npm test
npm run buildLive Lists Tests
The project supports real API tests for lists endpoints.
Create a .env file in project root:
YEE_API_KEY=your_api_key
YEE_BASE_URL=https://api.yeeflow.com/v1
YEE_APP_ID=41
YEE_LIST_ID=1278240778311831552
YEE_LIST_ITEM_ID=your_list_item_id
YEE_AGENT_ID=your_agent_id
YEE_DEPARTMENT_PARENT_ID=0
YEE_GROUP_TEST_USER_ID=your_user_id
YEE_SERVICE_PORTAL_ID=your_portal_id
YEE_SERVICE_PORTAL_TEST_PASSWORD=your_password
RUN_LIVE_LIST_TESTS=trueThen run:
npm run test:liveVersioning
This project follows Semantic Versioning. See VERSIONING.md and CHANGELOG.md.
