@rachelallyson/planning-center-people-ts 2.14.1 → 3.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/CHANGELOG.md +82 -7
- package/README.md +42 -4
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +14 -6
- package/dist/client.d.ts +33 -8
- package/dist/client.js +47 -22
- package/dist/core.d.ts +4 -2
- package/dist/core.js +3 -2
- package/dist/error-handling.d.ts +4 -4
- package/dist/error-handling.js +13 -2
- package/dist/error-scenarios.d.ts +11 -7
- package/dist/error-scenarios.js +26 -10
- package/dist/helpers.d.ts +124 -48
- package/dist/helpers.js +237 -93
- package/dist/index.d.ts +10 -8
- package/dist/index.js +31 -72
- package/dist/matching/matcher.d.ts +8 -4
- package/dist/matching/matcher.js +51 -58
- package/dist/matching/scoring.d.ts +9 -6
- package/dist/matching/scoring.js +18 -14
- package/dist/modules/campus.d.ts +31 -36
- package/dist/modules/campus.js +36 -49
- package/dist/modules/contacts.d.ts +33 -29
- package/dist/modules/contacts.js +36 -12
- package/dist/modules/fields.d.ts +39 -55
- package/dist/modules/fields.js +65 -105
- package/dist/modules/forms.d.ts +35 -24
- package/dist/modules/forms.js +41 -23
- package/dist/modules/households.d.ts +17 -19
- package/dist/modules/households.js +25 -34
- package/dist/modules/lists.d.ts +38 -28
- package/dist/modules/lists.js +62 -42
- package/dist/modules/notes.d.ts +32 -30
- package/dist/modules/notes.js +40 -52
- package/dist/modules/people.d.ts +83 -71
- package/dist/modules/people.js +323 -172
- package/dist/modules/reports.d.ts +18 -32
- package/dist/modules/reports.js +28 -40
- package/dist/modules/service-time.d.ts +19 -24
- package/dist/modules/service-time.js +28 -28
- package/dist/modules/workflows.d.ts +42 -47
- package/dist/modules/workflows.js +52 -53
- package/dist/performance.d.ts +14 -10
- package/dist/performance.js +61 -25
- package/dist/testing/recorder.js +11 -2
- package/dist/testing/simple-builders.d.ts +6 -4
- package/dist/testing/simple-builders.js +36 -49
- package/dist/testing/types.d.ts +4 -0
- package/dist/types/api-options.d.ts +380 -0
- package/dist/types/api-options.js +6 -0
- package/dist/types/client.d.ts +4 -2
- package/dist/types/client.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/people.d.ts +61 -9
- package/package.json +7 -7
- package/dist/core/http.d.ts +0 -56
- package/dist/core/http.js +0 -360
- package/dist/core/pagination.d.ts +0 -34
- package/dist/core/pagination.js +0 -178
- package/dist/people/contacts.d.ts +0 -43
- package/dist/people/contacts.js +0 -122
- package/dist/people/core.d.ts +0 -28
- package/dist/people/core.js +0 -69
- package/dist/people/fields.d.ts +0 -68
- package/dist/people/fields.js +0 -305
- package/dist/people/households.d.ts +0 -15
- package/dist/people/households.js +0 -31
- package/dist/people/index.d.ts +0 -8
- package/dist/people/index.js +0 -25
- package/dist/people/lists.d.ts +0 -34
- package/dist/people/lists.js +0 -48
- package/dist/people/notes.d.ts +0 -30
- package/dist/people/notes.js +0 -37
- package/dist/people/organization.d.ts +0 -12
- package/dist/people/organization.js +0 -15
- package/dist/people/workflows.d.ts +0 -37
- package/dist/people/workflows.js +0 -75
package/dist/helpers.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_TRUST_WINDOW = void 0;
|
|
4
|
-
exports.buildQueryParams = buildQueryParams;
|
|
3
|
+
exports.mapIncludedToRelationships = exports.DEFAULT_TRUST_WINDOW = void 0;
|
|
5
4
|
exports.calculateAge = calculateAge;
|
|
6
5
|
exports.calculateAgeSafe = calculateAgeSafe;
|
|
7
6
|
exports.isAdult = isAdult;
|
|
@@ -30,37 +29,26 @@ exports.getListsWithCategories = getListsWithCategories;
|
|
|
30
29
|
exports.getPersonWorkflowCardsWithNotes = getPersonWorkflowCardsWithNotes;
|
|
31
30
|
exports.createWorkflowCardWithNote = createWorkflowCardWithNote;
|
|
32
31
|
exports.exportAllPeopleData = exportAllPeopleData;
|
|
32
|
+
exports.findIncluded = findIncluded;
|
|
33
|
+
exports.resolveIncluded = resolveIncluded;
|
|
34
|
+
exports.createIncludedLookup = createIncludedLookup;
|
|
33
35
|
exports.extractFileUrl = extractFileUrl;
|
|
34
36
|
exports.isFileUrl = isFileUrl;
|
|
35
37
|
exports.getFileExtension = getFileExtension;
|
|
36
38
|
exports.getFilename = getFilename;
|
|
37
39
|
exports.isFileUpload = isFileUpload;
|
|
38
40
|
exports.processFileValue = processFileValue;
|
|
39
|
-
const
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (params?.include) {
|
|
51
|
-
queryParams.include = params.include.join(',');
|
|
52
|
-
}
|
|
53
|
-
if (params?.per_page) {
|
|
54
|
-
queryParams.per_page = params.per_page;
|
|
55
|
-
}
|
|
56
|
-
if (params?.page) {
|
|
57
|
-
queryParams.page = params.page;
|
|
58
|
-
}
|
|
59
|
-
if (params?.filter) {
|
|
60
|
-
queryParams.filter = params.filter;
|
|
61
|
-
}
|
|
62
|
-
return queryParams;
|
|
63
|
-
}
|
|
41
|
+
const planning_center_base_ts_1 = require("@rachelallyson/planning-center-base-ts");
|
|
42
|
+
/** Log to debug stream when client has debug enabled; no-op otherwise */
|
|
43
|
+
function debugLogIfEnabled(client, message, data) {
|
|
44
|
+
const config = 'getConfig' in client && typeof client.getConfig === 'function'
|
|
45
|
+
? client.getConfig()
|
|
46
|
+
: undefined;
|
|
47
|
+
const logger = (0, planning_center_base_ts_1.createDebugLogger)(config);
|
|
48
|
+
if (logger.enabled)
|
|
49
|
+
logger.log(message, data);
|
|
50
|
+
}
|
|
51
|
+
const planning_center_base_ts_2 = require("@rachelallyson/planning-center-base-ts");
|
|
64
52
|
/**
|
|
65
53
|
* Calculate age from birthdate string
|
|
66
54
|
*/
|
|
@@ -321,7 +309,7 @@ exports.DEFAULT_TRUST_WINDOW = 60 * 60 * 1000; // 1 hour
|
|
|
321
309
|
* @param trustWindow - Trust window in milliseconds (default: 1 hour)
|
|
322
310
|
* @returns Object with trust decision, age, and reason
|
|
323
311
|
*
|
|
324
|
-
* @
|
|
312
|
+
* @gmail.com
|
|
325
313
|
* ```typescript
|
|
326
314
|
* const trust = calculateTrust(pcoInfo.personIdCreatedAt);
|
|
327
315
|
* if (trust.shouldTrust) {
|
|
@@ -438,42 +426,69 @@ function validatePersonData(data) {
|
|
|
438
426
|
/**
|
|
439
427
|
* Get primary contact information for a person
|
|
440
428
|
*/
|
|
441
|
-
async function getPrimaryContact(client, personId
|
|
429
|
+
async function getPrimaryContact(client, personId) {
|
|
430
|
+
debugLogIfEnabled(client, 'helpers getPrimaryContact', { personId });
|
|
442
431
|
const [emails, phones, addresses] = await Promise.all([
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
432
|
+
client.people.getEmails(personId),
|
|
433
|
+
client.people.getPhoneNumbers(personId),
|
|
434
|
+
client.people.getAddresses(personId)
|
|
446
435
|
]);
|
|
447
|
-
const primaryEmail = emails.data.find((e) => e.
|
|
448
|
-
const primaryPhone = phones.data.find((p) => p.
|
|
449
|
-
const primaryAddress = addresses.data.find((a) => a.
|
|
436
|
+
const primaryEmail = emails.data.find((e) => e.primary);
|
|
437
|
+
const primaryPhone = phones.data.find((p) => p.primary);
|
|
438
|
+
const primaryAddress = addresses.data.find((a) => a.primary);
|
|
439
|
+
const addressValue = primaryAddress?.street_line_1 ?? addresses.data[0]?.street_line_1;
|
|
440
|
+
const addressString = typeof addressValue === 'string' ? addressValue : undefined;
|
|
450
441
|
return {
|
|
451
|
-
email: primaryEmail?.
|
|
452
|
-
phone: primaryPhone?.
|
|
453
|
-
address:
|
|
442
|
+
email: primaryEmail?.address ?? emails.data[0]?.address,
|
|
443
|
+
phone: primaryPhone?.number ?? phones.data[0]?.number,
|
|
444
|
+
address: addressString
|
|
454
445
|
};
|
|
455
446
|
}
|
|
456
447
|
/**
|
|
457
448
|
* Create a person with contact information
|
|
458
449
|
*/
|
|
459
|
-
async function createPersonWithContact(client, personData, contactData
|
|
460
|
-
|
|
450
|
+
async function createPersonWithContact(client, personData, contactData) {
|
|
451
|
+
debugLogIfEnabled(client, 'helpers createPersonWithContact', { firstName: personData.first_name, lastName: personData.last_name });
|
|
452
|
+
const createData = {};
|
|
453
|
+
if (personData.first_name)
|
|
454
|
+
createData.firstName = personData.first_name;
|
|
455
|
+
if (personData.last_name)
|
|
456
|
+
createData.lastName = personData.last_name;
|
|
457
|
+
if (personData.nickname !== null && personData.nickname !== undefined) {
|
|
458
|
+
createData.nickname = personData.nickname;
|
|
459
|
+
}
|
|
460
|
+
const person = await client.people.create(createData);
|
|
461
461
|
const results = { person };
|
|
462
462
|
if (contactData?.email) {
|
|
463
|
-
|
|
463
|
+
// Ensure required fields are present
|
|
464
|
+
if (contactData.email.address && contactData.email.location) {
|
|
465
|
+
results.email = await client.people.addEmail(person.id, {
|
|
466
|
+
address: contactData.email.address,
|
|
467
|
+
location: contactData.email.location,
|
|
468
|
+
primary: contactData.email.primary,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
464
471
|
}
|
|
465
472
|
if (contactData?.phone) {
|
|
466
|
-
|
|
473
|
+
// Ensure required fields are present
|
|
474
|
+
if (contactData.phone.number && contactData.phone.location) {
|
|
475
|
+
results.phone = await client.people.addPhoneNumber(person.id, {
|
|
476
|
+
number: contactData.phone.number,
|
|
477
|
+
location: contactData.phone.location,
|
|
478
|
+
primary: contactData.phone.primary,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
467
481
|
}
|
|
468
482
|
if (contactData?.address) {
|
|
469
|
-
results.address = await
|
|
483
|
+
results.address = await client.people.addAddress(person.id, contactData.address);
|
|
470
484
|
}
|
|
471
485
|
return results;
|
|
472
486
|
}
|
|
473
487
|
/**
|
|
474
488
|
* Search people by multiple criteria
|
|
475
489
|
*/
|
|
476
|
-
async function searchPeople(client, criteria
|
|
490
|
+
async function searchPeople(client, criteria) {
|
|
491
|
+
debugLogIfEnabled(client, 'helpers searchPeople', { criteria });
|
|
477
492
|
const where = {};
|
|
478
493
|
if (criteria.status) {
|
|
479
494
|
where.status = criteria.status;
|
|
@@ -485,37 +500,63 @@ async function searchPeople(client, criteria, context) {
|
|
|
485
500
|
else if (criteria.name) {
|
|
486
501
|
where.search_name = criteria.name;
|
|
487
502
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
503
|
+
// If pagination options are provided, use getPage instead of getAll
|
|
504
|
+
if (criteria.perPage !== undefined || criteria.page !== undefined) {
|
|
505
|
+
const result = await client.people.getPage({
|
|
506
|
+
where,
|
|
507
|
+
perPage: criteria.perPage,
|
|
508
|
+
page: criteria.page,
|
|
509
|
+
});
|
|
510
|
+
return result;
|
|
511
|
+
}
|
|
512
|
+
const result = await client.people.getAll({ where });
|
|
513
|
+
return result;
|
|
492
514
|
}
|
|
493
515
|
/**
|
|
494
516
|
* Get people by household
|
|
495
517
|
*/
|
|
496
|
-
async function getPeopleByHousehold(client, householdId
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
include: ['
|
|
500
|
-
}
|
|
518
|
+
async function getPeopleByHousehold(client, householdId) {
|
|
519
|
+
debugLogIfEnabled(client, 'helpers getPeopleByHousehold', { householdId });
|
|
520
|
+
const result = await client.people.getAll({
|
|
521
|
+
include: ['households']
|
|
522
|
+
});
|
|
523
|
+
// Filter by household_id manually since it's not in the where clause
|
|
524
|
+
// getAll returns PaginationResult with FlattenedPersonResource[], so return the same type
|
|
525
|
+
const filtered = {
|
|
526
|
+
...result,
|
|
527
|
+
data: result.data.filter((p) => {
|
|
528
|
+
const household = p.household;
|
|
529
|
+
if (!household)
|
|
530
|
+
return false;
|
|
531
|
+
// household can be a HouseholdResource, ResourceIdentifier, or array at runtime (types say to-one only)
|
|
532
|
+
if (Array.isArray(household)) {
|
|
533
|
+
return household.some((h) => h && 'id' in h && h.id === householdId);
|
|
534
|
+
}
|
|
535
|
+
// Check if it has an id property (both ResourceIdentifier and HouseholdResource have it)
|
|
536
|
+
const h = household;
|
|
537
|
+
return 'id' in h && h.id === householdId;
|
|
538
|
+
})
|
|
539
|
+
};
|
|
540
|
+
return filtered;
|
|
501
541
|
}
|
|
502
542
|
/**
|
|
503
543
|
* Get complete person profile with all related data
|
|
504
544
|
*/
|
|
505
|
-
async function getCompletePersonProfile(client, personId
|
|
545
|
+
async function getCompletePersonProfile(client, personId) {
|
|
546
|
+
debugLogIfEnabled(client, 'helpers getCompletePersonProfile', { personId });
|
|
506
547
|
const [person, emails, phones, addresses, fieldData, workflowCards] = await Promise.all([
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
548
|
+
client.people.getById(personId, ['households']),
|
|
549
|
+
client.people.getEmails(personId),
|
|
550
|
+
client.people.getPhoneNumbers(personId),
|
|
551
|
+
client.people.getAddresses(personId),
|
|
552
|
+
client.people.getFieldData(personId),
|
|
553
|
+
client.people.getWorkflowCards(personId)
|
|
513
554
|
]);
|
|
514
555
|
return {
|
|
515
556
|
person,
|
|
516
|
-
emails,
|
|
517
|
-
phones,
|
|
518
|
-
addresses,
|
|
557
|
+
emails: emails,
|
|
558
|
+
phones: phones,
|
|
559
|
+
addresses: addresses,
|
|
519
560
|
fieldData,
|
|
520
561
|
workflowCards
|
|
521
562
|
};
|
|
@@ -523,15 +564,15 @@ async function getCompletePersonProfile(client, personId, context) {
|
|
|
523
564
|
/**
|
|
524
565
|
* Get organization info with statistics
|
|
525
566
|
*/
|
|
526
|
-
async function getOrganizationInfo(client
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
567
|
+
async function getOrganizationInfo(client) {
|
|
568
|
+
debugLogIfEnabled(client, 'helpers getOrganizationInfo', {});
|
|
569
|
+
const [people, households, lists] = await Promise.all([
|
|
570
|
+
client.people.getPage({ perPage: 1 }),
|
|
571
|
+
client.households.getPage({ perPage: 1 }),
|
|
572
|
+
client.lists.getPage({ perPage: 1 })
|
|
532
573
|
]);
|
|
533
574
|
return {
|
|
534
|
-
organization,
|
|
575
|
+
organization: null,
|
|
535
576
|
stats: {
|
|
536
577
|
totalPeople: Number(people.meta?.total_count) || 0,
|
|
537
578
|
totalHouseholds: Number(households.meta?.total_count) || 0,
|
|
@@ -542,22 +583,27 @@ async function getOrganizationInfo(client, context) {
|
|
|
542
583
|
/**
|
|
543
584
|
* Get lists with their categories
|
|
544
585
|
*/
|
|
545
|
-
async function getListsWithCategories(client
|
|
586
|
+
async function getListsWithCategories(client) {
|
|
587
|
+
debugLogIfEnabled(client, 'helpers getListsWithCategories', {});
|
|
546
588
|
const [lists, categories] = await Promise.all([
|
|
547
|
-
|
|
548
|
-
|
|
589
|
+
client.lists.getAll(),
|
|
590
|
+
client.lists.getListCategories()
|
|
549
591
|
]);
|
|
550
|
-
return {
|
|
592
|
+
return {
|
|
593
|
+
lists: lists,
|
|
594
|
+
categories: categories
|
|
595
|
+
};
|
|
551
596
|
}
|
|
552
597
|
/**
|
|
553
598
|
* Get workflow cards with notes for a person
|
|
554
599
|
*/
|
|
555
|
-
async function getPersonWorkflowCardsWithNotes(client, personId
|
|
556
|
-
|
|
600
|
+
async function getPersonWorkflowCardsWithNotes(client, personId) {
|
|
601
|
+
debugLogIfEnabled(client, 'helpers getPersonWorkflowCardsWithNotes', { personId });
|
|
602
|
+
const workflowCards = await client.people.getWorkflowCards(personId);
|
|
557
603
|
const notes = {};
|
|
558
604
|
for (const card of workflowCards.data) {
|
|
559
605
|
try {
|
|
560
|
-
notes[card.id] = await
|
|
606
|
+
notes[card.id] = await client.workflows.getWorkflowCardNotes(personId, card.id);
|
|
561
607
|
}
|
|
562
608
|
catch (error) {
|
|
563
609
|
notes[card.id] = { data: [], meta: { total_count: 0 } };
|
|
@@ -568,42 +614,140 @@ async function getPersonWorkflowCardsWithNotes(client, personId, context) {
|
|
|
568
614
|
/**
|
|
569
615
|
* Create a workflow card with a note
|
|
570
616
|
*/
|
|
571
|
-
async function createWorkflowCardWithNote(client, workflowId, personId, noteData
|
|
572
|
-
|
|
573
|
-
const
|
|
574
|
-
|
|
617
|
+
async function createWorkflowCardWithNote(client, workflowId, personId, noteData) {
|
|
618
|
+
debugLogIfEnabled(client, 'helpers createWorkflowCardWithNote', { workflowId, personId });
|
|
619
|
+
const workflowCard = await client.workflows.createWorkflowCard(workflowId, personId);
|
|
620
|
+
const note = await client.workflows.createWorkflowCardNote(personId, workflowCard.id, noteData);
|
|
621
|
+
return {
|
|
622
|
+
workflowCard,
|
|
623
|
+
note
|
|
624
|
+
};
|
|
575
625
|
}
|
|
576
626
|
/**
|
|
577
627
|
* Export all people data in a structured format
|
|
578
628
|
*/
|
|
579
|
-
async function exportAllPeopleData(client, options = {}
|
|
580
|
-
|
|
629
|
+
async function exportAllPeopleData(client, options = {}) {
|
|
630
|
+
debugLogIfEnabled(client, 'helpers exportAllPeopleData', options);
|
|
631
|
+
const { includeInactive = false, includeFieldData = false, includeWorkflowCards = false } = options;
|
|
581
632
|
const where = {};
|
|
582
633
|
if (!includeInactive) {
|
|
583
634
|
where.status = 'active';
|
|
584
635
|
}
|
|
585
|
-
const include = ['
|
|
636
|
+
const include = ['households'];
|
|
586
637
|
if (includeFieldData) {
|
|
587
638
|
include.push('field_data');
|
|
588
639
|
}
|
|
589
|
-
if
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
(0, people_1.getHouseholds)(client, { per_page: perPage }, context),
|
|
595
|
-
(0, people_1.getLists)(client, { per_page: perPage }, context),
|
|
596
|
-
(0, people_1.getOrganization)(client, undefined, context)
|
|
640
|
+
// Note: workflow_cards is not a valid PersonInclude, so we'll fetch it separately if needed
|
|
641
|
+
const [people, households, lists] = await Promise.all([
|
|
642
|
+
client.people.getAll({ where, include }),
|
|
643
|
+
client.households.getAll(),
|
|
644
|
+
client.lists.getAll()
|
|
597
645
|
]);
|
|
646
|
+
// Try to get organization info, but it may not be available
|
|
647
|
+
let organization = null;
|
|
648
|
+
try {
|
|
649
|
+
const orgInfo = await getOrganizationInfo(client);
|
|
650
|
+
organization = orgInfo.organization;
|
|
651
|
+
}
|
|
652
|
+
catch {
|
|
653
|
+
// Organization endpoint may not be available
|
|
654
|
+
organization = null;
|
|
655
|
+
}
|
|
598
656
|
return {
|
|
599
657
|
people: people.data,
|
|
600
658
|
households: households.data,
|
|
601
659
|
lists: lists.data,
|
|
602
|
-
organization
|
|
660
|
+
organization,
|
|
603
661
|
exportDate: new Date().toISOString(),
|
|
604
662
|
totalCount: Number(people.meta?.total_count) || 0
|
|
605
663
|
};
|
|
606
664
|
}
|
|
665
|
+
// ===== JSON:API Included Resources Helpers =====
|
|
666
|
+
/**
|
|
667
|
+
* Find an included resource by type and id
|
|
668
|
+
*
|
|
669
|
+
* In JSON:API, relationships contain resource identifiers like { type: 'Email', id: '456' }
|
|
670
|
+
* This helper finds the full resource object from the included array.
|
|
671
|
+
*
|
|
672
|
+
* @param included - Array of included resources from JSON:API response
|
|
673
|
+
* @param type - Resource type to find
|
|
674
|
+
* @param id - Resource id to find
|
|
675
|
+
* @returns The matching resource object, or undefined if not found
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* ```typescript
|
|
679
|
+
* const person = await client.people.getPage({ include: ['emails'] });
|
|
680
|
+
* // Data is flattened: person.data[0].emails is the resolved array
|
|
681
|
+
* const email = person.data[0].emails?.[0];
|
|
682
|
+
* console.log(email?.address); // 'john@gmail.com'
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
function findIncluded(included, type, id) {
|
|
686
|
+
if (!included || !Array.isArray(included)) {
|
|
687
|
+
return undefined;
|
|
688
|
+
}
|
|
689
|
+
return included.find((resource) => resource.type === type && resource.id === id);
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Resolve all resources from a relationship to their full included objects
|
|
693
|
+
*
|
|
694
|
+
* Takes a relationship's data array (which contains resource identifiers)
|
|
695
|
+
* and resolves them to full resource objects from the included array.
|
|
696
|
+
*
|
|
697
|
+
* @param included - Array of included resources from JSON:API response
|
|
698
|
+
* @param relationshipData - Relationship data array (from relationships.xxx.data)
|
|
699
|
+
* @returns Array of full resource objects, or empty array if none found
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const person = await client.people.getPage({ include: ['emails', 'phone_numbers'] });
|
|
704
|
+
* // Data is flattened: person.data[0].emails is the resolved array
|
|
705
|
+
* const emails = person.data[0].emails ?? [];
|
|
706
|
+
* emails.forEach(email => console.log(email.address));
|
|
707
|
+
* ```
|
|
708
|
+
*/
|
|
709
|
+
function resolveIncluded(included, relationshipData) {
|
|
710
|
+
if (!included || !Array.isArray(included) || !relationshipData) {
|
|
711
|
+
return [];
|
|
712
|
+
}
|
|
713
|
+
const identifiers = Array.isArray(relationshipData) ? relationshipData : [relationshipData];
|
|
714
|
+
return identifiers
|
|
715
|
+
.map((ref) => findIncluded(included, ref.type, ref.id))
|
|
716
|
+
.filter((resource) => resource !== undefined);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Create a lookup map for included resources by type and id
|
|
720
|
+
*
|
|
721
|
+
* This is more efficient than calling findIncluded() multiple times.
|
|
722
|
+
*
|
|
723
|
+
* @param included - Array of included resources from JSON:API response
|
|
724
|
+
* @returns Map with key format "type:id" -> resource object
|
|
725
|
+
*
|
|
726
|
+
* @gmail.com
|
|
727
|
+
* ```typescript
|
|
728
|
+
* const person = await client.people.getPage({ include: ['emails', 'phone_numbers'] });
|
|
729
|
+
* const lookup = createIncludedLookup(person.included);
|
|
730
|
+
* const email = lookup.get('Email:456'); // Fast lookup
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
function createIncludedLookup(included) {
|
|
734
|
+
const lookup = new Map();
|
|
735
|
+
if (!included || !Array.isArray(included)) {
|
|
736
|
+
return lookup;
|
|
737
|
+
}
|
|
738
|
+
for (const resource of included) {
|
|
739
|
+
const key = `${resource.type}:${resource.id}`;
|
|
740
|
+
lookup.set(key, resource);
|
|
741
|
+
}
|
|
742
|
+
return lookup;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Automatically map included resources to their relationships
|
|
746
|
+
*
|
|
747
|
+
* Re-exported from @rachelallyson/planning-center-base-ts for convenience.
|
|
748
|
+
* The mapping is now automatically applied in getList()/getPage() methods.
|
|
749
|
+
*/
|
|
750
|
+
exports.mapIncludedToRelationships = planning_center_base_ts_2.mapIncludedToRelationships;
|
|
607
751
|
// ===== File Handling Utilities =====
|
|
608
752
|
/**
|
|
609
753
|
* Extracts clean URL from HTML markup that contains file links
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
export { PcoClient } from './client';
|
|
2
2
|
export { PcoClientManager } from './client-manager';
|
|
3
|
-
export type { PcoClientConfig, PcoAuthConfig, PersonalAccessTokenAuth, OAuthAuth } from './types/client';
|
|
3
|
+
export type { PcoClientConfig, PcoAuthConfig, PersonalAccessTokenAuth, OAuthAuth, PeopleClientConfig, PcoDebugOptions, } from './types/client';
|
|
4
|
+
export { attachDebugListener, createDebugLogger, formatDebugEvent, } from '@rachelallyson/planning-center-base-ts';
|
|
5
|
+
export type { PcoDebugListenable } from '@rachelallyson/planning-center-base-ts';
|
|
4
6
|
export type { PcoEvent, EventHandler, EventType } from '@rachelallyson/planning-center-base-ts';
|
|
5
7
|
export type { BatchOperation, BatchResult, BatchOptions, BatchSummary } from '@rachelallyson/planning-center-base-ts';
|
|
6
8
|
export type { Paginated, Relationship, ResourceIdentifier, ResourceObject, } from '@rachelallyson/planning-center-base-ts';
|
|
7
9
|
export type { PersonResource, PersonAttributes, PersonSingle, PeopleList, EmailResource, EmailAttributes, PhoneNumberResource, PhoneNumberAttributes, AddressResource, AddressAttributes, SocialProfileResource, SocialProfileAttributes, } from './types';
|
|
8
10
|
export type { FieldDefinitionResource, FieldDefinitionAttributes, FieldDatumResource, FieldDatumAttributes, FieldOptionResource, FieldOptionAttributes, TabResource, TabAttributes, } from './types';
|
|
9
11
|
export type { WorkflowResource, WorkflowAttributes, WorkflowCardResource, WorkflowCardAttributes, WorkflowCardNoteResource, WorkflowCardNoteAttributes, } from './types';
|
|
10
|
-
export type { HouseholdResource, HouseholdAttributes, NoteResource, NoteAttributes, ListResource, ListAttributes, OrganizationResource, OrganizationAttributes, CampusResource, CampusAttributes, CampusesList, ServiceTimeResource, ServiceTimeAttributes, ServiceTimesList, FormResource, FormAttributes, FormsList, FormCategoryResource, FormCategoryAttributes, FormFieldResource, FormFieldAttributes, FormFieldOptionResource, FormFieldOptionAttributes, FormSubmissionResource, FormSubmissionAttributes, FormSubmissionValueResource, FormSubmissionValueAttributes, ReportResource, ReportAttributes, ReportsList, } from './types';
|
|
12
|
+
export type { HouseholdResource, HouseholdAttributes, NoteResource, NoteAttributes, ListResource, ListAttributes, ListRuleResource, ListRuleAttributes, ListRulesList, OrganizationResource, OrganizationAttributes, CampusResource, CampusAttributes, CampusesList, ServiceTimeResource, ServiceTimeAttributes, ServiceTimesList, FormResource, FormAttributes, FormsList, FormCategoryResource, FormCategoryAttributes, FormFieldResource, FormFieldAttributes, FormFieldOptionResource, FormFieldOptionAttributes, FormSubmissionResource, FormSubmissionAttributes, FormSubmissionValueResource, FormSubmissionValueAttributes, ReportResource, ReportAttributes, ReportsList, } from './types';
|
|
13
|
+
export { createPcoClient, getRateLimitInfo } from './core';
|
|
14
|
+
export type { PcoClientState, PcoClientConfig as CorePcoClientConfig } from './core';
|
|
15
|
+
export { attemptTokenRefresh, refreshAccessToken, updateClientTokens, hasRefreshTokenCapability } from './auth';
|
|
16
|
+
export type { TokenResponse, PcoClientConfigWithRefresh } from './auth';
|
|
11
17
|
export * from './types';
|
|
12
|
-
export type { PcoClientConfig as PcoClientConfigV1, PcoClientState } from './core';
|
|
13
|
-
export { createPcoClient, del, getAllPages, getList, getRateLimitInfo, getSingle, patch, post, } from './core';
|
|
14
|
-
export type { TokenResponse, TokenRefreshCallback, TokenRefreshFailureCallback } from './auth';
|
|
15
|
-
export { attemptTokenRefresh, hasRefreshTokenCapability, refreshAccessToken, updateClientTokens, } from './auth';
|
|
16
18
|
export { PcoApiError } from '@rachelallyson/planning-center-base-ts';
|
|
17
19
|
export type { RateLimitHeaders, RateLimitInfo } from '@rachelallyson/planning-center-base-ts';
|
|
18
20
|
export { PcoRateLimiter } from '@rachelallyson/planning-center-base-ts';
|
|
19
21
|
export type { ErrorContext } from '@rachelallyson/planning-center-base-ts';
|
|
20
22
|
export { ErrorCategory, ErrorSeverity, handleNetworkError, handleTimeoutError, handleValidationError, PcoError, retryWithBackoff, shouldNotRetry, withErrorBoundary, } from '@rachelallyson/planning-center-base-ts';
|
|
21
|
-
export { createFieldDefinition, createFieldOption, createPerson, createPersonAddress, createPersonEmail, createPersonFieldData, createPersonPhoneNumber, createPersonSocialProfile, createWorkflowCard, createWorkflowCardNote, deleteFieldDefinition, deletePerson, deletePersonFieldData, deleteSocialProfile, getFieldDefinitions, getFieldOptions, getHousehold, getHouseholds, getTabs, getTab, getListById, getListCategories, getLists, runList, getNote, getNoteCategories, getNotes, getOrganization, getPeople, getPerson, getPersonAddresses, getPersonEmails, getPersonFieldData, getPersonPhoneNumbers, getPersonSocialProfiles, getWorkflow, getWorkflowCardNotes, getWorkflowCards, getWorkflows, updatePerson, updatePersonAddress, } from './people';
|
|
22
23
|
export { attemptRecovery, CircuitBreaker, classifyError, createErrorReport, DEFAULT_RETRY_CONFIG, executeBulkOperation, retryWithExponentialBackoff, TIMEOUT_CONFIG, withTimeout, } from './error-scenarios';
|
|
23
|
-
export {
|
|
24
|
+
export { calculateAge, calculateTrust, createPersonWithContact, createWorkflowCardWithNote, DEFAULT_TRUST_WINDOW, emailDomainsMatch, exportAllPeopleData, extractEmailDomain, extractFileUrl, formatDate, formatPersonName, getCompletePersonProfile, getFileExtension, getFilename, getListsWithCategories, getOrganizationInfo, getPeopleByHousehold, getPersonWorkflowCardsWithNotes, getPrimaryContact, isFileUpload, isFileUrl, isValidEmail, isValidPhone, normalizeEmail, normalizePhone, phoneNumbersSimilar, processFileValue, searchPeople, validateContactSimilarity, validatePersonData, findIncluded, resolveIncluded, createIncludedLookup, } from './helpers';
|
|
24
25
|
export type { TrustResult } from './helpers';
|
|
25
26
|
export { DEFAULT_INITIAL_RETRY_CONFIG, DEFAULT_AGGRESSIVE_RETRY_CONFIG, } from './modules/people';
|
|
26
27
|
export type { RetryConfig, PersonMatchOptions } from './modules/people';
|
|
28
|
+
export type { PersonListOptions, PersonPageOptions, PersonInclude, PersonOrderField, PersonWhereClause, FieldDefinitionListOptions, FieldDefinitionInclude, FieldDefinitionOrderField, FieldDefinitionWhereClause, WorkflowListOptions, WorkflowPageOptions, WorkflowInclude, WorkflowOrderField, WorkflowWhereClause, NoteListOptions, NotePageOptions, NoteInclude, NoteOrderField, NoteWhereClause, ListListOptions, ListPageOptions, ListInclude, ListOrderField, ListWhereClause, HouseholdListOptions, HouseholdPageOptions, HouseholdInclude, HouseholdOrderField, HouseholdWhereClause, CampusListOptions, CampusPageOptions, CampusInclude, CampusOrderField, CampusWhereClause, FormListOptions, FormPageOptions, ReportListOptions, ReportPageOptions, ServiceTimeListOptions, ServiceTimePageOptions, } from './types/api-options';
|
|
27
29
|
export { AdaptiveRateLimiter, ApiCache, batchFetchPersonDetails, fetchAllPages, getCachedPeople, monitorPerformance, PerformanceMonitor, processInBatches, processLargeDataset, streamPeopleData, } from './performance';
|
|
28
30
|
export { MockPcoClient, MockResponseBuilder, RequestRecorder, createMockClient, createRecordingClient, createTestClient, createErrorMockClient, createSlowMockClient, } from './testing';
|
|
29
31
|
export type { MockClientConfig, RecordingConfig } from './testing';
|