@rachelallyson/planning-center-people-ts 1.0.0 → 2.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 +248 -1
- package/README.md +28 -0
- package/dist/auth.d.ts +64 -0
- package/dist/auth.js +98 -0
- package/dist/batch.d.ts +47 -0
- package/dist/batch.js +376 -0
- package/dist/client-manager.d.ts +66 -0
- package/dist/client-manager.js +150 -0
- package/dist/client.d.ts +71 -0
- package/dist/client.js +123 -0
- package/dist/core/http.d.ts +47 -0
- package/dist/core/http.js +242 -0
- package/dist/core/pagination.d.ts +34 -0
- package/dist/core/pagination.js +164 -0
- package/dist/core.d.ts +5 -0
- package/dist/core.js +12 -0
- package/dist/helpers.d.ts +125 -100
- package/dist/helpers.js +315 -275
- package/dist/index.d.ts +17 -5
- package/dist/index.js +39 -5
- package/dist/matching/matcher.d.ts +41 -0
- package/dist/matching/matcher.js +161 -0
- package/dist/matching/scoring.d.ts +35 -0
- package/dist/matching/scoring.js +141 -0
- package/dist/matching/strategies.d.ts +35 -0
- package/dist/matching/strategies.js +79 -0
- package/dist/modules/base.d.ts +46 -0
- package/dist/modules/base.js +82 -0
- package/dist/modules/contacts.d.ts +103 -0
- package/dist/modules/contacts.js +130 -0
- package/dist/modules/fields.d.ts +157 -0
- package/dist/modules/fields.js +294 -0
- package/dist/modules/households.d.ts +42 -0
- package/dist/modules/households.js +74 -0
- package/dist/modules/lists.d.ts +62 -0
- package/dist/modules/lists.js +92 -0
- package/dist/modules/notes.d.ts +74 -0
- package/dist/modules/notes.js +125 -0
- package/dist/modules/people.d.ts +196 -0
- package/dist/modules/people.js +221 -0
- package/dist/modules/workflows.d.ts +131 -0
- package/dist/modules/workflows.js +221 -0
- package/dist/monitoring.d.ts +53 -0
- package/dist/monitoring.js +142 -0
- package/dist/people/contacts.d.ts +43 -0
- package/dist/people/contacts.js +122 -0
- package/dist/people/core.d.ts +28 -0
- package/dist/people/core.js +69 -0
- package/dist/people/fields.d.ts +62 -0
- package/dist/people/fields.js +293 -0
- package/dist/people/households.d.ts +15 -0
- package/dist/people/households.js +31 -0
- package/dist/people/index.d.ts +8 -0
- package/dist/people/index.js +25 -0
- package/dist/people/lists.d.ts +30 -0
- package/dist/people/lists.js +37 -0
- package/dist/people/notes.d.ts +30 -0
- package/dist/people/notes.js +37 -0
- package/dist/people/organization.d.ts +12 -0
- package/dist/people/organization.js +15 -0
- package/dist/people/workflows.d.ts +37 -0
- package/dist/people/workflows.js +75 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.js +24 -0
- package/dist/testing/recorder.d.ts +58 -0
- package/dist/testing/recorder.js +195 -0
- package/dist/testing/simple-builders.d.ts +33 -0
- package/dist/testing/simple-builders.js +124 -0
- package/dist/testing/simple-factories.d.ts +91 -0
- package/dist/testing/simple-factories.js +279 -0
- package/dist/testing/types.d.ts +160 -0
- package/dist/testing/types.js +5 -0
- package/dist/types/batch.d.ts +50 -0
- package/dist/types/batch.js +5 -0
- package/dist/types/client.d.ts +81 -0
- package/dist/types/client.js +5 -0
- package/dist/types/events.d.ts +85 -0
- package/dist/types/events.js +5 -0
- package/dist/types/people.d.ts +73 -79
- package/package.json +14 -3
- package/dist/people.d.ts +0 -205
- package/dist/people.js +0 -598
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,254 @@ 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
|
-
## [
|
|
8
|
+
## [2.0.0] - 2025-01-17
|
|
9
|
+
|
|
10
|
+
### 🚀 **MAJOR RELEASE - Complete API Redesign**
|
|
11
|
+
|
|
12
|
+
This is a **breaking change** release that completely redesigns the API for better developer experience, type safety, and maintainability.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
#### **🏗️ New Class-Based Architecture**
|
|
17
|
+
|
|
18
|
+
- **PcoClient Class**: Main client with modular architecture
|
|
19
|
+
- **PcoClientManager**: Automatic client caching and lifecycle management
|
|
20
|
+
- **Event System**: Comprehensive event emission for monitoring and debugging
|
|
21
|
+
- **Module Architecture**: Organized API interactions into focused modules
|
|
22
|
+
|
|
23
|
+
#### **🔧 Core Utilities**
|
|
24
|
+
|
|
25
|
+
- **Built-in Pagination**: `getAllPages()` method for automatic pagination
|
|
26
|
+
- **Batch Operations**: Execute multiple operations with dependency resolution
|
|
27
|
+
- **Person Matching**: Smart person matching with fuzzy logic and `findOrCreate`
|
|
28
|
+
- **Type-Safe Field Operations**: Enhanced custom field operations with caching
|
|
29
|
+
- **Workflow State Management**: Smart workflow operations with duplicate detection
|
|
30
|
+
|
|
31
|
+
#### **📦 New Modules**
|
|
32
|
+
|
|
33
|
+
- **PeopleModule**: Core person operations with smart matching
|
|
34
|
+
- **FieldsModule**: Type-safe custom field operations with caching
|
|
35
|
+
- **WorkflowsModule**: Complete workflow and workflow card management
|
|
36
|
+
- **ContactsModule**: Email, phone, address, and social profile management
|
|
37
|
+
- **HouseholdsModule**: Household operations and member management
|
|
38
|
+
- **NotesModule**: Note and note category operations
|
|
39
|
+
- **ListsModule**: List and list category operations with rule-based membership
|
|
40
|
+
|
|
41
|
+
#### **🔐 Enhanced Authentication**
|
|
42
|
+
|
|
43
|
+
- **OAuth 2.0 Support**: Full OAuth with automatic token refresh
|
|
44
|
+
- **Personal Access Token**: HTTP Basic Auth support
|
|
45
|
+
- **Token Refresh**: Automatic refresh with callback support
|
|
46
|
+
- **Environment Persistence**: Automatic token persistence in test environments
|
|
47
|
+
|
|
48
|
+
#### **⚡ Performance & Reliability**
|
|
49
|
+
|
|
50
|
+
- **Rate Limiting**: Built-in rate limiting (100 req/min)
|
|
51
|
+
- **Error Handling**: Comprehensive error handling with retry logic
|
|
52
|
+
- **Request Timeouts**: Configurable request timeouts
|
|
53
|
+
- **Event Monitoring**: Real-time request/response monitoring
|
|
54
|
+
|
|
55
|
+
#### **🧪 Testing Infrastructure**
|
|
56
|
+
|
|
57
|
+
- **MockPcoClient**: Complete mock implementation for testing
|
|
58
|
+
- **MockResponseBuilder**: Response building utilities
|
|
59
|
+
- **RequestRecorder**: Request recording for testing
|
|
60
|
+
- **Integration Tests**: 129 comprehensive integration tests
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
#### **🔄 Breaking Changes**
|
|
65
|
+
|
|
66
|
+
- **API Design**: Complete redesign from functional to class-based approach
|
|
67
|
+
- **Import Structure**: New import structure with `PcoClient` class
|
|
68
|
+
- **Method Names**: Updated method names for consistency
|
|
69
|
+
- **Type Definitions**: Enhanced type definitions with better type safety
|
|
70
|
+
|
|
71
|
+
#### **📈 Improvements**
|
|
72
|
+
|
|
73
|
+
- **Type Safety**: Enhanced TypeScript support with strict typing
|
|
74
|
+
- **Error Messages**: More descriptive error messages and handling
|
|
75
|
+
- **Documentation**: Comprehensive inline documentation
|
|
76
|
+
- **Performance**: Optimized request handling and caching
|
|
77
|
+
|
|
78
|
+
### Migration Guide
|
|
79
|
+
|
|
80
|
+
#### **Before (v1.x)**
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createPcoClient, getPeople, createPerson } from '@rachelallyson/planning-center-people-ts';
|
|
84
|
+
|
|
85
|
+
const client = createPcoClient({
|
|
86
|
+
personalAccessToken: 'your-token',
|
|
87
|
+
appId: 'your-app-id',
|
|
88
|
+
appSecret: 'your-app-secret'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const people = await getPeople(client, { per_page: 10 });
|
|
92
|
+
const person = await createPerson(client, { first_name: 'John', last_name: 'Doe' });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### **After (v2.0.0)**
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { PcoClient } from '@rachelallyson/planning-center-people-ts';
|
|
99
|
+
|
|
100
|
+
const client = new PcoClient({
|
|
101
|
+
auth: {
|
|
102
|
+
type: 'personal_access_token',
|
|
103
|
+
personalAccessToken: 'your-token'
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const people = await client.people.getAll({ perPage: 10 });
|
|
108
|
+
const person = await client.people.create({ first_name: 'John', last_name: 'Doe' });
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Removed
|
|
112
|
+
|
|
113
|
+
- **Functional API**: All functional API methods removed in favor of class-based approach
|
|
114
|
+
- **Legacy Types**: Old type definitions replaced with enhanced versions
|
|
115
|
+
- **Deprecated Methods**: All deprecated methods removed
|
|
116
|
+
|
|
117
|
+
### Fixed
|
|
118
|
+
|
|
119
|
+
- **Type Safety**: Resolved all TypeScript strict mode issues
|
|
120
|
+
- **Error Handling**: Improved error handling and retry logic
|
|
121
|
+
- **Rate Limiting**: Fixed rate limiting edge cases
|
|
122
|
+
- **Authentication**: Resolved token refresh and persistence issues
|
|
123
|
+
|
|
124
|
+
## [1.1.0] - 2025-10-08
|
|
125
|
+
|
|
126
|
+
### Added
|
|
127
|
+
|
|
128
|
+
- **Complete API Modularization**: Split monolithic `people.ts` into 9 focused modules for better maintainability
|
|
129
|
+
- **36 New API Functions**: Complete coverage of all PCO People API endpoints
|
|
130
|
+
- **File Upload Support**: New file handling capabilities with smart field type detection
|
|
131
|
+
- **Comprehensive Integration Tests**: 9 new integration test suites with 2,660+ lines of test coverage
|
|
132
|
+
- **Enhanced Helper Functions**: New file processing utilities and validation functions
|
|
133
|
+
- **Complete Function Checklist**: Comprehensive documentation of all available functions
|
|
134
|
+
|
|
135
|
+
### New API Functions
|
|
136
|
+
|
|
137
|
+
#### Core People Operations (`src/people/core.ts`)
|
|
138
|
+
|
|
139
|
+
- `getPeople()` - Get all people with filtering and pagination
|
|
140
|
+
- `getPerson()` - Get single person by ID
|
|
141
|
+
- `createPerson()` - Create new person
|
|
142
|
+
- `updatePerson()` - Update existing person
|
|
143
|
+
- `deletePerson()` - Delete person
|
|
144
|
+
|
|
145
|
+
#### Contact Management (`src/people/contacts.ts`)
|
|
146
|
+
|
|
147
|
+
- `getPersonEmails()` - Get all emails for a person
|
|
148
|
+
- `createPersonEmail()` - Create email for a person
|
|
149
|
+
- `getPersonPhoneNumbers()` - Get all phone numbers for a person
|
|
150
|
+
- `createPersonPhoneNumber()` - Create phone number for a person
|
|
151
|
+
- `getPersonAddresses()` - Get all addresses for a person
|
|
152
|
+
- `createPersonAddress()` - Create address for a person
|
|
153
|
+
- `updatePersonAddress()` - Update existing address
|
|
154
|
+
- `getPersonSocialProfiles()` - Get social profiles for a person
|
|
155
|
+
- `createPersonSocialProfile()` - Create social profile for a person
|
|
156
|
+
- `deleteSocialProfile()` - Delete social profile
|
|
157
|
+
|
|
158
|
+
#### Field Data Management (`src/people/fields.ts`)
|
|
159
|
+
|
|
160
|
+
- `createPersonFieldData()` - Create field data with smart file handling
|
|
161
|
+
- `deletePersonFieldData()` - Delete field data
|
|
162
|
+
- `getPersonFieldData()` - Get custom field data for a person
|
|
163
|
+
- `getFieldDefinitions()` - Get all field definitions
|
|
164
|
+
- `getFieldDefinition()` - Get single field definition
|
|
165
|
+
- `getFieldOptions()` - Get field options for a field definition
|
|
166
|
+
- `createFieldOption()` - Create field option
|
|
167
|
+
- `getTabs()` - Get field definition tabs
|
|
168
|
+
- `createFieldDefinition()` - Create new field definition
|
|
169
|
+
- `deleteFieldDefinition()` - Delete field definition
|
|
170
|
+
|
|
171
|
+
#### Household Operations (`src/people/households.ts`)
|
|
172
|
+
|
|
173
|
+
- `getHouseholds()` - Get all households
|
|
174
|
+
- `getHousehold()` - Get single household by ID
|
|
175
|
+
|
|
176
|
+
#### List Management (`src/people/lists.ts`)
|
|
177
|
+
|
|
178
|
+
- `getLists()` - Get all people lists
|
|
179
|
+
- `getListById()` - Get single list by ID
|
|
180
|
+
- `getListCategories()` - Get all list categories
|
|
181
|
+
|
|
182
|
+
#### Note Operations (`src/people/notes.ts`)
|
|
183
|
+
|
|
184
|
+
- `getNotes()` - Get all notes
|
|
185
|
+
- `getNote()` - Get single note by ID
|
|
186
|
+
- `getNoteCategories()` - Get all note categories
|
|
187
|
+
|
|
188
|
+
#### Workflow Management (`src/people/workflows.ts`)
|
|
189
|
+
|
|
190
|
+
- `getWorkflowCardNotes()` - Get notes for a workflow card
|
|
191
|
+
- `createWorkflowCardNote()` - Create note for workflow card
|
|
192
|
+
- `getWorkflowCards()` - Get workflow cards for a person
|
|
193
|
+
- `createWorkflowCard()` - Create workflow card for a person
|
|
194
|
+
- `getWorkflows()` - Get all workflows
|
|
195
|
+
- `getWorkflow()` - Get single workflow by ID
|
|
196
|
+
|
|
197
|
+
#### Organization Operations (`src/people/organization.ts`)
|
|
198
|
+
|
|
199
|
+
- `getOrganization()` - Get organization information
|
|
200
|
+
|
|
201
|
+
### New Helper Functions
|
|
202
|
+
|
|
203
|
+
#### File Upload Utilities
|
|
204
|
+
|
|
205
|
+
- `extractFileUrl()` - Extract clean URLs from HTML markup
|
|
206
|
+
- `isFileUrl()` - Check if string is a valid file URL
|
|
207
|
+
- `getFileExtension()` - Extract file extension from URL
|
|
208
|
+
- `getFilename()` - Extract filename from URL
|
|
209
|
+
- `isFileUpload()` - Detect if value contains file upload
|
|
210
|
+
- `processFileValue()` - Smart processing of file values based on field type
|
|
211
|
+
|
|
212
|
+
#### Enhanced Validation
|
|
213
|
+
|
|
214
|
+
- `validatePersonData()` - Comprehensive person data validation
|
|
215
|
+
- `isValidEmail()` - Email format validation
|
|
216
|
+
- `isValidPhone()` - Phone number format validation
|
|
217
|
+
|
|
218
|
+
#### Utility Functions
|
|
219
|
+
|
|
220
|
+
- `formatPersonName()` - Format person names with nickname support
|
|
221
|
+
- `formatDate()` - Flexible date formatting
|
|
222
|
+
- `calculateAge()` - Calculate age from birthdate
|
|
223
|
+
- `buildQueryParams()` - Transform complex params to flat query params
|
|
224
|
+
|
|
225
|
+
### Testing
|
|
226
|
+
|
|
227
|
+
- **9 New Integration Test Suites**: Complete integration testing for all API modules
|
|
228
|
+
- **2,660+ Lines of Test Code**: Comprehensive test coverage for all new functions
|
|
229
|
+
- **File Upload Testing**: Dedicated tests for file handling functionality
|
|
230
|
+
- **Edge Case Coverage**: Testing for error scenarios and edge cases
|
|
231
|
+
- **Type Validation**: Runtime validation of all API responses
|
|
232
|
+
|
|
233
|
+
### Documentation
|
|
234
|
+
|
|
235
|
+
- **Function Checklist**: Complete documentation of all 36 available functions
|
|
236
|
+
- **File Upload Examples**: New example showing file upload usage patterns
|
|
237
|
+
- **Updated API Guide**: Enhanced documentation with new function examples
|
|
238
|
+
- **Usage Examples**: Comprehensive examples for all new functionality
|
|
239
|
+
|
|
240
|
+
### Changed
|
|
241
|
+
|
|
242
|
+
- **Modular Architecture**: Restructured codebase for better maintainability and organization
|
|
243
|
+
- **Enhanced Error Handling**: Improved error handling across all new functions
|
|
244
|
+
- **Type Safety**: Enhanced TypeScript definitions for all new functions
|
|
245
|
+
- **Performance**: Optimized API calls with better parameter handling
|
|
246
|
+
|
|
247
|
+
### Technical Improvements
|
|
248
|
+
|
|
249
|
+
- **Better Code Organization**: Logical separation of concerns across modules
|
|
250
|
+
- **Consistent Patterns**: Standardized function signatures and error handling
|
|
251
|
+
- **Enhanced TypeScript**: Improved type definitions and inference
|
|
252
|
+
- **Comprehensive Testing**: Full test coverage for all new functionality
|
|
253
|
+
- **Documentation**: Complete API documentation and usage examples
|
|
254
|
+
|
|
255
|
+
## [1.0.0] - 2025-01-08
|
|
9
256
|
|
|
10
257
|
### Added
|
|
11
258
|
|
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
|
|
@@ -503,6 +515,22 @@ See [TYPE_VALIDATION_SUMMARY.md](./TYPE_VALIDATION_SUMMARY.md) for detailed docu
|
|
|
503
515
|
4. Add tests (both unit and integration)
|
|
504
516
|
5. Submit a pull request
|
|
505
517
|
|
|
518
|
+
## 📚 Comprehensive Documentation
|
|
519
|
+
|
|
520
|
+
This library includes extensive documentation covering all aspects of usage:
|
|
521
|
+
|
|
522
|
+
- **[📖 Complete Documentation](./docs/README.md)** - Comprehensive guide covering all features
|
|
523
|
+
- **[🚀 Getting Started](./docs/OVERVIEW.md)** - What this library does and why you should use it
|
|
524
|
+
- **[⚙️ Installation Guide](./docs/INSTALLATION.md)** - Complete setup instructions for all environments
|
|
525
|
+
- **[🔐 Authentication Guide](./docs/AUTHENTICATION.md)** - All authentication methods and token management
|
|
526
|
+
- **[📋 API Reference](./docs/API_REFERENCE.md)** - Complete reference for all 40+ functions
|
|
527
|
+
- **[💡 Examples & Patterns](./docs/EXAMPLES.md)** - Real-world examples and common patterns
|
|
528
|
+
- **[🛠️ Error Handling](./docs/ERROR_HANDLING.md)** - Advanced error management and recovery
|
|
529
|
+
- **[⚡ Performance Guide](./docs/PERFORMANCE.md)** - Optimization techniques and bulk operations
|
|
530
|
+
- **[🔧 Troubleshooting](./docs/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
531
|
+
- **[🔄 Migration Guide](./docs/MIGRATION.md)** - Switching from other libraries
|
|
532
|
+
- **[⭐ Best Practices](./docs/BEST_PRACTICES.md)** - Production-ready patterns and security
|
|
533
|
+
|
|
506
534
|
## License
|
|
507
535
|
|
|
508
536
|
MIT
|
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/batch.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 Batch Operations Executor
|
|
3
|
+
*/
|
|
4
|
+
import type { PcoClient } from './client';
|
|
5
|
+
import type { PcoEventEmitter } from './monitoring';
|
|
6
|
+
import type { BatchOperation, BatchOptions, BatchSummary } from './types/batch';
|
|
7
|
+
export declare class BatchExecutor {
|
|
8
|
+
private client;
|
|
9
|
+
private eventEmitter;
|
|
10
|
+
constructor(client: PcoClient, eventEmitter: PcoEventEmitter);
|
|
11
|
+
/**
|
|
12
|
+
* Execute a batch of operations
|
|
13
|
+
*/
|
|
14
|
+
execute<T = any>(operations: BatchOperation[], options?: BatchOptions): Promise<BatchSummary>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve operation dependencies and references
|
|
17
|
+
*/
|
|
18
|
+
private resolveOperations;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve references in operation data
|
|
21
|
+
*/
|
|
22
|
+
private resolveReferences;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve string references like "$0.id" or "$1.data.attributes.name"
|
|
25
|
+
*/
|
|
26
|
+
private resolveStringReferences;
|
|
27
|
+
/**
|
|
28
|
+
* Get nested value from object using dot notation
|
|
29
|
+
*/
|
|
30
|
+
private getNestedValue;
|
|
31
|
+
/**
|
|
32
|
+
* Find dependencies for an operation
|
|
33
|
+
*/
|
|
34
|
+
private findDependencies;
|
|
35
|
+
/**
|
|
36
|
+
* Execute a single operation
|
|
37
|
+
*/
|
|
38
|
+
private executeOperation;
|
|
39
|
+
/**
|
|
40
|
+
* Rollback successful operations
|
|
41
|
+
*/
|
|
42
|
+
private rollbackOperations;
|
|
43
|
+
/**
|
|
44
|
+
* Rollback a single operation
|
|
45
|
+
*/
|
|
46
|
+
private rollbackOperation;
|
|
47
|
+
}
|