attio-ts-sdk 0.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +214 -22
- package/dist/index.d.mts +692 -277
- package/dist/index.mjs +1689 -873
- package/dist/index.mjs.map +1 -1
- package/package.json +30 -26
- package/dist/browser.d.ts +0 -14933
- package/dist/browser.js +0 -8
- package/dist/browser.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Attio CRM TypeScript SDK
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/attio-ts-sdk)
|
|
4
|
+
[](https://github.com/hbmartin/attio-ts-sdk/actions/workflows/ci.yml)
|
|
5
|
+
[](https://codecov.io/gh/hbmartin/attio-ts-sdk)
|
|
6
|
+
[](https://github.com/hbmartin/attio-ts-sdk/blob/main/LICENSE)
|
|
7
|
+
[](https://context7.com/hbmartin/attio-ts-sdk)
|
|
8
|
+
[](https://deepwiki.com/hbmartin/attio-ts-sdk)
|
|
9
|
+
|
|
3
10
|
A modern, type-safe TypeScript SDK for the [Attio](https://attio.com) CRM API. Built with Zod v4 and a new Attio‑aware client layer that adds retries, error normalization, caching, and higher‑level helpers on top of the generated OpenAPI client.
|
|
4
11
|
|
|
5
12
|
- **Create an Attio client in one line** (`createAttioClient({ apiKey })`)
|
|
@@ -8,6 +15,8 @@ A modern, type-safe TypeScript SDK for the [Attio](https://attio.com) CRM API. B
|
|
|
8
15
|
- **Record normalization** (handles inconsistent response shapes)
|
|
9
16
|
- **Metadata caching** (attributes, select options, statuses)
|
|
10
17
|
- **Pagination helpers** (`paginate` + cursor handling)
|
|
18
|
+
- **Response helpers** (`assertOk`, `toResult`)
|
|
19
|
+
- **Offset pagination support** (`paginateOffset`)
|
|
11
20
|
|
|
12
21
|
You still have full access to the generated, spec‑accurate endpoints.
|
|
13
22
|
|
|
@@ -15,9 +24,7 @@ You still have full access to the generated, spec‑accurate endpoints.
|
|
|
15
24
|
|
|
16
25
|
- **Full Attio API Coverage** - People, companies, lists, notes, tasks, meetings, webhooks, and more
|
|
17
26
|
- **Runtime Validation** - Every request and response validated with Zod v4 schemas
|
|
18
|
-
- **Tiny Bundle** - Browser build under 3.5KB gzipped
|
|
19
27
|
- **Tree-Shakeable** - Import only what you need
|
|
20
|
-
- **Isomorphic** - Works in Node.js, Bun, Deno, and browsers
|
|
21
28
|
- **TypeScript First** - Complete type definitions generated from OpenAPI spec
|
|
22
29
|
- **Attio-Aware Client** - Retries, normalized errors, caching, helpers
|
|
23
30
|
- **Zero Config** - Sensible defaults, just add your API key
|
|
@@ -72,6 +79,42 @@ const { data: people } = await postV2ObjectsByObjectRecordsQuery({
|
|
|
72
79
|
});
|
|
73
80
|
```
|
|
74
81
|
|
|
82
|
+
### Recommended Pattern
|
|
83
|
+
|
|
84
|
+
Prefer the Attio convenience layer, throw on errors by default, and unwrap responses with helpers.
|
|
85
|
+
This keeps request code compact and consistent.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import {
|
|
89
|
+
assertOk,
|
|
90
|
+
createAttioClient,
|
|
91
|
+
createAttioSdk,
|
|
92
|
+
getV2Objects,
|
|
93
|
+
value,
|
|
94
|
+
} from 'attio-ts-sdk';
|
|
95
|
+
|
|
96
|
+
const client = createAttioClient({
|
|
97
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
98
|
+
responseStyle: 'data',
|
|
99
|
+
throwOnError: true,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const sdk = createAttioSdk({ client });
|
|
103
|
+
|
|
104
|
+
const company = await sdk.records.create({
|
|
105
|
+
object: 'companies',
|
|
106
|
+
values: {
|
|
107
|
+
name: value.string('Acme Corp'),
|
|
108
|
+
domains: value.domain('acme.com'),
|
|
109
|
+
annual_revenue: value.currency(50000, 'USD'),
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Use assertOk with generated endpoints when you need raw access
|
|
114
|
+
const objects = assertOk(await getV2Objects({ client }));
|
|
115
|
+
console.log(objects);
|
|
116
|
+
```
|
|
117
|
+
|
|
75
118
|
### Attio Convenience Layer
|
|
76
119
|
|
|
77
120
|
The Attio helpers wrap the generated endpoints with retries, error normalization,
|
|
@@ -100,6 +143,36 @@ const matches = await searchRecords({
|
|
|
100
143
|
});
|
|
101
144
|
```
|
|
102
145
|
|
|
146
|
+
### Schema Helpers
|
|
147
|
+
|
|
148
|
+
Create a schema from cached metadata and use accessors to reduce raw string keys:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { createSchema } from 'attio-ts-sdk';
|
|
152
|
+
|
|
153
|
+
const schema = await createSchema({
|
|
154
|
+
client,
|
|
155
|
+
target: 'objects',
|
|
156
|
+
identifier: 'companies',
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const name = schema.getAccessorOrThrow('name').getFirstValue(company);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Record Value Helpers
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { getFirstValue, getValue, value } from 'attio-ts-sdk';
|
|
166
|
+
|
|
167
|
+
const values = {
|
|
168
|
+
name: value.string('Acme'),
|
|
169
|
+
domains: value.domain('acme.com'),
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const name = getFirstValue(company, 'name');
|
|
173
|
+
const domains = getValue(company, 'domains');
|
|
174
|
+
```
|
|
175
|
+
|
|
103
176
|
### Client Configuration
|
|
104
177
|
|
|
105
178
|
```typescript
|
|
@@ -135,10 +208,31 @@ try {
|
|
|
135
208
|
}
|
|
136
209
|
```
|
|
137
210
|
|
|
211
|
+
If you use the generated endpoints directly, you can normalize and unwrap responses:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { assertOk, toResult, getV2Objects } from 'attio-ts-sdk';
|
|
215
|
+
|
|
216
|
+
const objects = assertOk(await getV2Objects({ client }));
|
|
217
|
+
|
|
218
|
+
const result = toResult(await getV2Objects({ client }));
|
|
219
|
+
if (result.ok) {
|
|
220
|
+
console.log(result.value);
|
|
221
|
+
} else {
|
|
222
|
+
console.error(result.error);
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
138
226
|
### Pagination Helpers
|
|
139
227
|
|
|
140
228
|
```typescript
|
|
141
|
-
import {
|
|
229
|
+
import {
|
|
230
|
+
createAttioClient,
|
|
231
|
+
paginate,
|
|
232
|
+
paginateOffset,
|
|
233
|
+
getV2Meetings,
|
|
234
|
+
postV2ObjectsByObjectRecordsQuery,
|
|
235
|
+
} from 'attio-ts-sdk';
|
|
142
236
|
|
|
143
237
|
const client = createAttioClient({ apiKey: process.env.ATTIO_API_KEY });
|
|
144
238
|
|
|
@@ -150,8 +244,123 @@ const meetings = await paginate(async (cursor) => {
|
|
|
150
244
|
});
|
|
151
245
|
return result;
|
|
152
246
|
});
|
|
247
|
+
|
|
248
|
+
const offsetResults = await paginateOffset(async (offset, limit) => {
|
|
249
|
+
const result = await postV2ObjectsByObjectRecordsQuery({
|
|
250
|
+
client,
|
|
251
|
+
path: { object: 'companies' },
|
|
252
|
+
body: { offset, limit },
|
|
253
|
+
});
|
|
254
|
+
return result;
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Caching
|
|
259
|
+
|
|
260
|
+
The SDK includes two levels of caching to reduce API calls and improve performance:
|
|
261
|
+
|
|
262
|
+
#### Metadata Caching
|
|
263
|
+
|
|
264
|
+
Attribute metadata (attributes, select options, and statuses) is automatically cached with a 5-minute TTL. This reduces redundant API calls when working with the same objects repeatedly.
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { getAttributeOptions, getAttributeStatuses, listAttributes } from 'attio-ts-sdk';
|
|
268
|
+
|
|
269
|
+
// These calls are cached for 5 minutes
|
|
270
|
+
const options = await getAttributeOptions({
|
|
271
|
+
client,
|
|
272
|
+
target: 'objects',
|
|
273
|
+
identifier: 'companies',
|
|
274
|
+
attribute: 'stage',
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Subsequent calls with the same parameters return cached data
|
|
278
|
+
const optionsAgain = await getAttributeOptions({
|
|
279
|
+
client,
|
|
280
|
+
target: 'objects',
|
|
281
|
+
identifier: 'companies',
|
|
282
|
+
attribute: 'stage',
|
|
283
|
+
}); // Returns cached result, no API call
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The metadata caches have the following defaults:
|
|
287
|
+
- **Attributes cache**: 200 entries max
|
|
288
|
+
- **Options cache**: 500 entries max
|
|
289
|
+
- **Statuses cache**: 500 entries max
|
|
290
|
+
|
|
291
|
+
When a cache reaches its limit, the oldest entry is evicted.
|
|
292
|
+
|
|
293
|
+
You can customize TTL, max entries, and adapters per client:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
const client = createAttioClient({
|
|
297
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
298
|
+
cache: {
|
|
299
|
+
enabled: true,
|
|
300
|
+
metadata: {
|
|
301
|
+
ttlMs: 2 * 60 * 1000,
|
|
302
|
+
maxEntries: { attributes: 300, options: 800, statuses: 800 },
|
|
303
|
+
adapter: {
|
|
304
|
+
create: ({ scope, ttlMs, maxEntries }) =>
|
|
305
|
+
new YourCacheAdapter({ scope, ttlMs, maxEntries }),
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Clear metadata caches for this client
|
|
312
|
+
client.cache.clear();
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Client Instance Caching
|
|
316
|
+
|
|
317
|
+
You can cache `AttioClient` instances to reuse them across your application. This is useful when you want to avoid creating new client instances for repeated operations.
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { getAttioClient } from 'attio-ts-sdk';
|
|
321
|
+
|
|
322
|
+
// With cache.key set, the client instance is cached and reused
|
|
323
|
+
const client = getAttioClient({
|
|
324
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
325
|
+
cache: { key: 'my-app' },
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Returns the same cached client instance
|
|
329
|
+
const sameClient = getAttioClient({
|
|
330
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
331
|
+
cache: { key: 'my-app' },
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// Disable caching if needed
|
|
335
|
+
const freshClient = getAttioClient({
|
|
336
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
337
|
+
cache: { enabled: false },
|
|
338
|
+
});
|
|
153
339
|
```
|
|
154
340
|
|
|
341
|
+
### Debug Hooks
|
|
342
|
+
|
|
343
|
+
You can tap into request/response/error lifecycles for logging and tracing.
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
const client = createAttioClient({
|
|
347
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
348
|
+
hooks: {
|
|
349
|
+
onRequest: ({ request }) => console.log("request", request.method, request.url),
|
|
350
|
+
onResponse: ({ response }) => console.log("response", response.status),
|
|
351
|
+
onError: ({ error }) => console.error("error", error.message),
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Or wire a logger (debug/info/warn/error)
|
|
356
|
+
const clientWithLogger = createAttioClient({
|
|
357
|
+
apiKey: process.env.ATTIO_API_KEY,
|
|
358
|
+
logger: console,
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Note: `createAttioClient` always creates a new client instance. Use `getAttioClient` when you want caching behavior.
|
|
363
|
+
|
|
155
364
|
### Metadata Helpers
|
|
156
365
|
|
|
157
366
|
```typescript
|
|
@@ -329,23 +538,6 @@ const { data: webhook } = await postV2Webhooks({
|
|
|
329
538
|
const { data: webhooks } = await getV2Webhooks({ client });
|
|
330
539
|
```
|
|
331
540
|
|
|
332
|
-
### Browser Usage
|
|
333
|
-
|
|
334
|
-
For browsers, import from the `/browser` entry point:
|
|
335
|
-
|
|
336
|
-
```typescript
|
|
337
|
-
import { createClient, getV2Self } from 'attio-ts-sdk/browser';
|
|
338
|
-
|
|
339
|
-
const client = createClient({
|
|
340
|
-
baseUrl: 'https://api.attio.com',
|
|
341
|
-
headers: {
|
|
342
|
-
Authorization: `Bearer ${apiKey}`,
|
|
343
|
-
},
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
const { data: self } = await getV2Self({ client });
|
|
347
|
-
```
|
|
348
|
-
|
|
349
541
|
### Error Handling
|
|
350
542
|
|
|
351
543
|
```typescript
|
|
@@ -380,10 +572,10 @@ try {
|
|
|
380
572
|
|
|
381
573
|
### Tools
|
|
382
574
|
|
|
575
|
+
- **[Hey API](https://heyapi.dev/)**: OpenAPI client and Zod schema generation
|
|
383
576
|
- **Biome**: lint and format with a single tool
|
|
384
577
|
- **Vitest**: fast tests with coverage and thresholds
|
|
385
|
-
- **
|
|
386
|
-
- **tsdown**: ESM builds for Node and a separate browser bundle
|
|
578
|
+
- **tsdown**: ESM builds for Node
|
|
387
579
|
- **CI**: lint, typecheck, test, coverage, and size comments/badges
|
|
388
580
|
- **Deno-friendly**: `.ts` source imports for direct consumption
|
|
389
581
|
- **OIDC + Provenance**: publish to npm and JSR via manual CI release
|