@rachelallyson/planning-center-people-ts 2.9.0 โ†’ 2.10.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 CHANGED
@@ -5,6 +5,55 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.10.0] - 2025-01-15
9
+
10
+ ### โœจ **New Features**
11
+
12
+ - **๐Ÿ“ง Email Normalization & Validation**: Added email normalization and format validation to improve search accuracy
13
+ - New `normalizeEmail()` helper function (lowercase and trim)
14
+ - Email is now normalized before search to improve PCO API search results
15
+ - Email format validation prevents wasted API calls on invalid emails
16
+ - **๐Ÿ“ฑ Phone Normalization**: Added phone normalization to improve search accuracy
17
+ - New `normalizePhone()` helper function (normalizes to `+1XXXXXXXXXX` format)
18
+ - Phone numbers are now normalized before search to improve PCO API search results
19
+ - **โœ… First Name Validation**: Added firstName validation in person creation
20
+ - Validates firstName is required before attempting person creation
21
+ - Provides clearer error messages: "First name is required to create a person"
22
+ - Fails fast instead of waiting for API error response
23
+
24
+ ### ๐Ÿ”ง **Improvements**
25
+
26
+ - **Normalization Consistency**: Refactored normalization logic into reusable helper functions
27
+ - All email/phone normalization now uses consistent helper functions
28
+ - Updated both `matcher.ts` and `scoring.ts` to use shared normalization functions
29
+ - Removed duplicate inline normalization code
30
+
31
+ ### ๐Ÿ“ฆ **Exports**
32
+
33
+ - Exported `normalizeEmail` and `normalizePhone` helper functions from main package index for library users
34
+
35
+ ## [2.9.1] - 2025-01-14
36
+
37
+ ### ๐Ÿ› **Bug Fixes**
38
+
39
+ - **Type System Accuracy**: Fixed TypeScript type definitions to match actual API responses
40
+ - Updated nullable fields to properly use `string | null` and `number | null` types
41
+ - Fixed `PersonAttributes`: `given_name`, `middle_name`, `nickname`, `anniversary`, `gender`, `grade`, `graduation_year`, `medical_notes`, `remote_id`, `inactivated_at` now correctly typed as `string | null`
42
+ - Fixed `CampusAttributes`: `latitude`, `longitude` now `string | null`; `phone_number`, `website` now `string | null`; `twenty_four_hour_time` now `boolean | null`; `date_format` now `number | null`
43
+ - Fixed `WorkflowCardAttributes`: `calculated_due_at_in_days_ago`, `snooze_until`, `removed_at`, `flagged_for_notification_at`, `moved_to_step_at` now correctly typed as nullable
44
+ - **Test Suite Fixes**: Fixed integration test expectations to match actual API behavior
45
+ - Relaxed relationship validation tests to make `links` optional (not always present in API responses)
46
+ - Fixed batch test data structure access to use `batchResult.data.data` (batch results wrap API responses)
47
+ - Fixed error handling tests to check error `status` property and use correct event name (`request:error`)
48
+ - Updated v2 service-time test to use `getAll()` instead of `getAllPagesPaginated()`
49
+ - Relaxed batch test expectations to handle API validation behavior
50
+
51
+ ### ๐Ÿงช **Testing Improvements**
52
+
53
+ - Comprehensive integration test suite now passes (655+ tests)
54
+ - All type validation tests align with actual API response structures
55
+ - Error handling tests verify correct error structure and event emission
56
+
8
57
  ## [2.9.0] - 2025-01-14
9
58
 
10
59
  ### ๐ŸŽฏ **Matching Logic Improvements**
