@rachelallyson/planning-center-people-ts 1.0.0 → 1.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 CHANGED
@@ -5,7 +5,138 @@ 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
- ## [1.0.0] - 2024-01-XX
8
+ ## [1.1.0] - 2025-10-08
9
+
10
+ ### Added
11
+
12
+ - **Complete API Modularization**: Split monolithic `people.ts` into 9 focused modules for better maintainability
13
+ - **36 New API Functions**: Complete coverage of all PCO People API endpoints
14
+ - **File Upload Support**: New file handling capabilities with smart field type detection
15
+ - **Comprehensive Integration Tests**: 9 new integration test suites with 2,660+ lines of test coverage
16
+ - **Enhanced Helper Functions**: New file processing utilities and validation functions
17
+ - **Complete Function Checklist**: Comprehensive documentation of all available functions
18
+
19
+ ### New API Functions
20
+
21
+ #### Core People Operations (`src/people/core.ts`)
22
+
23
+ - `getPeople()` - Get all people with filtering and pagination
24
+ - `getPerson()` - Get single person by ID
25
+ - `createPerson()` - Create new person
26
+ - `updatePerson()` - Update existing person
27
+ - `deletePerson()` - Delete person
28
+
29
+ #### Contact Management (`src/people/contacts.ts`)
30
+
31
+ - `getPersonEmails()` - Get all emails for a person
32
+ - `createPersonEmail()` - Create email for a person
33
+ - `getPersonPhoneNumbers()` - Get all phone numbers for a person
34
+ - `createPersonPhoneNumber()` - Create phone number for a person
35
+ - `getPersonAddresses()` - Get all addresses for a person
36
+ - `createPersonAddress()` - Create address for a person
37
+ - `updatePersonAddress()` - Update existing address
38
+ - `getPersonSocialProfiles()` - Get social profiles for a person
39
+ - `createPersonSocialProfile()` - Create social profile for a person
40
+ - `deleteSocialProfile()` - Delete social profile
41
+
42
+ #### Field Data Management (`src/people/fields.ts`)
43
+
44
+ - `createPersonFieldData()` - Create field data with smart file handling
45
+ - `deletePersonFieldData()` - Delete field data
46
+ - `getPersonFieldData()` - Get custom field data for a person
47
+ - `getFieldDefinitions()` - Get all field definitions
48
+ - `getFieldDefinition()` - Get single field definition
49
+ - `getFieldOptions()` - Get field options for a field definition
50
+ - `createFieldOption()` - Create field option
51
+ - `getTabs()` - Get field definition tabs
52
+ - `createFieldDefinition()` - Create new field definition
53
+ - `deleteFieldDefinition()` - Delete field definition
54
+
55
+ #### Household Operations (`src/people/households.ts`)
56
+
57
+ - `getHouseholds()` - Get all households
58
+ - `getHousehold()` - Get single household by ID
59
+
60
+ #### List Management (`src/people/lists.ts`)
61
+
62
+ - `getLists()` - Get all people lists
63
+ - `getListById()` - Get single list by ID
64
+ - `getListCategories()` - Get all list categories
65
+
66
+ #### Note Operations (`src/people/notes.ts`)
67
+
68
+ - `getNotes()` - Get all notes
69
+ - `getNote()` - Get single note by ID
70
+ - `getNoteCategories()` - Get all note categories
71
+
72
+ #### Workflow Management (`src/people/workflows.ts`)
73
+
74
+ - `getWorkflowCardNotes()` - Get notes for a workflow card
75
+ - `createWorkflowCardNote()` - Create note for workflow card
76
+ - `getWorkflowCards()` - Get workflow cards for a person
77
+ - `createWorkflowCard()` - Create workflow card for a person
78
+ - `getWorkflows()` - Get all workflows
79
+ - `getWorkflow()` - Get single workflow by ID
80
+
81
+ #### Organization Operations (`src/people/organization.ts`)
82
+
83
+ - `getOrganization()` - Get organization information
84
+
85
+ ### New Helper Functions
86
+
87
+ #### File Upload Utilities
88
+
89
+ - `extractFileUrl()` - Extract clean URLs from HTML markup
90
+ - `isFileUrl()` - Check if string is a valid file URL
91
+ - `getFileExtension()` - Extract file extension from URL
92
+ - `getFilename()` - Extract filename from URL
93
+ - `isFileUpload()` - Detect if value contains file upload
94
+ - `processFileValue()` - Smart processing of file values based on field type
95
+
96
+ #### Enhanced Validation
97
+
98
+ - `validatePersonData()` - Comprehensive person data validation
99
+ - `isValidEmail()` - Email format validation
100
+ - `isValidPhone()` - Phone number format validation
101
+
102
+ #### Utility Functions
103
+
104
+ - `formatPersonName()` - Format person names with nickname support
105
+ - `formatDate()` - Flexible date formatting
106
+ - `calculateAge()` - Calculate age from birthdate
107
+ - `buildQueryParams()` - Transform complex params to flat query params
108
+
109
+ ### Testing
110
+
111
+ - **9 New Integration Test Suites**: Complete integration testing for all API modules
112
+ - **2,660+ Lines of Test Code**: Comprehensive test coverage for all new functions
113
+ - **File Upload Testing**: Dedicated tests for file handling functionality
114
+ - **Edge Case Coverage**: Testing for error scenarios and edge cases
115
+ - **Type Validation**: Runtime validation of all API responses
116
+
117
+ ### Documentation
118
+
119
+ - **Function Checklist**: Complete documentation of all 36 available functions
120
+ - **File Upload Examples**: New example showing file upload usage patterns
121
+ - **Updated API Guide**: Enhanced documentation with new function examples
122
+ - **Usage Examples**: Comprehensive examples for all new functionality
123
+
124
+ ### Changed
125
+
126
+ - **Modular Architecture**: Restructured codebase for better maintainability and organization
127
+ - **Enhanced Error Handling**: Improved error handling across all new functions
128
+ - **Type Safety**: Enhanced TypeScript definitions for all new functions
129
+ - **Performance**: Optimized API calls with better parameter handling
130
+
131
+ ### Technical Improvements
132
+
133
+ - **Better Code Organization**: Logical separation of concerns across modules
134
+ - **Consistent Patterns**: Standardized function signatures and error handling
135
+ - **Enhanced TypeScript**: Improved type definitions and inference
136
+ - **Comprehensive Testing**: Full test coverage for all new functionality
137
+ - **Documentation**: Complete API documentation and usage examples
138
+
139
+ ## [1.0.0] - 2025-01-08
9
140
 
