attio-ts-sdk 1.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 CHANGED
@@ -15,6 +15,8 @@ A modern, type-safe TypeScript SDK for the [Attio](https://attio.com) CRM API. B
15
15
  - **Record normalization** (handles inconsistent response shapes)
16
16
  - **Metadata caching** (attributes, select options, statuses)
17
17
  - **Pagination helpers** (`paginate` + cursor handling)
18
+ - **Response helpers** (`assertOk`, `toResult`)
19
+ - **Offset pagination support** (`paginateOffset`)
18
20
 
19
21
  You still have full access to the generated, spec‑accurate endpoints.
20
22
 
@@ -77,6 +79,42 @@ const { data: people } = await postV2ObjectsByObjectRecordsQuery({
77
79
  });
78
80
  ```
79
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
+
80
118
  ### Attio Convenience Layer
81
119
 
82
120
  The Attio helpers wrap the generated endpoints with retries, error normalization,
@@ -105,6 +143,36 @@ const matches = await searchRecords({
105
143
  });
106
144
  ```
107
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
+
108
176
  ### Client Configuration
109
177
 
110
178
  ```typescript
@@ -140,10 +208,31 @@ try {
140
208
  }
141
209
  ```
142
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
+
143
226
  ### Pagination Helpers
144
227
 
145
228
  ```typescript
146
- import { createAttioClient, paginate, getV2Meetings } from 'attio-ts-sdk';
229
+ import {
230
+ createAttioClient,
231
+ paginate,
232
+ paginateOffset,
233
+ getV2Meetings,
234
+ postV2ObjectsByObjectRecordsQuery,
235
+ } from 'attio-ts-sdk';
147
236
 
148
237
  const client = createAttioClient({ apiKey: process.env.ATTIO_API_KEY });
149
238
 
@@ -155,6 +244,15 @@ const meetings = await paginate(async (cursor) => {
155
244
  });
156
245
  return result;
157
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
+ });
158
256
  ```
159
257
 
160
258
  ### Caching
@@ -185,13 +283,35 @@ const optionsAgain = await getAttributeOptions({
185
283
  }); // Returns cached result, no API call
186
284
  ```
187
285
 
188
- The metadata caches have the following limits:
286
+ The metadata caches have the following defaults:
189
287
  - **Attributes cache**: 200 entries max
190
288
  - **Options cache**: 500 entries max
191
289
  - **Statuses cache**: 500 entries max
192
290
 
193
291
  When a cache reaches its limit, the oldest entry is evicted.
194
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
+
195
315
  #### Client Instance Caching
196
316
 
197
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.
@@ -218,6 +338,27 @@ const freshClient = getAttioClient({
218
338
  });
219
339
  ```
220
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
+
221
362
  Note: `createAttioClient` always creates a new client instance. Use `getAttioClient` when you want caching behavior.
222
363
 
223
364
  ### Metadata Helpers