@@ -119,9 +119,11 @@ class PcoClientManager {
119
119
  // Create a hash of the configuration
120
120
  const configStr = JSON.stringify({
121
121
  authType: config.auth.type,
122
- hasAccessToken: config.auth.type === 'oauth' ? !!config.auth.accessToken : false,
123
- hasRefreshToken: config.auth.type === 'oauth' ? !!config.auth.refreshToken : false,
124
- hasPersonalAccessToken: config.auth.type === 'personal_access_token' ? !!config.auth.personalAccessToken : false,
122
+ accessToken: config.auth.type === 'oauth' ? config.auth.accessToken : undefined,
123
+ refreshToken: config.auth.type === 'oauth' ? config.auth.refreshToken : undefined,
124
+ personalAccessToken: config.auth.type === 'personal_access_token' ? config.auth.personalAccessToken : undefined,
125
+ appId: config.auth.type === 'basic' ? config.auth.appId : undefined,
126
+ appSecret: config.auth.type === 'basic' ? config.auth.appSecret : undefined,
125
127
  baseURL: config.baseURL,
126
128
  timeout: config.timeout,
127
129
  });
package/dist/core/http.js CHANGED
@@ -186,6 +186,10 @@ class PcoHttpClient {
186
186
  }
187
187
  catch (error) {
188
188
  clearTimeout(timeoutId);
189
+ // Handle timeout/abort errors
190
+ if (error instanceof Error && error.name === 'AbortError') {
191
+ throw new Error(`Request timeout after ${timeout}ms`);
192
+ }
189
193
  throw error;
190
194
  }
191
195
  }
@@ -263,11 +267,11 @@ class PcoHttpClient {
263
267
  const tokens = await response.json();
264
268
  // Update the config with new tokens
265
269
  this.config.auth.accessToken = tokens.access_token;
266
- this.config.auth.refreshToken = tokens.refresh_token;
267
- // Call the onRefresh callback
270
+ this.config.auth.refreshToken = tokens.refresh_token || this.config.auth.refreshToken;
271
+ // Call the onRefresh callback with the expected format
268
272
  await this.config.auth.onRefresh({
269
273
  accessToken: tokens.access_token,
270
- refreshToken: tokens.refresh_token,
274
+ refreshToken: tokens.refresh_token || this.config.auth.refreshToken,
271
275
  });
272
276
  }