10
141
  ### Added
11
142
 
package/README.md CHANGED
@@ -14,6 +14,7 @@ A strictly typed TypeScript client for Planning Center Online People API, built
14
14
  - ✅ **Automatic Retries**: Configurable exponential backoff with smart retry logic
15
15
  - ✅ **Request Timeouts**: Configurable request timeouts
16
16
  - ✅ **Pagination**: Automatic pagination support
17
+ - ✅ **File Upload Handling**: Intelligent file upload detection and processing for custom fields
17
18
  - ✅ **No Index Signatures**: Clean type definitions without index signatures
18
19
 
19
20
  ## Installation
@@ -68,6 +69,17 @@ const updatedPerson = await updatePerson(client, 'person-id', {
68
69
 
69
70
  // Delete a person
70
71
  await deletePerson(client, 'person-id');
72
+
73
+ // Smart file upload handling for custom fields
74
+ import { createPersonFieldData } from '@planning-center-people-ts';
75
+
76
+ // Automatically determines field type and handles file uploads appropriately
77
+ await createPersonFieldData(
78
+ client,
79
+ 'person-id',
80
+ 'field-definition-id',
81
+ '<a href="https://example.com/document.pdf" download>View File</a>'
82
+ );
71
83
  ```
72
84
 
73
85
  ## Configuration
package/dist/auth.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ import type { PcoClientState } from './core';
2
+ export interface TokenResponse {
3
+ access_token: string;
4
+ refresh_token?: string;
5
+ token_type: string;
6
+ expires_in: number;
7
+ scope?: string;
8
+ }
9
+ export type TokenRefreshCallback = (newTokens: TokenResponse) => void | Promise<void>;
10
+ export type TokenRefreshFailureCallback = (error: Error, context: {
11
+ originalError?: Error;
12
+ refreshToken?: string;
13
+ attemptCount?: number;
14
+ }) => void | Promise<void>;
15
+ export interface PcoClientConfigWithRefresh {
16
+ /** Personal Access Token (for single-user apps) */
17
+ personalAccessToken?: string;
18
+ /** OAuth 2.0 Access Token (for multi-user apps) */
19
+ accessToken?: string;
20
+ /** OAuth 2.0 Refresh Token (for multi-user apps) */
21
+ refreshToken?: string;
22
+ /** App ID (for Personal Access Token auth) */
23
+ appId?: string;
24
+ /** App Secret (for Personal Access Token auth) */
25
+ appSecret?: string;
26
+ /** Callback to handle token refresh */
27
+ onTokenRefresh?: TokenRefreshCallback;
28
+ /** Callback to handle token refresh failures */
29
+ onTokenRefreshFailure?: TokenRefreshFailureCallback;
30
+ /** Base URL override (defaults to people/v2) */
31
+ baseURL?: string;
32
+ /** Rate limiting configuration */
33
+ rateLimit?: {
34
+ maxRequests: number;
35
+ perMilliseconds: number;
36
+ };
37
+ /** Custom headers to include in all requests */
38
+ headers?: Record<string, string>;
39
+ /** Request timeout in milliseconds */
40
+ timeout?: number;
41
+ /** Retry configuration */
42
+ retry?: {
43
+ maxRetries?: number;
44
+ baseDelay?: number;
45
+ maxDelay?: number;
46
+ onRetry?: (error: any, attempt: number) => void;
47
+ };
48
+ }
49
+ /**
50
+ * Refresh an OAuth access token using the refresh token
51
+ */
52
+ export declare function refreshAccessToken(client: PcoClientState, refreshToken: string): Promise<TokenResponse>;
53
+ /**
54
+ * Update client configuration with new tokens
55
+ */
56
+ export declare function updateClientTokens(client: PcoClientState, newTokens: TokenResponse): void;
57
+ /**
58
+ * Check if a client has refresh token capability
59
+ */
60
+ export declare function hasRefreshTokenCapability(client: PcoClientState): boolean;
61
+ /**
62
+ * Attempt to refresh tokens and retry the original request
63
+ */
64
+ export declare function attemptTokenRefresh<T>(client: PcoClientState, originalRequest: () => Promise<T>): Promise<T>;
package/dist/auth.js ADDED
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refreshAccessToken = refreshAccessToken;
4
+ exports.updateClientTokens = updateClientTokens;
5
+ exports.hasRefreshTokenCapability = hasRefreshTokenCapability;
6
+ exports.attemptTokenRefresh = attemptTokenRefresh;
7
+ /**
8
+ * Refresh an OAuth access token using the refresh token
9
+ */
10
+ async function refreshAccessToken(client, refreshToken) {
11
+ const baseURL = client.config.baseURL ?? 'https://api.planningcenteronline.com';
12
+ const tokenUrl = `${baseURL}/oauth/token`;
13
+ // Prepare the request body for token refresh
14
+ const body = new URLSearchParams({
15
+ grant_type: 'refresh_token',
16
+ refresh_token: refreshToken,
17
+ });
18
+ // Add client credentials if available
19
+ if (client.config.appId && client.config.appSecret) {
20
+ body.append('client_id', client.config.appId);
21
+ body.append('client_secret', client.config.appSecret);
22
+ }
23
+ const response = await fetch(tokenUrl, {
24
+ method: 'POST',
25
+ headers: {
26
+ 'Content-Type': 'application/x-www-form-urlencoded',
27
+ 'Accept': 'application/json',
28
+ },
29
+ body: body.toString(),
30
+ });
31
+ if (!response.ok) {
32
+ const errorData = await response.json().catch(() => ({}));
33
+ throw new Error(`Token refresh failed: ${response.status} ${response.statusText}. ${JSON.stringify(errorData)}`);
34
+ }
35
+ const tokenData = await response.json();
36
+ return tokenData;
37
+ }
38
+ /**
39
+ * Update client configuration with new tokens
40
+ */
41
+ function updateClientTokens(client, newTokens) {
42
+ // Update the client's access token
43
+ client.config.accessToken = newTokens.access_token;
44
+ // Update refresh token if provided
45
+ if (newTokens.refresh_token) {
46
+ client.config.refreshToken = newTokens.refresh_token;
47
+ }
48
+ }
49
+ /**
50
+ * Check if a client has refresh token capability
51
+ */
52
+ function hasRefreshTokenCapability(client) {
53
+ return !!(client.config.refreshToken && (client.config.onTokenRefresh || client.config.onTokenRefreshFailure));
54
+ }
55
+ /**
56
+ * Attempt to refresh tokens and retry the original request
57
+ */
58
+ async function attemptTokenRefresh(client, originalRequest) {
59
+ if (!hasRefreshTokenCapability(client)) {
60
+ throw new Error('No refresh token or callback configured');
61
+ }
62
+ try {
63
+ // Attempt to refresh the token
64
+ const newTokens = await refreshAccessToken(client, client.config.refreshToken);
65
+ // Update the client with new tokens
66
+ updateClientTokens(client, newTokens);
67
+ // Call the token refresh callback if provided
68
+ if (client.config.onTokenRefresh) {
69
+ try {
70
+ await client.config.onTokenRefresh(newTokens);
71
+ }
72
+ catch (callbackError) {
73
+ // Log callback error but don't fail the token refresh
74
+ console.warn('Token refresh callback failed:', callbackError);
75
+ }
76
+ }
77
+ // Retry the original request with the new token
78
+ return await originalRequest();
79
+ }
80
+ catch (error) {
81
+ const refreshError = new Error(`Token refresh failed: ${error instanceof Error ? error.message : String(error)}`);
82
+ // Call the failure callback if provided
83
+ if (client.config.onTokenRefreshFailure) {
84
+ try {
85
+ await client.config.onTokenRefreshFailure(refreshError, {
86
+ originalError: error instanceof Error ? error : undefined,
87
+ refreshToken: client.config.refreshToken,
88
+ attemptCount: 1, // Could be enhanced to track retry attempts
89
+ });
90
+ }
91
+ catch (callbackError) {
92
+ // Log callback error but don't fail the refresh error
93
+ console.warn('Token refresh failure callback failed:', callbackError);
94
+ }
95
+ }
96
+ throw refreshError;
97
+ }
98
+ }
package/dist/core.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type ErrorContext, PcoError } from './error-handling';
2
2
  import { PcoRateLimiter } from './rate-limiter';
3
3
  import { Paginated, ResourceObject, Response as JsonApiResponse } from './types';
4
+ import { type TokenRefreshCallback, type TokenRefreshFailureCallback } from './auth';
4
5
  export interface PcoClientConfig {
5
6
  /** Personal Access Token (for single-user apps) */
6
7
  personalAccessToken?: string;
@@ -8,6 +9,10 @@ export interface PcoClientConfig {
8
9
  accessToken?: string;
9
10
  /** OAuth 2.0 Refresh Token (for multi-user apps) */
10
11
  refreshToken?: string;
12
+ /** Callback to handle token refresh */
13
+ onTokenRefresh?: TokenRefreshCallback;
14
+ /** Callback to handle token refresh failures */
15
+ onTokenRefreshFailure?: TokenRefreshFailureCallback;
11
16
  /** App ID (for Personal Access Token auth) */
12
17
  appId?: string;
13
18
  /** App Secret (for Personal Access Token auth) */
package/dist/core.js CHANGED
@@ -11,6 +11,7 @@ exports.getAllPages = getAllPages;
11
11
  exports.getRateLimitInfo = getRateLimitInfo;
12
12
  const error_handling_1 = require("./error-handling");
13
13
  const rate_limiter_1 = require("./rate-limiter");
14
+ const auth_1 = require("./auth");
14
15
  // Re-export PcoApiError for convenience
15
16
  var api_error_1 = require("./api-error");
16
17
  Object.defineProperty(exports, "PcoApiError", { enumerable: true, get: function () { return api_error_1.PcoApiError; } });
@@ -211,6 +212,17 @@ async function makeFetchRequest(client, method, endpoint, data, params, context)
211
212
  }
212
213
  // Handle other errors
213
214
  if (!response.ok) {
215
+ // Handle 401 errors with token refresh if available
216
+ if (response.status === 401 && (0, auth_1.hasRefreshTokenCapability)(client)) {
217
+ try {
218
+ // Attempt to refresh the token and retry the request
219
+ return await (0, auth_1.attemptTokenRefresh)(client, () => makeFetchRequest(client, method, endpoint, data, params, context));
220
+ }
221
+ catch (refreshError) {
222
+ // If token refresh fails, fall through to normal error handling
223
+ console.warn('Token refresh failed:', refreshError);
224
+ }
225
+ }
214
226
  let errorData;
215
227
  try {
216
228
  errorData = await response.json();
package/dist/helpers.d.ts CHANGED
@@ -1,144 +1,169 @@
1
+ import type { PcoClientState } from './core';
2
+ import type { ErrorContext } from './error-handling';
3
+ import type { PersonAttributes, EmailAttributes, PhoneNumberAttributes, AddressAttributes, WorkflowCardNoteAttributes, PeopleList, PersonSingle, EmailSingle, PhoneNumberSingle, AddressSingle, WorkflowCardSingle, WorkflowCardNoteSingle, ListsList, ListCategoriesList, OrganizationSingle } from './types';
1
4
  /**
2
- * Helper Functions for Common PCO People API Operations
3
- *
4
- * This module provides convenient helper functions for common operations
5
- * that combine multiple API calls or provide higher-level abstractions.
5
+ * Transform complex params object into flat query params for API calls
6
6
  */
7
- import type { PcoClientState } from './core';
8
- import type { AddressResource, EmailResource, FieldDatumResource, ListResource, NoteResource, OrganizationResource, PersonResource, PhoneNumberResource, SocialProfileResource, WorkflowCardNoteResource, WorkflowCardResource } from './types';
9
- /**
10
- * Get a complete person profile with all related data
11
- */
12
- export declare function getCompletePersonProfile(client: PcoClientState, personId: string): Promise<{
13
- person: PersonResource;
14
- emails: EmailResource[];
15
- phoneNumbers: PhoneNumberResource[];
16
- addresses: AddressResource[];
17
- socialProfiles: SocialProfileResource[];
18
- fieldData: FieldDatumResource[];
19
- workflowCards: WorkflowCardResource[];
20
- notes: NoteResource[];
21
- }>;
7
+ export declare function buildQueryParams(params?: {
8
+ where?: Record<string, any>;
9
+ include?: string[];
10
+ per_page?: number;
11
+ page?: number;
12
+ filter?: string;
13
+ }): Record<string, any>;
14
+ /**
15
+ * Calculate age from birthdate string
16
+ */
17
+ export declare function calculateAge(birthdate: string): number;
18
+ /**
19
+ * Validate email format
20
+ */
21
+ export declare function isValidEmail(email: string): boolean;
22
+ /**
23
+ * Validate phone number format (basic validation)
24
+ */
25
+ export declare function isValidPhone(phone: string): boolean;
26
+ /**
27
+ * Format person name from attributes
28
+ */
29
+ export declare function formatPersonName(person: {
30
+ first_name?: string;
31
+ last_name?: string;
32
+ nickname?: string;
33
+ }): string;
22
34
  /**
23
- * Create a person with initial contact information
35
+ * Format date string in various formats
24
36
  */
25
- export declare function createPersonWithContact(client: PcoClientState, personData: {
26
- first_name: string;
27
- last_name: string;
37
+ export declare function formatDate(dateString: string, format?: 'short' | 'long' | 'iso'): string;
38
+ /**
39
+ * Validate person data
40
+ */
41
+ export declare function validatePersonData(data: Partial<PersonAttributes>): {
42
+ isValid: boolean;
43
+ errors: string[];
44
+ };
45
+ /**
46
+ * Get primary contact information for a person
47
+ */
48
+ export declare function getPrimaryContact(client: PcoClientState, personId: string, context?: Partial<ErrorContext>): Promise<{
28
49
  email?: string;
29
50
  phone?: string;
30
- address?: {
31
- address1: string;
32
- city: string;
33
- state: string;
34
- zip: string;
35
- };
36
- }): Promise<{
37
- person: PersonResource;
38
- email?: EmailResource;
39
- phone?: PhoneNumberResource;
40
- address?: AddressResource;
51
+ address?: string;
41
52
  }>;
42
53
  /**
43
- * Search for people by multiple criteria
54
+ * Create a person with contact information
55
+ */
56
+ export declare function createPersonWithContact(client: PcoClientState, personData: Partial<PersonAttributes>, contactData?: {
57
+ email?: Partial<EmailAttributes>;
58
+ phone?: Partial<PhoneNumberAttributes>;
59
+ address?: Partial<AddressAttributes>;
60
+ }, context?: Partial<ErrorContext>): Promise<{
61
+ person: PersonSingle;
62
+ email?: EmailSingle;
63
+ phone?: PhoneNumberSingle;
64
+ address?: AddressSingle;
65
+ }>;
66
+ /**
67
+ * Search people by multiple criteria
44
68
  */
45
69
  export declare function searchPeople(client: PcoClientState, criteria: {
70
+ status?: string;
46
71
  name?: string;
47
72
  email?: string;
48
- phone?: string;
49
- status?: string;
50
- household?: string;
51
- }): Promise<PersonResource[]>;
73
+ per_page?: number;
74
+ }, context?: Partial<ErrorContext>): Promise<PeopleList>;
52
75
  /**
53
76
  * Get people by household
54
77
  */
55
- export declare function getPeopleByHousehold(client: PcoClientState, householdId: string): Promise<PersonResource[]>;
56
- /**
57
- * Get all workflow cards for a person with their notes
58
- */
59
- export declare function getPersonWorkflowCardsWithNotes(client: PcoClientState, personId: string): Promise<(WorkflowCardResource & {
60
- notes: WorkflowCardNoteResource[];
61
- })[]>;
78
+ export declare function getPeopleByHousehold(client: PcoClientState, householdId: string, context?: Partial<ErrorContext>): Promise<PeopleList>;
62
79
  /**
63
- * Create a workflow card with an initial note
80
+ * Get complete person profile with all related data
64
81
  */
65
- export declare function createWorkflowCardWithNote(client: PcoClientState, personId: string, workflowId: string, cardData: {
66
- title: string;
67
- description?: string;
68
- initialNote?: string;
69
- }): Promise<{
70
- card: WorkflowCardResource;
71
- note?: WorkflowCardNoteResource;
82
+ export declare function getCompletePersonProfile(client: PcoClientState, personId: string, context?: Partial<ErrorContext>): Promise<{
83
+ person: PersonSingle;
84
+ emails: any;
85
+ phones: any;
86
+ addresses: any;
87
+ fieldData: any;
88
+ workflowCards: any;
72
89
  }>;
73
90
  /**
74
- * Get all lists with their categories
91
+ * Get organization info with statistics
75
92
  */
76
- export declare function getListsWithCategories(client: PcoClientState): Promise<(ListResource & {
77
- category?: any;
78
- })[]>;
79
- /**
80
- * Get organization information with statistics
81
- */
82
- export declare function getOrganizationInfo(client: PcoClientState): Promise<{
83
- organization: OrganizationResource;
93
+ export declare function getOrganizationInfo(client: PcoClientState, context?: Partial<ErrorContext>): Promise<{
94
+ organization: OrganizationSingle;
84
95
  stats: {
85
96
  totalPeople: number;
86
97
  totalHouseholds: number;
87
98
  totalLists: number;
88
- totalWorkflows: number;
89
99
  };
90
100
  }>;
91
101
  /**
92
- * Export all people data to a structured format
102
+ * Get lists with their categories
103
+ */
104
+ export declare function getListsWithCategories(client: PcoClientState, context?: Partial<ErrorContext>): Promise<{
105
+ lists: ListsList;
106
+ categories: ListCategoriesList;
107
+ }>;
108
+ /**
109
+ * Get workflow cards with notes for a person
110
+ */
111
+ export declare function getPersonWorkflowCardsWithNotes(client: PcoClientState, personId: string, context?: Partial<ErrorContext>): Promise<{
112
+ workflowCards: any;
113
+ notes: {
114
+ [cardId: string]: any;
115
+ };
116
+ }>;
117
+ /**
118
+ * Create a workflow card with a note
119
+ */
120
+ export declare function createWorkflowCardWithNote(client: PcoClientState, workflowId: string, personId: string, noteData: Partial<WorkflowCardNoteAttributes>, context?: Partial<ErrorContext>): Promise<{
121
+ workflowCard: WorkflowCardSingle;
122
+ note: WorkflowCardNoteSingle;
123
+ }>;
124
+ /**
125
+ * Export all people data in a structured format
93
126
  */
94
127
  export declare function exportAllPeopleData(client: PcoClientState, options?: {
95
128
  includeInactive?: boolean;
96
129
  includeFieldData?: boolean;
97
130
  includeWorkflowCards?: boolean;
98
- batchSize?: number;
99
- }): Promise<{
100
- person: PersonResource;
101
- emails: EmailResource[];
102
- phoneNumbers: PhoneNumberResource[];
103
- addresses: AddressResource[];
104
- socialProfiles: SocialProfileResource[];
105
- fieldData?: FieldDatumResource[];
106
- workflowCards?: WorkflowCardResource[];
107
- }[]>;
108
- /**
109
- * Validate person data before creation/update
110
- */
111
- export declare function validatePersonData(data: any): {
112
- isValid: boolean;
113
- errors: string[];
114
- };
131
+ perPage?: number;
132
+ }, context?: Partial<ErrorContext>): Promise<{
133
+ people: any[];
134
+ households: any[];
135
+ lists: any[];
136
+ organization: any;
137
+ exportDate: string;
138
+ totalCount: number;
139
+ }>;
115
140
  /**
116
- * Validate email format
141
+ * Extracts clean URL from HTML markup that contains file links
142
+ * Handles cases like: <a href="https://onark.s3.us-east-1.amazonaws.com/file.pdf" download>View File: https://onark.s3.us-east-1.amazonaws.com/file.pdf</a>
117
143
  */
118
- export declare function isValidEmail(email: string): boolean;
144
+ export declare function extractFileUrl(value: string): string;
119
145
  /**
120
- * Validate phone format (basic validation)
146
+ * Determines if a value contains a file URL
121
147
  */
122
- export declare function isValidPhone(phone: string): boolean;
148
+ export declare function isFileUrl(value: string): boolean;
123
149
  /**
124
- * Format person name for display
150
+ * Gets file extension from URL
125
151
  */
126
- export declare function formatPersonName(person: PersonResource): string;
152
+ export declare function getFileExtension(url: string): string;
127
153
  /**
128
- * Get primary contact information for a person
154
+ * Gets filename from URL
129
155
  */
130
- export declare function getPrimaryContact(person: PersonResource, relatedData: {
131
- emails?: EmailResource[];
132
- phoneNumbers?: PhoneNumberResource[];
133
- }): {
134
- email?: string;
135
- phone?: string;
136
- };
156
+ export declare function getFilename(url: string): string;
137
157
  /**
138
- * Calculate age from birthdate
158
+ * Determines if a field value represents a file upload
139
159
  */
140
- export declare function calculateAge(birthdate: string): number | null;
160
+ export declare function isFileUpload(value: string): boolean;
141
161
  /**
142
- * Format date for display
162
+ * Processes file upload value for PCO field
163
+ * Returns clean URL for text fields, or file data for file fields
143
164
  */
144
- export declare function formatDate(dateString: string, format?: 'short' | 'long' | 'iso'): string;
165
+ export declare function processFileValue(value: string, fieldType?: 'text' | 'file'): string | {
166
+ url: string;
167
+ filename: string;
168
+ contentType: string;
169
+ };