@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.
Files changed (82) hide show
  1. package/CHANGELOG.md +248 -1
  2. package/README.md +28 -0
  3. package/dist/auth.d.ts +64 -0
  4. package/dist/auth.js +98 -0
  5. package/dist/batch.d.ts +47 -0
  6. package/dist/batch.js +376 -0
  7. package/dist/client-manager.d.ts +66 -0
  8. package/dist/client-manager.js +150 -0
  9. package/dist/client.d.ts +71 -0
  10. package/dist/client.js +123 -0
  11. package/dist/core/http.d.ts +47 -0
  12. package/dist/core/http.js +242 -0
  13. package/dist/core/pagination.d.ts +34 -0
  14. package/dist/core/pagination.js +164 -0
  15. package/dist/core.d.ts +5 -0
  16. package/dist/core.js +12 -0
  17. package/dist/helpers.d.ts +125 -100
  18. package/dist/helpers.js +315 -275
  19. package/dist/index.d.ts +17 -5
  20. package/dist/index.js +39 -5
  21. package/dist/matching/matcher.d.ts +41 -0
  22. package/dist/matching/matcher.js +161 -0
  23. package/dist/matching/scoring.d.ts +35 -0
  24. package/dist/matching/scoring.js +141 -0
  25. package/dist/matching/strategies.d.ts +35 -0
  26. package/dist/matching/strategies.js +79 -0
  27. package/dist/modules/base.d.ts +46 -0
  28. package/dist/modules/base.js +82 -0
  29. package/dist/modules/contacts.d.ts +103 -0
  30. package/dist/modules/contacts.js +130 -0
  31. package/dist/modules/fields.d.ts +157 -0
  32. package/dist/modules/fields.js +294 -0
  33. package/dist/modules/households.d.ts +42 -0
  34. package/dist/modules/households.js +74 -0
  35. package/dist/modules/lists.d.ts +62 -0
  36. package/dist/modules/lists.js +92 -0
  37. package/dist/modules/notes.d.ts +74 -0
  38. package/dist/modules/notes.js +125 -0
  39. package/dist/modules/people.d.ts +196 -0
  40. package/dist/modules/people.js +221 -0
  41. package/dist/modules/workflows.d.ts +131 -0
  42. package/dist/modules/workflows.js +221 -0
  43. package/dist/monitoring.d.ts +53 -0
  44. package/dist/monitoring.js +142 -0
  45. package/dist/people/contacts.d.ts +43 -0
  46. package/dist/people/contacts.js +122 -0
  47. package/dist/people/core.d.ts +28 -0
  48. package/dist/people/core.js +69 -0
  49. package/dist/people/fields.d.ts +62 -0
  50. package/dist/people/fields.js +293 -0
  51. package/dist/people/households.d.ts +15 -0
  52. package/dist/people/households.js +31 -0
  53. package/dist/people/index.d.ts +8 -0
  54. package/dist/people/index.js +25 -0
  55. package/dist/people/lists.d.ts +30 -0
  56. package/dist/people/lists.js +37 -0
  57. package/dist/people/notes.d.ts +30 -0
  58. package/dist/people/notes.js +37 -0
  59. package/dist/people/organization.d.ts +12 -0
  60. package/dist/people/organization.js +15 -0
  61. package/dist/people/workflows.d.ts +37 -0
  62. package/dist/people/workflows.js +75 -0
  63. package/dist/testing/index.d.ts +9 -0
  64. package/dist/testing/index.js +24 -0
  65. package/dist/testing/recorder.d.ts +58 -0
  66. package/dist/testing/recorder.js +195 -0
  67. package/dist/testing/simple-builders.d.ts +33 -0
  68. package/dist/testing/simple-builders.js +124 -0
  69. package/dist/testing/simple-factories.d.ts +91 -0
  70. package/dist/testing/simple-factories.js +279 -0
  71. package/dist/testing/types.d.ts +160 -0
  72. package/dist/testing/types.js +5 -0
  73. package/dist/types/batch.d.ts +50 -0
  74. package/dist/types/batch.js +5 -0
  75. package/dist/types/client.d.ts +81 -0
  76. package/dist/types/client.js +5 -0
  77. package/dist/types/events.d.ts +85 -0
  78. package/dist/types/events.js +5 -0
  79. package/dist/types/people.d.ts +73 -79
  80. package/package.json +14 -3
  81. package/dist/people.d.ts +0 -205
  82. 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
- ## [1.0.0] - 2024-01-XX
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
+ }
@@ -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
+ }