@rachelallyson/planning-center-people-ts 2.14.1 → 3.0.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 +76 -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 +236 -93
- package/dist/index.d.ts +9 -7
- 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 +30 -28
- package/dist/modules/lists.js +55 -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 +50 -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 +47 -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,62 @@ 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 or ResourceIdentifier (both have id)
|
|
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
|
+
return 'id' in household && household.id === householdId;
|
|
537
|
+
})
|
|
538
|
+
};
|
|
539
|
+
return filtered;
|
|
501
540
|
}
|
|
502
541
|
/**
|
|
503
542
|
* Get complete person profile with all related data
|
|
504
543
|
*/
|
|
505
|
-
async function getCompletePersonProfile(client, personId
|
|
544
|
+
async function getCompletePersonProfile(client, personId) {
|
|
545
|
+
debugLogIfEnabled(client, 'helpers getCompletePersonProfile', { personId });
|
|
506
546
|
const [person, emails, phones, addresses, fieldData, workflowCards] = await Promise.all([
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
547
|
+
client.people.getById(personId, ['households']),
|
|
548
|
+
client.people.getEmails(personId),
|
|
549
|
+
client.people.getPhoneNumbers(personId),
|
|
550
|
+
client.people.getAddresses(personId),
|
|
551
|
+
client.people.getFieldData(personId),
|
|
552
|
+
client.people.getWorkflowCards(personId)
|
|
513
553
|
]);
|
|
514
554
|
return {
|
|
515
555
|
person,
|
|
516
|
-
emails,
|
|
517
|
-
phones,
|
|
518
|
-
addresses,
|
|
556
|
+
emails: emails,
|
|
557
|
+
phones: phones,
|
|
558
|
+
addresses: addresses,
|
|
519
559
|
fieldData,
|
|
520
560
|
workflowCards
|
|
521
561
|
};
|
|
@@ -523,15 +563,15 @@ async function getCompletePersonProfile(client, personId, context) {
|
|
|
523
563
|
/**
|
|
524
564
|
* Get organization info with statistics
|
|
525
565
|
*/
|
|
526
|
-
async function getOrganizationInfo(client
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
566
|
+
async function getOrganizationInfo(client) {
|
|
567
|
+
debugLogIfEnabled(client, 'helpers getOrganizationInfo', {});
|
|
568
|
+
const [people, households, lists] = await Promise.all([
|
|
569
|
+
client.people.getPage({ perPage: 1 }),
|
|
570
|
+
client.households.getPage({ perPage: 1 }),
|
|
571
|
+
client.lists.getPage({ perPage: 1 })
|
|
532
572
|
]);
|
|
533
573
|
return {
|
|
534
|
-
organization,
|
|
574
|
+
organization: null,
|
|
535
575
|
stats: {
|
|
536
576
|
totalPeople: Number(people.meta?.total_count) || 0,
|
|
537
577
|
totalHouseholds: Number(households.meta?.total_count) || 0,
|
|
@@ -542,22 +582,27 @@ async function getOrganizationInfo(client, context) {
|
|
|
542
582
|
/**
|
|
543
583
|
* Get lists with their categories
|
|
544
584
|
*/
|
|
545
|
-
async function getListsWithCategories(client
|
|
585
|
+
async function getListsWithCategories(client) {
|
|
586
|
+
debugLogIfEnabled(client, 'helpers getListsWithCategories', {});
|
|
546
587
|
const [lists, categories] = await Promise.all([
|
|
547
|
-
|
|
548
|
-
|
|
588
|
+
client.lists.getAll(),
|
|
589
|
+
client.lists.getListCategories()
|
|
549
590
|
]);
|
|
550
|
-
return {
|
|
591
|
+
return {
|
|
592
|
+
lists: lists,
|
|
593
|
+
categories: categories
|
|
594
|
+
};
|
|
551
595
|
}
|
|
552
596
|
/**
|
|
553
597
|
* Get workflow cards with notes for a person
|
|
554
598
|
*/
|
|
555
|
-
async function getPersonWorkflowCardsWithNotes(client, personId
|
|
556
|
-
|
|
599
|
+
async function getPersonWorkflowCardsWithNotes(client, personId) {
|
|
600
|
+
debugLogIfEnabled(client, 'helpers getPersonWorkflowCardsWithNotes', { personId });
|
|
601
|
+
const workflowCards = await client.people.getWorkflowCards(personId);
|
|
557
602
|
const notes = {};
|
|
558
603
|
for (const card of workflowCards.data) {
|
|
559
604
|
try {
|
|
560
|
-
notes[card.id] = await
|
|
605
|
+
notes[card.id] = await client.workflows.getWorkflowCardNotes(personId, card.id);
|
|
561
606
|
}
|
|
562
607
|
catch (error) {
|
|
563
608
|
notes[card.id] = { data: [], meta: { total_count: 0 } };
|
|
@@ -568,42 +613,140 @@ async function getPersonWorkflowCardsWithNotes(client, personId, context) {
|
|
|
568
613
|
/**
|
|
569
614
|
* Create a workflow card with a note
|
|
570
615
|
*/
|
|
571
|
-
async function createWorkflowCardWithNote(client, workflowId, personId, noteData
|
|
572
|
-
|
|
573
|
-
const
|
|
574
|
-
|
|
616
|
+
async function createWorkflowCardWithNote(client, workflowId, personId, noteData) {
|
|
617
|
+
debugLogIfEnabled(client, 'helpers createWorkflowCardWithNote', { workflowId, personId });
|
|
618
|
+
const workflowCard = await client.workflows.createWorkflowCard(workflowId, personId);
|
|
619
|
+
const note = await client.workflows.createWorkflowCardNote(personId, workflowCard.id, noteData);
|
|
620
|
+
return {
|
|
621
|
+
workflowCard,
|
|
622
|
+
note
|
|
623
|
+
};
|
|
575
624
|
}
|
|
576
625
|
/**
|
|
577
626
|
* Export all people data in a structured format
|
|
578
627
|
*/
|
|
579
|
-
async function exportAllPeopleData(client, options = {}
|
|
580
|
-
|
|
628
|
+
async function exportAllPeopleData(client, options = {}) {
|
|
629
|
+
debugLogIfEnabled(client, 'helpers exportAllPeopleData', options);
|
|
630
|
+
const { includeInactive = false, includeFieldData = false, includeWorkflowCards = false } = options;
|
|
581
631
|
const where = {};
|
|
582
632
|
if (!includeInactive) {
|
|
583
633
|
where.status = 'active';
|
|
584
634
|
}
|
|
585
|
-
const include = ['
|
|
635
|
+
const include = ['households'];
|
|
586
636
|
if (includeFieldData) {
|
|
587
637
|
include.push('field_data');
|
|
588
638
|
}
|
|
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)
|
|
639
|
+
// Note: workflow_cards is not a valid PersonInclude, so we'll fetch it separately if needed
|
|
640
|
+
const [people, households, lists] = await Promise.all([
|
|
641
|
+
client.people.getAll({ where, include }),
|
|
642
|
+
client.households.getAll(),
|
|
643
|
+
client.lists.getAll()
|
|
597
644
|
]);
|
|
645
|
+
// Try to get organization info, but it may not be available
|
|
646
|
+
let organization = null;
|
|
647
|
+
try {
|
|
648
|
+
const orgInfo = await getOrganizationInfo(client);
|
|
649
|
+
organization = orgInfo.organization;
|
|
650
|
+
}
|
|
651
|
+
catch {
|
|
652
|
+
// Organization endpoint may not be available
|
|
653
|
+
organization = null;
|
|
654
|
+
}
|
|
598
655
|
return {
|
|
599
656
|
people: people.data,
|
|
600
657
|
households: households.data,
|
|
601
658
|
lists: lists.data,
|
|
602
|
-
organization
|
|
659
|
+
organization,
|
|
603
660
|
exportDate: new Date().toISOString(),
|
|
604
661
|
totalCount: Number(people.meta?.total_count) || 0
|
|
605
662
|
};
|
|
606
663
|
}
|
|
664
|
+
// ===== JSON:API Included Resources Helpers =====
|
|
665
|
+
/**
|
|
666
|
+
* Find an included resource by type and id
|
|
667
|
+
*
|
|
668
|
+
* In JSON:API, relationships contain resource identifiers like { type: 'Email', id: '456' }
|
|
669
|
+
* This helper finds the full resource object from the included array.
|
|
670
|
+
*
|
|
671
|
+
* @param included - Array of included resources from JSON:API response
|
|
672
|
+
* @param type - Resource type to find
|
|
673
|
+
* @param id - Resource id to find
|
|
674
|
+
* @returns The matching resource object, or undefined if not found
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```typescript
|
|
678
|
+
* const person = await client.people.getPage({ include: ['emails'] });
|
|
679
|
+
* // Data is flattened: person.data[0].emails is the resolved array
|
|
680
|
+
* const email = person.data[0].emails?.[0];
|
|
681
|
+
* console.log(email?.address); // 'john@gmail.com'
|
|
682
|
+
* ```
|
|
683
|
+
*/
|
|
684
|
+
function findIncluded(included, type, id) {
|
|
685
|
+
if (!included || !Array.isArray(included)) {
|
|
686
|
+
return undefined;
|
|
687
|
+
}
|
|
688
|
+
return included.find((resource) => resource.type === type && resource.id === id);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Resolve all resources from a relationship to their full included objects
|
|
692
|
+
*
|
|
693
|
+
* Takes a relationship's data array (which contains resource identifiers)
|
|
694
|
+
* and resolves them to full resource objects from the included array.
|
|
695
|
+
*
|
|
696
|
+
* @param included - Array of included resources from JSON:API response
|
|
697
|
+
* @param relationshipData - Relationship data array (from relationships.xxx.data)
|
|
698
|
+
* @returns Array of full resource objects, or empty array if none found
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```typescript
|
|
702
|
+
* const person = await client.people.getPage({ include: ['emails', 'phone_numbers'] });
|
|
703
|
+
* // Data is flattened: person.data[0].emails is the resolved array
|
|
704
|
+
* const emails = person.data[0].emails ?? [];
|
|
705
|
+
* emails.forEach(email => console.log(email.address));
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
function resolveIncluded(included, relationshipData) {
|
|
709
|
+
if (!included || !Array.isArray(included) || !relationshipData) {
|
|
710
|
+
return [];
|
|
711
|
+
}
|
|
712
|
+
const identifiers = Array.isArray(relationshipData) ? relationshipData : [relationshipData];
|
|
713
|
+
return identifiers
|
|
714
|
+
.map((ref) => findIncluded(included, ref.type, ref.id))
|
|
715
|
+
.filter((resource) => resource !== undefined);
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Create a lookup map for included resources by type and id
|
|
719
|
+
*
|
|
720
|
+
* This is more efficient than calling findIncluded() multiple times.
|
|
721
|
+
*
|
|
722
|
+
* @param included - Array of included resources from JSON:API response
|
|
723
|
+
* @returns Map with key format "type:id" -> resource object
|
|
724
|
+
*
|
|
725
|
+
* @gmail.com
|
|
726
|
+
* ```typescript
|
|
727
|
+
* const person = await client.people.getPage({ include: ['emails', 'phone_numbers'] });
|
|
728
|
+
* const lookup = createIncludedLookup(person.included);
|
|
729
|
+
* const email = lookup.get('Email:456'); // Fast lookup
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
732
|
+
function createIncludedLookup(included) {
|
|
733
|
+
const lookup = new Map();
|
|
734
|
+
if (!included || !Array.isArray(included)) {
|
|
735
|
+
return lookup;
|
|
736
|
+
}
|
|
737
|
+
for (const resource of included) {
|
|
738
|
+
const key = `${resource.type}:${resource.id}`;
|
|
739
|
+
lookup.set(key, resource);
|
|
740
|
+
}
|
|
741
|
+
return lookup;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Automatically map included resources to their relationships
|
|
745
|
+
*
|
|
746
|
+
* Re-exported from @rachelallyson/planning-center-base-ts for convenience.
|
|
747
|
+
* The mapping is now automatically applied in getList()/getPage() methods.
|
|
748
|
+
*/
|
|
749
|
+
exports.mapIncludedToRelationships = planning_center_base_ts_2.mapIncludedToRelationships;
|
|
607
750
|
// ===== File Handling Utilities =====
|
|
608
751
|
/**
|
|
609
752
|
* Extracts clean URL from HTML markup that contains file links
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
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';
|
|
@@ -8,22 +10,22 @@ export type { PersonResource, PersonAttributes, PersonSingle, PeopleList, EmailR
|
|
|
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
12
|
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';
|
|
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';
|