@hardlydifficult/rest-client 1.0.54 → 1.0.56
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 +74 -314
- package/dist/Operation.d.ts +16 -5
- package/dist/Operation.d.ts.map +1 -1
- package/dist/Operation.js +24 -0
- package/dist/Operation.js.map +1 -1
- package/dist/RestClient.d.ts +11 -2
- package/dist/RestClient.d.ts.map +1 -1
- package/dist/RestClient.js +69 -20
- package/dist/RestClient.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hardlydifficult/rest-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Opinionated REST client helpers for APIs that should feel small and obvious at the call site.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,354 +8,114 @@ A typed REST client library with declarative operation definitions, OAuth2/beare
|
|
|
8
8
|
npm install @hardlydifficult/rest-client
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Preferred API
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import {
|
|
14
|
+
import { createRestClient, operation } from "@hardlydifficult/rest-client";
|
|
15
15
|
import { z } from "zod";
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
method: "GET",
|
|
21
|
-
url: (p, base) => `${base}/users/${p.id}`,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// Create a client with OAuth2 auth
|
|
25
|
-
class MyApi extends RestClient {
|
|
26
|
-
getUser = this.bind(GetUser);
|
|
17
|
+
interface User {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
27
20
|
}
|
|
28
21
|
|
|
29
|
-
const api =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
const api = createRestClient(
|
|
23
|
+
{
|
|
24
|
+
baseUrl: "https://api.example.com/v1",
|
|
25
|
+
auth: {
|
|
26
|
+
type: "oauth2",
|
|
27
|
+
tokenUrl: "https://auth.example.com/oauth/token",
|
|
28
|
+
clientId: "client-id",
|
|
29
|
+
clientSecret: "secret",
|
|
30
|
+
},
|
|
36
31
|
},
|
|
37
|
-
|
|
32
|
+
{
|
|
33
|
+
getUser: operation.get<User>({
|
|
34
|
+
params: z.object({ id: z.string() }),
|
|
35
|
+
path: ({ id }) => `/users/${id}`,
|
|
36
|
+
}),
|
|
37
|
+
listUsers: operation.get<User[]>({
|
|
38
|
+
path: "/users",
|
|
39
|
+
}),
|
|
40
|
+
createUser: operation.post<User>({
|
|
41
|
+
params: z.object({ name: z.string().min(1) }),
|
|
42
|
+
path: "/users",
|
|
43
|
+
body: ({ name }) => ({ name }),
|
|
44
|
+
}),
|
|
45
|
+
}
|
|
46
|
+
);
|
|
38
47
|
|
|
39
|
-
// Make a request
|
|
40
48
|
const user = await api.getUser({ id: "123" });
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
## Core Classes
|
|
45
|
-
|
|
46
|
-
### RestClient
|
|
47
|
-
|
|
48
|
-
Opinionated REST client with OAuth2, retries, and declarative operations.
|
|
49
|
-
|
|
50
|
-
#### Constructor
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
new RestClient(config: RestClientConfig)
|
|
49
|
+
const users = await api.listUsers();
|
|
50
|
+
await api.createUser({ name: "Alice" });
|
|
54
51
|
```
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|----------|------|-------------|
|
|
58
|
-
| `baseUrl` | `string` | Base URL for all requests (required) |
|
|
59
|
-
| `auth` | `AuthConfig?` | Authentication configuration (optional, default: `{ type: "none" }`) |
|
|
60
|
-
| `retry` | `RetryConfig?` | Retry settings (optional, default: `{ maxAttempts: 3, delayMs: 6000 }`) |
|
|
61
|
-
| `defaultHeaders` | `Record<string, string>?` | Default HTTP headers (optional) |
|
|
62
|
-
| `logger` | `RestClientLogger?` | Logger instance (optional) |
|
|
63
|
-
|
|
64
|
-
#### Methods
|
|
53
|
+
What this gives you:
|
|
65
54
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Bind a declarative operation to the client.
|
|
55
|
+
- No subclass ceremony just to bind a few endpoints.
|
|
56
|
+
- Relative `path` values resolve against `baseUrl`.
|
|
57
|
+
- Zero-input operations are zero-arg functions.
|
|
58
|
+
- `body` derives request payloads from validated params.
|
|
73
59
|
|
|
74
|
-
|
|
75
|
-
await authenticate(): Promise<string>
|
|
76
|
-
```
|
|
60
|
+
## Parsing Responses
|
|
77
61
|
|
|
78
|
-
|
|
62
|
+
Use `parse` when the server shape is not the shape you want in client code.
|
|
79
63
|
|
|
80
64
|
```typescript
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
Get the logger instance.
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
await get<T>(url: string): Promise<T>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Perform a GET request.
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
await post<T>(url: string, data?: unknown): Promise<T>
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Perform a POST request.
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
await delete<T>(url: string): Promise<T>
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Perform a DELETE request.
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
await patch<T>(url: string, data?: unknown): Promise<T>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Perform a PATCH request.
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
await put<T>(url: string, data?: unknown): Promise<T>
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Perform a PUT request.
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
getTokenExpiryTime(): number | null
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Token expiry timestamp (ms since epoch), or `null` if unavailable.
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
getTokenIssuedAt(): number | null
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Token issue timestamp (ms since epoch), or `null` if unavailable.
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
getTokenLifetimeMs(): number | null
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Token lifetime in milliseconds, or `null` if unavailable.
|
|
145
|
-
|
|
146
|
-
### HttpClient
|
|
147
|
-
|
|
148
|
-
HTTP client with automatic retries and structured error formatting.
|
|
149
|
-
|
|
150
|
-
#### Constructor
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
new HttpClient(options?: {
|
|
154
|
-
logger?: RestClientLogger;
|
|
155
|
-
retry?: RetryConfig;
|
|
156
|
-
defaultHeaders?: Record<string, string>;
|
|
157
|
-
})
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
#### Methods
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
setBearerToken(token: string): void
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Set the Authorization header with Bearer token.
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
clearBearerToken(): void
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Clear the Authorization header.
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
await get<T>(url: string): Promise<T>
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
Perform a GET request.
|
|
179
|
-
|
|
180
|
-
```typescript
|
|
181
|
-
await post<T>(url: string, data?: unknown): Promise<T>
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Perform a POST request.
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
await delete<T>(url: string): Promise<T>
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Perform a DELETE request.
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
await patch<T>(url: string, data?: unknown): Promise<T>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Perform a PATCH request.
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
await put<T>(url: string, data?: unknown): Promise<T>
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
Perform a PUT request.
|
|
203
|
-
|
|
204
|
-
#### Retry Behavior
|
|
205
|
-
|
|
206
|
-
- Automatically retries on 5xx errors and network failures
|
|
207
|
-
- Default: 3 attempts with 6000ms delay between retries
|
|
208
|
-
- Custom retryable status codes or conditions可通过 `retryableStatuses` and `isRetryable`
|
|
209
|
-
|
|
210
|
-
### AuthenticationManager
|
|
211
|
-
|
|
212
|
-
Manages token lifecycle for all supported auth strategies.
|
|
213
|
-
|
|
214
|
-
#### Constructor
|
|
65
|
+
const api = createRestClient(
|
|
66
|
+
{ baseUrl: "https://api.example.com" },
|
|
67
|
+
{
|
|
68
|
+
searchUserNames: operation.get<
|
|
69
|
+
string[],
|
|
70
|
+
{ q: string },
|
|
71
|
+
{ items: Array<{ name: string }> }
|
|
72
|
+
>({
|
|
73
|
+
params: z.object({ q: z.string().min(1) }),
|
|
74
|
+
path: ({ q }) => `/users/search?q=${encodeURIComponent(q)}`,
|
|
75
|
+
parse: (response) => response.items.map((user) => user.name),
|
|
76
|
+
}),
|
|
77
|
+
}
|
|
78
|
+
);
|
|
215
79
|
|
|
216
|
-
|
|
217
|
-
new AuthenticationManager(config: AuthConfig, logger?: RestClientLogger)
|
|
80
|
+
const names = await api.searchUserNames({ q: "ali" });
|
|
218
81
|
```
|
|
219
82
|
|
|
220
|
-
|
|
83
|
+
## Direct Requests
|
|
221
84
|
|
|
222
|
-
|
|
223
|
-
await authenticate(): Promise<string>
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
Authenticate and return the bearer token.
|
|
85
|
+
Direct HTTP helpers also accept relative paths.
|
|
227
86
|
|
|
228
87
|
```typescript
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Clear cached token and timing info.
|
|
88
|
+
const api = createRestClient({ baseUrl: "https://api.example.com/v1" }, {});
|
|
233
89
|
|
|
234
|
-
|
|
235
|
-
|
|
90
|
+
const health = await api.get<{ ok: boolean }>("/health");
|
|
91
|
+
await api.post("/users", { name: "Alice" });
|
|
236
92
|
```
|
|
237
93
|
|
|
238
|
-
|
|
94
|
+
## Advanced Usage
|
|
239
95
|
|
|
240
|
-
|
|
241
|
-
getTokenIssuedAt(): number | null
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Token issue timestamp (ms since epoch), or `null` if unavailable.
|
|
96
|
+
`RestClient` is still available if you want a class-based wrapper:
|
|
245
97
|
|
|
246
98
|
```typescript
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Token lifetime in milliseconds, or `null` if unavailable.
|
|
251
|
-
|
|
252
|
-
#### Supported Auth Types
|
|
253
|
-
|
|
254
|
-
| Type | Config | Description |
|
|
255
|
-
|------|--------|-------------|
|
|
256
|
-
| `bearer` | `{ type: "bearer", token: string }` | Static bearer token |
|
|
257
|
-
| `generator` | `{ type: "generator", generate: () => Promise<string>, cacheDurationMs?: number }` | Async token generator with optional cache |
|
|
258
|
-
| `oauth2` | `{ type: "oauth2", tokenUrl: string, clientId: string, clientSecret?: string, audience?: string, scope?: string, grantType?: "client_credentials" \| "password", username?: string, password?: string }` | OAuth2 client credentials or password grant |
|
|
259
|
-
| `none` | `{ type: "none" }` | No authentication (default) |
|
|
260
|
-
|
|
261
|
-
### defineOperation
|
|
262
|
-
|
|
263
|
-
Define a REST operation declaratively.
|
|
99
|
+
import { operation, RestClient } from "@hardlydifficult/rest-client";
|
|
100
|
+
import { z } from "zod";
|
|
264
101
|
|
|
265
|
-
|
|
266
|
-
const GetUser = defineOperation<{ id: string }, User>({
|
|
102
|
+
const GetUser = operation.get<User>({
|
|
267
103
|
params: z.object({ id: z.string() }),
|
|
268
|
-
|
|
269
|
-
url: (p, base) => `${base}/users/${p.id}`,
|
|
104
|
+
path: ({ id }) => `/users/${id}`,
|
|
270
105
|
});
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
#### Config Fields
|
|
274
|
-
|
|
275
|
-
| Field | Type | Required | Description |
|
|
276
|
-
|-------|------|----------|-------------|
|
|
277
|
-
| `params` | `z.ZodType<Params>` | Yes | Zod schema for request parameters |
|
|
278
|
-
| `method` | `HttpMethod` | Yes | HTTP method: `"GET"`, `"POST"`, `"DELETE"`, `"PATCH"`, `"PUT"` |
|
|
279
|
-
| `url` | `(params: Params, baseUrl: string) => string` | Yes | URL builder function |
|
|
280
|
-
| `body` | `(params: Params) => Record<string, unknown> \| string \| undefined` | No | Optional body builder |
|
|
281
|
-
| `transform` | `(response: Response) => Response` | No | Optional response transformer |
|
|
282
|
-
|
|
283
|
-
### validateParams
|
|
284
|
-
|
|
285
|
-
Validate params against a Zod schema, throwing `ValidationError` on failure.
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
validateParams<T>(params: T, schema: z.ZodType<T>): T
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
const validated = validateParams({ id: "123" }, z.object({ id: z.string() }));
|
|
293
|
-
// => { id: "123" }
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
## Error Handling
|
|
297
|
-
|
|
298
|
-
All errors extend `RestClientError` and include a `code` and optional `context`.
|
|
299
106
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
| `ConfigurationError` | `"CONFIGURATION_ERROR"` | Invalid client configuration (e.g., missing `baseUrl`) |
|
|
303
|
-
| `AuthenticationError` | `"AUTHENTICATION_ERROR"` | Authentication failure |
|
|
304
|
-
| `HttpError` | `"HTTP_ERROR"` | HTTP error with status, statusText, and response data |
|
|
305
|
-
| `ValidationError` | `"VALIDATION_ERROR"` | Parameter validation failure (via Zod) |
|
|
306
|
-
| `NetworkError` | `"NETWORK_ERROR"` | Network-level errors (e.g., DNS failure, connection refused) |
|
|
307
|
-
|
|
308
|
-
Example:
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
311
|
-
try {
|
|
312
|
-
await api.getUser({ id: "123" });
|
|
313
|
-
} catch (error) {
|
|
314
|
-
if (error instanceof HttpError) {
|
|
315
|
-
console.log(error.status, error.message);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
## Types
|
|
321
|
-
|
|
322
|
-
### AuthConfig
|
|
323
|
-
|
|
324
|
-
Union type of auth configurations: `OAuth2Auth | BearerAuth | TokenGeneratorAuth | NoAuth`
|
|
325
|
-
|
|
326
|
-
### RetryConfig
|
|
327
|
-
|
|
328
|
-
| Property | Type | Default | Description |
|
|
329
|
-
|----------|------|---------|-------------|
|
|
330
|
-
| `maxAttempts` | `number` | `3` | Number of retries after the initial attempt |
|
|
331
|
-
| `delayMs` | `number` | `6000` | Delay between retries in milliseconds |
|
|
332
|
-
| `retryableStatuses` | `readonly number[]?` | `undefined` | Additional HTTP status codes to retry on |
|
|
333
|
-
| `isRetryable` | `(status: number, body: Record<string, unknown>) => boolean?` | `undefined` | Custom retryable check |
|
|
334
|
-
|
|
335
|
-
### RestClientLogger
|
|
336
|
-
|
|
337
|
-
Minimal logger interface (compatible with `@hardlydifficult/logger`):
|
|
338
|
-
|
|
339
|
-
```typescript
|
|
340
|
-
interface RestClientLogger {
|
|
341
|
-
debug?(message: string, context?: Record<string, unknown>): void;
|
|
342
|
-
info?(message: string, context?: Record<string, unknown>): void;
|
|
343
|
-
warn?(message: string, context?: Record<string, unknown>): void;
|
|
344
|
-
error?(message: string, context?: Record<string, unknown>): void;
|
|
107
|
+
class MyApi extends RestClient {
|
|
108
|
+
getUser = this.bind(GetUser);
|
|
345
109
|
}
|
|
346
110
|
```
|
|
347
111
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
## Appendix
|
|
351
|
-
|
|
352
|
-
### Retryable Status Codes
|
|
112
|
+
## Authentication
|
|
353
113
|
|
|
354
|
-
|
|
114
|
+
Supported auth config types:
|
|
355
115
|
|
|
356
|
-
-
|
|
357
|
-
-
|
|
358
|
-
-
|
|
359
|
-
-
|
|
116
|
+
- `none`
|
|
117
|
+
- `bearer`
|
|
118
|
+
- `generator`
|
|
119
|
+
- `oauth2`
|
|
360
120
|
|
|
361
|
-
|
|
121
|
+
`createRestClient` and `RestClient` share the same auth, retry, logging, and error behavior.
|
package/dist/Operation.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { HttpMethod } from "./types.js";
|
|
3
3
|
/** Declarative configuration for a REST operation. */
|
|
4
|
-
export interface OperationConfig<Params, Response> {
|
|
5
|
-
readonly params
|
|
4
|
+
export interface OperationConfig<Params = undefined, Response = unknown, RawResponse = Response> {
|
|
5
|
+
readonly params?: z.ZodType<Params>;
|
|
6
6
|
readonly method: HttpMethod;
|
|
7
|
-
readonly
|
|
7
|
+
readonly path?: string | ((params: Params) => string);
|
|
8
|
+
readonly url?: (params: Params, baseUrl: string) => string;
|
|
8
9
|
readonly body?: (params: Params) => Record<string, unknown> | string | undefined;
|
|
9
|
-
readonly
|
|
10
|
+
readonly parse?: (response: RawResponse, params: Params) => Response;
|
|
11
|
+
readonly transform?: (response: RawResponse, params: Params) => Response;
|
|
10
12
|
}
|
|
13
|
+
export type OperationOptions<Params = undefined, Response = unknown, RawResponse = Response> = Omit<OperationConfig<Params, Response, RawResponse>, "method">;
|
|
14
|
+
export type BoundOperation<Params, Response> = [Params] extends [undefined] ? () => Promise<Response> : (params: Params) => Promise<Response>;
|
|
11
15
|
/**
|
|
12
16
|
* Define a REST operation declaratively.
|
|
13
17
|
*
|
|
@@ -18,7 +22,14 @@ export interface OperationConfig<Params, Response> {
|
|
|
18
22
|
* url: (p, base) => `${base}/users/${p.id}`,
|
|
19
23
|
* });
|
|
20
24
|
*/
|
|
21
|
-
export declare function defineOperation<Params, Response>(config: OperationConfig<Params, Response>): OperationConfig<Params, Response>;
|
|
25
|
+
export declare function defineOperation<Params = undefined, Response = unknown, RawResponse = Response>(config: OperationConfig<Params, Response, RawResponse>): OperationConfig<Params, Response, RawResponse>;
|
|
22
26
|
/** Validate params against a Zod schema, throwing ValidationError on failure. */
|
|
23
27
|
export declare function validateParams<T>(params: T, schema: z.ZodType<T>): T;
|
|
28
|
+
export declare const operation: {
|
|
29
|
+
readonly get: <Response, Params = undefined, RawResponse = Response>(config: OperationOptions<Params, Response, RawResponse>) => OperationConfig<Params, Response, RawResponse>;
|
|
30
|
+
readonly post: <Response, Params = undefined, RawResponse = Response>(config: OperationOptions<Params, Response, RawResponse>) => OperationConfig<Params, Response, RawResponse>;
|
|
31
|
+
readonly delete: <Response, Params = undefined, RawResponse = Response>(config: OperationOptions<Params, Response, RawResponse>) => OperationConfig<Params, Response, RawResponse>;
|
|
32
|
+
readonly patch: <Response, Params = undefined, RawResponse = Response>(config: OperationOptions<Params, Response, RawResponse>) => OperationConfig<Params, Response, RawResponse>;
|
|
33
|
+
readonly put: <Response, Params = undefined, RawResponse = Response>(config: OperationOptions<Params, Response, RawResponse>) => OperationConfig<Params, Response, RawResponse>;
|
|
34
|
+
};
|
|
24
35
|
//# sourceMappingURL=Operation.d.ts.map
|
package/dist/Operation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Operation.d.ts","sourceRoot":"","sources":["../src/Operation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,sDAAsD;AACtD,MAAM,WAAW,eAAe,
|
|
1
|
+
{"version":3,"file":"Operation.d.ts","sourceRoot":"","sources":["../src/Operation.ts"],"names":[],"mappings":"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"}
|
package/dist/Operation.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.operation = void 0;
|
|
3
4
|
exports.defineOperation = defineOperation;
|
|
4
5
|
exports.validateParams = validateParams;
|
|
5
6
|
const zod_1 = require("zod");
|
|
@@ -15,6 +16,9 @@ const errors_js_1 = require("./errors.js");
|
|
|
15
16
|
* });
|
|
16
17
|
*/
|
|
17
18
|
function defineOperation(config) {
|
|
19
|
+
if (config.path === undefined && config.url === undefined) {
|
|
20
|
+
throw new errors_js_1.ConfigurationError("Operation requires either path or url");
|
|
21
|
+
}
|
|
18
22
|
return config;
|
|
19
23
|
}
|
|
20
24
|
/** Validate params against a Zod schema, throwing ValidationError on failure. */
|
|
@@ -29,4 +33,24 @@ function validateParams(params, schema) {
|
|
|
29
33
|
throw error;
|
|
30
34
|
}
|
|
31
35
|
}
|
|
36
|
+
function defineMethodOperation(method, config) {
|
|
37
|
+
return defineOperation({ ...config, method });
|
|
38
|
+
}
|
|
39
|
+
exports.operation = {
|
|
40
|
+
get(config) {
|
|
41
|
+
return defineMethodOperation("GET", config);
|
|
42
|
+
},
|
|
43
|
+
post(config) {
|
|
44
|
+
return defineMethodOperation("POST", config);
|
|
45
|
+
},
|
|
46
|
+
delete(config) {
|
|
47
|
+
return defineMethodOperation("DELETE", config);
|
|
48
|
+
},
|
|
49
|
+
patch(config) {
|
|
50
|
+
return defineMethodOperation("PATCH", config);
|
|
51
|
+
},
|
|
52
|
+
put(config) {
|
|
53
|
+
return defineMethodOperation("PUT", config);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
32
56
|
//# sourceMappingURL=Operation.js.map
|
package/dist/Operation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Operation.js","sourceRoot":"","sources":["../src/Operation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Operation.js","sourceRoot":"","sources":["../src/Operation.ts"],"names":[],"mappings":";;;AA0CA,0CAWC;AAGD,wCAWC;AAnED,6BAAwB;AAExB,2CAAkE;AA8BlE;;;;;;;;;GASG;AACH,SAAgB,eAAe,CAK7B,MAAsD;IAEtD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC1D,MAAM,IAAI,8BAAkB,CAAC,uCAAuC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,SAAgB,cAAc,CAAI,MAAS,EAAE,MAAoB;IAC/D,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,2BAAe,CACvB,gCAAgC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1G,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAK5B,MAAkB,EAClB,MAAuD;IAEvD,OAAO,eAAe,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAChD,CAAC;AAEY,QAAA,SAAS,GAAG;IACvB,GAAG,CACD,MAAuD;QAEvD,OAAO,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,CACF,MAAuD;QAEvD,OAAO,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,CACJ,MAAuD;QAEvD,OAAO,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IACD,KAAK,CACH,MAAuD;QAEvD,OAAO,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IACD,GAAG,CACD,MAAuD;QAEvD,OAAO,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;CACO,CAAC"}
|
package/dist/RestClient.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { type OperationConfig } from "./Operation.js";
|
|
1
|
+
import { type BoundOperation, type OperationConfig } from "./Operation.js";
|
|
2
2
|
import type { RestClientConfig, RestClientLogger } from "./types.js";
|
|
3
|
+
export type AnyOperationConfig = OperationConfig<unknown, unknown, unknown>;
|
|
4
|
+
export type OperationMap = Record<string, AnyOperationConfig>;
|
|
5
|
+
export type BoundOperations<TOperations extends OperationMap> = {
|
|
6
|
+
[Name in keyof TOperations]: TOperations[Name] extends OperationConfig<infer Params, infer Response, infer _RawResponse> ? BoundOperation<Params, Response> : never;
|
|
7
|
+
};
|
|
8
|
+
export type RestClientApi<TOperations extends OperationMap> = RestClient & BoundOperations<TOperations>;
|
|
3
9
|
/**
|
|
4
10
|
* Opinionated REST client with OAuth2, retries, and declarative operations.
|
|
5
11
|
*
|
|
@@ -33,7 +39,7 @@ export declare class RestClient {
|
|
|
33
39
|
* getUser = this.bind(GetUser);
|
|
34
40
|
* }
|
|
35
41
|
*/
|
|
36
|
-
bind<Params, Response>(config: OperationConfig<Params, Response>):
|
|
42
|
+
bind<Params = undefined, Response = unknown, RawResponse = Response>(config: OperationConfig<Params, Response, RawResponse>): BoundOperation<Params, Response>;
|
|
37
43
|
/** Authenticate and set the bearer token for subsequent requests. */
|
|
38
44
|
authenticate(): Promise<string>;
|
|
39
45
|
/** Clear the cached token, forcing re-authentication on next request. */
|
|
@@ -50,5 +56,8 @@ export declare class RestClient {
|
|
|
50
56
|
patch<T>(url: string, data?: unknown): Promise<T>;
|
|
51
57
|
put<T>(url: string, data?: unknown): Promise<T>;
|
|
52
58
|
private executeMethod;
|
|
59
|
+
private resolveUrl;
|
|
53
60
|
}
|
|
61
|
+
/** Create a RestClient instance with operation configs bound as typed methods. */
|
|
62
|
+
export declare function createRestClient<TOperations extends OperationMap>(config: RestClientConfig, operations: TOperations): RestClientApi<TOperations>;
|
|
54
63
|
//# sourceMappingURL=RestClient.d.ts.map
|
package/dist/RestClient.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestClient.d.ts","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RestClient.d.ts","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAEV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAKpB,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5E,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAE9D,MAAM,MAAM,eAAe,CAAC,WAAW,SAAS,YAAY,IAAI;KAC7D,IAAI,IAAI,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,eAAe,CACpE,MAAM,MAAM,EACZ,MAAM,QAAQ,EACd,MAAM,YAAY,CACnB,GACG,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,GAChC,KAAK;CACV,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,WAAW,SAAS,YAAY,IAAI,UAAU,GACtE,eAAe,CAAC,WAAW,CAAC,CAAC;AAE/B;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,EAAE,gBAAgB;IAmBpC,iCAAiC;IACjC,UAAU,IAAI,MAAM;IAIpB,sCAAsC;IACtC,SAAS,IAAI,gBAAgB,GAAG,SAAS;IAIzC;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,GAAG,SAAS,EAAE,QAAQ,GAAG,OAAO,EAAE,WAAW,GAAG,QAAQ,EACjE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,GACrD,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;IAqBnC,qEAAqE;IAC/D,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAQrC,yEAAyE;IACzE,UAAU,IAAI,IAAI;IAKlB,uEAAuE;IACvE,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAInC,sEAAsE;IACtE,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,8DAA8D;IAC9D,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAI7B,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/B,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhD,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIlC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;YAIvC,aAAa;IAyB3B,OAAO,CAAC,UAAU;CAGnB;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,WAAW,SAAS,YAAY,EAC/D,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,WAAW,GACtB,aAAa,CAAC,WAAW,CAAC,CAsB5B"}
|
package/dist/RestClient.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RestClient = void 0;
|
|
4
|
+
exports.createRestClient = createRestClient;
|
|
5
|
+
const zod_1 = require("zod");
|
|
4
6
|
const AuthenticationManager_js_1 = require("./AuthenticationManager.js");
|
|
5
7
|
const errors_js_1 = require("./errors.js");
|
|
6
8
|
const HttpClient_js_1 = require("./HttpClient.js");
|
|
7
9
|
const Operation_js_1 = require("./Operation.js");
|
|
10
|
+
const NO_PARAMS_SCHEMA = zod_1.z.void();
|
|
11
|
+
const ABSOLUTE_URL_PATTERN = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
|
|
8
12
|
/**
|
|
9
13
|
* Opinionated REST client with OAuth2, retries, and declarative operations.
|
|
10
14
|
*
|
|
@@ -56,14 +60,16 @@ class RestClient {
|
|
|
56
60
|
* }
|
|
57
61
|
*/
|
|
58
62
|
bind(config) {
|
|
59
|
-
|
|
60
|
-
const validated = (0, Operation_js_1.validateParams)(params, config.params);
|
|
61
|
-
const url = config
|
|
63
|
+
const bound = async (params) => {
|
|
64
|
+
const validated = (0, Operation_js_1.validateParams)(params, getParamsSchema(config.params));
|
|
65
|
+
const url = resolveOperationUrl(config, validated, this.getBaseUrl());
|
|
62
66
|
const response = await this.executeMethod(config.method, url, config.body?.(validated));
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
const parser = config.parse ?? config.transform;
|
|
68
|
+
return parser !== undefined
|
|
69
|
+
? parser(response, validated)
|
|
65
70
|
: response;
|
|
66
71
|
};
|
|
72
|
+
return bound;
|
|
67
73
|
}
|
|
68
74
|
/** Authenticate and set the bearer token for subsequent requests. */
|
|
69
75
|
async authenticate() {
|
|
@@ -91,42 +97,85 @@ class RestClient {
|
|
|
91
97
|
return this.authManager.getTokenLifetimeMs();
|
|
92
98
|
}
|
|
93
99
|
async get(url) {
|
|
94
|
-
|
|
95
|
-
return this.httpClient.get(url);
|
|
100
|
+
return this.executeMethod("GET", url);
|
|
96
101
|
}
|
|
97
102
|
async post(url, data) {
|
|
98
|
-
|
|
99
|
-
return this.httpClient.post(url, data);
|
|
103
|
+
return this.executeMethod("POST", url, data);
|
|
100
104
|
}
|
|
101
105
|
async delete(url) {
|
|
102
|
-
|
|
103
|
-
return this.httpClient.delete(url);
|
|
106
|
+
return this.executeMethod("DELETE", url);
|
|
104
107
|
}
|
|
105
108
|
async patch(url, data) {
|
|
106
|
-
|
|
107
|
-
return this.httpClient.patch(url, data);
|
|
109
|
+
return this.executeMethod("PATCH", url, data);
|
|
108
110
|
}
|
|
109
111
|
async put(url, data) {
|
|
110
|
-
|
|
111
|
-
return this.httpClient.put(url, data);
|
|
112
|
+
return this.executeMethod("PUT", url, data);
|
|
112
113
|
}
|
|
113
114
|
async executeMethod(method, url, data) {
|
|
114
115
|
await this.authenticate();
|
|
116
|
+
const resolvedUrl = this.resolveUrl(url);
|
|
115
117
|
switch (method) {
|
|
116
118
|
case "GET":
|
|
117
|
-
return this.httpClient.get(
|
|
119
|
+
return this.httpClient.get(resolvedUrl);
|
|
118
120
|
case "POST":
|
|
119
|
-
return this.httpClient.post(
|
|
121
|
+
return this.httpClient.post(resolvedUrl, data);
|
|
120
122
|
case "DELETE":
|
|
121
|
-
return this.httpClient.delete(
|
|
123
|
+
return this.httpClient.delete(resolvedUrl);
|
|
122
124
|
case "PATCH":
|
|
123
|
-
return this.httpClient.patch(
|
|
125
|
+
return this.httpClient.patch(resolvedUrl, data);
|
|
124
126
|
case "PUT":
|
|
125
|
-
return this.httpClient.put(
|
|
127
|
+
return this.httpClient.put(resolvedUrl, data);
|
|
126
128
|
default:
|
|
127
129
|
throw new errors_js_1.ConfigurationError(`Unsupported HTTP method: ${method}`);
|
|
128
130
|
}
|
|
129
131
|
}
|
|
132
|
+
resolveUrl(url) {
|
|
133
|
+
return resolveUrl(this.getBaseUrl(), url);
|
|
134
|
+
}
|
|
130
135
|
}
|
|
131
136
|
exports.RestClient = RestClient;
|
|
137
|
+
/** Create a RestClient instance with operation configs bound as typed methods. */
|
|
138
|
+
function createRestClient(config, operations) {
|
|
139
|
+
const client = new RestClient(config);
|
|
140
|
+
for (const [name, operation] of Object.entries(operations)) {
|
|
141
|
+
if (name in client) {
|
|
142
|
+
throw new errors_js_1.ConfigurationError(`Operation name "${name}" conflicts with an existing RestClient property`);
|
|
143
|
+
}
|
|
144
|
+
Object.defineProperty(client, name, {
|
|
145
|
+
configurable: false,
|
|
146
|
+
enumerable: true,
|
|
147
|
+
value: client.bind(operation),
|
|
148
|
+
writable: false,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return client;
|
|
152
|
+
}
|
|
153
|
+
function getParamsSchema(schema) {
|
|
154
|
+
return (schema ?? NO_PARAMS_SCHEMA);
|
|
155
|
+
}
|
|
156
|
+
function resolveOperationUrl(config, params, baseUrl) {
|
|
157
|
+
if (config.path !== undefined) {
|
|
158
|
+
const path = typeof config.path === "function" ? config.path(params) : config.path;
|
|
159
|
+
return resolveUrl(baseUrl, path);
|
|
160
|
+
}
|
|
161
|
+
if (config.url !== undefined) {
|
|
162
|
+
return resolveUrl(baseUrl, config.url(params, baseUrl));
|
|
163
|
+
}
|
|
164
|
+
throw new errors_js_1.ConfigurationError("Operation requires either path or url");
|
|
165
|
+
}
|
|
166
|
+
function resolveUrl(baseUrl, urlOrPath) {
|
|
167
|
+
if (ABSOLUTE_URL_PATTERN.test(urlOrPath)) {
|
|
168
|
+
return urlOrPath;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
172
|
+
const normalizedPath = urlOrPath.startsWith("/")
|
|
173
|
+
? urlOrPath.slice(1)
|
|
174
|
+
: urlOrPath;
|
|
175
|
+
return new URL(normalizedPath, normalizedBaseUrl).toString();
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
throw new errors_js_1.ConfigurationError(`Invalid URL or path: ${urlOrPath} (baseUrl: ${baseUrl})`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
132
181
|
//# sourceMappingURL=RestClient.js.map
|
package/dist/RestClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RestClient.js","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"RestClient.js","sourceRoot":"","sources":["../src/RestClient.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { RestClient } from "./RestClient.js";
|
|
2
|
-
export { defineOperation, validateParams } from "./Operation.js";
|
|
3
|
-
export type { OperationConfig } from "./Operation.js";
|
|
1
|
+
export { RestClient, createRestClient } from "./RestClient.js";
|
|
2
|
+
export { defineOperation, operation, validateParams } from "./Operation.js";
|
|
3
|
+
export type { BoundOperation, OperationConfig, OperationOptions, } from "./Operation.js";
|
|
4
|
+
export type { AnyOperationConfig, BoundOperations, OperationMap, RestClientApi, } from "./RestClient.js";
|
|
4
5
|
export { AuthenticationManager } from "./AuthenticationManager.js";
|
|
5
6
|
export { HttpClient } from "./HttpClient.js";
|
|
6
7
|
export { RestClientError, ConfigurationError, AuthenticationError, HttpError, ValidationError, NetworkError, ErrorCode, } from "./errors.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5E,YAAY,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,SAAS,EACT,eAAe,EACf,YAAY,EACZ,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/D,YAAY,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,UAAU,GACX,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ErrorCode = exports.NetworkError = exports.ValidationError = exports.HttpError = exports.AuthenticationError = exports.ConfigurationError = exports.RestClientError = exports.HttpClient = exports.AuthenticationManager = exports.validateParams = exports.defineOperation = exports.RestClient = void 0;
|
|
3
|
+
exports.ErrorCode = exports.NetworkError = exports.ValidationError = exports.HttpError = exports.AuthenticationError = exports.ConfigurationError = exports.RestClientError = exports.HttpClient = exports.AuthenticationManager = exports.validateParams = exports.operation = exports.defineOperation = exports.createRestClient = exports.RestClient = void 0;
|
|
4
4
|
var RestClient_js_1 = require("./RestClient.js");
|
|
5
5
|
Object.defineProperty(exports, "RestClient", { enumerable: true, get: function () { return RestClient_js_1.RestClient; } });
|
|
6
|
+
Object.defineProperty(exports, "createRestClient", { enumerable: true, get: function () { return RestClient_js_1.createRestClient; } });
|
|
6
7
|
var Operation_js_1 = require("./Operation.js");
|
|
7
8
|
Object.defineProperty(exports, "defineOperation", { enumerable: true, get: function () { return Operation_js_1.defineOperation; } });
|
|
9
|
+
Object.defineProperty(exports, "operation", { enumerable: true, get: function () { return Operation_js_1.operation; } });
|
|
8
10
|
Object.defineProperty(exports, "validateParams", { enumerable: true, get: function () { return Operation_js_1.validateParams; } });
|
|
9
11
|
var AuthenticationManager_js_1 = require("./AuthenticationManager.js");
|
|
10
12
|
Object.defineProperty(exports, "AuthenticationManager", { enumerable: true, get: function () { return AuthenticationManager_js_1.AuthenticationManager; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAA+D;AAAtD,2GAAA,UAAU,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AACrC,+CAA4E;AAAnE,+GAAA,eAAe,OAAA;AAAE,yGAAA,SAAS,OAAA;AAAE,8GAAA,cAAc,OAAA;AAYnD,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA;AAC9B,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AAEnB,yCAQqB;AAPnB,4GAAA,eAAe,OAAA;AACf,+GAAA,kBAAkB,OAAA;AAClB,gHAAA,mBAAmB,OAAA;AACnB,sGAAA,SAAS,OAAA;AACT,4GAAA,eAAe,OAAA;AACf,yGAAA,YAAY,OAAA;AACZ,sGAAA,SAAS,OAAA"}
|