@memberjunction/actions-apollo 6.1.0-edge.4 → 6.1.0-edge.6

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.
Files changed (54) hide show
  1. package/README.md +79 -0
  2. package/dist/__tests__/apollo-enrichment.test.js +75 -1
  3. package/dist/__tests__/apollo-enrichment.test.js.map +1 -1
  4. package/dist/__tests__/apollo-lists.test.d.ts +2 -0
  5. package/dist/__tests__/apollo-lists.test.d.ts.map +1 -0
  6. package/dist/__tests__/apollo-lists.test.js +957 -0
  7. package/dist/__tests__/apollo-lists.test.js.map +1 -0
  8. package/dist/accounts.d.ts.map +1 -1
  9. package/dist/accounts.js +6 -4
  10. package/dist/accounts.js.map +1 -1
  11. package/dist/config.d.ts +10 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +10 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/contacts.d.ts.map +1 -1
  16. package/dist/contacts.js +14 -6
  17. package/dist/contacts.js.map +1 -1
  18. package/dist/generic/apollo-lists.types.d.ts +246 -0
  19. package/dist/generic/apollo-lists.types.d.ts.map +1 -0
  20. package/dist/generic/apollo-lists.types.js +42 -0
  21. package/dist/generic/apollo-lists.types.js.map +1 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +11 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/lists/ApolloListActions.d.ts +49 -0
  27. package/dist/lists/ApolloListActions.d.ts.map +1 -0
  28. package/dist/lists/ApolloListActions.js +135 -0
  29. package/dist/lists/ApolloListActions.js.map +1 -0
  30. package/dist/lists/ApolloMoveActions.d.ts +33 -0
  31. package/dist/lists/ApolloMoveActions.d.ts.map +1 -0
  32. package/dist/lists/ApolloMoveActions.js +272 -0
  33. package/dist/lists/ApolloMoveActions.js.map +1 -0
  34. package/dist/lists/ApolloRESTBaseAction.d.ts +49 -0
  35. package/dist/lists/ApolloRESTBaseAction.d.ts.map +1 -0
  36. package/dist/lists/ApolloRESTBaseAction.js +70 -0
  37. package/dist/lists/ApolloRESTBaseAction.js.map +1 -0
  38. package/dist/lists/ApolloRESTClient.d.ts +136 -0
  39. package/dist/lists/ApolloRESTClient.d.ts.map +1 -0
  40. package/dist/lists/ApolloRESTClient.js +561 -0
  41. package/dist/lists/ApolloRESTClient.js.map +1 -0
  42. package/dist/lists/ApolloSearchActions.d.ts +64 -0
  43. package/dist/lists/ApolloSearchActions.d.ts.map +1 -0
  44. package/dist/lists/ApolloSearchActions.js +239 -0
  45. package/dist/lists/ApolloSearchActions.js.map +1 -0
  46. package/dist/lists/credentials.d.ts +57 -0
  47. package/dist/lists/credentials.d.ts.map +1 -0
  48. package/dist/lists/credentials.js +161 -0
  49. package/dist/lists/credentials.js.map +1 -0
  50. package/dist/lists/params.d.ts +61 -0
  51. package/dist/lists/params.d.ts.map +1 -0
  52. package/dist/lists/params.js +113 -0
  53. package/dist/lists/params.js.map +1 -0
  54. package/package.json +8 -7