273
277
  updateRateLimitTracking(endpoint, headers) {
package/dist/helpers.d.ts CHANGED
@@ -44,10 +44,21 @@ export declare function calculateBirthYearFromAge(age: number): number;
44
44
  * Validate email format
45
45
  */
46
46
  export declare function isValidEmail(email: string): boolean;
47
+ /**
48
+ * Normalize email address (lowercase and trim)
49
+ */
50
+ export declare function normalizeEmail(email: string): string;
47
51
  /**
48
52
  * Validate phone number format (basic validation)
49
53
  */
50
54
  export declare function isValidPhone(phone: string): boolean;
55
+ /**
56
+ * Normalize phone number to +1XXXXXXXXXX format
57
+ * - 10 digits: adds +1 prefix
58
+ * - 11 digits starting with 1: adds + prefix
59
+ * - Other lengths: adds + prefix to all digits
60
+ */
61
+ export declare function normalizePhone(phone: string): string;
51
62
  /**
52
63
  * Format person name from attributes
53
64
  */
package/dist/helpers.js CHANGED
@@ -8,7 +8,9 @@ exports.isChild = isChild;
8
8
  exports.matchesAgeCriteria = matchesAgeCriteria;
9
9
  exports.calculateBirthYearFromAge = calculateBirthYearFromAge;
10
10
  exports.isValidEmail = isValidEmail;
11
+ exports.normalizeEmail = normalizeEmail;
11
12
  exports.isValidPhone = isValidPhone;
13
+ exports.normalizePhone = normalizePhone;
12
14
  exports.formatPersonName = formatPersonName;
13
15
  exports.formatDate = formatDate;
14
16
  exports.validatePersonData = validatePersonData;
@@ -137,6 +139,12 @@ function isValidEmail(email) {
137
139
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
138
140
  return emailRegex.test(email);
139
141
  }
142
+ /**
143
+ * Normalize email address (lowercase and trim)
144
+ */
145
+ function normalizeEmail(email) {
146
+ return email.toLowerCase().trim();
147
+ }
140
148
  /**
141
149
  * Validate phone number format (basic validation)
142
150
  */
@@ -144,6 +152,22 @@ function isValidPhone(phone) {
144
152
  const phoneRegex = /^[\+]?[1-9][\d]{6,14}$/;
145
153
  return phoneRegex.test(phone.replace(/[\s\-\(\)]/g, ''));
146
154
  }
155
+ /**
156
+ * Normalize phone number to +1XXXXXXXXXX format
157
+ * - 10 digits: adds +1 prefix
158
+ * - 11 digits starting with 1: adds + prefix
159
+ * - Other lengths: adds + prefix to all digits
160
+ */
161
+ function normalizePhone(phone) {
162
+ const digits = phone.replace(/\D/g, '');
163
+ if (digits.length === 10) {
164
+ return `+1${digits}`;
165
+ }
166
+ if (digits.length === 11 && digits.startsWith('1')) {
167
+ return `+${digits}`;
168
+ }
169
+ return `+${digits}`;
170
+ }
147
171
  /**
148
172
  * Format person name from attributes
149
173
  */
package/dist/index.d.ts CHANGED
@@ -20,7 +20,7 @@ export type { ErrorContext } from '@rachelallyson/planning-center-base-ts';
20
20
  export { ErrorCategory, ErrorSeverity, handleNetworkError, handleTimeoutError, handleValidationError, PcoError, retryWithBackoff, shouldNotRetry, withErrorBoundary, } from '@rachelallyson/planning-center-base-ts';
21
21
  export { createFieldDefinition, createFieldOption, createPerson, createPersonAddress, createPersonEmail, createPersonFieldData, createPersonPhoneNumber, createPersonSocialProfile, createWorkflowCard, createWorkflowCardNote, deleteFieldDefinition, deletePerson, deletePersonFieldData, deleteSocialProfile, getFieldDefinitions, getFieldOptions, getHousehold, getHouseholds, getTabs, getListById, getListCategories, getLists, getNote, getNoteCategories, getNotes, getOrganization, getPeople, getPerson, getPersonAddresses, getPersonEmails, getPersonFieldData, getPersonPhoneNumbers, getPersonSocialProfiles, getWorkflow, getWorkflowCardNotes, getWorkflowCards, getWorkflows, updatePerson, updatePersonAddress, } from './people';
22
22
  export { attemptRecovery, CircuitBreaker, classifyError, createErrorReport, DEFAULT_RETRY_CONFIG, executeBulkOperation, retryWithExponentialBackoff, TIMEOUT_CONFIG, withTimeout, } from './error-scenarios';
23
- export { buildQueryParams, calculateAge, createPersonWithContact, createWorkflowCardWithNote, exportAllPeopleData, extractFileUrl, formatDate, formatPersonName, getCompletePersonProfile, getFileExtension, getFilename, getListsWithCategories, getOrganizationInfo, getPeopleByHousehold, getPersonWorkflowCardsWithNotes, getPrimaryContact, isFileUpload, isFileUrl, isValidEmail, isValidPhone, processFileValue, searchPeople, validatePersonData, } from './helpers';
23
+ export { buildQueryParams, calculateAge, createPersonWithContact, createWorkflowCardWithNote, exportAllPeopleData, extractFileUrl, formatDate, formatPersonName, getCompletePersonProfile, getFileExtension, getFilename, getListsWithCategories, getOrganizationInfo, getPeopleByHousehold, getPersonWorkflowCardsWithNotes, getPrimaryContact, isFileUpload, isFileUrl, isValidEmail, isValidPhone, normalizeEmail, normalizePhone, processFileValue, searchPeople, validatePersonData, } from './helpers';
24
24
  export { AdaptiveRateLimiter, ApiCache, batchFetchPersonDetails, fetchAllPages, getCachedPeople, monitorPerformance, PerformanceMonitor, processInBatches, processLargeDataset, streamPeopleData, } from './performance';
25
25
  export { MockPcoClient, MockResponseBuilder, RequestRecorder, createMockClient, createRecordingClient, createTestClient, createErrorMockClient, createSlowMockClient, } from './testing';
26
26
  export type { MockClientConfig, RecordingConfig } from './testing';
package/dist/index.js CHANGED
@@ -16,8 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.getNotes = exports.getNoteCategories = exports.getNote = exports.getLists = exports.getListCategories = exports.getListById = exports.getTabs = exports.getHouseholds = exports.getHousehold = exports.getFieldOptions = exports.getFieldDefinitions = exports.deleteSocialProfile = exports.deletePersonFieldData = exports.deletePerson = exports.deleteFieldDefinition = exports.createWorkflowCardNote = exports.createWorkflowCard = exports.createPersonSocialProfile = exports.createPersonPhoneNumber = exports.createPersonFieldData = exports.createPersonEmail = exports.createPersonAddress = exports.createPerson = exports.createFieldOption = exports.createFieldDefinition = exports.withErrorBoundary = exports.shouldNotRetry = exports.retryWithBackoff = exports.PcoError = exports.handleValidationError = exports.handleTimeoutError = exports.handleNetworkError = exports.ErrorSeverity = exports.ErrorCategory = exports.PcoRateLimiter = exports.PcoApiError = exports.updateClientTokens = exports.refreshAccessToken = exports.hasRefreshTokenCapability = exports.attemptTokenRefresh = exports.post = exports.patch = exports.getSingle = exports.getRateLimitInfo = exports.getList = exports.getAllPages = exports.del = exports.createPcoClient = exports.PcoClientManager = exports.PcoClient = void 0;
19
- exports.fetchAllPages = exports.batchFetchPersonDetails = exports.ApiCache = exports.AdaptiveRateLimiter = exports.validatePersonData = exports.searchPeople = exports.processFileValue = exports.isValidPhone = exports.isValidEmail = exports.isFileUrl = exports.isFileUpload = exports.getPrimaryContact = exports.getPersonWorkflowCardsWithNotes = exports.getPeopleByHousehold = exports.getOrganizationInfo = exports.getListsWithCategories = exports.getFilename = exports.getFileExtension = exports.getCompletePersonProfile = exports.formatPersonName = exports.formatDate = exports.extractFileUrl = exports.exportAllPeopleData = exports.createWorkflowCardWithNote = exports.createPersonWithContact = exports.calculateAge = exports.buildQueryParams = exports.withTimeout = exports.TIMEOUT_CONFIG = exports.retryWithExponentialBackoff = exports.executeBulkOperation = exports.DEFAULT_RETRY_CONFIG = exports.createErrorReport = exports.classifyError = exports.CircuitBreaker = exports.attemptRecovery = exports.updatePersonAddress = exports.updatePerson = exports.getWorkflows = exports.getWorkflowCards = exports.getWorkflowCardNotes = exports.getWorkflow = exports.getPersonSocialProfiles = exports.getPersonPhoneNumbers = exports.getPersonFieldData = exports.getPersonEmails = exports.getPersonAddresses = exports.getPerson = exports.getPeople = exports.getOrganization = void 0;
20
- exports.createSlowMockClient = exports.createErrorMockClient = exports.createTestClient = exports.createRecordingClient = exports.createMockClient = exports.RequestRecorder = exports.MockResponseBuilder = exports.MockPcoClient = exports.streamPeopleData = exports.processLargeDataset = exports.processInBatches = exports.PerformanceMonitor = exports.monitorPerformance = exports.getCachedPeople = void 0;
19
+ exports.ApiCache = exports.AdaptiveRateLimiter = exports.validatePersonData = exports.searchPeople = exports.processFileValue = exports.normalizePhone = exports.normalizeEmail = exports.isValidPhone = exports.isValidEmail = exports.isFileUrl = exports.isFileUpload = exports.getPrimaryContact = exports.getPersonWorkflowCardsWithNotes = exports.getPeopleByHousehold = exports.getOrganizationInfo = exports.getListsWithCategories = exports.getFilename = exports.getFileExtension = exports.getCompletePersonProfile = exports.formatPersonName = exports.formatDate = exports.extractFileUrl = exports.exportAllPeopleData = exports.createWorkflowCardWithNote = exports.createPersonWithContact = exports.calculateAge = exports.buildQueryParams = exports.withTimeout = exports.TIMEOUT_CONFIG = exports.retryWithExponentialBackoff = exports.executeBulkOperation = exports.DEFAULT_RETRY_CONFIG = exports.createErrorReport = exports.classifyError = exports.CircuitBreaker = exports.attemptRecovery = exports.updatePersonAddress = exports.updatePerson = exports.getWorkflows = exports.getWorkflowCards = exports.getWorkflowCardNotes = exports.getWorkflow = exports.getPersonSocialProfiles = exports.getPersonPhoneNumbers = exports.getPersonFieldData = exports.getPersonEmails = exports.getPersonAddresses = exports.getPerson = exports.getPeople = exports.getOrganization = void 0;
20
+ exports.createSlowMockClient = exports.createErrorMockClient = exports.createTestClient = exports.createRecordingClient = exports.createMockClient = exports.RequestRecorder = exports.MockResponseBuilder = exports.MockPcoClient = exports.streamPeopleData = exports.processLargeDataset = exports.processInBatches = exports.PerformanceMonitor = exports.monitorPerformance = exports.getCachedPeople = exports.fetchAllPages = exports.batchFetchPersonDetails = void 0;
21
21
  // Main client class
22
22
  var client_1 = require("./client");
23
23
  Object.defineProperty(exports, "PcoClient", { enumerable: true, get: function () { return client_1.PcoClient; } });
@@ -130,6 +130,8 @@ Object.defineProperty(exports, "isFileUpload", { enumerable: true, get: function
130
130
  Object.defineProperty(exports, "isFileUrl", { enumerable: true, get: function () { return helpers_1.isFileUrl; } });
131
131
  Object.defineProperty(exports, "isValidEmail", { enumerable: true, get: function () { return helpers_1.isValidEmail; } });
132
132
  Object.defineProperty(exports, "isValidPhone", { enumerable: true, get: function () { return helpers_1.isValidPhone; } });
133
+ Object.defineProperty(exports, "normalizeEmail", { enumerable: true, get: function () { return helpers_1.normalizeEmail; } });
134
+ Object.defineProperty(exports, "normalizePhone", { enumerable: true, get: function () { return helpers_1.normalizePhone; } });
133
135
  Object.defineProperty(exports, "processFileValue", { enumerable: true, get: function () { return helpers_1.processFileValue; } });
134
136
  Object.defineProperty(exports, "searchPeople", { enumerable: true, get: function () { return helpers_1.searchPeople; } });
135
137
  Object.defineProperty(exports, "validatePersonData", { enumerable: true, get: function () { return helpers_1.validatePersonData; } });
@@ -50,20 +50,30 @@ class PersonMatcher {
50
50
  // Step 1: Try email/phone search first
51
51
  const emailPhoneMatches = [];
52
52
  const nameOnlyMatches = [];
53
- // Search by email
53
+ // Search by email (with normalization and validation)
54
54
  if (email) {
55
- try {
56
- const emailResults = await this.peopleModule.search({ email });
57
- emailPhoneMatches.push(...emailResults.data);
55
+ // Validate email format to avoid wasted API calls
56
+ if (!(0, helpers_1.isValidEmail)(email)) {
57
+ console.warn('Invalid email format, skipping email search:', email);
58
58
  }
59
- catch (error) {
60
- console.warn('Email search failed:', error);
59
+ else {
60
+ try {
61
+ // Normalize email before search to improve PCO search results
62
+ const normalizedEmail = (0, helpers_1.normalizeEmail)(email);
63
+ const emailResults = await this.peopleModule.search({ email: normalizedEmail });
64
+ emailPhoneMatches.push(...emailResults.data);
65
+ }
66
+ catch (error) {
67
+ console.warn('Email search failed:', error);
68
+ }
61
69
  }
62
70
  }
63
- // Search by phone
71
+ // Search by phone (with normalization)
64
72
  if (phone) {
65
73
  try {
66
- const phoneResults = await this.peopleModule.search({ phone });
74
+ // Normalize phone before search to improve PCO search results
75
+ const normalizedPhone = (0, helpers_1.normalizePhone)(phone);
76
+ const phoneResults = await this.peopleModule.search({ phone: normalizedPhone });
67
77
  emailPhoneMatches.push(...phoneResults.data);
68
78
  }
69
79
  catch (error) {
@@ -203,8 +213,8 @@ class PersonMatcher {
203
213
  async verifyEmailMatch(person, email) {
204
214
  try {
205
215
  const personEmails = await this.peopleModule.getEmails(person.id);
206
- const normalizedSearchEmail = email.toLowerCase().trim();
207
- const emails = personEmails.data?.map(e => e.attributes?.address?.toLowerCase().trim()).filter(Boolean) || [];
216
+ const normalizedSearchEmail = (0, helpers_1.normalizeEmail)(email);
217
+ const emails = personEmails.data?.map(e => (0, helpers_1.normalizeEmail)(e.attributes?.address || '')).filter(Boolean) || [];
208
218
  return emails.includes(normalizedSearchEmail);
209
219
  }
210
220
  catch {
@@ -217,14 +227,8 @@ class PersonMatcher {
217
227
  async verifyPhoneMatch(person, phone) {
218
228
  try {
219
229
  const personPhones = await this.peopleModule.getPhoneNumbers(person.id);
220
- const normalizePhone = (num) => {
221
- const digits = num.replace(/\D/g, '');
222
- return digits.length === 10 ? `+1${digits}` :
223
- digits.length === 11 && digits.startsWith('1') ? `+${digits}` :
224
- `+${digits}`;
225
- };
226
- const normalizedSearchPhone = normalizePhone(phone);
227
- const phones = personPhones.data?.map(p => normalizePhone(p.attributes?.number || '')).filter(Boolean) || [];
230
+ const normalizedSearchPhone = (0, helpers_1.normalizePhone)(phone);
231
+ const phones = personPhones.data?.map(p => (0, helpers_1.normalizePhone)(p.attributes?.number || '')).filter(Boolean) || [];
228
232
  return phones.includes(normalizedSearchPhone);
229
233
  }
230
234
  catch {
@@ -294,6 +298,10 @@ class PersonMatcher {
294
298
  * Create a new person
295
299
  */
296
300
  async createPerson(options) {
301
+ // Validate firstName is required for person creation
302
+ if (!options.firstName?.trim()) {
303
+ throw new Error('First name is required to create a person');
304
+ }
297
305
  // Create basic person data (only name fields)
298
306
  const personData = {};
299
307
  if (options.firstName)
@@ -98,9 +98,9 @@ class MatchScorer {
98
98
  async scoreEmailMatch(person, email) {
99
99
  try {
100
100
  const personEmails = await this.peopleModule.getEmails(person.id);
101
- const normalizedSearchEmail = email.toLowerCase().trim();
101
+ const normalizedSearchEmail = (0, helpers_1.normalizeEmail)(email);
102
102
  // Check if any of the person's emails match
103
- const emails = personEmails.data?.map(e => e.attributes?.address?.toLowerCase().trim()).filter(Boolean) || [];
103
+ const emails = personEmails.data?.map(e => (0, helpers_1.normalizeEmail)(e.attributes?.address || '')).filter(Boolean) || [];
104
104
  return emails.includes(normalizedSearchEmail) ? 1.0 : 0.0;
105
105
  }
106
106
  catch (error) {
@@ -114,15 +114,8 @@ class MatchScorer {
114
114
  async scorePhoneMatch(person, phone) {
115
115
  try {
116
116
  const personPhones = await this.peopleModule.getPhoneNumbers(person.id);
117
- // Normalize phone numbers for comparison
118
- const normalizePhone = (num) => {
119
- const digits = num.replace(/\D/g, '');
120
- return digits.length === 10 ? `+1${digits}` :
121
- digits.length === 11 && digits.startsWith('1') ? `+${digits}` :
122
- `+${digits}`;
123
- };
124
- const normalizedSearchPhone = normalizePhone(phone);
125
- const phones = personPhones.data?.map(p => normalizePhone(p.attributes?.number || '')).filter(Boolean) || [];
117
+ const normalizedSearchPhone = (0, helpers_1.normalizePhone)(phone);
118
+ const phones = personPhones.data?.map(p => (0, helpers_1.normalizePhone)(p.attributes?.number || '')).filter(Boolean) || [];
126
119
  return phones.includes(normalizedSearchPhone) ? 1.0 : 0.0;
127
120
  }
128
121
  catch (error) {
@@ -89,7 +89,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
89
89
  return this.httpClient.request({
90
90
  method: 'GET',
91
91
  endpoint: `/campuses/${campusData.id}`
92
- }).then(response => response.data);
92
+ }).then(response => response.data.data);
93
93
  }
94
94
  /**
95
95
  * Set a person's primary campus
@@ -107,7 +107,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
107
107
  }
108
108
  }
109
109
  }
110
- }).then(response => response.data);
110
+ }).then(response => response.data.data);
111
111
  }
112
112
  /**
113
113
  * Remove a person's primary campus
@@ -125,7 +125,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
125
125
  }
126
126
  }
127
127
  }
128
- }).then(response => response.data);
128
+ }).then(response => response.data.data);
129
129
  }
130
130
  /**
131
131
  * Get a person's household
@@ -140,7 +140,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
140
140
  return this.httpClient.request({
141
141
  method: 'GET',
142
142
  endpoint: `/households/${householdData.id}`
143
- }).then(response => response.data);
143
+ }).then(response => response.data.data);
144
144
  }
145
145
  /**
146
146
  * Set a person's household
@@ -158,7 +158,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
158
158
  }
159
159
  }
160
160
  }
161
- }).then(response => response.data);
161
+ }).then(response => response.data.data);
162
162
  }
163
163
  /**
164
164
  * Remove a person from their household
@@ -176,7 +176,7 @@ class PeopleModule extends planning_center_base_ts_1.BaseModule {
176
176
  }
177
177
  }
178
178
  }
179
- }).then(response => response.data);
179
+ }).then(response => response.data.data);
180
180
  }
181
181
  /**
182
182
  * Get all people in a specific household
@@ -6,16 +6,16 @@ import { Attributes, Paginated, Relationship, ResourceObject, Response } from '.
6
6
  export interface PersonAttributes extends Attributes {
7
7
  first_name?: string;
8
8
  last_name?: string;
9
- given_name?: string;
10
- middle_name?: string;
11
- nickname?: string;
9
+ given_name?: string | null;
10
+ middle_name?: string | null;
11
+ nickname?: string | null;
12
12
  birthdate?: string;
13
- anniversary?: string;
14
- gender?: string;
15
- grade?: string;
13
+ anniversary?: string | null;
14
+ gender?: string | null;
15
+ grade?: string | null;
16
16
  child?: boolean;
17
17
  status?: string;
18
- medical_notes?: string;
18
+ medical_notes?: string | null;
19
19
  created_at?: string;
20
20
  updated_at?: string;
21
21
  name?: string;
@@ -23,7 +23,7 @@ export interface PersonAttributes extends Attributes {
23
23
  job_title?: string;
24
24
  employer?: string;
25
25
  school?: string;
26
- graduation_year?: string;
26
+ graduation_year?: string | null;
27
27
  avatar?: string;
28
28
  site_administrator?: boolean;
29
29
  accounting_administrator?: boolean;
@@ -315,7 +315,7 @@ export interface WorkflowCardAttributes extends Attributes {
315
315
  stage?: string;
316
316
  completed_at?: string | null;
317
317
  overdue?: boolean;
318
- calculated_due_at_in_days_ago?: number;
318
+ calculated_due_at_in_days_ago?: number | null;
319
319
  flagged_for_notification_at?: string | null;
320
320
  moved_to_step_at?: string | null;
321
321
  snooze_until?: string | null;
@@ -385,18 +385,18 @@ export type OrganizationStatisticsList = Paginated<OrganizationStatisticResource
385
385
  export type OrganizationStatisticSingle = Response<OrganizationStatisticResource>;
386
386
  export interface CampusAttributes extends Attributes {
387
387
  name: string;
388
- latitude?: number;
389
- longitude?: number;
388
+ latitude?: string | null;
389
+ longitude?: string | null;
390
390
  description?: string;
391
391
  street?: string;
392
392
  city?: string;
393
393
  state?: string;
394
394
  zip?: string;
395
395
  country?: string;
396
- phone_number?: string;
397
- website?: string;
398
- twenty_four_hour_time?: boolean;
399
- date_format?: number;
396
+ phone_number?: string | null;
397
+ website?: string | null;
398
+ twenty_four_hour_time?: boolean | null;
399
+ date_format?: number | null;
400
400
  church_center_enabled?: boolean;
401
401
  created_at?: string;
402
402
  updated_at?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rachelallyson/planning-center-people-ts",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "description": "A strictly typed TypeScript client for Planning Center Online People API with comprehensive functionality and enhanced developer experience",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -69,6 +69,7 @@
69
69
  "access": "public"
70
70
  },
71
71
  "dependencies": {
72
- "@rachelallyson/planning-center-base-ts": "^1.0.0"
72
+ "@rachelallyson/planning-center-base-ts": "^1.0.0",
73
+ "form-data": "^4.0.4"
73
74
  }
74
75
  }