@heymantle/core-api-client 0.1.9 → 0.1.11
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/dist/index.d.mts +181 -1
- package/dist/index.d.ts +181 -1
- package/dist/index.js +209 -2
- package/dist/index.mjs +206 -1
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -1798,6 +1798,19 @@ interface Agent {
|
|
|
1798
1798
|
interface AgentListResponse {
|
|
1799
1799
|
agents: Agent[];
|
|
1800
1800
|
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Parameters for creating an agent
|
|
1803
|
+
*/
|
|
1804
|
+
interface AgentCreateParams {
|
|
1805
|
+
email: string;
|
|
1806
|
+
name?: string;
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Response from creating/retrieving an agent
|
|
1810
|
+
*/
|
|
1811
|
+
interface AgentResponse {
|
|
1812
|
+
agent: Agent;
|
|
1813
|
+
}
|
|
1801
1814
|
|
|
1802
1815
|
/**
|
|
1803
1816
|
* Task status
|
|
@@ -2063,6 +2076,45 @@ interface EntitiesSearchResponse {
|
|
|
2063
2076
|
entities: Entity[];
|
|
2064
2077
|
}
|
|
2065
2078
|
|
|
2079
|
+
/**
|
|
2080
|
+
* Resource type for custom data
|
|
2081
|
+
*/
|
|
2082
|
+
type CustomDataResourceType = 'ticket' | 'customer' | 'contact';
|
|
2083
|
+
/**
|
|
2084
|
+
* Parameters for setting custom data
|
|
2085
|
+
*/
|
|
2086
|
+
interface CustomDataSetParams {
|
|
2087
|
+
resourceId: string;
|
|
2088
|
+
resourceType: CustomDataResourceType;
|
|
2089
|
+
key: string;
|
|
2090
|
+
value: string;
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Parameters for getting custom data
|
|
2094
|
+
*/
|
|
2095
|
+
interface CustomDataGetParams {
|
|
2096
|
+
resourceId: string;
|
|
2097
|
+
resourceType: CustomDataResourceType;
|
|
2098
|
+
key: string;
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Response from getting custom data
|
|
2102
|
+
*/
|
|
2103
|
+
interface CustomDataResponse {
|
|
2104
|
+
resourceId: string;
|
|
2105
|
+
resourceType: CustomDataResourceType;
|
|
2106
|
+
key: string;
|
|
2107
|
+
value: string;
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Parameters for deleting custom data
|
|
2111
|
+
*/
|
|
2112
|
+
interface CustomDataDeleteParams {
|
|
2113
|
+
resourceId: string;
|
|
2114
|
+
resourceType: CustomDataResourceType;
|
|
2115
|
+
key: string;
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2066
2118
|
/**
|
|
2067
2119
|
* Resource for managing customers
|
|
2068
2120
|
*/
|
|
@@ -3098,6 +3150,23 @@ declare class AgentsResource extends BaseResource {
|
|
|
3098
3150
|
* List support agents
|
|
3099
3151
|
*/
|
|
3100
3152
|
list(): Promise<AgentListResponse>;
|
|
3153
|
+
/**
|
|
3154
|
+
* Retrieve a specific agent by ID
|
|
3155
|
+
*/
|
|
3156
|
+
retrieve(agentId: string): Promise<AgentResponse>;
|
|
3157
|
+
/**
|
|
3158
|
+
* Create a new agent
|
|
3159
|
+
*/
|
|
3160
|
+
create(params: AgentCreateParams): Promise<AgentResponse>;
|
|
3161
|
+
/**
|
|
3162
|
+
* Find an existing agent by email, or create one if not found.
|
|
3163
|
+
* This is useful for sync operations where you want to ensure
|
|
3164
|
+
* an agent exists without duplicating.
|
|
3165
|
+
*
|
|
3166
|
+
* @param params - Agent data (email required, name optional)
|
|
3167
|
+
* @returns The existing or newly created agent
|
|
3168
|
+
*/
|
|
3169
|
+
findOrCreate(params: AgentCreateParams): Promise<AgentResponse>;
|
|
3101
3170
|
}
|
|
3102
3171
|
|
|
3103
3172
|
/**
|
|
@@ -3215,6 +3284,33 @@ declare class EntitiesResource extends BaseResource {
|
|
|
3215
3284
|
search(params?: EntitiesSearchParams): Promise<EntitiesSearchResponse>;
|
|
3216
3285
|
}
|
|
3217
3286
|
|
|
3287
|
+
/**
|
|
3288
|
+
* Resource for managing custom data on entities.
|
|
3289
|
+
* Custom data allows storing arbitrary key-value pairs on tickets, customers, and contacts.
|
|
3290
|
+
*/
|
|
3291
|
+
declare class CustomDataResource extends BaseResource {
|
|
3292
|
+
/**
|
|
3293
|
+
* Set custom data on a resource.
|
|
3294
|
+
* This will create or update the value for the given key.
|
|
3295
|
+
*
|
|
3296
|
+
* @param params - The custom data parameters
|
|
3297
|
+
*/
|
|
3298
|
+
set(params: CustomDataSetParams): Promise<void>;
|
|
3299
|
+
/**
|
|
3300
|
+
* Get custom data from a resource.
|
|
3301
|
+
*
|
|
3302
|
+
* @param params - Parameters identifying the custom data to retrieve
|
|
3303
|
+
* @returns The custom data value
|
|
3304
|
+
*/
|
|
3305
|
+
getValue(params: CustomDataGetParams): Promise<CustomDataResponse>;
|
|
3306
|
+
/**
|
|
3307
|
+
* Delete custom data from a resource.
|
|
3308
|
+
*
|
|
3309
|
+
* @param params - Parameters identifying the custom data to delete
|
|
3310
|
+
*/
|
|
3311
|
+
del(params: CustomDataDeleteParams): Promise<void>;
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3218
3314
|
/**
|
|
3219
3315
|
* Mantle Core API Client
|
|
3220
3316
|
*
|
|
@@ -3269,6 +3365,7 @@ declare class MantleCoreClient {
|
|
|
3269
3365
|
readonly agents: AgentsResource;
|
|
3270
3366
|
readonly docs: DocsResource;
|
|
3271
3367
|
readonly entities: EntitiesResource;
|
|
3368
|
+
readonly customData: CustomDataResource;
|
|
3272
3369
|
constructor(config: MantleCoreClientConfig);
|
|
3273
3370
|
/**
|
|
3274
3371
|
* Register a middleware function
|
|
@@ -3474,4 +3571,87 @@ interface AuthRefreshOptions {
|
|
|
3474
3571
|
*/
|
|
3475
3572
|
declare function createAuthRefreshMiddleware(options: AuthRefreshOptions): Middleware;
|
|
3476
3573
|
|
|
3477
|
-
|
|
3574
|
+
/**
|
|
3575
|
+
* Options for the rate limit middleware
|
|
3576
|
+
*/
|
|
3577
|
+
interface RateLimitOptions {
|
|
3578
|
+
/**
|
|
3579
|
+
* Enable automatic retry on 429 responses
|
|
3580
|
+
* @default false
|
|
3581
|
+
*/
|
|
3582
|
+
enableRetry?: boolean;
|
|
3583
|
+
/**
|
|
3584
|
+
* Enable preemptive throttling to avoid hitting rate limits
|
|
3585
|
+
* @default false
|
|
3586
|
+
*/
|
|
3587
|
+
enableThrottle?: boolean;
|
|
3588
|
+
/**
|
|
3589
|
+
* Maximum number of retry attempts
|
|
3590
|
+
* @default 3
|
|
3591
|
+
*/
|
|
3592
|
+
maxRetries?: number;
|
|
3593
|
+
/**
|
|
3594
|
+
* Base delay in milliseconds for retries when no retryAfter is provided
|
|
3595
|
+
* @default 1000
|
|
3596
|
+
*/
|
|
3597
|
+
baseDelay?: number;
|
|
3598
|
+
/**
|
|
3599
|
+
* Use exponential backoff for retries
|
|
3600
|
+
* @default true
|
|
3601
|
+
*/
|
|
3602
|
+
exponentialBackoff?: boolean;
|
|
3603
|
+
/**
|
|
3604
|
+
* Add random jitter to retry delays to prevent thundering herd
|
|
3605
|
+
* @default true
|
|
3606
|
+
*/
|
|
3607
|
+
jitter?: boolean;
|
|
3608
|
+
/**
|
|
3609
|
+
* Maximum requests per minute (primary limit)
|
|
3610
|
+
* @default 1000
|
|
3611
|
+
*/
|
|
3612
|
+
requestsPerMinute?: number;
|
|
3613
|
+
/**
|
|
3614
|
+
* Maximum requests per burst window
|
|
3615
|
+
* @default 5000
|
|
3616
|
+
*/
|
|
3617
|
+
burstLimit?: number;
|
|
3618
|
+
/**
|
|
3619
|
+
* Burst window in milliseconds
|
|
3620
|
+
* @default 300000 (5 minutes)
|
|
3621
|
+
*/
|
|
3622
|
+
burstWindowMs?: number;
|
|
3623
|
+
/**
|
|
3624
|
+
* Start throttling when usage reaches this percentage of the limit (0-1)
|
|
3625
|
+
* @default 0.9
|
|
3626
|
+
*/
|
|
3627
|
+
throttleThreshold?: number;
|
|
3628
|
+
}
|
|
3629
|
+
/**
|
|
3630
|
+
* Creates a middleware that handles rate limiting with optional retry and throttling
|
|
3631
|
+
*
|
|
3632
|
+
* @example
|
|
3633
|
+
* ```typescript
|
|
3634
|
+
* const client = new MantleCoreClient({ ... });
|
|
3635
|
+
*
|
|
3636
|
+
* // Enable retry on 429 responses
|
|
3637
|
+
* client.use(createRateLimitMiddleware({
|
|
3638
|
+
* enableRetry: true,
|
|
3639
|
+
* }));
|
|
3640
|
+
*
|
|
3641
|
+
* // Enable preemptive throttling
|
|
3642
|
+
* client.use(createRateLimitMiddleware({
|
|
3643
|
+
* enableThrottle: true,
|
|
3644
|
+
* }));
|
|
3645
|
+
*
|
|
3646
|
+
* // Enable both features
|
|
3647
|
+
* client.use(createRateLimitMiddleware({
|
|
3648
|
+
* enableRetry: true,
|
|
3649
|
+
* enableThrottle: true,
|
|
3650
|
+
* maxRetries: 5,
|
|
3651
|
+
* requestsPerMinute: 500,
|
|
3652
|
+
* }));
|
|
3653
|
+
* ```
|
|
3654
|
+
*/
|
|
3655
|
+
declare function createRateLimitMiddleware(options?: RateLimitOptions): Middleware;
|
|
3656
|
+
|
|
3657
|
+
export { type AccountOwner, type AccountOwnersListResponse, type Affiliate, type AffiliateCommission, type AffiliateCommissionListParams, type AffiliateCommissionListResponse, AffiliateCommissionsResource, type AffiliateListParams, type AffiliateListResponse, type AffiliatePayout, type AffiliatePayoutListParams, type AffiliatePayoutListResponse, AffiliatePayoutsResource, type AffiliateProgram, type AffiliateProgramCreateParams, type AffiliateProgramUpdateParams, AffiliateProgramsResource, type AffiliateReferral, type AffiliateReferralListParams, type AffiliateReferralListResponse, AffiliateReferralsResource, type AffiliateUpdateParams, AffiliatesResource, type Agent, type AgentCreateParams, type AgentListResponse, type AgentResponse, AgentsResource, type App, type AppEvent, type AppEventListParams, type AppEventListResponse, type AppInstallation, type AppInstallationParams, type AppListParams, AppsResource, type AuthRefreshOptions, BaseResource, type Channel, type ChannelCreateParams, type ChannelListParams, ChannelsResource, type Charge, type ChargeListParams, type ChargeListResponse, ChargesResource, CompaniesResource, type Company, type CompanyCreateParams, type CompanyListParams, type CompanyListResponse, type CompanyUpdateParams, type Contact, type ContactCreateParams, type ContactEntity, type ContactListParams, type ContactListResponse, type ContactUpdateParams, ContactsResource, type CustomDataDeleteParams, type CustomDataGetParams, CustomDataResource, type CustomDataResourceType, type CustomDataResponse, type CustomDataSetParams, type CustomField, type CustomFieldCreateParams, type CustomFieldUpdateParams, type Customer, type CustomerCreateParams, type CustomerEntity, type CustomerListParams, type CustomerListResponse, type CustomerRetrieveParams, type CustomerSegment, type CustomerSegmentListParams, type CustomerSegmentListResponse, CustomerSegmentsResource, type CustomerUpdateParams, CustomersResource, type DateRangeType, type Deal, DealActivitiesResource, type DealActivity, type DealActivityCreateParams, type DealActivityUpdateParams, type DealContactInput, type DealCreateParams, type DealCustomerInput, type DealEvent, type DealEventCreateParams, type DealEventCreateResponse, type DealEventListResponse, type DealFlow, type DealFlowCreateParams, type DealFlowUpdateParams, DealFlowsResource, type DealListParams, type DealListResponse, type DealStage, type DealUpdateParams, DealsResource, type DeleteResponse, type DocCollection, type DocCollectionCreateParams, type DocCollectionUpdateParams, type DocGroup, type DocGroupCreateParams, type DocGroupUpdateParams, type DocPage, type DocPageCreateParams, type DocPageListParams, type DocPageListResponse, type DocPageStatus, type DocPageUpdateParams, type DocTreeNode, type DocTreeResponse, DocsResource, EntitiesResource, type EntitiesSearchParams, type EntitiesSearchResponse, type Entity, type EntityType, type Feature, type FeatureCreateParams, type FeatureUpdateParams, type Flow, type FlowCreateParams, type FlowListParams, type FlowListResponse, type FlowStatus, type FlowUpdateParams, FlowsResource, type HttpMethod, type ListParams, MantleAPIError, MantleAuthenticationError, MantleCoreClient, type MantleCoreClientConfig, MantleNotFoundError, MantlePermissionError, MantleRateLimitError, MantleValidationError, MeResource, type MeResponse, type MessageAttachment, type MetricDataPoint, type MetricType, type MetricsBaseParams, type MetricsGetParams, MetricsResource, type MetricsResponse, type Middleware, type MiddlewareContext, MiddlewareManager, type MiddlewareOptions, type MiddlewareRequest, type MiddlewareResponse, type NextFunction, type Organization, OrganizationResource, type PaginatedResponse, type Plan, type PlanCreateParams, type PlanFeature, type PlanListParams, type PlanListResponse, type PlanUpdateParams, type PlanUsageCharge, type RateLimitOptions, type RequestOptions, type Review, type ReviewCreateParams, type ReviewUpdateParams, type SocialProfile, type SocialProfileType, type Subscription, type SubscriptionListParams, type SubscriptionListResponse, SubscriptionsResource, type Task, type TaskCreateParams, type TaskListParams, type TaskListResponse, type TaskPriority, type TaskStatus, type TaskUpdateParams, TasksResource, type Ticket, type TicketContactData, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TicketMessage, type TicketMessageCreateParams, type TicketMessageUpdateParams, type TicketUpdateParams, TicketsResource, type TimelineEvent, type TimelineListParams, type TimelineListResponse, type Transaction, type TransactionListParams, type TransactionListResponse, TransactionsResource, type UsageEvent, type UsageEventCreateData, type UsageEventCreateParams, type UsageEventCreateResponse, type UsageEventListParams, type UsageEventListResponse, type UsageEventMetricsParams, UsageEventsResource, type UsageMetric, type UsageMetricCreateParams, type UsageMetricParams, type UsageMetricUpdateParams, type User, type UserListParams, type UserListResponse, UsersResource, type Webhook, type WebhookCreateParams, type WebhookFilter, type WebhookListResponse, type WebhookTopic, type WebhookUpdateParams, WebhooksResource, createAuthRefreshMiddleware, createRateLimitMiddleware };
|
package/dist/index.d.ts
CHANGED
|
@@ -1798,6 +1798,19 @@ interface Agent {
|
|
|
1798
1798
|
interface AgentListResponse {
|
|
1799
1799
|
agents: Agent[];
|
|
1800
1800
|
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Parameters for creating an agent
|
|
1803
|
+
*/
|
|
1804
|
+
interface AgentCreateParams {
|
|
1805
|
+
email: string;
|
|
1806
|
+
name?: string;
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Response from creating/retrieving an agent
|
|
1810
|
+
*/
|
|
1811
|
+
interface AgentResponse {
|
|
1812
|
+
agent: Agent;
|
|
1813
|
+
}
|
|
1801
1814
|
|
|
1802
1815
|
/**
|
|
1803
1816
|
* Task status
|
|
@@ -2063,6 +2076,45 @@ interface EntitiesSearchResponse {
|
|
|
2063
2076
|
entities: Entity[];
|
|
2064
2077
|
}
|
|
2065
2078
|
|
|
2079
|
+
/**
|
|
2080
|
+
* Resource type for custom data
|
|
2081
|
+
*/
|
|
2082
|
+
type CustomDataResourceType = 'ticket' | 'customer' | 'contact';
|
|
2083
|
+
/**
|
|
2084
|
+
* Parameters for setting custom data
|
|
2085
|
+
*/
|
|
2086
|
+
interface CustomDataSetParams {
|
|
2087
|
+
resourceId: string;
|
|
2088
|
+
resourceType: CustomDataResourceType;
|
|
2089
|
+
key: string;
|
|
2090
|
+
value: string;
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Parameters for getting custom data
|
|
2094
|
+
*/
|
|
2095
|
+
interface CustomDataGetParams {
|
|
2096
|
+
resourceId: string;
|
|
2097
|
+
resourceType: CustomDataResourceType;
|
|
2098
|
+
key: string;
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Response from getting custom data
|
|
2102
|
+
*/
|
|
2103
|
+
interface CustomDataResponse {
|
|
2104
|
+
resourceId: string;
|
|
2105
|
+
resourceType: CustomDataResourceType;
|
|
2106
|
+
key: string;
|
|
2107
|
+
value: string;
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Parameters for deleting custom data
|
|
2111
|
+
*/
|
|
2112
|
+
interface CustomDataDeleteParams {
|
|
2113
|
+
resourceId: string;
|
|
2114
|
+
resourceType: CustomDataResourceType;
|
|
2115
|
+
key: string;
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2066
2118
|
/**
|
|
2067
2119
|
* Resource for managing customers
|
|
2068
2120
|
*/
|
|
@@ -3098,6 +3150,23 @@ declare class AgentsResource extends BaseResource {
|
|
|
3098
3150
|
* List support agents
|
|
3099
3151
|
*/
|
|
3100
3152
|
list(): Promise<AgentListResponse>;
|
|
3153
|
+
/**
|
|
3154
|
+
* Retrieve a specific agent by ID
|
|
3155
|
+
*/
|
|
3156
|
+
retrieve(agentId: string): Promise<AgentResponse>;
|
|
3157
|
+
/**
|
|
3158
|
+
* Create a new agent
|
|
3159
|
+
*/
|
|
3160
|
+
create(params: AgentCreateParams): Promise<AgentResponse>;
|
|
3161
|
+
/**
|
|
3162
|
+
* Find an existing agent by email, or create one if not found.
|
|
3163
|
+
* This is useful for sync operations where you want to ensure
|
|
3164
|
+
* an agent exists without duplicating.
|
|
3165
|
+
*
|
|
3166
|
+
* @param params - Agent data (email required, name optional)
|
|
3167
|
+
* @returns The existing or newly created agent
|
|
3168
|
+
*/
|
|
3169
|
+
findOrCreate(params: AgentCreateParams): Promise<AgentResponse>;
|
|
3101
3170
|
}
|
|
3102
3171
|
|
|
3103
3172
|
/**
|
|
@@ -3215,6 +3284,33 @@ declare class EntitiesResource extends BaseResource {
|
|
|
3215
3284
|
search(params?: EntitiesSearchParams): Promise<EntitiesSearchResponse>;
|
|
3216
3285
|
}
|
|
3217
3286
|
|
|
3287
|
+
/**
|
|
3288
|
+
* Resource for managing custom data on entities.
|
|
3289
|
+
* Custom data allows storing arbitrary key-value pairs on tickets, customers, and contacts.
|
|
3290
|
+
*/
|
|
3291
|
+
declare class CustomDataResource extends BaseResource {
|
|
3292
|
+
/**
|
|
3293
|
+
* Set custom data on a resource.
|
|
3294
|
+
* This will create or update the value for the given key.
|
|
3295
|
+
*
|
|
3296
|
+
* @param params - The custom data parameters
|
|
3297
|
+
*/
|
|
3298
|
+
set(params: CustomDataSetParams): Promise<void>;
|
|
3299
|
+
/**
|
|
3300
|
+
* Get custom data from a resource.
|
|
3301
|
+
*
|
|
3302
|
+
* @param params - Parameters identifying the custom data to retrieve
|
|
3303
|
+
* @returns The custom data value
|
|
3304
|
+
*/
|
|
3305
|
+
getValue(params: CustomDataGetParams): Promise<CustomDataResponse>;
|
|
3306
|
+
/**
|
|
3307
|
+
* Delete custom data from a resource.
|
|
3308
|
+
*
|
|
3309
|
+
* @param params - Parameters identifying the custom data to delete
|
|
3310
|
+
*/
|
|
3311
|
+
del(params: CustomDataDeleteParams): Promise<void>;
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3218
3314
|
/**
|
|
3219
3315
|
* Mantle Core API Client
|
|
3220
3316
|
*
|
|
@@ -3269,6 +3365,7 @@ declare class MantleCoreClient {
|
|
|
3269
3365
|
readonly agents: AgentsResource;
|
|
3270
3366
|
readonly docs: DocsResource;
|
|
3271
3367
|
readonly entities: EntitiesResource;
|
|
3368
|
+
readonly customData: CustomDataResource;
|
|
3272
3369
|
constructor(config: MantleCoreClientConfig);
|
|
3273
3370
|
/**
|
|
3274
3371
|
* Register a middleware function
|
|
@@ -3474,4 +3571,87 @@ interface AuthRefreshOptions {
|
|
|
3474
3571
|
*/
|
|
3475
3572
|
declare function createAuthRefreshMiddleware(options: AuthRefreshOptions): Middleware;
|
|
3476
3573
|
|
|
3477
|
-
|
|
3574
|
+
/**
|
|
3575
|
+
* Options for the rate limit middleware
|
|
3576
|
+
*/
|
|
3577
|
+
interface RateLimitOptions {
|
|
3578
|
+
/**
|
|
3579
|
+
* Enable automatic retry on 429 responses
|
|
3580
|
+
* @default false
|
|
3581
|
+
*/
|
|
3582
|
+
enableRetry?: boolean;
|
|
3583
|
+
/**
|
|
3584
|
+
* Enable preemptive throttling to avoid hitting rate limits
|
|
3585
|
+
* @default false
|
|
3586
|
+
*/
|
|
3587
|
+
enableThrottle?: boolean;
|
|
3588
|
+
/**
|
|
3589
|
+
* Maximum number of retry attempts
|
|
3590
|
+
* @default 3
|
|
3591
|
+
*/
|
|
3592
|
+
maxRetries?: number;
|
|
3593
|
+
/**
|
|
3594
|
+
* Base delay in milliseconds for retries when no retryAfter is provided
|
|
3595
|
+
* @default 1000
|
|
3596
|
+
*/
|
|
3597
|
+
baseDelay?: number;
|
|
3598
|
+
/**
|
|
3599
|
+
* Use exponential backoff for retries
|
|
3600
|
+
* @default true
|
|
3601
|
+
*/
|
|
3602
|
+
exponentialBackoff?: boolean;
|
|
3603
|
+
/**
|
|
3604
|
+
* Add random jitter to retry delays to prevent thundering herd
|
|
3605
|
+
* @default true
|
|
3606
|
+
*/
|
|
3607
|
+
jitter?: boolean;
|
|
3608
|
+
/**
|
|
3609
|
+
* Maximum requests per minute (primary limit)
|
|
3610
|
+
* @default 1000
|
|
3611
|
+
*/
|
|
3612
|
+
requestsPerMinute?: number;
|
|
3613
|
+
/**
|
|
3614
|
+
* Maximum requests per burst window
|
|
3615
|
+
* @default 5000
|
|
3616
|
+
*/
|
|
3617
|
+
burstLimit?: number;
|
|
3618
|
+
/**
|
|
3619
|
+
* Burst window in milliseconds
|
|
3620
|
+
* @default 300000 (5 minutes)
|
|
3621
|
+
*/
|
|
3622
|
+
burstWindowMs?: number;
|
|
3623
|
+
/**
|
|
3624
|
+
* Start throttling when usage reaches this percentage of the limit (0-1)
|
|
3625
|
+
* @default 0.9
|
|
3626
|
+
*/
|
|
3627
|
+
throttleThreshold?: number;
|
|
3628
|
+
}
|
|
3629
|
+
/**
|
|
3630
|
+
* Creates a middleware that handles rate limiting with optional retry and throttling
|
|
3631
|
+
*
|
|
3632
|
+
* @example
|
|
3633
|
+
* ```typescript
|
|
3634
|
+
* const client = new MantleCoreClient({ ... });
|
|
3635
|
+
*
|
|
3636
|
+
* // Enable retry on 429 responses
|
|
3637
|
+
* client.use(createRateLimitMiddleware({
|
|
3638
|
+
* enableRetry: true,
|
|
3639
|
+
* }));
|
|
3640
|
+
*
|
|
3641
|
+
* // Enable preemptive throttling
|
|
3642
|
+
* client.use(createRateLimitMiddleware({
|
|
3643
|
+
* enableThrottle: true,
|
|
3644
|
+
* }));
|
|
3645
|
+
*
|
|
3646
|
+
* // Enable both features
|
|
3647
|
+
* client.use(createRateLimitMiddleware({
|
|
3648
|
+
* enableRetry: true,
|
|
3649
|
+
* enableThrottle: true,
|
|
3650
|
+
* maxRetries: 5,
|
|
3651
|
+
* requestsPerMinute: 500,
|
|
3652
|
+
* }));
|
|
3653
|
+
* ```
|
|
3654
|
+
*/
|
|
3655
|
+
declare function createRateLimitMiddleware(options?: RateLimitOptions): Middleware;
|
|
3656
|
+
|
|
3657
|
+
export { type AccountOwner, type AccountOwnersListResponse, type Affiliate, type AffiliateCommission, type AffiliateCommissionListParams, type AffiliateCommissionListResponse, AffiliateCommissionsResource, type AffiliateListParams, type AffiliateListResponse, type AffiliatePayout, type AffiliatePayoutListParams, type AffiliatePayoutListResponse, AffiliatePayoutsResource, type AffiliateProgram, type AffiliateProgramCreateParams, type AffiliateProgramUpdateParams, AffiliateProgramsResource, type AffiliateReferral, type AffiliateReferralListParams, type AffiliateReferralListResponse, AffiliateReferralsResource, type AffiliateUpdateParams, AffiliatesResource, type Agent, type AgentCreateParams, type AgentListResponse, type AgentResponse, AgentsResource, type App, type AppEvent, type AppEventListParams, type AppEventListResponse, type AppInstallation, type AppInstallationParams, type AppListParams, AppsResource, type AuthRefreshOptions, BaseResource, type Channel, type ChannelCreateParams, type ChannelListParams, ChannelsResource, type Charge, type ChargeListParams, type ChargeListResponse, ChargesResource, CompaniesResource, type Company, type CompanyCreateParams, type CompanyListParams, type CompanyListResponse, type CompanyUpdateParams, type Contact, type ContactCreateParams, type ContactEntity, type ContactListParams, type ContactListResponse, type ContactUpdateParams, ContactsResource, type CustomDataDeleteParams, type CustomDataGetParams, CustomDataResource, type CustomDataResourceType, type CustomDataResponse, type CustomDataSetParams, type CustomField, type CustomFieldCreateParams, type CustomFieldUpdateParams, type Customer, type CustomerCreateParams, type CustomerEntity, type CustomerListParams, type CustomerListResponse, type CustomerRetrieveParams, type CustomerSegment, type CustomerSegmentListParams, type CustomerSegmentListResponse, CustomerSegmentsResource, type CustomerUpdateParams, CustomersResource, type DateRangeType, type Deal, DealActivitiesResource, type DealActivity, type DealActivityCreateParams, type DealActivityUpdateParams, type DealContactInput, type DealCreateParams, type DealCustomerInput, type DealEvent, type DealEventCreateParams, type DealEventCreateResponse, type DealEventListResponse, type DealFlow, type DealFlowCreateParams, type DealFlowUpdateParams, DealFlowsResource, type DealListParams, type DealListResponse, type DealStage, type DealUpdateParams, DealsResource, type DeleteResponse, type DocCollection, type DocCollectionCreateParams, type DocCollectionUpdateParams, type DocGroup, type DocGroupCreateParams, type DocGroupUpdateParams, type DocPage, type DocPageCreateParams, type DocPageListParams, type DocPageListResponse, type DocPageStatus, type DocPageUpdateParams, type DocTreeNode, type DocTreeResponse, DocsResource, EntitiesResource, type EntitiesSearchParams, type EntitiesSearchResponse, type Entity, type EntityType, type Feature, type FeatureCreateParams, type FeatureUpdateParams, type Flow, type FlowCreateParams, type FlowListParams, type FlowListResponse, type FlowStatus, type FlowUpdateParams, FlowsResource, type HttpMethod, type ListParams, MantleAPIError, MantleAuthenticationError, MantleCoreClient, type MantleCoreClientConfig, MantleNotFoundError, MantlePermissionError, MantleRateLimitError, MantleValidationError, MeResource, type MeResponse, type MessageAttachment, type MetricDataPoint, type MetricType, type MetricsBaseParams, type MetricsGetParams, MetricsResource, type MetricsResponse, type Middleware, type MiddlewareContext, MiddlewareManager, type MiddlewareOptions, type MiddlewareRequest, type MiddlewareResponse, type NextFunction, type Organization, OrganizationResource, type PaginatedResponse, type Plan, type PlanCreateParams, type PlanFeature, type PlanListParams, type PlanListResponse, type PlanUpdateParams, type PlanUsageCharge, type RateLimitOptions, type RequestOptions, type Review, type ReviewCreateParams, type ReviewUpdateParams, type SocialProfile, type SocialProfileType, type Subscription, type SubscriptionListParams, type SubscriptionListResponse, SubscriptionsResource, type Task, type TaskCreateParams, type TaskListParams, type TaskListResponse, type TaskPriority, type TaskStatus, type TaskUpdateParams, TasksResource, type Ticket, type TicketContactData, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TicketMessage, type TicketMessageCreateParams, type TicketMessageUpdateParams, type TicketUpdateParams, TicketsResource, type TimelineEvent, type TimelineListParams, type TimelineListResponse, type Transaction, type TransactionListParams, type TransactionListResponse, TransactionsResource, type UsageEvent, type UsageEventCreateData, type UsageEventCreateParams, type UsageEventCreateResponse, type UsageEventListParams, type UsageEventListResponse, type UsageEventMetricsParams, UsageEventsResource, type UsageMetric, type UsageMetricCreateParams, type UsageMetricParams, type UsageMetricUpdateParams, type User, type UserListParams, type UserListResponse, UsersResource, type Webhook, type WebhookCreateParams, type WebhookFilter, type WebhookListResponse, type WebhookTopic, type WebhookUpdateParams, WebhooksResource, createAuthRefreshMiddleware, createRateLimitMiddleware };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
ChargesResource: () => ChargesResource,
|
|
33
33
|
CompaniesResource: () => CompaniesResource,
|
|
34
34
|
ContactsResource: () => ContactsResource,
|
|
35
|
+
CustomDataResource: () => CustomDataResource,
|
|
35
36
|
CustomerSegmentsResource: () => CustomerSegmentsResource,
|
|
36
37
|
CustomersResource: () => CustomersResource,
|
|
37
38
|
DealActivitiesResource: () => DealActivitiesResource,
|
|
@@ -58,7 +59,8 @@ __export(index_exports, {
|
|
|
58
59
|
UsageEventsResource: () => UsageEventsResource,
|
|
59
60
|
UsersResource: () => UsersResource,
|
|
60
61
|
WebhooksResource: () => WebhooksResource,
|
|
61
|
-
createAuthRefreshMiddleware: () => createAuthRefreshMiddleware
|
|
62
|
+
createAuthRefreshMiddleware: () => createAuthRefreshMiddleware,
|
|
63
|
+
createRateLimitMiddleware: () => createRateLimitMiddleware
|
|
62
64
|
});
|
|
63
65
|
module.exports = __toCommonJS(index_exports);
|
|
64
66
|
|
|
@@ -1711,6 +1713,42 @@ var AgentsResource = class extends BaseResource {
|
|
|
1711
1713
|
async list() {
|
|
1712
1714
|
return this.get("/agents");
|
|
1713
1715
|
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Retrieve a specific agent by ID
|
|
1718
|
+
*/
|
|
1719
|
+
async retrieve(agentId) {
|
|
1720
|
+
return this.get(`/agents/${agentId}`);
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Create a new agent
|
|
1724
|
+
*/
|
|
1725
|
+
async create(params) {
|
|
1726
|
+
return this.post("/agents", params);
|
|
1727
|
+
}
|
|
1728
|
+
/**
|
|
1729
|
+
* Find an existing agent by email, or create one if not found.
|
|
1730
|
+
* This is useful for sync operations where you want to ensure
|
|
1731
|
+
* an agent exists without duplicating.
|
|
1732
|
+
*
|
|
1733
|
+
* @param params - Agent data (email required, name optional)
|
|
1734
|
+
* @returns The existing or newly created agent
|
|
1735
|
+
*/
|
|
1736
|
+
async findOrCreate(params) {
|
|
1737
|
+
try {
|
|
1738
|
+
return await this.create(params);
|
|
1739
|
+
} catch (error) {
|
|
1740
|
+
if (error instanceof MantleAPIError && error.statusCode === 409) {
|
|
1741
|
+
const { agents } = await this.list();
|
|
1742
|
+
const existingAgent = agents.find(
|
|
1743
|
+
(agent) => agent.email.toLowerCase() === params.email.toLowerCase()
|
|
1744
|
+
);
|
|
1745
|
+
if (existingAgent) {
|
|
1746
|
+
return { agent: existingAgent };
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
throw error;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1714
1752
|
};
|
|
1715
1753
|
|
|
1716
1754
|
// src/resources/docs.ts
|
|
@@ -1853,6 +1891,42 @@ var EntitiesResource = class extends BaseResource {
|
|
|
1853
1891
|
}
|
|
1854
1892
|
};
|
|
1855
1893
|
|
|
1894
|
+
// src/resources/custom-data.ts
|
|
1895
|
+
var CustomDataResource = class extends BaseResource {
|
|
1896
|
+
/**
|
|
1897
|
+
* Set custom data on a resource.
|
|
1898
|
+
* This will create or update the value for the given key.
|
|
1899
|
+
*
|
|
1900
|
+
* @param params - The custom data parameters
|
|
1901
|
+
*/
|
|
1902
|
+
async set(params) {
|
|
1903
|
+
await this.put("/custom_data", params);
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1906
|
+
* Get custom data from a resource.
|
|
1907
|
+
*
|
|
1908
|
+
* @param params - Parameters identifying the custom data to retrieve
|
|
1909
|
+
* @returns The custom data value
|
|
1910
|
+
*/
|
|
1911
|
+
async getValue(params) {
|
|
1912
|
+
const { resourceType, resourceId, key } = params;
|
|
1913
|
+
return this.get(
|
|
1914
|
+
`/custom_data/${resourceType}/${resourceId}/${encodeURIComponent(key)}`
|
|
1915
|
+
);
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Delete custom data from a resource.
|
|
1919
|
+
*
|
|
1920
|
+
* @param params - Parameters identifying the custom data to delete
|
|
1921
|
+
*/
|
|
1922
|
+
async del(params) {
|
|
1923
|
+
const { resourceType, resourceId, key } = params;
|
|
1924
|
+
await this._delete(
|
|
1925
|
+
`/custom_data/${resourceType}/${resourceId}/${encodeURIComponent(key)}`
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
};
|
|
1929
|
+
|
|
1856
1930
|
// src/client.ts
|
|
1857
1931
|
var MantleCoreClient = class {
|
|
1858
1932
|
constructor(config) {
|
|
@@ -1904,6 +1978,7 @@ var MantleCoreClient = class {
|
|
|
1904
1978
|
this.agents = new AgentsResource(this);
|
|
1905
1979
|
this.docs = new DocsResource(this);
|
|
1906
1980
|
this.entities = new EntitiesResource(this);
|
|
1981
|
+
this.customData = new CustomDataResource(this);
|
|
1907
1982
|
}
|
|
1908
1983
|
/**
|
|
1909
1984
|
* Register a middleware function
|
|
@@ -2180,6 +2255,136 @@ function createAuthRefreshMiddleware(options) {
|
|
|
2180
2255
|
}
|
|
2181
2256
|
};
|
|
2182
2257
|
}
|
|
2258
|
+
|
|
2259
|
+
// src/middleware/rate-limit.ts
|
|
2260
|
+
var RateLimiter = class {
|
|
2261
|
+
constructor(options) {
|
|
2262
|
+
this.timestamps = [];
|
|
2263
|
+
this.requestsPerMinute = options.requestsPerMinute;
|
|
2264
|
+
this.burstLimit = options.burstLimit;
|
|
2265
|
+
this.burstWindowMs = options.burstWindowMs;
|
|
2266
|
+
this.throttleThreshold = options.throttleThreshold;
|
|
2267
|
+
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Prune timestamps older than the burst window
|
|
2270
|
+
*/
|
|
2271
|
+
prune() {
|
|
2272
|
+
const now = Date.now();
|
|
2273
|
+
const cutoff = now - this.burstWindowMs;
|
|
2274
|
+
this.timestamps = this.timestamps.filter((ts) => ts > cutoff);
|
|
2275
|
+
}
|
|
2276
|
+
/**
|
|
2277
|
+
* Get current usage statistics
|
|
2278
|
+
*/
|
|
2279
|
+
getUsage() {
|
|
2280
|
+
this.prune();
|
|
2281
|
+
const now = Date.now();
|
|
2282
|
+
const oneMinuteAgo = now - 6e4;
|
|
2283
|
+
const minuteUsage = this.timestamps.filter((ts) => ts > oneMinuteAgo).length;
|
|
2284
|
+
const burstUsage = this.timestamps.length;
|
|
2285
|
+
return { minuteUsage, burstUsage };
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* Calculate the delay needed before the next request can be made
|
|
2289
|
+
* Returns 0 if no delay is needed
|
|
2290
|
+
*/
|
|
2291
|
+
getDelay() {
|
|
2292
|
+
const { minuteUsage, burstUsage } = this.getUsage();
|
|
2293
|
+
const minuteThreshold = Math.floor(this.requestsPerMinute * this.throttleThreshold);
|
|
2294
|
+
const burstThreshold = Math.floor(this.burstLimit * this.throttleThreshold);
|
|
2295
|
+
if (minuteUsage >= minuteThreshold) {
|
|
2296
|
+
const now = Date.now();
|
|
2297
|
+
const oneMinuteAgo = now - 6e4;
|
|
2298
|
+
const oldestInMinute = this.timestamps.find((ts) => ts > oneMinuteAgo);
|
|
2299
|
+
if (oldestInMinute) {
|
|
2300
|
+
const delay = oldestInMinute + 6e4 - now;
|
|
2301
|
+
if (delay > 0) {
|
|
2302
|
+
return delay;
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
if (burstUsage >= burstThreshold) {
|
|
2307
|
+
const now = Date.now();
|
|
2308
|
+
const burstCutoff = now - this.burstWindowMs;
|
|
2309
|
+
const oldestInBurst = this.timestamps.find((ts) => ts > burstCutoff);
|
|
2310
|
+
if (oldestInBurst) {
|
|
2311
|
+
const delay = oldestInBurst + this.burstWindowMs - now;
|
|
2312
|
+
if (delay > 0) {
|
|
2313
|
+
return delay;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
return 0;
|
|
2318
|
+
}
|
|
2319
|
+
/**
|
|
2320
|
+
* Record a request timestamp
|
|
2321
|
+
*/
|
|
2322
|
+
recordRequest() {
|
|
2323
|
+
this.timestamps.push(Date.now());
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
function calculateRetryDelay(retryAfter, retryCount, options) {
|
|
2327
|
+
let delay;
|
|
2328
|
+
if (retryAfter !== void 0 && retryAfter > 0) {
|
|
2329
|
+
return retryAfter * 1e3;
|
|
2330
|
+
} else if (options.exponentialBackoff) {
|
|
2331
|
+
delay = options.baseDelay * Math.pow(2, retryCount);
|
|
2332
|
+
} else {
|
|
2333
|
+
delay = options.baseDelay;
|
|
2334
|
+
}
|
|
2335
|
+
if (options.jitter) {
|
|
2336
|
+
const jitterFactor = 0.75 + Math.random() * 0.5;
|
|
2337
|
+
delay = Math.floor(delay * jitterFactor);
|
|
2338
|
+
}
|
|
2339
|
+
return delay;
|
|
2340
|
+
}
|
|
2341
|
+
function createRateLimitMiddleware(options = {}) {
|
|
2342
|
+
const {
|
|
2343
|
+
enableRetry = false,
|
|
2344
|
+
enableThrottle = false,
|
|
2345
|
+
maxRetries = 3,
|
|
2346
|
+
baseDelay = 1e3,
|
|
2347
|
+
exponentialBackoff = true,
|
|
2348
|
+
jitter = true,
|
|
2349
|
+
requestsPerMinute = 1e3,
|
|
2350
|
+
burstLimit = 5e3,
|
|
2351
|
+
burstWindowMs = 3e5,
|
|
2352
|
+
throttleThreshold = 0.9
|
|
2353
|
+
} = options;
|
|
2354
|
+
const rateLimiter = enableThrottle ? new RateLimiter({
|
|
2355
|
+
requestsPerMinute,
|
|
2356
|
+
burstLimit,
|
|
2357
|
+
burstWindowMs,
|
|
2358
|
+
throttleThreshold
|
|
2359
|
+
}) : null;
|
|
2360
|
+
return async (ctx, next) => {
|
|
2361
|
+
if (rateLimiter) {
|
|
2362
|
+
const delay = rateLimiter.getDelay();
|
|
2363
|
+
if (delay > 0) {
|
|
2364
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
try {
|
|
2368
|
+
await next();
|
|
2369
|
+
rateLimiter?.recordRequest();
|
|
2370
|
+
} catch (error) {
|
|
2371
|
+
rateLimiter?.recordRequest();
|
|
2372
|
+
if (enableRetry && error instanceof MantleRateLimitError) {
|
|
2373
|
+
if (ctx.retryCount < maxRetries) {
|
|
2374
|
+
const delay = calculateRetryDelay(error.retryAfter, ctx.retryCount, {
|
|
2375
|
+
baseDelay,
|
|
2376
|
+
exponentialBackoff,
|
|
2377
|
+
jitter
|
|
2378
|
+
});
|
|
2379
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2380
|
+
ctx.retry = true;
|
|
2381
|
+
return;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
throw error;
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2183
2388
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2184
2389
|
0 && (module.exports = {
|
|
2185
2390
|
AffiliateCommissionsResource,
|
|
@@ -2194,6 +2399,7 @@ function createAuthRefreshMiddleware(options) {
|
|
|
2194
2399
|
ChargesResource,
|
|
2195
2400
|
CompaniesResource,
|
|
2196
2401
|
ContactsResource,
|
|
2402
|
+
CustomDataResource,
|
|
2197
2403
|
CustomerSegmentsResource,
|
|
2198
2404
|
CustomersResource,
|
|
2199
2405
|
DealActivitiesResource,
|
|
@@ -2220,5 +2426,6 @@ function createAuthRefreshMiddleware(options) {
|
|
|
2220
2426
|
UsageEventsResource,
|
|
2221
2427
|
UsersResource,
|
|
2222
2428
|
WebhooksResource,
|
|
2223
|
-
createAuthRefreshMiddleware
|
|
2429
|
+
createAuthRefreshMiddleware,
|
|
2430
|
+
createRateLimitMiddleware
|
|
2224
2431
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1647,6 +1647,42 @@ var AgentsResource = class extends BaseResource {
|
|
|
1647
1647
|
async list() {
|
|
1648
1648
|
return this.get("/agents");
|
|
1649
1649
|
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Retrieve a specific agent by ID
|
|
1652
|
+
*/
|
|
1653
|
+
async retrieve(agentId) {
|
|
1654
|
+
return this.get(`/agents/${agentId}`);
|
|
1655
|
+
}
|
|
1656
|
+
/**
|
|
1657
|
+
* Create a new agent
|
|
1658
|
+
*/
|
|
1659
|
+
async create(params) {
|
|
1660
|
+
return this.post("/agents", params);
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Find an existing agent by email, or create one if not found.
|
|
1664
|
+
* This is useful for sync operations where you want to ensure
|
|
1665
|
+
* an agent exists without duplicating.
|
|
1666
|
+
*
|
|
1667
|
+
* @param params - Agent data (email required, name optional)
|
|
1668
|
+
* @returns The existing or newly created agent
|
|
1669
|
+
*/
|
|
1670
|
+
async findOrCreate(params) {
|
|
1671
|
+
try {
|
|
1672
|
+
return await this.create(params);
|
|
1673
|
+
} catch (error) {
|
|
1674
|
+
if (error instanceof MantleAPIError && error.statusCode === 409) {
|
|
1675
|
+
const { agents } = await this.list();
|
|
1676
|
+
const existingAgent = agents.find(
|
|
1677
|
+
(agent) => agent.email.toLowerCase() === params.email.toLowerCase()
|
|
1678
|
+
);
|
|
1679
|
+
if (existingAgent) {
|
|
1680
|
+
return { agent: existingAgent };
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
throw error;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1650
1686
|
};
|
|
1651
1687
|
|
|
1652
1688
|
// src/resources/docs.ts
|
|
@@ -1789,6 +1825,42 @@ var EntitiesResource = class extends BaseResource {
|
|
|
1789
1825
|
}
|
|
1790
1826
|
};
|
|
1791
1827
|
|
|
1828
|
+
// src/resources/custom-data.ts
|
|
1829
|
+
var CustomDataResource = class extends BaseResource {
|
|
1830
|
+
/**
|
|
1831
|
+
* Set custom data on a resource.
|
|
1832
|
+
* This will create or update the value for the given key.
|
|
1833
|
+
*
|
|
1834
|
+
* @param params - The custom data parameters
|
|
1835
|
+
*/
|
|
1836
|
+
async set(params) {
|
|
1837
|
+
await this.put("/custom_data", params);
|
|
1838
|
+
}
|
|
1839
|
+
/**
|
|
1840
|
+
* Get custom data from a resource.
|
|
1841
|
+
*
|
|
1842
|
+
* @param params - Parameters identifying the custom data to retrieve
|
|
1843
|
+
* @returns The custom data value
|
|
1844
|
+
*/
|
|
1845
|
+
async getValue(params) {
|
|
1846
|
+
const { resourceType, resourceId, key } = params;
|
|
1847
|
+
return this.get(
|
|
1848
|
+
`/custom_data/${resourceType}/${resourceId}/${encodeURIComponent(key)}`
|
|
1849
|
+
);
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Delete custom data from a resource.
|
|
1853
|
+
*
|
|
1854
|
+
* @param params - Parameters identifying the custom data to delete
|
|
1855
|
+
*/
|
|
1856
|
+
async del(params) {
|
|
1857
|
+
const { resourceType, resourceId, key } = params;
|
|
1858
|
+
await this._delete(
|
|
1859
|
+
`/custom_data/${resourceType}/${resourceId}/${encodeURIComponent(key)}`
|
|
1860
|
+
);
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
|
|
1792
1864
|
// src/client.ts
|
|
1793
1865
|
var MantleCoreClient = class {
|
|
1794
1866
|
constructor(config) {
|
|
@@ -1840,6 +1912,7 @@ var MantleCoreClient = class {
|
|
|
1840
1912
|
this.agents = new AgentsResource(this);
|
|
1841
1913
|
this.docs = new DocsResource(this);
|
|
1842
1914
|
this.entities = new EntitiesResource(this);
|
|
1915
|
+
this.customData = new CustomDataResource(this);
|
|
1843
1916
|
}
|
|
1844
1917
|
/**
|
|
1845
1918
|
* Register a middleware function
|
|
@@ -2116,6 +2189,136 @@ function createAuthRefreshMiddleware(options) {
|
|
|
2116
2189
|
}
|
|
2117
2190
|
};
|
|
2118
2191
|
}
|
|
2192
|
+
|
|
2193
|
+
// src/middleware/rate-limit.ts
|
|
2194
|
+
var RateLimiter = class {
|
|
2195
|
+
constructor(options) {
|
|
2196
|
+
this.timestamps = [];
|
|
2197
|
+
this.requestsPerMinute = options.requestsPerMinute;
|
|
2198
|
+
this.burstLimit = options.burstLimit;
|
|
2199
|
+
this.burstWindowMs = options.burstWindowMs;
|
|
2200
|
+
this.throttleThreshold = options.throttleThreshold;
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* Prune timestamps older than the burst window
|
|
2204
|
+
*/
|
|
2205
|
+
prune() {
|
|
2206
|
+
const now = Date.now();
|
|
2207
|
+
const cutoff = now - this.burstWindowMs;
|
|
2208
|
+
this.timestamps = this.timestamps.filter((ts) => ts > cutoff);
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Get current usage statistics
|
|
2212
|
+
*/
|
|
2213
|
+
getUsage() {
|
|
2214
|
+
this.prune();
|
|
2215
|
+
const now = Date.now();
|
|
2216
|
+
const oneMinuteAgo = now - 6e4;
|
|
2217
|
+
const minuteUsage = this.timestamps.filter((ts) => ts > oneMinuteAgo).length;
|
|
2218
|
+
const burstUsage = this.timestamps.length;
|
|
2219
|
+
return { minuteUsage, burstUsage };
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Calculate the delay needed before the next request can be made
|
|
2223
|
+
* Returns 0 if no delay is needed
|
|
2224
|
+
*/
|
|
2225
|
+
getDelay() {
|
|
2226
|
+
const { minuteUsage, burstUsage } = this.getUsage();
|
|
2227
|
+
const minuteThreshold = Math.floor(this.requestsPerMinute * this.throttleThreshold);
|
|
2228
|
+
const burstThreshold = Math.floor(this.burstLimit * this.throttleThreshold);
|
|
2229
|
+
if (minuteUsage >= minuteThreshold) {
|
|
2230
|
+
const now = Date.now();
|
|
2231
|
+
const oneMinuteAgo = now - 6e4;
|
|
2232
|
+
const oldestInMinute = this.timestamps.find((ts) => ts > oneMinuteAgo);
|
|
2233
|
+
if (oldestInMinute) {
|
|
2234
|
+
const delay = oldestInMinute + 6e4 - now;
|
|
2235
|
+
if (delay > 0) {
|
|
2236
|
+
return delay;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
if (burstUsage >= burstThreshold) {
|
|
2241
|
+
const now = Date.now();
|
|
2242
|
+
const burstCutoff = now - this.burstWindowMs;
|
|
2243
|
+
const oldestInBurst = this.timestamps.find((ts) => ts > burstCutoff);
|
|
2244
|
+
if (oldestInBurst) {
|
|
2245
|
+
const delay = oldestInBurst + this.burstWindowMs - now;
|
|
2246
|
+
if (delay > 0) {
|
|
2247
|
+
return delay;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
return 0;
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Record a request timestamp
|
|
2255
|
+
*/
|
|
2256
|
+
recordRequest() {
|
|
2257
|
+
this.timestamps.push(Date.now());
|
|
2258
|
+
}
|
|
2259
|
+
};
|
|
2260
|
+
function calculateRetryDelay(retryAfter, retryCount, options) {
|
|
2261
|
+
let delay;
|
|
2262
|
+
if (retryAfter !== void 0 && retryAfter > 0) {
|
|
2263
|
+
return retryAfter * 1e3;
|
|
2264
|
+
} else if (options.exponentialBackoff) {
|
|
2265
|
+
delay = options.baseDelay * Math.pow(2, retryCount);
|
|
2266
|
+
} else {
|
|
2267
|
+
delay = options.baseDelay;
|
|
2268
|
+
}
|
|
2269
|
+
if (options.jitter) {
|
|
2270
|
+
const jitterFactor = 0.75 + Math.random() * 0.5;
|
|
2271
|
+
delay = Math.floor(delay * jitterFactor);
|
|
2272
|
+
}
|
|
2273
|
+
return delay;
|
|
2274
|
+
}
|
|
2275
|
+
function createRateLimitMiddleware(options = {}) {
|
|
2276
|
+
const {
|
|
2277
|
+
enableRetry = false,
|
|
2278
|
+
enableThrottle = false,
|
|
2279
|
+
maxRetries = 3,
|
|
2280
|
+
baseDelay = 1e3,
|
|
2281
|
+
exponentialBackoff = true,
|
|
2282
|
+
jitter = true,
|
|
2283
|
+
requestsPerMinute = 1e3,
|
|
2284
|
+
burstLimit = 5e3,
|
|
2285
|
+
burstWindowMs = 3e5,
|
|
2286
|
+
throttleThreshold = 0.9
|
|
2287
|
+
} = options;
|
|
2288
|
+
const rateLimiter = enableThrottle ? new RateLimiter({
|
|
2289
|
+
requestsPerMinute,
|
|
2290
|
+
burstLimit,
|
|
2291
|
+
burstWindowMs,
|
|
2292
|
+
throttleThreshold
|
|
2293
|
+
}) : null;
|
|
2294
|
+
return async (ctx, next) => {
|
|
2295
|
+
if (rateLimiter) {
|
|
2296
|
+
const delay = rateLimiter.getDelay();
|
|
2297
|
+
if (delay > 0) {
|
|
2298
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
try {
|
|
2302
|
+
await next();
|
|
2303
|
+
rateLimiter?.recordRequest();
|
|
2304
|
+
} catch (error) {
|
|
2305
|
+
rateLimiter?.recordRequest();
|
|
2306
|
+
if (enableRetry && error instanceof MantleRateLimitError) {
|
|
2307
|
+
if (ctx.retryCount < maxRetries) {
|
|
2308
|
+
const delay = calculateRetryDelay(error.retryAfter, ctx.retryCount, {
|
|
2309
|
+
baseDelay,
|
|
2310
|
+
exponentialBackoff,
|
|
2311
|
+
jitter
|
|
2312
|
+
});
|
|
2313
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2314
|
+
ctx.retry = true;
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
throw error;
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
}
|
|
2119
2322
|
export {
|
|
2120
2323
|
AffiliateCommissionsResource,
|
|
2121
2324
|
AffiliatePayoutsResource,
|
|
@@ -2129,6 +2332,7 @@ export {
|
|
|
2129
2332
|
ChargesResource,
|
|
2130
2333
|
CompaniesResource,
|
|
2131
2334
|
ContactsResource,
|
|
2335
|
+
CustomDataResource,
|
|
2132
2336
|
CustomerSegmentsResource,
|
|
2133
2337
|
CustomersResource,
|
|
2134
2338
|
DealActivitiesResource,
|
|
@@ -2155,5 +2359,6 @@ export {
|
|
|
2155
2359
|
UsageEventsResource,
|
|
2156
2360
|
UsersResource,
|
|
2157
2361
|
WebhooksResource,
|
|
2158
|
-
createAuthRefreshMiddleware
|
|
2362
|
+
createAuthRefreshMiddleware,
|
|
2363
|
+
createRateLimitMiddleware
|
|
2159
2364
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heymantle/core-api-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "TypeScript SDK for the Mantle Core API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
20
20
|
"test": "vitest run",
|
|
21
21
|
"test:watch": "vitest",
|
|
22
|
+
"test:ui": "vitest --ui",
|
|
22
23
|
"test:coverage": "vitest run --coverage",
|
|
23
24
|
"typecheck": "tsc --noEmit",
|
|
24
25
|
"build-and-publish": "npm install && npm run build && npm publish"
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/node": "^20.11.0",
|
|
48
49
|
"@vitest/coverage-v8": "^1.2.0",
|
|
50
|
+
"@vitest/ui": "^1.2.0",
|
|
49
51
|
"tsup": "^8.0.2",
|
|
50
52
|
"typescript": "^5.4.3",
|
|
51
53
|
"vitest": "^1.2.0"
|