@@ -0,0 +1,561 @@
1
+ /**
2
+ * Apollo.io REST client for label management, saved-record search and prospecting.
3
+ *
4
+ * The five API behaviours this encodes are documented once, on
5
+ * `../generic/apollo-lists.types.ts`. Read that first; the methods below refer to
6
+ * them by number.
7
+ *
8
+ * Everything here goes through {@link ApolloRESTEndpoint} (`api.apollo.io/api/v1`),
9
+ * which is a different base path from the enrichment actions in this package.
10
+ * Auth is the `X-Api-Key` header — Apollo's REST convention, even though the
11
+ * docs' generic auth widget renders a "Bearer" label — and every write, plus the
12
+ * labels endpoints, needs a MASTER key. A scoped key returns 403, which this
13
+ * client rewrites into a message that says so instead of passing the bare status
14
+ * through.
15
+ *
16
+ * Endpoints used:
17
+ * GET /labels list labels
18
+ * POST /labels create a label
19
+ * POST /accounts/search saved accounts
20
+ * POST /contacts/search saved contacts
21
+ * POST /mixed_people/api_search prospecting people
22
+ * PATCH /accounts/{id} update one account's labels (master key)
23
+ * PATCH /contacts/{id} update one contact's labels (master key)
24
+ *
25
+ * The write body key is `label_names` (strings), not `label_ids`. Apollo's
26
+ * update-a-contact reference documents it explicitly along with the full-replace
27
+ * semantics; the update-an-account reference documents no label parameter at all,
28
+ * but mirrors the contact body in practice. If a future Apollo change rejects
29
+ * names on the account PATCH, the fix is to resolve names → ids through the
30
+ * cached map and send `label_ids` — still as a COMPLETE set, since the
31
+ * full-replace behaviour is the part that matters.
32
+ *
33
+ * No delete surface. The only writes are label-array updates and label creation.
34
+ */
35
+ import { LogError, LogStatus } from '@memberjunction/core';
36
+ import { ApolloRESTEndpoint } from '../config.js';
37
+ /** Apollo's per-page cap on every search endpoint. */
38
+ const MAX_PER_PAGE = 100;
39
+ /** Apollo's page cap, a consequence of its 50,000-record display limit. */
40
+ const MAX_PAGE = 500;
41
+ function isRecord(value) {
42
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
43
+ }
44
+ function stringOr(value, fallback) {
45
+ return typeof value === 'string' ? value : fallback;
46
+ }
47
+ function stringOrNull(value) {
48
+ return typeof value === 'string' && value.length > 0 ? value : null;
49
+ }
50
+ function numberOr(value, fallback) {
51
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
52
+ }
53
+ /** Coerce an unknown into a string[], dropping anything that is not a string. */
54
+ function toStringArray(value) {
55
+ if (!Array.isArray(value))
56
+ return [];
57
+ return value.filter((v) => typeof v === 'string');
58
+ }
59
+ /**
60
+ * Resolve a record's raw `label_ids` into names (quirk #5). An id with no
61
+ * matching label is dropped and reported through {@link onUnresolved} so the
62
+ * caller can log one aggregated warning instead of one per id. Dropping is the
63
+ * safe choice: passing a raw id through into a later `label_names` write would
64
+ * create a new label named after a hex string.
65
+ */
66
+ function resolveLabelNames(labelIds, idToName, onUnresolved) {
67
+ const names = [];
68
+ for (const id of labelIds) {
69
+ const name = idToName.get(id);
70
+ if (name !== undefined) {
71
+ names.push(name);
72
+ }
73
+ else {
74
+ onUnresolved(id);
75
+ }
76
+ }
77
+ return names;
78
+ }
79
+ function mapPagination(value) {
80
+ const p = isRecord(value) ? value : {};
81
+ return {
82
+ page: numberOr(p.page, 1),
83
+ perPage: numberOr(p.per_page, 0),
84
+ totalEntries: numberOr(p.total_entries, 0),
85
+ totalPages: numberOr(p.total_pages, 0),
86
+ };
87
+ }
88
+ function mapAccount(item, idToName, onUnresolved) {
89
+ const labelIds = toStringArray(item.label_ids);
90
+ return {
91
+ id: stringOr(item.id, ''),
92
+ name: stringOr(item.name, ''),
93
+ primaryDomain: stringOr(item.primary_domain, ''),
94
+ labelIds,
95
+ labelNames: resolveLabelNames(labelIds, idToName, onUnresolved),
96
+ };
97
+ }
98
+ function mapContact(item, idToName, onUnresolved) {
99
+ const labelIds = toStringArray(item.label_ids);
100
+ return {
101
+ id: stringOr(item.id, ''),
102
+ firstName: stringOr(item.first_name, ''),
103
+ lastName: stringOr(item.last_name, ''),
104
+ name: stringOr(item.name, ''),
105
+ title: stringOr(item.title, ''),
106
+ email: stringOr(item.email, ''),
107
+ // Apollo returns either a flat `organization_name` or a nested `organization.name`.
108
+ organizationName: stringOr(item.organization_name, isRecord(item.organization) ? stringOr(item.organization.name, '') : ''),
109
+ labelIds,
110
+ labelNames: resolveLabelNames(labelIds, idToName, onUnresolved),
111
+ };
112
+ }
113
+ function mapPerson(item) {
114
+ const org = isRecord(item.organization) ? item.organization : {};
115
+ return {
116
+ id: stringOr(item.id, ''),
117
+ firstName: stringOr(item.first_name, ''),
118
+ lastName: stringOr(item.last_name, ''),
119
+ name: stringOr(item.name, ''),
120
+ title: stringOr(item.title, ''),
121
+ linkedinUrl: stringOr(item.linkedin_url, ''),
122
+ organizationId: stringOrNull(item.organization_id) ?? stringOrNull(org.id),
123
+ organizationName: stringOr(item.organization_name, stringOr(org.name, '')),
124
+ };
125
+ }
126
+ /** Clamp paging into Apollo's bounds, defaulting drain-safe (quirk #3). */
127
+ function normalizePaging(paging) {
128
+ const page = Math.min(Math.max(numberOr(paging?.page, 1), 1), MAX_PAGE);
129
+ const perPage = Math.min(Math.max(numberOr(paging?.perPage, MAX_PER_PAGE), 1), MAX_PER_PAGE);
130
+ return { page, perPage };
131
+ }
132
+ /**
133
+ * Apollo.io list/search client. See the module doc, and the quirk list on
134
+ * `apollo-lists.types.ts`, for the behaviours it encodes.
135
+ */
136
+ export class ApolloRESTClient {
137
+ constructor(apiKey, options) {
138
+ /**
139
+ * The label id↔name maps, built on first use and cached for the instance
140
+ * lifetime (quirk #5). One labels call per client, shared by every search and
141
+ * move. No TTL: a single drain or move operation uses one instance, and
142
+ * labels do not churn mid-operation. Construct a new client to see label
143
+ * changes made since.
144
+ */
145
+ this.labelMaps = null;
146
+ if (!apiKey || apiKey.trim().length === 0) {
147
+ throw new Error('ApolloRESTClient: apiKey is required');
148
+ }
149
+ this.apiKey = apiKey;
150
+ // Bind global fetch so it keeps its expected `this` when not injected.
151
+ this.fetchImpl = options?.fetchImpl ?? fetch.bind(globalThis);
152
+ }
153
+ // ─── HTTP ────────────────────────────────────────────────────────────────
154
+ /**
155
+ * Issue one request and return the parsed body. A non-2xx throws with the
156
+ * method, path, status and whatever detail Apollo supplied; a 403 on a
157
+ * master-key operation throws the master-key explanation instead (quirk #4).
158
+ * Nothing is swallowed — a body that will not parse still surfaces its text.
159
+ */
160
+ async request(args) {
161
+ const { method, path, context, body, masterKeyOp } = args;
162
+ const url = `${ApolloRESTEndpoint}${path}`;
163
+ const headers = {
164
+ 'X-Api-Key': this.apiKey,
165
+ accept: 'application/json',
166
+ };
167
+ if (body !== undefined) {
168
+ headers['Content-Type'] = 'application/json';
169
+ }
170
+ const response = await this.fetchImpl(url, {
171
+ method,
172
+ headers,
173
+ body: body !== undefined ? JSON.stringify(body) : undefined,
174
+ });
175
+ if (!response.ok) {
176
+ let rawText = '';
177
+ let detail = '';
178
+ try {
179
+ rawText = await response.text();
180
+ const parsed = JSON.parse(rawText);
181
+ if (isRecord(parsed)) {
182
+ detail = stringOr(parsed.error, stringOr(parsed.message, ''));
183
+ }
184
+ }
185
+ catch {
186
+ // Body was not JSON. The error thrown below still carries rawText,
187
+ // so nothing is lost here.
188
+ }
189
+ if (response.status === 403 && masterKeyOp) {
190
+ const message = `ApolloRESTClient.${context}: ${method} ${path} returned HTTP 403. ` +
191
+ `This endpoint requires a MASTER Apollo API key — scoped keys 403 on label reads/writes ` +
192
+ `and on account/contact updates.` +
193
+ (detail ? ` (${detail})` : '');
194
+ LogError(message);
195
+ throw new Error(message);
196
+ }
197
+ const fallback = detail || rawText.slice(0, 500);
198
+ const message = `ApolloRESTClient.${context}: ${method} ${path} failed with HTTP ${response.status}${fallback ? ` — ${fallback}` : ''}`;
199
+ LogError(message);
200
+ throw new Error(message);
201
+ }
202
+ try {
203
+ return (await response.json());
204
+ }
205
+ catch (error) {
206
+ const msg = error instanceof Error ? error.message : String(error);
207
+ const message = `ApolloRESTClient.${context}: ${method} ${path} returned a non-JSON body: ${msg}`;
208
+ LogError(message);
209
+ throw new Error(message);
210
+ }
211
+ }
212
+ // ─── Labels ──────────────────────────────────────────────────────────────
213
+ /**
214
+ * Every label, account lists and contact lists alike. Master key required.
215
+ * Apollo returns either a bare array or a `{ labels: [...] }` envelope
216
+ * depending on the account; both are accepted.
217
+ */
218
+ async listLabels() {
219
+ const data = await this.request({ method: 'GET', path: '/labels', context: 'listLabels', masterKeyOp: true });
220
+ const arr = Array.isArray(data) ? data : isRecord(data) && Array.isArray(data.labels) ? data.labels : null;
221
+ if (arr === null) {
222
+ throw new Error('ApolloRESTClient.listLabels: unexpected response shape — expected an array of labels or { labels: [...] }');
223
+ }
224
+ return arr.filter(isRecord).map((item) => ({
225
+ id: stringOr(item.id, ''),
226
+ name: stringOr(item.name, ''),
227
+ cachedCount: numberOr(item.cached_count, 0),
228
+ // Apollo's field is `modality`; surfaced as `kind`.
229
+ kind: stringOr(item.modality, 'unknown'),
230
+ createdAt: stringOr(item.created_at, ''),
231
+ updatedAt: stringOr(item.updated_at, ''),
232
+ }));
233
+ }
234
+ /**
235
+ * Create a label. Master key required.
236
+ *
237
+ * `modality` is not optional to Apollo despite reading like it should be:
238
+ * posting without it returns HTTP 422 "Please enter a non-empty modality!".
239
+ * It defaults to 'contacts' here because a people list is the common case.
240
+ *
241
+ * The create response shape is not pinned in Apollo's docs, so a bare label
242
+ * object, a `{ label: {...} }` envelope and a `{ labels: [...] }` envelope
243
+ * are all accepted — mirroring how {@link listLabels} tolerates two read
244
+ * shapes. A shape none of those match throws rather than returning a label
245
+ * with an empty id, which would then be written into a membership array.
246
+ */
247
+ async createLabel(name, modality = 'contacts') {
248
+ const trimmed = name.trim();
249
+ if (trimmed.length === 0) {
250
+ throw new Error('ApolloRESTClient.createLabel: name is required');
251
+ }
252
+ const data = await this.request({
253
+ method: 'POST',
254
+ path: '/labels',
255
+ context: 'createLabel',
256
+ body: { name: trimmed, modality },
257
+ masterKeyOp: true,
258
+ });
259
+ const raw = isRecord(data) && isRecord(data.label)
260
+ ? data.label
261
+ : isRecord(data) && Array.isArray(data.labels) && data.labels.length > 0
262
+ ? data.labels[0]
263
+ : data;
264
+ if (!isRecord(raw)) {
265
+ throw new Error('ApolloRESTClient.createLabel: unexpected response shape — expected a label object, { label: {...} }, or { labels: [...] }');
266
+ }
267
+ const id = stringOr(raw.id, '');
268
+ if (id.length === 0) {
269
+ throw new Error('ApolloRESTClient.createLabel: response carried no label id — cannot confirm the label was created');
270
+ }
271
+ return {
272
+ id,
273
+ name: stringOr(raw.name, trimmed),
274
+ cachedCount: numberOr(raw.cached_count, 0),
275
+ kind: stringOr(raw.modality, 'unknown'),
276
+ createdAt: stringOr(raw.created_at, ''),
277
+ updatedAt: stringOr(raw.updated_at, ''),
278
+ };
279
+ }
280
+ /**
281
+ * Resolve a label by exact name, case-insensitive; null when nothing matches.
282
+ * This is how a human-supplied list name becomes the id a search filter needs.
283
+ */
284
+ async findLabelByName(name) {
285
+ const target = name.trim().toLowerCase();
286
+ if (target.length === 0) {
287
+ throw new Error('ApolloRESTClient.findLabelByName: name is required');
288
+ }
289
+ const labels = await this.listLabels();
290
+ return labels.find((l) => l.name.trim().toLowerCase() === target) ?? null;
291
+ }
292
+ /**
293
+ * Build (once per instance) the id↔name maps that resolve search-response
294
+ * `label_ids` into names (quirk #5). When two labels share a name — rare — the
295
+ * last one wins in `nameToId`.
296
+ */
297
+ async getLabelMaps() {
298
+ if (this.labelMaps !== null) {
299
+ return this.labelMaps;
300
+ }
301
+ const labels = await this.listLabels();
302
+ const idToName = new Map();
303
+ const nameToId = new Map();
304
+ for (const label of labels) {
305
+ if (label.id.length > 0) {
306
+ idToName.set(label.id, label.name);
307
+ }
308
+ if (label.name.length > 0) {
309
+ nameToId.set(label.name, label.id);
310
+ }
311
+ }
312
+ this.labelMaps = { idToName, nameToId };
313
+ return this.labelMaps;
314
+ }
315
+ /** One aggregated warning for label ids that did not resolve to a name (quirk #5). */
316
+ warnUnresolvedLabels(context, unresolved) {
317
+ if (unresolved.size > 0) {
318
+ LogStatus(`ApolloRESTClient.${context}: ${unresolved.size} label id(s) had no matching label and were dropped from labelNames ` +
319
+ `(the raw ids stay on labelIds): ${[...unresolved].join(', ')}`);
320
+ }
321
+ }
322
+ // ─── Searches ────────────────────────────────────────────────────────────
323
+ /**
324
+ * One page of saved accounts. Paging defaults to page 1 — when draining a
325
+ * list, never advance (quirk #3).
326
+ */
327
+ async searchAccounts(filter, paging) {
328
+ const { page, perPage } = normalizePaging(paging);
329
+ const body = { page, per_page: perPage };
330
+ if (filter.labelIds && filter.labelIds.length > 0)
331
+ body.account_label_ids = filter.labelIds;
332
+ if (filter.keywords)
333
+ body.q_organization_name = filter.keywords;
334
+ const { idToName } = await this.getLabelMaps();
335
+ const data = await this.request({ method: 'POST', path: '/accounts/search', context: 'searchAccounts', body });
336
+ if (!isRecord(data)) {
337
+ throw new Error('ApolloRESTClient.searchAccounts: unexpected response shape — expected an object with accounts + pagination');
338
+ }
339
+ // Saved-account search returns `accounts`; some responses use `organizations`.
340
+ const rows = Array.isArray(data.accounts) ? data.accounts : Array.isArray(data.organizations) ? data.organizations : [];
341
+ const unresolved = new Set();
342
+ const accounts = rows.filter(isRecord).map((item) => mapAccount(item, idToName, (id) => unresolved.add(id)));
343
+ this.warnUnresolvedLabels('searchAccounts', unresolved);
344
+ return { accounts, pagination: mapPagination(data.pagination) };
345
+ }
346
+ /** One page of saved contacts. Same drain-page-1 default as {@link searchAccounts}. */
347
+ async searchContacts(filter, paging) {
348
+ const { page, perPage } = normalizePaging(paging);
349
+ const body = { page, per_page: perPage };
350
+ if (filter.labelIds && filter.labelIds.length > 0)
351
+ body.contact_label_ids = filter.labelIds;
352
+ if (filter.keywords)
353
+ body.q_keywords = filter.keywords;
354
+ const { idToName } = await this.getLabelMaps();
355
+ const data = await this.request({ method: 'POST', path: '/contacts/search', context: 'searchContacts', body });
356
+ if (!isRecord(data)) {
357
+ throw new Error('ApolloRESTClient.searchContacts: unexpected response shape — expected an object with contacts + pagination');
358
+ }
359
+ const rows = Array.isArray(data.contacts) ? data.contacts : [];
360
+ const unresolved = new Set();
361
+ const contacts = rows.filter(isRecord).map((item) => mapContact(item, idToName, (id) => unresolved.add(id)));
362
+ this.warnUnresolvedLabels('searchContacts', unresolved);
363
+ return { contacts, pagination: mapPagination(data.pagination) };
364
+ }
365
+ /**
366
+ * One page of prospecting people — net-new, not your saved contacts. Apollo
367
+ * does not return emails or phones here by design.
368
+ *
369
+ * Unlike the two searches above, this one does not need the label maps: the
370
+ * prospecting response carries no memberships, so fetching them would be a
371
+ * wasted master-key call on a read a scoped key can otherwise serve.
372
+ */
373
+ async searchPeople(filter, paging) {
374
+ const { page, perPage } = normalizePaging(paging);
375
+ const body = { page, per_page: perPage };
376
+ if (filter.organizationDomains && filter.organizationDomains.length > 0) {
377
+ body.q_organization_domains_list = filter.organizationDomains;
378
+ }
379
+ if (filter.organizationIds && filter.organizationIds.length > 0)
380
+ body.organization_ids = filter.organizationIds;
381
+ if (filter.titles && filter.titles.length > 0)
382
+ body.person_titles = filter.titles;
383
+ if (filter.seniorities && filter.seniorities.length > 0)
384
+ body.person_seniorities = filter.seniorities;
385
+ const data = await this.request({ method: 'POST', path: '/mixed_people/api_search', context: 'searchPeople', body });
386
+ if (!isRecord(data)) {
387
+ throw new Error('ApolloRESTClient.searchPeople: unexpected response shape — expected an object with people + pagination');
388
+ }
389
+ // Matches arrive under `people`, and historically under `contacts`.
390
+ const rows = Array.isArray(data.people) ? data.people : Array.isArray(data.contacts) ? data.contacts : [];
391
+ return { people: rows.filter(isRecord).map(mapPerson), pagination: mapPagination(data.pagination) };
392
+ }
393
+ // ─── Label writes: the two-step, label-preserving move ───────────────────
394
+ /**
395
+ * Replace one account's label set with `labelNames` — which must be the
396
+ * COMPLETE intended set, because Apollo overwrites wholesale (quirk #1).
397
+ * Master key required.
398
+ */
399
+ async updateAccountLabels(accountId, labelNames) {
400
+ if (!accountId || accountId.trim().length === 0) {
401
+ throw new Error('ApolloRESTClient.updateAccountLabels: accountId is required');
402
+ }
403
+ await this.request({
404
+ method: 'PATCH',
405
+ path: `/accounts/${encodeURIComponent(accountId)}`,
406
+ context: 'updateAccountLabels',
407
+ body: { label_names: labelNames },
408
+ masterKeyOp: true,
409
+ });
410
+ }
411
+ /** The same for one contact. Identical full-replace and master-key semantics. */
412
+ async updateContactLabels(contactId, labelNames) {
413
+ if (!contactId || contactId.trim().length === 0) {
414
+ throw new Error('ApolloRESTClient.updateContactLabels: contactId is required');
415
+ }
416
+ await this.request({
417
+ method: 'PATCH',
418
+ path: `/contacts/${encodeURIComponent(contactId)}`,
419
+ context: 'updateContactLabels',
420
+ body: { label_names: labelNames },
421
+ masterKeyOp: true,
422
+ });
423
+ }
424
+ /**
425
+ * Re-read one account's current labels for the verify pass (quirk #2), by
426
+ * searching the destination list and matching on id. Null when the record is
427
+ * not on that page, which is not the same as "the remove worked" — hence
428
+ * `possiblyStuck` stays null rather than becoming false.
429
+ */
430
+ async readAccountLabels(accountId, toListLabelId) {
431
+ const filter = toListLabelId ? { labelIds: [toListLabelId] } : {};
432
+ const pageData = await this.searchAccounts(filter, { page: 1, perPage: MAX_PER_PAGE });
433
+ const found = pageData.accounts.find((a) => a.id === accountId);
434
+ return found ? found.labelNames : null;
435
+ }
436
+ async readContactLabels(contactId, toListLabelId) {
437
+ const filter = toListLabelId ? { labelIds: [toListLabelId] } : {};
438
+ const pageData = await this.searchContacts(filter, { page: 1, perPage: MAX_PER_PAGE });
439
+ const found = pageData.contacts.find((c) => c.id === contactId);
440
+ return found ? found.labelNames : null;
441
+ }
442
+ /**
443
+ * The ADD phase's label set: current ∪ {toList}. Idempotent — adding a label
444
+ * the record already carries is a set no-op, so re-running a partial move
445
+ * does not duplicate anything.
446
+ */
447
+ addPhaseLabels(currentLabels, toList) {
448
+ return currentLabels.includes(toList) ? [...currentLabels] : [...currentLabels, toList];
449
+ }
450
+ /**
451
+ * The REMOVE phase's label set: (current ∪ {toList}) \ {fromList}.
452
+ *
453
+ * It is computed from the post-add state rather than from `current` so that
454
+ * the destination label survives the second write. Deriving it from `current`
455
+ * alone would add the record to the destination and then immediately take it
456
+ * back out.
457
+ */
458
+ removePhaseLabels(currentLabels, fromList, toList) {
459
+ const postAdd = this.addPhaseLabels(currentLabels, toList);
460
+ return postAdd.filter((l) => l !== fromList);
461
+ }
462
+ /**
463
+ * The move engine, shared by accounts and contacts through the injected
464
+ * update/read closures so the label-preservation math and the stuck detection
465
+ * exist in exactly one place.
466
+ */
467
+ async moveRecords(records, fromList, toList, ops, options) {
468
+ if (fromList.trim().length === 0 || toList.trim().length === 0) {
469
+ throw new Error('ApolloRESTClient.moveRecords: fromList and toList are both required');
470
+ }
471
+ if (fromList === toList) {
472
+ throw new Error(`ApolloRESTClient.moveRecords: fromList and toList are identical ('${fromList}') — nothing to move`);
473
+ }
474
+ const verify = options?.verify === true;
475
+ const items = [];
476
+ let movedCount = 0;
477
+ let failedCount = 0;
478
+ let possiblyStuckCount = 0;
479
+ for (const record of records) {
480
+ const item = { id: record.id, added: false, removed: false, possiblyStuck: null, error: null };
481
+ // Phase 1 — add the destination, preserving every current label (quirk #1).
482
+ try {
483
+ await ops.update(record.id, this.addPhaseLabels(record.labelNames, toList));
484
+ item.added = true;
485
+ }
486
+ catch (error) {
487
+ item.error = `add phase: ${error instanceof Error ? error.message : String(error)}`;
488
+ failedCount++;
489
+ items.push(item);
490
+ // Never attempt the remove when the add failed — that would strip the
491
+ // record from the source list without it having reached the destination.
492
+ continue;
493
+ }
494
+ // Phase 2 — remove the source, from the post-add state (quirk #1).
495
+ try {
496
+ await ops.update(record.id, this.removePhaseLabels(record.labelNames, fromList, toList));
497
+ item.removed = true;
498
+ }
499
+ catch (error) {
500
+ item.error = `remove phase: ${error instanceof Error ? error.message : String(error)}`;
501
+ failedCount++;
502
+ items.push(item);
503
+ continue;
504
+ }
505
+ // Optional verify — catches Apollo's silent-fail removes (quirk #2).
506
+ if (verify) {
507
+ try {
508
+ const after = await ops.readLabels(record.id);
509
+ // A null read means the record was not on the destination page,
510
+ // which is not evidence that the remove worked — so the stuck
511
+ // state stays unknown rather than being reported as verified.
512
+ item.possiblyStuck = after === null ? null : after.includes(fromList);
513
+ }
514
+ catch (error) {
515
+ // A failed verify read is not a failed move. Note it and leave the
516
+ // stuck state unknown rather than guessing either way.
517
+ LogStatus(`ApolloRESTClient.move(${ops.kind}): verify re-read failed for ${record.id} — leaving possiblyStuck=null: ` +
518
+ `${error instanceof Error ? error.message : String(error)}`);
519
+ }
520
+ }
521
+ if (item.possiblyStuck === true) {
522
+ possiblyStuckCount++;
523
+ }
524
+ else {
525
+ movedCount++;
526
+ }
527
+ items.push(item);
528
+ }
529
+ LogStatus(`ApolloRESTClient.move(${ops.kind}): '${fromList}' → '${toList}' — ${movedCount} moved, ` +
530
+ `${possiblyStuckCount} possibly stuck (Apollo silent-fail, retried on the next drain), ${failedCount} failed of ${records.length}.`);
531
+ return { movedCount, failedCount, possiblyStuckCount, items };
532
+ }
533
+ /**
534
+ * Move accounts between lists. The supplied accounts must carry current
535
+ * `labelNames` from a fresh {@link searchAccounts} read — this method writes
536
+ * whatever it is given as the intended set, so stale labels here mean real
537
+ * memberships silently disappear.
538
+ *
539
+ * With `verify`, the destination list is re-read after each remove to flag
540
+ * silent-fail records. Never deletes, never auto-retries.
541
+ */
542
+ async moveAccounts(accounts, fromList, toList, options) {
543
+ // Resolve the destination label id once, for the verify re-reads.
544
+ const toLabelId = options?.verify ? (await this.findLabelByName(toList))?.id ?? null : null;
545
+ return this.moveRecords(accounts, fromList, toList, {
546
+ update: (id, labels) => this.updateAccountLabels(id, labels),
547
+ readLabels: (id) => this.readAccountLabels(id, toLabelId),
548
+ kind: 'accounts',
549
+ }, options);
550
+ }
551
+ /** Move contacts between lists. Same two-step and verify semantics as accounts. */
552
+ async moveContacts(contacts, fromList, toList, options) {
553
+ const toLabelId = options?.verify ? (await this.findLabelByName(toList))?.id ?? null : null;
554
+ return this.moveRecords(contacts, fromList, toList, {
555
+ update: (id, labels) => this.updateContactLabels(id, labels),
556
+ readLabels: (id) => this.readContactLabels(id, toLabelId),
557
+ kind: 'contacts',
558
+ }, options);
559
+ }
560
+ }
561
+ //# sourceMappingURL=ApolloRESTClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApolloRESTClient.js","sourceRoot":"","sources":["../../src/lists/ApolloRESTClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
2
+ import { ApolloRESTBaseAction } from './ApolloRESTBaseAction.js';
3
+ /**
4
+ * Pages through the accounts in an Apollo list, addressed by exact list name.
5
+ *
6
+ * Returns each account's id, name, primary domain and current label names.
7
+ *
8
+ * When draining a list — reading members in order to move them out — read page 1
9
+ * every time. Removals shift every later page, so advancing to page 2 skips
10
+ * records. Read-only.
11
+ *
12
+ * Inputs:
13
+ * - ListName (required) exact label name; run Apollo Get Lists to see them
14
+ * - Keywords (optional) organization-name filter within the list
15
+ * - Page (optional, default 1, max 500)
16
+ * - PerPage (optional, default 100, max 100)
17
+ * - CompanyID (optional) per-company credential resolution
18
+ *
19
+ * Outputs:
20
+ * - Accounts / Pagination / Count / ResolvedListName / ListID / KeySource
21
+ */
22
+ export declare class ApolloGetListAccountsAction extends ApolloRESTBaseAction {
23
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
24
+ }
25
+ /**
26
+ * Pages through the contacts in an Apollo list. Same shape and same drain
27
+ * discipline as {@link ApolloGetListAccountsAction}; `Keywords` here matches
28
+ * names, titles, employers and emails rather than organization names.
29
+ *
30
+ * Outputs: Contacts / Pagination / Count / ResolvedListName / ListID / KeySource
31
+ */
32
+ export declare class ApolloGetListContactsAction extends ApolloRESTBaseAction {
33
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
34
+ }
35
+ /**
36
+ * Searches Apollo's people database for net-new prospects by organization, title
37
+ * and seniority — the list-building workhorse.
38
+ *
39
+ * This endpoint does not return emails or phones. That is Apollo's design, not an
40
+ * omission here: contact details come from the enrichment actions in this package,
41
+ * which are metered separately.
42
+ *
43
+ * At least one filter is required. Apollo will accept a request with none and
44
+ * return an unscoped result set, which burns the rate limit to produce something
45
+ * nobody asked for, so that case is rejected before the call.
46
+ *
47
+ * Inputs:
48
+ * - OrganizationDomains (optional) company domains
49
+ * - OrganizationIDs (optional) Apollo organization ids
50
+ * - Titles (optional) job titles, e.g. ["VP of Marketing"]
51
+ * - Seniorities (optional) owner | founder | c_suite | vp | director | manager
52
+ * - Page / PerPage (optional)
53
+ * - CompanyID (optional)
54
+ *
55
+ * Each list param accepts a real array, a JSON array string, or a
56
+ * comma-separated string.
57
+ *
58
+ * Outputs: People / Pagination / Count / KeySource
59
+ */
60
+ export declare class ApolloSearchPeopleAction extends ApolloRESTBaseAction {
61
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
62
+ }
63
+ export declare function LoadApolloSearchActions(): void;
64
+ //# sourceMappingURL=ApolloSearchActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApolloSearchActions.d.ts","sourceRoot":"","sources":["../../src/lists/ApolloSearchActions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAOxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAgBjE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,2BAA4B,SAAQ,oBAAoB;cACjD,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAiD1F;AAED;;;;;;GAMG;AACH,qBACa,2BAA4B,SAAQ,oBAAoB;cACjD,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAiD1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,wBAAyB,SAAQ,oBAAoB;cAC9C,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA2D1F;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}