-
Notifications
You must be signed in to change notification settings - Fork 0
/
list_entries.ts
342 lines (320 loc) · 11 KB
/
list_entries.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
import type { AxiosInstance } from 'axios'
import type { EntityType, GetQuery } from './lists.ts'
import { listEntriesUrl } from './urls.ts'
import { defaultTransformers } from './axios_default_transformers.ts'
import type { DateTime, Replace } from './types.ts'
import { PersonType } from './persons.ts'
import { Organization } from './organizations.ts'
import { transformListEntryReference } from './transform_list_entry_reference.ts'
import { PagedResponse } from './paged_response.ts'
export type Person = {
id: number
type: PersonType
first_name: string
last_name: string
primary_email: string
emails: string[]
}
export type Opportunity = {
id: number
name: string
}
/**
* The entity object contains details about the person, organization or opportunity corresponding to the list entry.
*/
export type Entity =
| Person
| Organization
| Opportunity
export type ListEntryReferenceRaw = {
/**
* The unique identifier of the list entry object.
*/
id: number
/**
* The unique identifier of the list on which the list entry resides.
*/
list_id: number
/**
* The unique identifier of the user who created the list entry. If you create a list entry through the API, the user corresponding to the API token will be the creator by default.
*/
creator_id: number
/**
* The unique identifier of the entity corresponding to the list entry.
*/
entity_id: number
/**
* The time when the list entry was created.
*/
created_at: DateTime
}
export type ListEntryResponseRaw =
& {
/**
* The type of the entity corresponding to the list entry.
*/
entity_type: EntityType
/**
* Object containing entity-specific details like name, email address, domain etc. for the entity corresponding to entity_id.
*/
entity: Entity
}
& ListEntryReferenceRaw
export type PagedListEntryResponseRaw =
& {
list_entries: ListEntryResponseRaw[]
}
& PagedResponse
export type ListEntryResponse = Replace<ListEntryResponseRaw, {
created_at: Date
}>
export type PagedListEntryResponse = Replace<PagedListEntryResponseRaw, {
list_entries: ListEntryResponse[]
}>
/**
* Paging parameters for retrieving list entries.
*/
export type PagingParameters = {
/**
* How many results to return per page. (Default is to return all results.)
*
* *Note:* This is required in the paging parameters, as a `page_token` without a `page_size` will be ignored and the endpoint just returns all results.
*/
page_size: number
/**
* The {@link PagedListEntryResponse.next_page_token} from the previous response required to retrieve the next page of results.
*/
page_token?: string
}
export type ListEntryReference = {
/**
* The unique ID of the list that contains the specified `list_entry_id`.
*/
list_id: number
/**
* The unique ID of the list entry object to be retrieved.
*/
list_entry_id: number
}
/**
* Request payload for creating a new list entry.
*/
export type CreateListEntryParameters = {
/**
* The unique ID of the list whose list entries are to be retrieved.
*/
list_id: number
/**
* The unique ID of the person or organization to add to this list. Opportunities cannot be created using this endpoint.
*/
entity_id: number
/**
* The ID of a Person resource who should be recorded as adding the entry to the list.
* Must be a person who can access Affinity.
* If not provided the creator defaults to the owner of the API key.
*/
creator_id?: number
}
/**
* @module
*
* *Notes*: Although list entries correspond to rows in an Affinity spreadsheet, the values associated with the entity are not stored inside the list entry resource.
* If you are trying to update, create, or delete a value in one of the custom columns for this list entry, please refer to the [Field Values](https://api-docs.affinity.co/#field-values) section.
* The list entry API is only used for getting, adding, or removing entities from a list.
* It does not handle updating individual cells in columns.
*/
export class ListEntries {
/** @hidden */
constructor(private readonly axios: AxiosInstance) {
}
/**
* Fetches all list entries in the list with the supplied list id.
*
* *Please note:* the returned response has a different shape than when using a paginated request (see below)
*
* @returns An array of all list entries in the list with the supplied list id.
*
* @example
* ```typescript
* const entries = await affinity.lists.entries.all({ list_id: 123 })
* console.log(`The first of ${entries.length} entries is for`, entries?.[0].entity)
* ```
*/
async all(query: GetQuery): Promise<ListEntryResponse[]>
/**
* Fetches up to the number specified in {@link PagingParameters.page_size} of list entries in the list with the supplied list id.
*
* *Please note*: the returned response has a different shape than when using a non-paginated request (see above).
*
* @returns A chunk of list entries with the maximum size specified in the query.
*
* @example
* ```typescript
* const { list_entries, next_page_token } = await affinity.lists.entries.all({
* list_id: 123,
* page_size: 10
* })
* console.log(`The first of ${list_entries.length} entries in this page is for`, list_entries?.[0].entity)
* console.log(next_page_token
* ? `The next page token is '${next_page_token}'`
* : 'No more pages to fetch'
* )
* ```
*/
async all(
query: GetQuery & PagingParameters,
): Promise<PagedListEntryResponse>
/**
* Fetches entries in a given list
* @returns Either an array of all list entries or a chunk of list entries with the maximum size specified in the query
*/
async all(
query: GetQuery | GetQuery & PagingParameters,
): Promise<ListEntryResponse[] | PagedListEntryResponse> {
const { list_id, ...params } = query
const response = await this.axios.get<ListEntryResponse[]>(
listEntriesUrl(list_id),
{
params,
transformResponse: [
...defaultTransformers(),
(
json:
| ListEntryResponseRaw[]
| PagedListEntryResponseRaw,
) => {
if ('list_entries' in json) {
return {
...json,
list_entries: json.list_entries.map(
transformListEntryReference,
),
}
} else {
return json.map(transformListEntryReference)
}
},
],
},
)
return response.data
}
/**
* Fetches a list entry with a specified id.
*
* @returns The list entry object corresponding to the list_entry_id.
*
* @example
* ```typescript
* const listEntry = await affinity.lists.entries.get({ list_id: 450, list_entry_id: 16367 })
* console.log(listEntry)
* ```
*/
async get(
reference: ListEntryReference,
): Promise<ListEntryResponse> {
const { list_id, list_entry_id } = reference
const response = await this.axios.get<ListEntryResponse>(
listEntriesUrl(list_id, list_entry_id),
{
transformResponse: [
...defaultTransformers(),
transformListEntryReference,
],
},
)
return response.data
}
/**
* Returns an async iterator that yields all list entries in the list with the supplied list id.
* Each yielded array contains up to the number specified in {@link PagingParameters.page_size} of list entries.
* Use this method if you want to process the list entries in a streaming fashion.
*
* *Please note:* the yielded list entries array may be empty on the last page.
*
* @example
* ```typescript
* let page = 0
* for await (const entries of affinity.lists.entries.pagedIterator({
* list_id: 123,
* page_size: 10
* })) {
* console.log(`Page ${++page} of entries:`, entries)
* }
* ```
*/
async *pagedIterator(
query: GetQuery & Omit<PagingParameters, 'page_token'>,
): AsyncGenerator<ListEntryResponse[]> {
let page_token: string | undefined = undefined
while (true) {
const response: PagedListEntryResponse = await this.all(
page_token ? { ...query, page_token } : query,
)
yield response.list_entries
if (response.next_page_token === null) {
// no more pages to fetch
return
} else {
page_token = response.next_page_token
}
}
}
/**
* Deletes a specific list entry.
*
* @returns boolean indicating whether the list entry was successfully deleted.
*
* @example
* ```typescript
* const success = await affinity.lists.entries.delete({
* list_id: 450,
* list_entry_id: 16367
* })
* console.log(success ? 'List entry deleted': 'List entry not deleted')
* ```
*/
async delete(
reference: ListEntryReference,
): Promise<boolean> {
const { list_id, list_entry_id } = reference
const response = await this.axios.delete<{ success: boolean }>(
listEntriesUrl(list_id, list_entry_id),
)
return response.data.success === true
}
/**
* Creates a new list entry in the list with the supplied list_id.
*
* *Notes*:
* - Opportunities cannot be created using this endpoint. Instead use the POST /opportunities endpoint.
* - Person and company lists can contain the same entity multiple times. Depending on your use case, before you add an entry, you may want to verify whether or not it exists in the list already.
*
* @returns The created list entry object.
*
* @example
* ```typescript
* const newListEntry = await affinity.lists.entries.create({
* list_id: 450,
* entity_id: 38706
* })
* console.log(newListEntry)
* ```
*/
async create(
request: CreateListEntryParameters,
): Promise<ListEntryResponse> {
const { list_id, ...rest } = request
const response = await this.axios.post<ListEntryResponse>(
listEntriesUrl(list_id),
rest,
{
transformResponse: [
...defaultTransformers(),
transformListEntryReference,
],
},
)
return response.data
}
}