@voltade/envoy-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -0
- package/dist/client.d.ts +57 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +59 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +91 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-client.d.ts +64 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +159 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/conversations/index.d.ts +75 -0
- package/dist/resources/conversations/index.d.ts.map +1 -0
- package/dist/resources/conversations/index.js +89 -0
- package/dist/resources/conversations/index.js.map +1 -0
- package/dist/resources/conversations/types.d.ts +958 -0
- package/dist/resources/conversations/types.d.ts.map +1 -0
- package/dist/resources/conversations/types.js +160 -0
- package/dist/resources/conversations/types.js.map +1 -0
- package/dist/resources/inboxes/index.d.ts +39 -0
- package/dist/resources/inboxes/index.d.ts.map +1 -0
- package/dist/resources/inboxes/index.js +46 -0
- package/dist/resources/inboxes/index.js.map +1 -0
- package/dist/resources/inboxes/types.d.ts +88 -0
- package/dist/resources/inboxes/types.d.ts.map +1 -0
- package/dist/resources/inboxes/types.js +24 -0
- package/dist/resources/inboxes/types.js.map +1 -0
- package/dist/resources/index.d.ts +7 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +7 -0
- package/dist/resources/index.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Envoy SDK
|
|
2
|
+
|
|
3
|
+
A comprehensive TypeScript SDK for the Envoy API with built-in error handling and resource-based architecture.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @voltade/envoy-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { EnvoyClient } from '@voltade/envoy-sdk';
|
|
15
|
+
|
|
16
|
+
// Initialize the client
|
|
17
|
+
const client = new EnvoyClient({
|
|
18
|
+
apiKey: 'your-api-key',
|
|
19
|
+
accountId: 'your-account-id',
|
|
20
|
+
baseUrl: 'https://envoy-crm.voltade.com', // optional, defaults to this
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Create and send a message to a conversation
|
|
24
|
+
const message = await client.conversations.createMessage(123, {
|
|
25
|
+
content: 'Hello, how can I help you?',
|
|
26
|
+
message_type: 'outgoing',
|
|
27
|
+
private: false
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Escalate a conversation to a human agent
|
|
31
|
+
const result = await client.conversations.escalateToHuman(123);
|
|
32
|
+
console.log(`Escalated: ${result.success}`);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Type-safe**: Full TypeScript support with comprehensive type definitions
|
|
38
|
+
- **Resource-based**: Organized API methods by resource (conversations, messages, etc.)
|
|
39
|
+
- **Error handling**: Structured error types for different API failures
|
|
40
|
+
- **Easy to use**: Simple, intuitive API design
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### EnvoyClient
|
|
45
|
+
|
|
46
|
+
#### Configuration
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const client = new EnvoyClient({
|
|
50
|
+
apiKey: string; // Required: Your Envoy API key
|
|
51
|
+
accountId: string; // Required: Your Envoy account ID
|
|
52
|
+
baseUrl?: string; // Optional: Base URL (defaults to https://envoy-crm.voltade.com)
|
|
53
|
+
timeout?: number; // Optional: Request timeout in ms (defaults to 30000)
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Conversations
|
|
58
|
+
|
|
59
|
+
#### Create Message
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const message = await client.conversations.createMessage(conversationId, {
|
|
63
|
+
content: 'Your message',
|
|
64
|
+
message_type: 'outgoing',
|
|
65
|
+
private: false,
|
|
66
|
+
content_type: 'text',
|
|
67
|
+
content_attributes: {}
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### Escalate to Human
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
const result = await client.conversations.escalateToHuman(conversationId);
|
|
75
|
+
|
|
76
|
+
if (result.success) {
|
|
77
|
+
console.log(`Escalated to ${result.escalation_type}`);
|
|
78
|
+
if (result.agent) {
|
|
79
|
+
console.log(`Agent: ${result.agent.name}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Error Handling
|
|
85
|
+
|
|
86
|
+
The SDK provides structured error types:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import {
|
|
90
|
+
EnvoyError,
|
|
91
|
+
AuthenticationError,
|
|
92
|
+
BadRequestError,
|
|
93
|
+
NotFoundError,
|
|
94
|
+
RateLimitError,
|
|
95
|
+
ServerError,
|
|
96
|
+
NetworkError
|
|
97
|
+
} from '@voltade/envoy-sdk';
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
await client.conversations.createMessage(123, { content: 'Hello' });
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (error instanceof AuthenticationError) {
|
|
103
|
+
console.error('Invalid API key');
|
|
104
|
+
} else if (error instanceof NotFoundError) {
|
|
105
|
+
console.error('Conversation not found');
|
|
106
|
+
} else if (error instanceof RateLimitError) {
|
|
107
|
+
console.error('Rate limit exceeded');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Types
|
|
113
|
+
|
|
114
|
+
All TypeScript types are exported and available for use:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import type {
|
|
118
|
+
Message,
|
|
119
|
+
Conversation,
|
|
120
|
+
CreateMessageParams,
|
|
121
|
+
EscalationResponse,
|
|
122
|
+
MessageType,
|
|
123
|
+
ContentType,
|
|
124
|
+
ConversationStatus
|
|
125
|
+
} from '@voltade/envoy-sdk';
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Zod Schemas
|
|
129
|
+
|
|
130
|
+
The SDK exposes Zod schemas for runtime validation. All types are derived from these schemas using `z.infer`:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import {
|
|
134
|
+
MessageSchema,
|
|
135
|
+
CreateMessageParamsSchema,
|
|
136
|
+
EscalationResponseSchema,
|
|
137
|
+
ConversationSchema
|
|
138
|
+
} from '@voltade/envoy-sdk';
|
|
139
|
+
|
|
140
|
+
// Validate data at runtime
|
|
141
|
+
const messageData = {
|
|
142
|
+
id: 123,
|
|
143
|
+
content: 'Hello',
|
|
144
|
+
message_type: 'outgoing',
|
|
145
|
+
// ... other fields
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const validatedMessage = MessageSchema.parse(messageData);
|
|
149
|
+
|
|
150
|
+
// Validate user input
|
|
151
|
+
const userInput = {
|
|
152
|
+
content: 'Hello, world!',
|
|
153
|
+
message_type: 'outgoing',
|
|
154
|
+
private: false
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const validatedParams = CreateMessageParamsSchema.parse(userInput);
|
|
158
|
+
await client.conversations.createMessage(123, validatedParams);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Available Schemas
|
|
162
|
+
|
|
163
|
+
All schemas are exported from the SDK:
|
|
164
|
+
- `MessageTypeSchema`
|
|
165
|
+
- `ContentTypeSchema`
|
|
166
|
+
- `CreateMessageParamsSchema`
|
|
167
|
+
- `MessageSchema`
|
|
168
|
+
- `EscalationTypeSchema`
|
|
169
|
+
- `PrioritySchema`
|
|
170
|
+
- `TeamSchema`
|
|
171
|
+
- `AgentSchema`
|
|
172
|
+
- `EscalationResponseSchema`
|
|
173
|
+
- `ConversationStatusSchema`
|
|
174
|
+
- `ConversationSchema`
|
|
175
|
+
|
|
176
|
+
## Development
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Install dependencies
|
|
180
|
+
npm install
|
|
181
|
+
|
|
182
|
+
# Build the SDK
|
|
183
|
+
npm run build
|
|
184
|
+
|
|
185
|
+
# Lint
|
|
186
|
+
npm run lint
|
|
187
|
+
|
|
188
|
+
# Clean build artifacts
|
|
189
|
+
npm run clean
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { HttpClient } from './http-client.js';
|
|
2
|
+
import { Conversations, Inboxes } from './resources/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for EnvoyClient
|
|
5
|
+
*/
|
|
6
|
+
export interface EnvoyClientConfig {
|
|
7
|
+
apiKey: string;
|
|
8
|
+
accountId: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Envoy API Client
|
|
14
|
+
* A comprehensive SDK for interacting with the Envoy API
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // Initialize the client
|
|
19
|
+
* const client = new EnvoyClient({
|
|
20
|
+
* apiKey: 'your-api-key',
|
|
21
|
+
* accountId: 'your-account-id'
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Create and send a message to a conversation
|
|
25
|
+
* const message = await client.conversations.createMessage(123, {
|
|
26
|
+
* content: 'Hello, how can I help you?',
|
|
27
|
+
* message_type: 'outgoing',
|
|
28
|
+
* private: false
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Escalate a conversation to a human
|
|
32
|
+
* const result = await client.conversations.escalateToHuman(123);
|
|
33
|
+
*
|
|
34
|
+
* // Search knowledge base
|
|
35
|
+
* const articles = await client.inboxes.searchPortals(1, {
|
|
36
|
+
* queries: ['shipping', 'policy']
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class EnvoyClient {
|
|
41
|
+
private readonly httpClient;
|
|
42
|
+
/**
|
|
43
|
+
* Conversations resource for managing conversations and messages
|
|
44
|
+
*/
|
|
45
|
+
readonly conversations: Conversations;
|
|
46
|
+
/**
|
|
47
|
+
* Inboxes resource for managing inboxes and searching knowledge base
|
|
48
|
+
*/
|
|
49
|
+
readonly inboxes: Inboxes;
|
|
50
|
+
constructor(config: EnvoyClientConfig);
|
|
51
|
+
/**
|
|
52
|
+
* Get the HTTP client instance (for advanced use cases)
|
|
53
|
+
* @returns The underlying HTTP client
|
|
54
|
+
*/
|
|
55
|
+
getHttpClient(): HttpClient;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IAExC;;OAEG;IACH,SAAgB,aAAa,EAAE,aAAa,CAAC;IAE7C;;OAEG;IACH,SAAgB,OAAO,EAAE,OAAO,CAAC;gBAErB,MAAM,EAAE,iBAAiB;IAYrC;;;OAGG;IACH,aAAa,IAAI,UAAU;CAG5B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HttpClient } from './http-client.js';
|
|
2
|
+
import { Conversations, Inboxes } from './resources/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Envoy API Client
|
|
5
|
+
* A comprehensive SDK for interacting with the Envoy API
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Initialize the client
|
|
10
|
+
* const client = new EnvoyClient({
|
|
11
|
+
* apiKey: 'your-api-key',
|
|
12
|
+
* accountId: 'your-account-id'
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Create and send a message to a conversation
|
|
16
|
+
* const message = await client.conversations.createMessage(123, {
|
|
17
|
+
* content: 'Hello, how can I help you?',
|
|
18
|
+
* message_type: 'outgoing',
|
|
19
|
+
* private: false
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Escalate a conversation to a human
|
|
23
|
+
* const result = await client.conversations.escalateToHuman(123);
|
|
24
|
+
*
|
|
25
|
+
* // Search knowledge base
|
|
26
|
+
* const articles = await client.inboxes.searchPortals(1, {
|
|
27
|
+
* queries: ['shipping', 'policy']
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export class EnvoyClient {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
const httpConfig = {
|
|
34
|
+
...config,
|
|
35
|
+
};
|
|
36
|
+
this.httpClient = new HttpClient(httpConfig);
|
|
37
|
+
// Initialize resources
|
|
38
|
+
this.conversations = new Conversations(this.httpClient);
|
|
39
|
+
this.inboxes = new Inboxes(this.httpClient);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the HTTP client instance (for advanced use cases)
|
|
43
|
+
* @returns The underlying HTTP client
|
|
44
|
+
*/
|
|
45
|
+
getHttpClient() {
|
|
46
|
+
return this.httpClient;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAY9D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,WAAW;IAatB,YAAY,MAAyB;QACnC,MAAM,UAAU,GAAqB;YACnC,GAAG,MAAM;SACV,CAAC;QAEF,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;QAE7C,uBAAuB;QACvB,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Envoy API errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class EnvoyError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when the API returns a 400 Bad Request
|
|
9
|
+
*/
|
|
10
|
+
export declare class BadRequestError extends EnvoyError {
|
|
11
|
+
readonly statusCode: number;
|
|
12
|
+
readonly response?: unknown | undefined;
|
|
13
|
+
constructor(message: string, statusCode?: number, response?: unknown | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when authentication fails (401)
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthenticationError extends EnvoyError {
|
|
19
|
+
readonly statusCode: number;
|
|
20
|
+
constructor(message?: string, statusCode?: number);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when a resource is not found (404)
|
|
24
|
+
*/
|
|
25
|
+
export declare class NotFoundError extends EnvoyError {
|
|
26
|
+
readonly statusCode: number;
|
|
27
|
+
constructor(message: string, statusCode?: number);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Error thrown when rate limit is exceeded (429)
|
|
31
|
+
*/
|
|
32
|
+
export declare class RateLimitError extends EnvoyError {
|
|
33
|
+
readonly statusCode: number;
|
|
34
|
+
readonly retryAfter?: number | undefined;
|
|
35
|
+
constructor(message?: string, statusCode?: number, retryAfter?: number | undefined);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when the server returns a 5xx error
|
|
39
|
+
*/
|
|
40
|
+
export declare class ServerError extends EnvoyError {
|
|
41
|
+
readonly statusCode: number;
|
|
42
|
+
readonly response?: unknown | undefined;
|
|
43
|
+
constructor(message: string, statusCode: number, response?: unknown | undefined);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when a network error occurs
|
|
47
|
+
*/
|
|
48
|
+
export declare class NetworkError extends EnvoyError {
|
|
49
|
+
readonly originalError?: Error | undefined;
|
|
50
|
+
constructor(message?: string, originalError?: Error | undefined);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Error thrown when request validation fails
|
|
54
|
+
*/
|
|
55
|
+
export declare class ValidationError extends EnvoyError {
|
|
56
|
+
readonly errors?: Record<string, string[]> | undefined;
|
|
57
|
+
constructor(message: string, errors?: Record<string, string[]> | undefined);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU;aAG3B,UAAU,EAAE,MAAM;aAClB,QAAQ,CAAC,EAAE,OAAO;gBAFlC,OAAO,EAAE,MAAM,EACC,UAAU,GAAE,MAAY,EACxB,QAAQ,CAAC,EAAE,OAAO,YAAA;CAMrC;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,UAAU;aAG/B,UAAU,EAAE,MAAM;gBADlC,OAAO,GAAE,MAAoE,EAC7D,UAAU,GAAE,MAAY;CAM3C;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,UAAU;aAGzB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,GAAE,MAAY;CAM3C;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,UAAU;aAG1B,UAAU,EAAE,MAAM;aAClB,UAAU,CAAC,EAAE,MAAM;gBAFnC,OAAO,GAAE,MAAuD,EAChD,UAAU,GAAE,MAAY,EACxB,UAAU,CAAC,EAAE,MAAM,YAAA;CAMtC;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,UAAU;aAGvB,UAAU,EAAE,MAAM;aAClB,QAAQ,CAAC,EAAE,OAAO;gBAFlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,OAAO,YAAA;CAMrC;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,UAAU;aAGxB,aAAa,CAAC,EAAE,KAAK;gBADrC,OAAO,GAAE,MAAgE,EACzD,aAAa,CAAC,EAAE,KAAK,YAAA;CAMxC;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU;aAG3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBADjD,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,YAAA;CAMpD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Envoy API errors
|
|
3
|
+
*/
|
|
4
|
+
export class EnvoyError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'EnvoyError';
|
|
8
|
+
Object.setPrototypeOf(this, EnvoyError.prototype);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown when the API returns a 400 Bad Request
|
|
13
|
+
*/
|
|
14
|
+
export class BadRequestError extends EnvoyError {
|
|
15
|
+
constructor(message, statusCode = 400, response) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.statusCode = statusCode;
|
|
18
|
+
this.response = response;
|
|
19
|
+
this.name = 'BadRequestError';
|
|
20
|
+
Object.setPrototypeOf(this, BadRequestError.prototype);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Error thrown when authentication fails (401)
|
|
25
|
+
*/
|
|
26
|
+
export class AuthenticationError extends EnvoyError {
|
|
27
|
+
constructor(message = 'Authentication failed. Please check your API credentials.', statusCode = 401) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.statusCode = statusCode;
|
|
30
|
+
this.name = 'AuthenticationError';
|
|
31
|
+
Object.setPrototypeOf(this, AuthenticationError.prototype);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error thrown when a resource is not found (404)
|
|
36
|
+
*/
|
|
37
|
+
export class NotFoundError extends EnvoyError {
|
|
38
|
+
constructor(message, statusCode = 404) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.statusCode = statusCode;
|
|
41
|
+
this.name = 'NotFoundError';
|
|
42
|
+
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when rate limit is exceeded (429)
|
|
47
|
+
*/
|
|
48
|
+
export class RateLimitError extends EnvoyError {
|
|
49
|
+
constructor(message = 'Rate limit exceeded. Please try again later.', statusCode = 429, retryAfter) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.statusCode = statusCode;
|
|
52
|
+
this.retryAfter = retryAfter;
|
|
53
|
+
this.name = 'RateLimitError';
|
|
54
|
+
Object.setPrototypeOf(this, RateLimitError.prototype);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Error thrown when the server returns a 5xx error
|
|
59
|
+
*/
|
|
60
|
+
export class ServerError extends EnvoyError {
|
|
61
|
+
constructor(message, statusCode, response) {
|
|
62
|
+
super(message);
|
|
63
|
+
this.statusCode = statusCode;
|
|
64
|
+
this.response = response;
|
|
65
|
+
this.name = 'ServerError';
|
|
66
|
+
Object.setPrototypeOf(this, ServerError.prototype);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Error thrown when a network error occurs
|
|
71
|
+
*/
|
|
72
|
+
export class NetworkError extends EnvoyError {
|
|
73
|
+
constructor(message = 'Network error occurred. Please check your connection.', originalError) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.originalError = originalError;
|
|
76
|
+
this.name = 'NetworkError';
|
|
77
|
+
Object.setPrototypeOf(this, NetworkError.prototype);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Error thrown when request validation fails
|
|
82
|
+
*/
|
|
83
|
+
export class ValidationError extends EnvoyError {
|
|
84
|
+
constructor(message, errors) {
|
|
85
|
+
super(message);
|
|
86
|
+
this.errors = errors;
|
|
87
|
+
this.name = 'ValidationError';
|
|
88
|
+
Object.setPrototypeOf(this, ValidationError.prototype);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client configuration options
|
|
3
|
+
*/
|
|
4
|
+
export interface HttpClientConfig {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
accountId: string;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Request options for HTTP methods
|
|
12
|
+
*/
|
|
13
|
+
export interface RequestOptions {
|
|
14
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
timeout?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Base HTTP client for making requests to the Envoy API
|
|
20
|
+
*/
|
|
21
|
+
export declare class HttpClient {
|
|
22
|
+
private readonly apiKey;
|
|
23
|
+
private readonly accountId;
|
|
24
|
+
private readonly baseUrl;
|
|
25
|
+
private readonly timeout;
|
|
26
|
+
constructor(config: HttpClientConfig);
|
|
27
|
+
/**
|
|
28
|
+
* Get the default headers for all requests
|
|
29
|
+
*/
|
|
30
|
+
private getDefaultHeaders;
|
|
31
|
+
/**
|
|
32
|
+
* Build the full URL with path and query parameters
|
|
33
|
+
*/
|
|
34
|
+
private buildUrl;
|
|
35
|
+
/**
|
|
36
|
+
* Handle HTTP response and throw appropriate errors
|
|
37
|
+
*/
|
|
38
|
+
private handleResponse;
|
|
39
|
+
/**
|
|
40
|
+
* Make an HTTP request
|
|
41
|
+
*/
|
|
42
|
+
private request;
|
|
43
|
+
/**
|
|
44
|
+
* Make a GET request
|
|
45
|
+
*/
|
|
46
|
+
get<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Make a POST request
|
|
49
|
+
*/
|
|
50
|
+
post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Make a PUT request
|
|
53
|
+
*/
|
|
54
|
+
put<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Make a PATCH request
|
|
57
|
+
*/
|
|
58
|
+
patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Make a DELETE request
|
|
61
|
+
*/
|
|
62
|
+
delete<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../http-client.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,gBAAgB;IAOpC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAqBhB;;OAEG;YACW,cAAc;IAqD5B;;OAEG;YACW,OAAO;IA4CrB;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhE;;OAEG;IACG,IAAI,CAAC,CAAC,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC;IAIb;;OAEG;IACG,GAAG,CAAC,CAAC,EACT,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC;IAIb;;OAEG;IACG,KAAK,CAAC,CAAC,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC;IAIb;;OAEG;IACG,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;CAGpE"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { AuthenticationError, BadRequestError, EnvoyError, NetworkError, NotFoundError, RateLimitError, ServerError, } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base HTTP client for making requests to the Envoy API
|
|
4
|
+
*/
|
|
5
|
+
export class HttpClient {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.apiKey = config.apiKey;
|
|
8
|
+
this.accountId = config.accountId;
|
|
9
|
+
this.baseUrl = config.baseUrl || 'https://envoy-crm.voltade.com';
|
|
10
|
+
this.timeout = config.timeout ?? 30000; // 30 seconds default
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get the default headers for all requests
|
|
14
|
+
*/
|
|
15
|
+
getDefaultHeaders() {
|
|
16
|
+
return {
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
api_access_token: this.apiKey,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build the full URL with path and query parameters
|
|
23
|
+
*/
|
|
24
|
+
buildUrl(path, params) {
|
|
25
|
+
// Ensure path starts with a slash
|
|
26
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
27
|
+
const url = `${this.baseUrl}/api/v1/accounts/${this.accountId}${normalizedPath}`;
|
|
28
|
+
if (!params) {
|
|
29
|
+
return url;
|
|
30
|
+
}
|
|
31
|
+
// Filter out undefined values and build query string
|
|
32
|
+
const searchParams = new URLSearchParams();
|
|
33
|
+
for (const [key, value] of Object.entries(params)) {
|
|
34
|
+
if (value !== undefined && value !== null) {
|
|
35
|
+
searchParams.append(key, String(value));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const queryString = searchParams.toString();
|
|
39
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handle HTTP response and throw appropriate errors
|
|
43
|
+
*/
|
|
44
|
+
async handleResponse(response) {
|
|
45
|
+
// Success response
|
|
46
|
+
if (response.ok) {
|
|
47
|
+
const contentType = response.headers.get('content-type');
|
|
48
|
+
if (contentType?.includes('application/json')) {
|
|
49
|
+
return (await response.json());
|
|
50
|
+
}
|
|
51
|
+
// Return empty object for non-JSON responses
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
// Error handling
|
|
55
|
+
let errorMessage;
|
|
56
|
+
let errorData;
|
|
57
|
+
try {
|
|
58
|
+
const contentType = response.headers.get('content-type');
|
|
59
|
+
if (contentType?.includes('application/json')) {
|
|
60
|
+
errorData = await response.json();
|
|
61
|
+
errorMessage =
|
|
62
|
+
errorData.message ||
|
|
63
|
+
`Request failed with status ${response.status}`;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
errorMessage = await response.text();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
errorMessage = `Request failed with status ${response.status}`;
|
|
71
|
+
}
|
|
72
|
+
// Throw specific error types based on status code
|
|
73
|
+
switch (response.status) {
|
|
74
|
+
case 400:
|
|
75
|
+
throw new BadRequestError(errorMessage, response.status, errorData);
|
|
76
|
+
case 401:
|
|
77
|
+
throw new AuthenticationError(errorMessage, response.status);
|
|
78
|
+
case 404:
|
|
79
|
+
throw new NotFoundError(errorMessage, response.status);
|
|
80
|
+
case 429: {
|
|
81
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
82
|
+
throw new RateLimitError(errorMessage, response.status, retryAfter ? parseInt(retryAfter, 10) : undefined);
|
|
83
|
+
}
|
|
84
|
+
default:
|
|
85
|
+
if (response.status >= 500) {
|
|
86
|
+
throw new ServerError(errorMessage, response.status, errorData);
|
|
87
|
+
}
|
|
88
|
+
throw new EnvoyError(errorMessage);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Make an HTTP request
|
|
93
|
+
*/
|
|
94
|
+
async request(method, path, options = {}) {
|
|
95
|
+
const url = this.buildUrl(path, options.params);
|
|
96
|
+
const headers = {
|
|
97
|
+
...this.getDefaultHeaders(),
|
|
98
|
+
...options.headers,
|
|
99
|
+
};
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
102
|
+
try {
|
|
103
|
+
const response = await fetch(url, {
|
|
104
|
+
method,
|
|
105
|
+
headers,
|
|
106
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
});
|
|
109
|
+
clearTimeout(timeoutId);
|
|
110
|
+
return await this.handleResponse(response);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
clearTimeout(timeoutId);
|
|
114
|
+
// Re-throw Envoy errors as-is
|
|
115
|
+
if (error instanceof EnvoyError) {
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
// Handle network/timeout errors
|
|
119
|
+
if (error instanceof Error) {
|
|
120
|
+
if (error.name === 'AbortError') {
|
|
121
|
+
throw new NetworkError('Request timeout', error);
|
|
122
|
+
}
|
|
123
|
+
throw new NetworkError(`Network error: ${error.message}`, error);
|
|
124
|
+
}
|
|
125
|
+
throw new NetworkError('Unknown network error');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Make a GET request
|
|
130
|
+
*/
|
|
131
|
+
async get(path, options) {
|
|
132
|
+
return this.request('GET', path, options);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Make a POST request
|
|
136
|
+
*/
|
|
137
|
+
async post(path, body, options) {
|
|
138
|
+
return this.request('POST', path, { ...options, body });
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Make a PUT request
|
|
142
|
+
*/
|
|
143
|
+
async put(path, body, options) {
|
|
144
|
+
return this.request('PUT', path, { ...options, body });
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Make a PATCH request
|
|
148
|
+
*/
|
|
149
|
+
async patch(path, body, options) {
|
|
150
|
+
return this.request('PATCH', path, { ...options, body });
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Make a DELETE request
|
|
154
|
+
*/
|
|
155
|
+
async delete(path, options) {
|
|
156
|
+
return this.request('DELETE', path, options);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=http-client.js.map
|