@ycadence/sdk
v0.5.0
Published
TypeScript client for the YCadence API.
Maintainers
Readme
@ycadence/sdk
A TypeScript client for the YCadence REST API. The YCadence CLI and MCP server use it too.
- No runtime dependencies. It uses the platform
fetch. - It runs in Node 18+, Bun, Deno and browsers. Ships ESM with type declarations.
Install
npm install @ycadence/sdkIf npm is unavailable
Each release is mirrored to GitHub Packages when the npm publish fails, as
@yarlisaisolutions/ycadence-sdk. It needs a GitHub token with read:packages:
# ~/.npmrc
@yarlisaisolutions:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}npm install @yarlisaisolutions/ycadence-sdkUse
import { YCadenceClient, YCadenceError } from '@ycadence/sdk'
const client = new YCadenceClient({
baseUrl: 'https://ycadence.example.com',
apiKey: process.env.YCADENCE_API_KEY!, // a project, organization or personal key
})
const page = await client.listWorkItems('<projectId>', {
filter: { field: 'priority', operator: 'is', value: 'urgent' },
limit: 50,
})
try {
await client.createWorkItem('<projectId>', { name: 'Fix login redirect', priority: 'high' })
} catch (error) {
if (error instanceof YCadenceError) {
console.error(error.status, error.code, error.message, error.issues)
if (error.retryable) {
// 429 or 5xx
}
}
}Writes, retries and concurrency
Every method takes an optional last argument of request options:
await client.createWorkItem(projectId, { name: 'Fix login' }, { idempotencyKey: 'import-row-17' })
await client.updateWorkItem(id, { priority: 'urgent' }, { expectedVersion: 7 }) // If-Match: "7"idempotencyKeyis sent asIdempotency-Key, and makes the write safe to retry.expectedVersionis sent asIf-Match. A server that versions the resource answers 409version_conflict(or 412) when it has moved on; one that does not ignores the header.- GET requests, and writes that carry an idempotency key, are retried on 429, 5xx, timeouts
and network errors: twice by default, with exponential backoff and jitter, honouring
Retry-After. Other writes are never retried, since they may already have been applied.
Errors
Every failure is a YCadenceError with status, code, message, issues, details,
requestId and retryable, and is also an instance of a class for its kind:
YCadenceValidationError (400, 422), YCadencePermissionError (401, 403),
YCadenceNotFoundError (404), YCadenceConflictError (409), YCadencePreconditionError
(412), YCadenceRateLimitError (429, with retryAfter) and YCadenceNetworkError
(unreachable or timed out).
Pages
Lists return { items, nextCursor }. iterateWorkItems follows the cursor lazily, and
paginate / collect do the same for any list:
import { collect, paginate } from '@ycadence/sdk'
const all = await collect(paginate((cursor) => client.listWorkItems(projectId, { cursor })))Options
| Option | Meaning |
|---|---|
| baseUrl | Your instance, for example https://ycadence.example.com. Trailing slashes are fine. |
| apiKey | Sent as x-api-key. |
| identityToken | Only for an instance behind Google IAP or authenticated Cloud Run. Pass a string or a function, which is called before each request; it is sent as Authorization: Bearer. |
| timeoutMs | Defaults to 30000. |
| fetch | A custom fetch, for tests or proxies. |
| retry | { retries, baseDelayMs, maxDelayMs }; { retries: 0 } turns retrying off. |
| userAgent | Prepended to User-Agent (ycadence-sdk/<version>). |
| onResponse | Called after every response with method, path, status, request id, duration and attempt. Never sees credentials. |
Renamed from DevPulse
DevPulseClient and DevPulseError still work, as deprecated aliases of
YCadenceClient and YCadenceError. error instanceof DevPulseError still matches.
Existing API keys that start with dp_ keep working. New keys start with yc_.
License
Apache-2.0
