@rachelallyson/planning-center-people-ts 2.7.0 → 2.9.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 +174 -0
- package/LICENSE +1 -1
- package/README.md +12 -14
- package/dist/client.d.ts +8 -8
- package/dist/client.js +8 -11
- package/dist/core/http.d.ts +1 -1
- package/dist/core/http.js +18 -11
- package/dist/core/pagination.js +16 -2
- package/dist/core.d.ts +3 -3
- package/dist/core.js +4 -4
- package/dist/error-handling.d.ts +1 -1
- package/dist/error-handling.js +3 -3
- package/dist/error-scenarios.js +4 -4
- package/dist/helpers.js +5 -4
- package/dist/index.d.ts +8 -8
- package/dist/index.js +15 -15
- package/dist/matching/matcher.d.ts +22 -0
- package/dist/matching/matcher.js +260 -27
- package/dist/matching/scoring.d.ts +9 -7
- package/dist/matching/scoring.js +54 -23
- package/dist/matching/strategies.d.ts +1 -0
- package/dist/matching/strategies.js +17 -4
- package/dist/modules/campus.d.ts +5 -5
- package/dist/modules/campus.js +2 -2
- package/dist/modules/contacts.d.ts +1 -1
- package/dist/modules/contacts.js +2 -2
- package/dist/modules/fields.d.ts +4 -4
- package/dist/modules/fields.js +2 -2
- package/dist/modules/forms.d.ts +7 -4
- package/dist/modules/forms.js +5 -2
- package/dist/modules/households.d.ts +2 -2
- package/dist/modules/households.js +2 -2
- package/dist/modules/lists.d.ts +2 -2
- package/dist/modules/lists.js +2 -2
- package/dist/modules/notes.d.ts +2 -2
- package/dist/modules/notes.js +2 -2
- package/dist/modules/people.d.ts +57 -5
- package/dist/modules/people.js +44 -9
- package/dist/modules/reports.d.ts +5 -5
- package/dist/modules/reports.js +2 -2
- package/dist/modules/service-time.d.ts +5 -5
- package/dist/modules/service-time.js +2 -2
- package/dist/modules/workflows.d.ts +2 -2
- package/dist/modules/workflows.js +2 -2
- package/dist/people/contacts.d.ts +1 -1
- package/dist/people/core.d.ts +1 -1
- package/dist/people/fields.d.ts +1 -1
- package/dist/people/fields.js +4 -4
- package/dist/people/households.d.ts +1 -1
- package/dist/people/lists.d.ts +1 -1
- package/dist/people/notes.d.ts +1 -1
- package/dist/people/organization.d.ts +1 -1
- package/dist/people/workflows.d.ts +1 -1
- package/dist/types/client.d.ts +3 -96
- package/dist/types/client.js +2 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.js +0 -2
- package/package.json +16 -19
- package/dist/api-error.d.ts +0 -10
- package/dist/api-error.js +0 -32
- package/dist/batch.d.ts +0 -47
- package/dist/batch.js +0 -376
- package/dist/modules/base.d.ts +0 -46
- package/dist/modules/base.js +0 -82
- package/dist/monitoring.d.ts +0 -53
- package/dist/monitoring.js +0 -142
- package/dist/rate-limiter.d.ts +0 -79
- package/dist/rate-limiter.js +0 -137
- package/dist/types/batch.d.ts +0 -50
- package/dist/types/batch.js +0 -5
- package/dist/types/events.d.ts +0 -85
- package/dist/types/events.js +0 -5
package/dist/modules/base.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2.0.0 Base Module Class
|
|
3
|
-
*/
|
|
4
|
-
import type { PcoHttpClient } from '../core/http';
|
|
5
|
-
import type { PaginationHelper } from '../core/pagination';
|
|
6
|
-
import type { PcoEventEmitter } from '../monitoring';
|
|
7
|
-
import type { PaginationOptions, PaginationResult } from '../core/pagination';
|
|
8
|
-
import type { ResourceObject } from '../types';
|
|
9
|
-
export declare abstract class BaseModule {
|
|
10
|
-
protected httpClient: PcoHttpClient;
|
|
11
|
-
protected paginationHelper: PaginationHelper;
|
|
12
|
-
protected eventEmitter: PcoEventEmitter;
|
|
13
|
-
constructor(httpClient: PcoHttpClient, paginationHelper: PaginationHelper, eventEmitter: PcoEventEmitter);
|
|
14
|
-
/**
|
|
15
|
-
* Get a single resource
|
|
16
|
-
*/
|
|
17
|
-
protected getSingle<T extends ResourceObject<string, any, any>>(endpoint: string, params?: Record<string, any>): Promise<T>;
|
|
18
|
-
/**
|
|
19
|
-
* Get a list of resources
|
|
20
|
-
*/
|
|
21
|
-
protected getList<T extends ResourceObject<string, any, any>>(endpoint: string, params?: Record<string, any>): Promise<{
|
|
22
|
-
data: T[];
|
|
23
|
-
meta?: any;
|
|
24
|
-
links?: any;
|
|
25
|
-
}>;
|
|
26
|
-
/**
|
|
27
|
-
* Create a resource
|
|
28
|
-
*/
|
|
29
|
-
protected createResource<T extends ResourceObject<string, any, any>>(endpoint: string, data: any, params?: Record<string, any>): Promise<T>;
|
|
30
|
-
/**
|
|
31
|
-
* Update a resource
|
|
32
|
-
*/
|
|
33
|
-
protected updateResource<T extends ResourceObject<string, any, any>>(endpoint: string, data: any, params?: Record<string, any>): Promise<T>;
|
|
34
|
-
/**
|
|
35
|
-
* Delete a resource
|
|
36
|
-
*/
|
|
37
|
-
protected deleteResource(endpoint: string, params?: Record<string, any>): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* Get all pages of a resource
|
|
40
|
-
*/
|
|
41
|
-
protected getAllPages<T extends ResourceObject<string, any, any>>(endpoint: string, params?: Record<string, any>, options?: PaginationOptions): Promise<PaginationResult<T>>;
|
|
42
|
-
/**
|
|
43
|
-
* Stream pages of a resource
|
|
44
|
-
*/
|
|
45
|
-
protected streamPages<T extends ResourceObject<string, any, any>>(endpoint: string, params?: Record<string, any>, options?: PaginationOptions): AsyncGenerator<T[], void, unknown>;
|
|
46
|
-
}
|
package/dist/modules/base.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* v2.0.0 Base Module Class
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.BaseModule = void 0;
|
|
7
|
-
class BaseModule {
|
|
8
|
-
constructor(httpClient, paginationHelper, eventEmitter) {
|
|
9
|
-
this.httpClient = httpClient;
|
|
10
|
-
this.paginationHelper = paginationHelper;
|
|
11
|
-
this.eventEmitter = eventEmitter;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Get a single resource
|
|
15
|
-
*/
|
|
16
|
-
async getSingle(endpoint, params) {
|
|
17
|
-
const response = await this.httpClient.request({
|
|
18
|
-
method: 'GET',
|
|
19
|
-
endpoint,
|
|
20
|
-
params,
|
|
21
|
-
});
|
|
22
|
-
return response.data.data;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Get a list of resources
|
|
26
|
-
*/
|
|
27
|
-
async getList(endpoint, params) {
|
|
28
|
-
const response = await this.httpClient.request({
|
|
29
|
-
method: 'GET',
|
|
30
|
-
endpoint,
|
|
31
|
-
params,
|
|
32
|
-
});
|
|
33
|
-
return response.data;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Create a resource
|
|
37
|
-
*/
|
|
38
|
-
async createResource(endpoint, data, params) {
|
|
39
|
-
const response = await this.httpClient.request({
|
|
40
|
-
method: 'POST',
|
|
41
|
-
endpoint,
|
|
42
|
-
data,
|
|
43
|
-
params,
|
|
44
|
-
});
|
|
45
|
-
return response.data.data;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Update a resource
|
|
49
|
-
*/
|
|
50
|
-
async updateResource(endpoint, data, params) {
|
|
51
|
-
const response = await this.httpClient.request({
|
|
52
|
-
method: 'PATCH',
|
|
53
|
-
endpoint,
|
|
54
|
-
data,
|
|
55
|
-
params,
|
|
56
|
-
});
|
|
57
|
-
return response.data.data;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Delete a resource
|
|
61
|
-
*/
|
|
62
|
-
async deleteResource(endpoint, params) {
|
|
63
|
-
await this.httpClient.request({
|
|
64
|
-
method: 'DELETE',
|
|
65
|
-
endpoint,
|
|
66
|
-
params,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Get all pages of a resource
|
|
71
|
-
*/
|
|
72
|
-
async getAllPages(endpoint, params, options) {
|
|
73
|
-
return this.paginationHelper.getAllPages(endpoint, params, options);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Stream pages of a resource
|
|
77
|
-
*/
|
|
78
|
-
async *streamPages(endpoint, params, options) {
|
|
79
|
-
yield* this.paginationHelper.streamPages(endpoint, params, options);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
exports.BaseModule = BaseModule;
|
package/dist/monitoring.d.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2.0.0 Event System and Monitoring
|
|
3
|
-
*/
|
|
4
|
-
import type { PcoEvent, EventHandler, EventType, EventEmitter } from './types/events';
|
|
5
|
-
export declare class PcoEventEmitter implements EventEmitter {
|
|
6
|
-
private handlers;
|
|
7
|
-
on<T extends PcoEvent>(eventType: T['type'], handler: EventHandler<T>): void;
|
|
8
|
-
off<T extends PcoEvent>(eventType: T['type'], handler: EventHandler<T>): void;
|
|
9
|
-
emit<T extends PcoEvent>(event: T): void;
|
|
10
|
-
/** Remove all event handlers */
|
|
11
|
-
removeAllListeners(eventType?: EventType): void;
|
|
12
|
-
/** Get the number of listeners for an event type */
|
|
13
|
-
listenerCount(eventType: EventType): number;
|
|
14
|
-
/** Get all registered event types */
|
|
15
|
-
eventTypes(): EventType[];
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Request ID generator for tracking requests
|
|
19
|
-
*/
|
|
20
|
-
export declare class RequestIdGenerator {
|
|
21
|
-
private counter;
|
|
22
|
-
generate(): string;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Performance metrics collector
|
|
26
|
-
*/
|
|
27
|
-
export declare class PerformanceMetrics {
|
|
28
|
-
private metrics;
|
|
29
|
-
record(operation: string, duration: number, success?: boolean): void;
|
|
30
|
-
getMetrics(): Record<string, {
|
|
31
|
-
count: number;
|
|
32
|
-
averageTime: number;
|
|
33
|
-
minTime: number;
|
|
34
|
-
maxTime: number;
|
|
35
|
-
errorRate: number;
|
|
36
|
-
}>;
|
|
37
|
-
reset(): void;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Rate limit tracker
|
|
41
|
-
*/
|
|
42
|
-
export declare class RateLimitTracker {
|
|
43
|
-
private limits;
|
|
44
|
-
update(endpoint: string, limit: number, remaining: number, resetTime: number): void;
|
|
45
|
-
getRemaining(endpoint: string): number;
|
|
46
|
-
getResetTime(endpoint: string): number;
|
|
47
|
-
isRateLimited(endpoint: string): boolean;
|
|
48
|
-
getAllLimits(): Record<string, {
|
|
49
|
-
limit: number;
|
|
50
|
-
remaining: number;
|
|
51
|
-
resetTime: number;
|
|
52
|
-
}>;
|
|
53
|
-
}
|
package/dist/monitoring.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* v2.0.0 Event System and Monitoring
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RateLimitTracker = exports.PerformanceMetrics = exports.RequestIdGenerator = exports.PcoEventEmitter = void 0;
|
|
7
|
-
class PcoEventEmitter {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.handlers = new Map();
|
|
10
|
-
}
|
|
11
|
-
on(eventType, handler) {
|
|
12
|
-
if (!this.handlers.has(eventType)) {
|
|
13
|
-
this.handlers.set(eventType, new Set());
|
|
14
|
-
}
|
|
15
|
-
this.handlers.get(eventType).add(handler);
|
|
16
|
-
}
|
|
17
|
-
off(eventType, handler) {
|
|
18
|
-
const eventHandlers = this.handlers.get(eventType);
|
|
19
|
-
if (eventHandlers) {
|
|
20
|
-
eventHandlers.delete(handler);
|
|
21
|
-
if (eventHandlers.size === 0) {
|
|
22
|
-
this.handlers.delete(eventType);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
emit(event) {
|
|
27
|
-
const eventHandlers = this.handlers.get(event.type);
|
|
28
|
-
if (eventHandlers) {
|
|
29
|
-
for (const handler of eventHandlers) {
|
|
30
|
-
try {
|
|
31
|
-
handler(event);
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
console.error(`Error in event handler for ${event.type}:`, error);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/** Remove all event handlers */
|
|
40
|
-
removeAllListeners(eventType) {
|
|
41
|
-
if (eventType) {
|
|
42
|
-
this.handlers.delete(eventType);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
this.handlers.clear();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/** Get the number of listeners for an event type */
|
|
49
|
-
listenerCount(eventType) {
|
|
50
|
-
return this.handlers.get(eventType)?.size || 0;
|
|
51
|
-
}
|
|
52
|
-
/** Get all registered event types */
|
|
53
|
-
eventTypes() {
|
|
54
|
-
return Array.from(this.handlers.keys());
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
exports.PcoEventEmitter = PcoEventEmitter;
|
|
58
|
-
/**
|
|
59
|
-
* Request ID generator for tracking requests
|
|
60
|
-
*/
|
|
61
|
-
class RequestIdGenerator {
|
|
62
|
-
constructor() {
|
|
63
|
-
this.counter = 0;
|
|
64
|
-
}
|
|
65
|
-
generate() {
|
|
66
|
-
return `req_${Date.now()}_${++this.counter}`;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
exports.RequestIdGenerator = RequestIdGenerator;
|
|
70
|
-
/**
|
|
71
|
-
* Performance metrics collector
|
|
72
|
-
*/
|
|
73
|
-
class PerformanceMetrics {
|
|
74
|
-
constructor() {
|
|
75
|
-
this.metrics = new Map();
|
|
76
|
-
}
|
|
77
|
-
record(operation, duration, success = true) {
|
|
78
|
-
const existing = this.metrics.get(operation) || {
|
|
79
|
-
count: 0,
|
|
80
|
-
totalTime: 0,
|
|
81
|
-
minTime: Infinity,
|
|
82
|
-
maxTime: 0,
|
|
83
|
-
errors: 0,
|
|
84
|
-
};
|
|
85
|
-
existing.count++;
|
|
86
|
-
existing.totalTime += duration;
|
|
87
|
-
existing.minTime = Math.min(existing.minTime, duration);
|
|
88
|
-
existing.maxTime = Math.max(existing.maxTime, duration);
|
|
89
|
-
if (!success) {
|
|
90
|
-
existing.errors++;
|
|
91
|
-
}
|
|
92
|
-
this.metrics.set(operation, existing);
|
|
93
|
-
}
|
|
94
|
-
getMetrics() {
|
|
95
|
-
const result = {};
|
|
96
|
-
for (const [operation, metrics] of this.metrics) {
|
|
97
|
-
result[operation] = {
|
|
98
|
-
count: metrics.count,
|
|
99
|
-
averageTime: metrics.totalTime / metrics.count,
|
|
100
|
-
minTime: metrics.minTime === Infinity ? 0 : metrics.minTime,
|
|
101
|
-
maxTime: metrics.maxTime,
|
|
102
|
-
errorRate: metrics.errors / metrics.count,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
reset() {
|
|
108
|
-
this.metrics.clear();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
exports.PerformanceMetrics = PerformanceMetrics;
|
|
112
|
-
/**
|
|
113
|
-
* Rate limit tracker
|
|
114
|
-
*/
|
|
115
|
-
class RateLimitTracker {
|
|
116
|
-
constructor() {
|
|
117
|
-
this.limits = new Map();
|
|
118
|
-
}
|
|
119
|
-
update(endpoint, limit, remaining, resetTime) {
|
|
120
|
-
this.limits.set(endpoint, { limit, remaining, resetTime });
|
|
121
|
-
}
|
|
122
|
-
getRemaining(endpoint) {
|
|
123
|
-
const limit = this.limits.get(endpoint);
|
|
124
|
-
return limit?.remaining || 0;
|
|
125
|
-
}
|
|
126
|
-
getResetTime(endpoint) {
|
|
127
|
-
const limit = this.limits.get(endpoint);
|
|
128
|
-
return limit?.resetTime || 0;
|
|
129
|
-
}
|
|
130
|
-
isRateLimited(endpoint) {
|
|
131
|
-
const limit = this.limits.get(endpoint);
|
|
132
|
-
return limit ? limit.remaining <= 0 : false;
|
|
133
|
-
}
|
|
134
|
-
getAllLimits() {
|
|
135
|
-
const result = {};
|
|
136
|
-
for (const [endpoint, limit] of this.limits) {
|
|
137
|
-
result[endpoint] = limit;
|
|
138
|
-
}
|
|
139
|
-
return result;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
exports.RateLimitTracker = RateLimitTracker;
|
package/dist/rate-limiter.d.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PCO Rate Limiter
|
|
3
|
-
*
|
|
4
|
-
* Planning Center Online has the following rate limits:
|
|
5
|
-
* - 100 requests per 20 seconds (subject to change)
|
|
6
|
-
* - Rate limit headers are returned on every response
|
|
7
|
-
* - 429 responses include Retry-After header
|
|
8
|
-
* - Limits and time periods can change dynamically
|
|
9
|
-
*
|
|
10
|
-
* This rate limiter tracks requests and enforces these limits.
|
|
11
|
-
*/
|
|
12
|
-
export interface RateLimitInfo {
|
|
13
|
-
limit: number;
|
|
14
|
-
remaining: number;
|
|
15
|
-
resetTime: number;
|
|
16
|
-
retryAfter?: number;
|
|
17
|
-
}
|
|
18
|
-
export interface RateLimitHeaders {
|
|
19
|
-
'X-PCO-API-Request-Rate-Limit'?: string;
|
|
20
|
-
'X-PCO-API-Request-Rate-Period'?: string;
|
|
21
|
-
'X-PCO-API-Request-Rate-Count'?: string;
|
|
22
|
-
'Retry-After'?: string;
|
|
23
|
-
}
|
|
24
|
-
export declare class PcoRateLimiter {
|
|
25
|
-
private requestCount;
|
|
26
|
-
private windowStart;
|
|
27
|
-
private readonly defaultLimit;
|
|
28
|
-
private readonly defaultWindow;
|
|
29
|
-
private limit;
|
|
30
|
-
private windowMs;
|
|
31
|
-
constructor(limit?: number, windowMs?: number);
|
|
32
|
-
/**
|
|
33
|
-
* Check if a request can be made
|
|
34
|
-
*/
|
|
35
|
-
canMakeRequest(): boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Record a request
|
|
38
|
-
*/
|
|
39
|
-
recordRequest(): void;
|
|
40
|
-
/**
|
|
41
|
-
* Get time until next window reset
|
|
42
|
-
*/
|
|
43
|
-
getTimeUntilReset(): number;
|
|
44
|
-
/**
|
|
45
|
-
* Get current rate limit info
|
|
46
|
-
*/
|
|
47
|
-
getRateLimitInfo(): RateLimitInfo;
|
|
48
|
-
/**
|
|
49
|
-
* Update rate limit info from response headers
|
|
50
|
-
*/
|
|
51
|
-
updateFromHeaders(headers: RateLimitHeaders): void;
|
|
52
|
-
/**
|
|
53
|
-
* Wait until a request can be made
|
|
54
|
-
*/
|
|
55
|
-
waitForAvailability(): Promise<void>;
|
|
56
|
-
/**
|
|
57
|
-
* Update the sliding window
|
|
58
|
-
*/
|
|
59
|
-
private updateWindow;
|
|
60
|
-
/**
|
|
61
|
-
* Parse rate limit error details from 429 response
|
|
62
|
-
*/
|
|
63
|
-
static parseRateLimitError(errorDetail: string): {
|
|
64
|
-
current: number;
|
|
65
|
-
limit: number;
|
|
66
|
-
period: number;
|
|
67
|
-
} | null;
|
|
68
|
-
/**
|
|
69
|
-
* Get debug information
|
|
70
|
-
*/
|
|
71
|
-
getDebugInfo(): {
|
|
72
|
-
canMakeRequest: boolean;
|
|
73
|
-
limit: number;
|
|
74
|
-
requestCount: number;
|
|
75
|
-
timeUntilReset: number;
|
|
76
|
-
windowMs: number;
|
|
77
|
-
windowStart: number;
|
|
78
|
-
};
|
|
79
|
-
}
|
package/dist/rate-limiter.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* PCO Rate Limiter
|
|
4
|
-
*
|
|
5
|
-
* Planning Center Online has the following rate limits:
|
|
6
|
-
* - 100 requests per 20 seconds (subject to change)
|
|
7
|
-
* - Rate limit headers are returned on every response
|
|
8
|
-
* - 429 responses include Retry-After header
|
|
9
|
-
* - Limits and time periods can change dynamically
|
|
10
|
-
*
|
|
11
|
-
* This rate limiter tracks requests and enforces these limits.
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.PcoRateLimiter = void 0;
|
|
15
|
-
class PcoRateLimiter {
|
|
16
|
-
constructor(limit, windowMs) {
|
|
17
|
-
this.requestCount = 0;
|
|
18
|
-
this.windowStart = Date.now();
|
|
19
|
-
this.defaultLimit = 100; // requests per 20 seconds
|
|
20
|
-
this.defaultWindow = 20000; // 20 seconds in milliseconds
|
|
21
|
-
this.limit = limit || this.defaultLimit;
|
|
22
|
-
this.windowMs = windowMs || this.defaultWindow;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Check if a request can be made
|
|
26
|
-
*/
|
|
27
|
-
canMakeRequest() {
|
|
28
|
-
this.updateWindow();
|
|
29
|
-
return this.requestCount < this.limit;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Record a request
|
|
33
|
-
*/
|
|
34
|
-
recordRequest() {
|
|
35
|
-
this.updateWindow();
|
|
36
|
-
this.requestCount++;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Get time until next window reset
|
|
40
|
-
*/
|
|
41
|
-
getTimeUntilReset() {
|
|
42
|
-
this.updateWindow();
|
|
43
|
-
const now = Date.now();
|
|
44
|
-
return Math.max(0, this.windowStart + this.windowMs - now);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Get current rate limit info
|
|
48
|
-
*/
|
|
49
|
-
getRateLimitInfo() {
|
|
50
|
-
this.updateWindow();
|
|
51
|
-
return {
|
|
52
|
-
limit: this.limit,
|
|
53
|
-
remaining: Math.max(0, this.limit - this.requestCount),
|
|
54
|
-
resetTime: this.windowStart + this.windowMs,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Update rate limit info from response headers
|
|
59
|
-
*/
|
|
60
|
-
updateFromHeaders(headers) {
|
|
61
|
-
if (headers['X-PCO-API-Request-Rate-Limit']) {
|
|
62
|
-
this.limit = parseInt(headers['X-PCO-API-Request-Rate-Limit'], 10);
|
|
63
|
-
}
|
|
64
|
-
if (headers['X-PCO-API-Request-Rate-Period']) {
|
|
65
|
-
// Update window period from server (in seconds, convert to milliseconds)
|
|
66
|
-
const periodSeconds = parseInt(headers['X-PCO-API-Request-Rate-Period'], 10);
|
|
67
|
-
if (!isNaN(periodSeconds)) {
|
|
68
|
-
this.windowMs = periodSeconds * 1000;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (headers['X-PCO-API-Request-Rate-Count']) {
|
|
72
|
-
this.requestCount = parseInt(headers['X-PCO-API-Request-Rate-Count'], 10);
|
|
73
|
-
}
|
|
74
|
-
if (headers['Retry-After']) {
|
|
75
|
-
const retryAfter = parseInt(headers['Retry-After'], 10);
|
|
76
|
-
if (!isNaN(retryAfter)) {
|
|
77
|
-
// If we get a retry-after, it means we hit the limit
|
|
78
|
-
// Reset the window to start after the retry period
|
|
79
|
-
this.windowStart = Date.now() + retryAfter * 1000;
|
|
80
|
-
this.requestCount = 0;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Wait until a request can be made
|
|
86
|
-
*/
|
|
87
|
-
async waitForAvailability() {
|
|
88
|
-
if (this.canMakeRequest()) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const waitTime = this.getTimeUntilReset();
|
|
92
|
-
if (waitTime > 0) {
|
|
93
|
-
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Update the sliding window
|
|
98
|
-
*/
|
|
99
|
-
updateWindow() {
|
|
100
|
-
const now = Date.now();
|
|
101
|
-
const windowEnd = this.windowStart + this.windowMs;
|
|
102
|
-
if (now >= windowEnd) {
|
|
103
|
-
// Reset the window
|
|
104
|
-
this.windowStart = now;
|
|
105
|
-
this.requestCount = 0;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Parse rate limit error details from 429 response
|
|
110
|
-
*/
|
|
111
|
-
static parseRateLimitError(errorDetail) {
|
|
112
|
-
// Parse error like "Rate limit exceeded: 118 of 100 requests per 20 seconds"
|
|
113
|
-
const match = errorDetail.match(/Rate limit exceeded: (\d+) of (\d+) requests per (\d+) seconds/);
|
|
114
|
-
if (match) {
|
|
115
|
-
return {
|
|
116
|
-
current: parseInt(match[1], 10),
|
|
117
|
-
limit: parseInt(match[2], 10),
|
|
118
|
-
period: parseInt(match[3], 10)
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Get debug information
|
|
125
|
-
*/
|
|
126
|
-
getDebugInfo() {
|
|
127
|
-
return {
|
|
128
|
-
canMakeRequest: this.canMakeRequest(),
|
|
129
|
-
limit: this.limit,
|
|
130
|
-
requestCount: this.requestCount,
|
|
131
|
-
timeUntilReset: this.getTimeUntilReset(),
|
|
132
|
-
windowMs: this.windowMs,
|
|
133
|
-
windowStart: this.windowStart,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
exports.PcoRateLimiter = PcoRateLimiter;
|
package/dist/types/batch.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2.0.0 Batch Operations Types
|
|
3
|
-
*/
|
|
4
|
-
export interface BatchOperation {
|
|
5
|
-
type: string;
|
|
6
|
-
data?: any;
|
|
7
|
-
dependencies?: string[];
|
|
8
|
-
[key: string]: any;
|
|
9
|
-
}
|
|
10
|
-
export interface BatchResult<T = any> {
|
|
11
|
-
index: number;
|
|
12
|
-
operation: BatchOperation;
|
|
13
|
-
success: boolean;
|
|
14
|
-
data?: T;
|
|
15
|
-
error?: Error;
|
|
16
|
-
}
|
|
17
|
-
export interface BatchOptions {
|
|
18
|
-
/** Continue processing other operations if one fails */
|
|
19
|
-
continueOnError?: boolean;
|
|
20
|
-
/** Maximum number of operations to run in parallel */
|
|
21
|
-
maxConcurrency?: number;
|
|
22
|
-
/** Enable automatic rollback on failure */
|
|
23
|
-
enableRollback?: boolean;
|
|
24
|
-
/** Callback for each completed operation */
|
|
25
|
-
onOperationComplete?: (result: BatchResult) => void;
|
|
26
|
-
/** Callback for batch completion */
|
|
27
|
-
onBatchComplete?: (results: BatchResult[]) => void;
|
|
28
|
-
}
|
|
29
|
-
export interface BatchSummary {
|
|
30
|
-
total: number;
|
|
31
|
-
successful: number;
|
|
32
|
-
failed: number;
|
|
33
|
-
successRate: number;
|
|
34
|
-
duration: number;
|
|
35
|
-
results: BatchResult[];
|
|
36
|
-
}
|
|
37
|
-
export interface OperationReference {
|
|
38
|
-
/** Reference to a previous operation result using $index.path syntax */
|
|
39
|
-
reference: string;
|
|
40
|
-
/** The operation index being referenced */
|
|
41
|
-
index: number;
|
|
42
|
-
/** The path within the result object */
|
|
43
|
-
path: string;
|
|
44
|
-
}
|
|
45
|
-
export interface ResolvedBatchOperation extends BatchOperation {
|
|
46
|
-
/** Resolved data with references replaced */
|
|
47
|
-
resolvedData?: any;
|
|
48
|
-
/** Dependencies on other operations */
|
|
49
|
-
dependencies?: string[];
|
|
50
|
-
}
|
package/dist/types/batch.js
DELETED
package/dist/types/events.d.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2.0.0 Event System Types
|
|
3
|
-
*/
|
|
4
|
-
export type EventType = 'request:start' | 'request:complete' | 'request:error' | 'auth:success' | 'auth:failure' | 'auth:refresh' | 'rate:limit' | 'rate:available' | 'cache:hit' | 'cache:miss' | 'cache:set' | 'cache:invalidate' | 'error';
|
|
5
|
-
export interface BaseEvent {
|
|
6
|
-
type: EventType;
|
|
7
|
-
timestamp: string;
|
|
8
|
-
requestId?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface RequestStartEvent extends BaseEvent {
|
|
11
|
-
type: 'request:start';
|
|
12
|
-
endpoint: string;
|
|
13
|
-
method: string;
|
|
14
|
-
requestId: string;
|
|
15
|
-
}
|
|
16
|
-
export interface RequestCompleteEvent extends BaseEvent {
|
|
17
|
-
type: 'request:complete';
|
|
18
|
-
endpoint: string;
|
|
19
|
-
method: string;
|
|
20
|
-
status: number;
|
|
21
|
-
duration: number;
|
|
22
|
-
requestId: string;
|
|
23
|
-
}
|
|
24
|
-
export interface RequestErrorEvent extends BaseEvent {
|
|
25
|
-
type: 'request:error';
|
|
26
|
-
endpoint: string;
|
|
27
|
-
method: string;
|
|
28
|
-
error: Error;
|
|
29
|
-
requestId: string;
|
|
30
|
-
}
|
|
31
|
-
export interface AuthSuccessEvent extends BaseEvent {
|
|
32
|
-
type: 'auth:success';
|
|
33
|
-
authType: 'oauth' | 'basic';
|
|
34
|
-
}
|
|
35
|
-
export interface AuthFailureEvent extends BaseEvent {
|
|
36
|
-
type: 'auth:failure';
|
|
37
|
-
authType: 'oauth' | 'basic';
|
|
38
|
-
error: Error;
|
|
39
|
-
}
|
|
40
|
-
export interface AuthRefreshEvent extends BaseEvent {
|
|
41
|
-
type: 'auth:refresh';
|
|
42
|
-
authType: 'oauth';
|
|
43
|
-
success: boolean;
|
|
44
|
-
}
|
|
45
|
-
export interface RateLimitEvent extends BaseEvent {
|
|
46
|
-
type: 'rate:limit';
|
|
47
|
-
limit: number;
|
|
48
|
-
remaining: number;
|
|
49
|
-
resetTime: string;
|
|
50
|
-
}
|
|
51
|
-
export interface RateAvailableEvent extends BaseEvent {
|
|
52
|
-
type: 'rate:available';
|
|
53
|
-
limit: number;
|
|
54
|
-
remaining: number;
|
|
55
|
-
}
|
|
56
|
-
export interface CacheHitEvent extends BaseEvent {
|
|
57
|
-
type: 'cache:hit';
|
|
58
|
-
key: string;
|
|
59
|
-
}
|
|
60
|
-
export interface CacheMissEvent extends BaseEvent {
|
|
61
|
-
type: 'cache:miss';
|
|
62
|
-
key: string;
|
|
63
|
-
}
|
|
64
|
-
export interface CacheSetEvent extends BaseEvent {
|
|
65
|
-
type: 'cache:set';
|
|
66
|
-
key: string;
|
|
67
|
-
ttl?: number;
|
|
68
|
-
}
|
|
69
|
-
export interface CacheInvalidateEvent extends BaseEvent {
|
|
70
|
-
type: 'cache:invalidate';
|
|
71
|
-
key: string;
|
|
72
|
-
}
|
|
73
|
-
export interface ErrorEvent extends BaseEvent {
|
|
74
|
-
type: 'error';
|
|
75
|
-
error: Error;
|
|
76
|
-
operation: string;
|
|
77
|
-
context?: Record<string, any>;
|
|
78
|
-
}
|
|
79
|
-
export type PcoEvent = RequestStartEvent | RequestCompleteEvent | RequestErrorEvent | AuthSuccessEvent | AuthFailureEvent | AuthRefreshEvent | RateLimitEvent | RateAvailableEvent | CacheHitEvent | CacheMissEvent | CacheSetEvent | CacheInvalidateEvent | ErrorEvent;
|
|
80
|
-
export type EventHandler<T extends PcoEvent = PcoEvent> = (event: T) => void | Promise<void>;
|
|
81
|
-
export interface EventEmitter {
|
|
82
|
-
on<T extends PcoEvent>(eventType: T['type'], handler: EventHandler<T>): void;
|
|
83
|
-
off<T extends PcoEvent>(eventType: T['type'], handler: EventHandler<T>): void;
|
|
84
|
-
emit<T extends PcoEvent>(event: T): void;
|
|
85
|
-
}
|