@nlabs/rip-hunter 2.6.4 → 3.0.2

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 CHANGED
@@ -1,211 +1,352 @@
1
- ![rip-hunter](https://nitrogenlabs.com/logos/gh-rip-hunter.png "rip-hunter")
1
+ # Rip Hunter: HTTP Client for REST & GraphQL**
2
2
 
3
- #### JS utilities for GraphQL
4
-
5
- rip-hunter is a small utility to parse objects formatted for GraphQL requests as well as use fetch to send query and
6
- mutation requests, returning a promise. Some helpers include sending an authorization token as well as custom headers.
3
+ > **Rip Hunter: Your Universal Gateway to Modern API Endpoints with Unmatched Speed and Reliability**
7
4
 
8
5
  [![npm version](https://img.shields.io/npm/v/rip-hunter.svg?style=flat-square)](https://www.npmjs.com/package/rip-hunter)
9
- [![Travis](https://img.shields.io/travis/nitrogenlabs/rip-hunter.svg?style=flat-square)](https://travis-ci.org/nitrogenlabs/rip-hunter)
10
6
  [![npm downloads](https://img.shields.io/npm/dm/rip-hunter.svg?style=flat-square)](https://www.npmjs.com/package/rip-hunter)
11
7
  [![Issues](http://img.shields.io/github/issues/nitrogenlabs/rip-hunter.svg?style=flat-square)](https://github.com/nitrogenlabs/rip-hunter/issues)
8
+ [![TypeScript](https://badges.frapsoft.com/typescript/version/typescript-next.svg?v=101)](https://github.com/ellerbrock/typescript-badges/)
12
9
  [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](http://opensource.org/licenses/MIT)
10
+ [![Chat](https://img.shields.io/discord/446122412715802649.svg)](https://discord.gg/Ttgev58)
11
+
12
+ **rip-hunter** is the all-in-one HTTP utility for developers who want a seamless, ESM-first way to connect to REST and GraphQL APIs. Whether you're building in Node.js, the browser, or serverless, rip-hunter makes data fetching, mutations, and error handling effortless—so you can focus on building features, not plumbing.
13
+
14
+ ---
15
+
16
+ ## 🚀 Why rip-hunter?
17
+
18
+ - **Unified API**: One package for both REST and GraphQL endpoints
19
+ - **ESM & TypeScript Native**: Modern, type-safe, and tree-shakable
20
+ - **Works Everywhere**: Node, browser, serverless—no config needed
21
+ - **Built-in Auth & Headers**: Effortlessly add tokens and custom headers
22
+ - **Automatic Error Handling**: Consistent, developer-friendly errors
23
+ - **Tiny & Fast**: Minimal dependencies, zero bloat
24
+ - **Request Caching**: Built-in caching for GET requests
25
+ - **Timeout Support**: Configurable request timeouts
26
+ - **Request Deduplication**: Prevents duplicate requests
27
+ - **Real-time Updates**: Server-Sent Events (SSE) support
28
+
29
+ ---
30
+
31
+ ## 📦 Installation
32
+
33
+ ```bash
34
+ npm install @nlabs/rip-hunter
35
+ # or
36
+ yarn add @nlabs/rip-hunter
13
37
 
14
- ### Installation
38
+ # For Node.js SSE support (optional)
39
+ npm install eventsource
40
+ ```
15
41
 
16
- Using [npm](https://www.npmjs.com/):
42
+ ---
17
43
 
18
- $ npm install @nlabs/rip-hunter
44
+ ## Quick Start
19
45
 
20
- ###App Usage
21
- Then with a module bundler like [webpack](https://webpack.github.io/) that supports either CommonJS or ES2015 modules, use as you would anything else:
46
+ ### REST Example
22
47
 
23
48
  ```js
24
- import {query} from '@nlabs/rip-hunter';
49
+ import { get, post } from '@nlabs/rip-hunter';
50
+
51
+ const url = 'https://api.example.com/data';
52
+
53
+ // GET request with caching
54
+ const data = await get(url, { userId: 123 }, { cache: true });
55
+
56
+ // POST request with auth token and timeout
57
+ const result = await post(url, { name: 'Rip Hunter' }, {
58
+ token: 'your_jwt_token',
59
+ timeout: 5000
60
+ });
25
61
  ```
26
62
 
27
- ### How to use
63
+ ### GraphQL Example
28
64
 
29
- **Example:**
65
+ ```js
66
+ import { query, mutation, toGql } from '@nlabs/rip-hunter';
67
+
68
+ const url = 'https://api.example.com/graphql';
69
+ const gql = '{ user { id name } }';
70
+
71
+ // Query with timeout
72
+ const userData = await query(url, gql, { timeout: 10000 });
73
+
74
+ // Mutation with variables
75
+ const input = { name: 'Rip Hunter' };
76
+ const mutationGql = `mutation { createUser(input: ${toGql(input)}) { id name } }`;
77
+ const created = await mutation(url, mutationGql, { timeout: 5000 });
78
+ ```
79
+
80
+ ### SSE Example
30
81
 
31
82
  ```js
32
- import {mutation, query, toGql} from '@nlabs/rip-hunter';
33
-
34
- const AppActions = {
35
- getData: () => {
36
- // Variables
37
- const url = 'http://www.example.com/graphql';
38
- const gql = '{ app { ping } }';
39
-
40
- // Query data
41
- return query(url, gql)
42
- .then(results => {
43
- console.log(results);
44
- // Assuming the results will return the JSON object, {status: 'ok'}
45
- // Output: {status: 'ok'}
46
- })
47
- .catch(error => {
48
- // ApiError will be returned if any problems occur.
49
- });
50
- },
83
+ import { subscribeSSE } from '@nlabs/rip-hunter';
51
84
 
52
- updateData: () => {
53
- // Variables
54
- const url = 'http://www.example.com/graphql';
55
- const data = {hello: 'world'};
56
- const gql = `{ user { update(data: ${toGql(data)}) } }`;
57
-
58
- // Mutate data
59
- return mutation(url, gql)
60
- .then(results => {
61
- console.log(results);
62
- // Assuming the results will return the JSON object, {id: 'test', hello: 'world'}
63
- // Output: {id: 'test', hello: 'world'}
64
- })
65
- .catch(error => {
66
- // ApiError will be returned if any problems occur.
67
- });
85
+ // Subscribe to real-time updates
86
+ const unsubscribe = subscribeSSE('https://api.example.com/stream', {
87
+ onMessage: (event) => {
88
+ console.log('Received:', event.data);
89
+ },
90
+ onError: (error) => {
91
+ console.error('SSE Error:', error);
92
+ },
93
+ onOpen: () => {
94
+ console.log('SSE connection opened');
68
95
  }
69
- }
70
-
96
+ }, {
97
+ token: 'your_jwt_token',
98
+ timeout: 30000,
99
+ retryInterval: 1000,
100
+ maxRetries: 5
101
+ });
102
+
103
+ // Later, to stop listening:
104
+ unsubscribe();
71
105
  ```
72
106
 
73
- ## API
107
+ ---
74
108
 
75
- ### Formatting
109
+ ## 🛠️ API Reference
76
110
 
77
- #### `toGql(data)`
111
+ ### REST Functions
112
+
113
+ #### `ajax(url, method, params?, options?)`
114
+
115
+ Low-level HTTP request for any method.
116
+
117
+ - **url**: `string` – Absolute URL
118
+ - **method**: `string` – HTTP method (GET, POST, etc.)
119
+ - **params**: `object` – Data to send (query for GET, body for others)
120
+ - **options**: `{ headers?, token?, timeout?, cache? }`
121
+ - **Returns**: `Promise<any>`
122
+
123
+ #### `get(url, params?, options?)`
124
+
125
+ HTTP GET request.
126
+
127
+ - **url**: `string`
128
+ - **params**: `object`
129
+ - **options**: `{ headers?, token?, timeout?, cache? }`
130
+ - **Returns**: `Promise<any>`
131
+
132
+ #### `post(url, params?, options?)`
133
+
134
+ HTTP POST request.
78
135
 
79
- Parses an immutable object, JSON object, string, or number into a GraphQL formatted string. This string is used when
80
- sending variables in a request.
136
+ - **url**: `string`
137
+ - **params**: `object`
138
+ - **options**: `{ headers?, token?, timeout? }`
139
+ - **Returns**: `Promise<any>`
81
140
 
82
- * [`data`] \(* Any *): An immutable object, JSON object, string or number to format for use with a GQL request.
141
+ #### `put(url, params?, options?)`
83
142
 
84
- ##### Returns
143
+ HTTP PUT request.
85
144
 
86
- A string formatted for use with GQL.
145
+ - **url**: `string`
146
+ - **params**: `object`
147
+ - **options**: `{ headers?, token?, timeout? }`
148
+ - **Returns**: `Promise<any>`
87
149
 
150
+ #### `del(url, params?, options?)`
88
151
 
89
- ### Events
152
+ HTTP DELETE request.
90
153
 
91
- #### `on(eventType, data)`
154
+ - **url**: `string`
155
+ - **params**: `object`
156
+ - **options**: `{ headers?, token?, timeout? }`
157
+ - **Returns**: `Promise<any>`
92
158
 
93
- Adds an event listener. The only event emitted is when an error occurs. The error event is _rip_hunter_error_.
159
+ ---
94
160
 
95
- * [`eventType`] \(*String*): Event to subscribe for store updates.
96
- * [`listener`] \(*Function*): The callback to be invoked any time an action has been dispatched.
161
+ ### GraphQL Functions
97
162
 
98
- #### `off(eventType, data)`
163
+ #### `query(url, body, options?)`
99
164
 
100
- Removes an event listener.
165
+ Send a GraphQL query.
101
166
 
102
- * [`eventType`] \(*String*): Event to unsubscribe.
103
- * [`listener`] \(*Function*): The callback associated with the subscribed event.
167
+ - **url**: `string` GraphQL endpoint
168
+ - **body**: `string` GraphQL query string
169
+ - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }`
170
+ - **Returns**: `Promise<any>`
104
171
 
172
+ #### `mutation(url, body, options?)`
105
173
 
106
- ### AJAX
174
+ Send a GraphQL mutation.
107
175
 
108
- #### `ajax(url, method, params, options)`
176
+ - **url**: `string`
177
+ - **body**: `string`
178
+ - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }`
179
+ - **Returns**: `Promise<any>`
109
180
 
110
- AJAX request.
181
+ #### `graphqlQuery(url, query, options?)`
111
182
 
112
- * [`url`] \(*String*): URL to send the request. Must be an absolute url.
113
- * [`method`] \(*String*): The HTTP method for the request.
114
- * [`params`] \(*Object*): Data to be sent with the request. Params will be converted to a query string for GET methods.
115
- * [`options`] \(*Object*): Rip Hunter options.
116
- * [`headers`] \(*Object*): Overwrite the default headers.
117
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
183
+ Low-level GraphQL request.
118
184
 
119
- ##### Returns
185
+ - **url**: `string` – GraphQL endpoint
186
+ - **query**: `HunterQueryType | HunterQueryType[]` – Query object(s)
187
+ - **options**: `{ headers?, token?, timeout? }`
188
+ - **Returns**: `Promise<any>`
120
189
 
121
- A promise with either the response data or ApiError.
190
+ #### `toGql(data)`
191
+
192
+ Convert JS objects, arrays, or primitives to GraphQL input strings.
193
+
194
+ - **data**: `any`
195
+ - **Returns**: `string`
196
+ - **Example**:
197
+
198
+ ```js
199
+ toGql({ name: 'Rip', age: 42 }) // => '{name: "Rip", age: 42}'
200
+ ```
201
+
202
+ ---
203
+
204
+ ### SSE Functions
205
+
206
+ #### `subscribeSSE(url, callbacks, options?)`
207
+
208
+ Subscribe to Server-Sent Events.
122
209
 
123
- #### `get(url, params, options)`
210
+ - **url**: `string` – SSE endpoint URL
211
+ - **callbacks**: `HunterSSECallbackType` – Event handlers
212
+ - `onMessage?: (event: HunterSSEEventType) => void`
213
+ - `onOpen?: (event: Event) => void`
214
+ - `onError?: (error: Error | Event) => void`
215
+ - `onRetry?: (attempt: number, delay: number) => void`
216
+ - **options**: `HunterSSEOptionsType` – Connection options
217
+ - `headers?: Headers`
218
+ - `token?: string`
219
+ - `timeout?: number` (default: 30000)
220
+ - `retryInterval?: number` (default: 1000)
221
+ - `maxRetries?: number` (default: 5)
222
+ - **Returns**: `() => void` – Cleanup function
124
223
 
125
- Server request using HTTP GET.
224
+ #### `HunterSSEEventType`
126
225
 
127
- * [`url`] \(*String*): URL to send the request. Must be an absolute url.
128
- * [`params`] \(*Object*): Data to be sent with the request.
129
- * [`options`] \(*Object*): Rip Hunter options.
130
- * [`headers`] \(*Object*): Overwrite the default headers.
131
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
226
+ SSE event object with:
132
227
 
133
- ##### Returns
228
+ - `data: string` – Event data
229
+ - `type: string` – Event type
230
+ - `id?: string` – Event ID
231
+ - `retry?: number` – Retry interval (if specified by server)
134
232
 
135
- A promise with either the response data or ApiError.
233
+ ---
136
234
 
137
- #### `post(url, params, options)`
235
+ ### Events & Error Handling
138
236
 
139
- Server request using HTTP POST.
237
+ #### `on(eventType, listener)`
140
238
 
141
- * [`url`] \(*String*): URL to send the request. Must be an absolute url.
142
- * [`params`] \(*Object*): Data to be sent with the request.
143
- * [`options`] \(*Object*): Rip Hunter options.
144
- * [`headers`] \(*Object*): Overwrite the default headers.
145
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
239
+ Subscribe to events (e.g., error events).
146
240
 
147
- ##### Returns
241
+ - **eventType**: `string` (e.g., 'rip_hunter_error')
242
+ - **listener**: `Function`
148
243
 
149
- A promise with either the response data or ApiError.
244
+ #### `off(eventType, listener)`
150
245
 
151
- #### `put(url, params, options)`
246
+ Unsubscribe from events.
152
247
 
153
- Server request using HTTP PUT.
248
+ #### `ApiError`
154
249
 
155
- * [`url`] \(*String*): URL to send the request. Must be an absolute url.
156
- * [`params`] \(*Object*): Data to be sent with the request.
157
- * [`options`] \(*Object*): Rip Hunter options.
158
- * [`headers`] \(*Object*): Overwrite the default headers.
159
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
250
+ All errors are wrapped in a consistent `ApiError` object for easy handling.
160
251
 
161
- ##### Returns
252
+ - **.errors**: `string[]` – List of error messages
253
+ - **.source**: `Error` – Original error object
162
254
 
163
- A promise with either the response data or ApiError.
255
+ ---
164
256
 
165
- #### `del(url, params, options)`
257
+ ## 💡 Advanced Usage
258
+
259
+ ### Request Caching
260
+
261
+ ```js
262
+ // Cache GET requests for 5 minutes
263
+ const data = await get('/api/users', {}, { cache: true });
264
+ ```
265
+
266
+ ### Timeout Handling
267
+
268
+ ```js
269
+ // Set 10 second timeout
270
+ const result = await post('/api/data', payload, { timeout: 10000 });
271
+ ```
166
272
 
167
- Server request using HTTP DEL.
273
+ ### Custom Headers
168
274
 
169
- * [`url`] \(*String*): GraphQL server endpoint. Must be an absolute url.
170
- * [`params`] \(*Object*): Data to be sent with the request.
171
- * [`options`] \(*Object*): Rip Hunter options.
172
- * [`headers`] \(*Object*): Overwrite the default headers.
173
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
275
+ ```js
276
+ const headers = new Headers({
277
+ 'X-Custom-Header': 'value',
278
+ 'Content-Type': 'application/json'
279
+ });
280
+
281
+ const data = await get('/api/data', {}, { headers });
282
+ ```
283
+
284
+ ### GraphQL Variables
285
+
286
+ ```js
287
+ const query = `
288
+ query GetUser($id: ID!) {
289
+ user(id: $id) { name email }
290
+ }
291
+ `;
292
+
293
+ const variables = { id: '123' };
294
+ const user = await query('/graphql', query, { variables });
295
+ ```
296
+
297
+ ### SSE with Authentication
298
+
299
+ ```js
300
+ const headers = new Headers({
301
+ 'Authorization': 'Bearer your-token',
302
+ 'Accept': 'text/event-stream'
303
+ });
304
+
305
+ const unsubscribe = subscribeSSE('/api/notifications', {
306
+ onMessage: (event) => {
307
+ const notification = JSON.parse(event.data);
308
+ console.log('New notification:', notification);
309
+ },
310
+ onError: (error) => {
311
+ console.error('SSE error:', error);
312
+ }
313
+ }, {
314
+ headers,
315
+ timeout: 60000,
316
+ maxRetries: 10
317
+ });
318
+ ```
174
319
 
175
- ##### Returns
320
+ ---
176
321
 
177
- A promise with either the response data or ApiError.
322
+ ## 🚀 Performance Features
178
323
 
179
- ### GraphQL
324
+ - **Request Deduplication**: Prevents duplicate requests to the same endpoint
325
+ - **Built-in Caching**: Automatic caching for GET requests with 5-minute TTL
326
+ - **Timeout Support**: Configurable request timeouts (default: 30s)
327
+ - **Optimized Functions**: Lightweight utility functions for better performance
328
+ - **Memory Efficient**: Minimal object creation and garbage collection
329
+ - **SSE Reconnection**: Automatic retry with exponential backoff for SSE connections
180
330
 
181
- #### `query(url, body, options)`
331
+ ---
182
332
 
183
- Queries a GraphQL server.
333
+ ## 🌐 Environment Support
184
334
 
185
- * [`url`] \(*String*): GraphQL server endpoint. Must be an absolute url.
186
- * [`body`] \(*String*): GraphQL query.
187
- * [`options`] \(*Object*): Rip Hunter options.
188
- * [`headers`] \(*Object*): Overwrite the default headers.
189
- * [`stripWhitespace`] \(*Boolean*): Removes whitespace in body. Default: false.
190
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
191
- * [`variables`] \(*Object*): Variables used in query. Default: {}.
335
+ - **Browser**: Full support for all features including SSE
336
+ - **Node.js**: Full REST/GraphQL support, SSE requires `eventsource` package
337
+ - **Serverless**: REST/GraphQL support (SSE not recommended in serverless)
192
338
 
193
- ##### Returns
339
+ ---
194
340
 
195
- A promise with either the response data or ApiError.
341
+ ## 🤝 Contributing
196
342
 
197
- #### `mutation(url, body, token, headers)`
343
+ PRs and issues welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
198
344
 
199
- Modifies data on a GraphQL server.
345
+ ## 📄 License
200
346
 
201
- * [`url`] \(*String*): GraphQL server endpoint. Must be an absolute url.
202
- * [`body`] \(*String*): GraphQL query.
203
- * [`options`] \(*Object*): Rip Hunter options.
204
- * [`headers`] \(*Object*): Overwrite the default headers.
205
- * [`stripWhitespace`] \(*Boolean*): Removes whitespace in body. Default: false.
206
- * [`token`] \(*String*): Add an _Authorization_ header with the value _Bearer [token]_.
207
- * [`variables`] \(*Object*): Variables used in query. Default: {}.
347
+ MIT © Nitrogen Labs, Inc.
208
348
 
209
- ##### Returns
349
+ ## 🔗 Links
210
350
 
211
- A promise with either the response data or ApiError.
351
+ - [GitHub](https://github.com/nitrogenlabs/rip-hunter)
352
+ - [NPM](https://www.npmjs.com/package/rip-hunter)
package/benchmark.js ADDED
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Performance benchmark for rip-hunter
5
+ */
6
+
7
+ // Mock fetch for benchmarking
8
+ global.fetch = () => Promise.resolve({
9
+ json: () => Promise.resolve({}),
10
+ text: () => Promise.resolve(''),
11
+ headers: new Headers()
12
+ });
13
+
14
+ import { queryString, removeSpaces, toGql } from './src/index.js';
15
+
16
+ console.log('🚀 rip-hunter Performance Benchmark\n');
17
+
18
+ // Benchmark toGql function
19
+ console.log('📊 toGql Performance Test:');
20
+ const testObject = {
21
+ name: 'Rip Hunter',
22
+ age: 42,
23
+ skills: ['time travel', 'combat'],
24
+ metadata: {
25
+ universe: 'DC',
26
+ team: 'Legion of Super-Heroes'
27
+ },
28
+ nullValue: null,
29
+ undefinedValue: undefined
30
+ };
31
+
32
+ const iterations = 100000;
33
+ const startTime = performance.now();
34
+
35
+ for (let i = 0; i < iterations; i++) {
36
+ toGql(testObject);
37
+ }
38
+
39
+ const endTime = performance.now();
40
+ const duration = endTime - startTime;
41
+ const opsPerSecond = Math.round(iterations / (duration / 1000));
42
+
43
+ console.log(` ✅ ${iterations.toLocaleString()} iterations in ${duration.toFixed(2)}ms`);
44
+ console.log(` 📈 ${opsPerSecond.toLocaleString()} operations/second\n`);
45
+
46
+ // Benchmark queryString function
47
+ console.log('📊 queryString Performance Test:');
48
+ const testParams = {
49
+ userId: 123,
50
+ name: 'Rip Hunter',
51
+ skills: ['time travel', 'combat'],
52
+ metadata: { universe: 'DC' }
53
+ };
54
+
55
+ const startTime2 = performance.now();
56
+
57
+ for (let i = 0; i < iterations; i++) {
58
+ queryString(testParams);
59
+ }
60
+
61
+ const endTime2 = performance.now();
62
+ const duration2 = endTime2 - startTime2;
63
+ const opsPerSecond2 = Math.round(iterations / (duration2 / 1000));
64
+
65
+ console.log(` ✅ ${iterations.toLocaleString()} iterations in ${duration2.toFixed(2)}ms`);
66
+ console.log(` 📈 ${opsPerSecond2.toLocaleString()} operations/second\n`);
67
+
68
+ // Benchmark removeSpaces function
69
+ console.log('📊 removeSpaces Performance Test:');
70
+ const testString = 'query { user { id name email } }';
71
+
72
+ const startTime3 = performance.now();
73
+
74
+ for (let i = 0; i < iterations; i++) {
75
+ removeSpaces(testString);
76
+ }
77
+
78
+ const endTime3 = performance.now();
79
+ const duration3 = endTime3 - startTime3;
80
+ const opsPerSecond3 = Math.round(iterations / (duration3 / 1000));
81
+
82
+ console.log(` ✅ ${iterations.toLocaleString()} iterations in ${duration3.toFixed(2)}ms`);
83
+ console.log(` 📈 ${opsPerSecond3.toLocaleString()} operations/second\n`);
84
+
85
+ console.log('🎉 Benchmark completed!');
package/index.js CHANGED
@@ -3,4 +3,4 @@
3
3
  * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
4
  */
5
5
 
6
- module.exports = require('./lib/index');
6
+ export * from './lib/index.js';
package/lex.config.js CHANGED
@@ -1,5 +1,11 @@
1
- module.exports = {
2
- outputPath: './lib',
1
+ export default {
2
+ ai: {
3
+ maxTokens: 4000,
4
+ model: 'cursor-code',
5
+ provider: 'cursor',
6
+ temperature: 0.1
7
+ },
8
+ outputPath: 'lib',
3
9
  targetEnvironment: 'node',
4
10
  useTypescript: true
5
11
  };
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2017-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */
1
5
  export declare class ApiError extends Error {
2
6
  source: Error;
3
7
  errors: string[];
@@ -1,34 +1,2 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
- var ApiError_exports = {};
19
- __export(ApiError_exports, {
20
- ApiError: () => ApiError
21
- });
22
- module.exports = __toCommonJS(ApiError_exports);
23
- class ApiError extends Error {
24
- constructor(list, error) {
25
- super("API Error");
26
- this.source = error;
27
- this.errors = list ? list.map((errorItem) => errorItem.message) : [];
28
- }
29
- }
30
- // Annotate the CommonJS export names for ESM import in node:
31
- 0 && (module.exports = {
32
- ApiError
33
- });
34
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2Vycm9ycy9BcGlFcnJvci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IGNsYXNzIEFwaUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzb3VyY2U6IEVycm9yO1xuICBlcnJvcnM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKGxpc3QsIGVycm9yKSB7XG4gICAgc3VwZXIoJ0FQSSBFcnJvcicpO1xuICAgIHRoaXMuc291cmNlID0gZXJyb3I7XG4gICAgdGhpcy5lcnJvcnMgPSBsaXN0ID8gbGlzdC5tYXAoKGVycm9ySXRlbTogRXJyb3IpID0+IGVycm9ySXRlbS5tZXNzYWdlKSA6IFtdO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBTyxNQUFNLGlCQUFpQixNQUFNO0FBQUEsRUFJbEMsWUFBWSxNQUFNLE9BQU87QUFDdkIsVUFBTSxXQUFXO0FBQ2pCLFNBQUssU0FBUztBQUNkLFNBQUssU0FBUyxPQUFPLEtBQUssSUFBSSxDQUFDLGNBQXFCLFVBQVUsT0FBTyxJQUFJLENBQUM7QUFBQSxFQUM1RTtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
1
+ class t extends Error{source;errors;constructor(r,s){super("API Error"),this.source=s,this.errors=r?r.map(o=>o.message):[]}}export{t as ApiError};
2
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2Vycm9ycy9BcGlFcnJvci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTctUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBBcGlFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgc291cmNlOiBFcnJvcjtcbiAgZXJyb3JzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihsaXN0LCBlcnJvcikge1xuICAgIHN1cGVyKCdBUEkgRXJyb3InKTtcbiAgICB0aGlzLnNvdXJjZSA9IGVycm9yO1xuICAgIHRoaXMuZXJyb3JzID0gbGlzdCA/IGxpc3QubWFwKChlcnJvckl0ZW06IEVycm9yKSA9PiBlcnJvckl0ZW0ubWVzc2FnZSkgOiBbXTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBSU8sTUFBTUEsVUFBaUIsS0FBTSxDQUNsQyxPQUNBLE9BRUEsWUFBWUMsRUFBTUMsRUFBTyxDQUN2QixNQUFNLFdBQVcsRUFDakIsS0FBSyxPQUFTQSxFQUNkLEtBQUssT0FBU0QsRUFBT0EsRUFBSyxJQUFLRSxHQUFxQkEsRUFBVSxPQUFPLEVBQUksQ0FBQyxDQUM1RSxDQUNGIiwKICAibmFtZXMiOiBbIkFwaUVycm9yIiwgImxpc3QiLCAiZXJyb3IiLCAiZXJyb3JJdGVtIl0KfQo=
package/lib/index.d.ts CHANGED
@@ -1,12 +1,37 @@
1
+ /**
2
+ * Copyright (c) 2017-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */
1
5
  export interface HunterOptionsType {
2
6
  readonly headers?: Headers;
3
7
  readonly token?: string;
4
8
  readonly variables?: any;
9
+ readonly timeout?: number;
10
+ readonly cache?: boolean;
5
11
  }
6
12
  export interface HunterQueryType {
7
13
  readonly query: string;
8
14
  readonly variables?: any;
9
15
  }
16
+ export interface HunterSSEOptionsType {
17
+ readonly headers?: Headers;
18
+ readonly token?: string;
19
+ readonly timeout?: number;
20
+ readonly retryInterval?: number;
21
+ readonly maxRetries?: number;
22
+ }
23
+ export interface HunterSSEEventType {
24
+ readonly data: string;
25
+ readonly type: string;
26
+ readonly id?: string;
27
+ readonly retry?: number | undefined;
28
+ }
29
+ export interface HunterSSECallbackType {
30
+ onMessage?: (event: HunterSSEEventType) => void;
31
+ onOpen?: (event: Event) => void;
32
+ onError?: (error: Error | Event) => void;
33
+ onRetry?: (attempt: number, delay: number) => void;
34
+ }
10
35
  export declare const removeSpaces: (str: string) => string;
11
36
  export declare const queryString: (json: any) => string;
12
37
  export declare const ajax: (url: string, method: string, params?: any, options?: HunterOptionsType) => Promise<any>;
@@ -16,4 +41,7 @@ export declare const put: (url: string, params?: any, options?: HunterOptionsTyp
16
41
  export declare const del: (url: string, params?: any, options?: HunterOptionsType) => Promise<any>;
17
42
  export declare const toGql: (obj: any) => string;
18
43
  export declare const graphqlQuery: (url: string, query: HunterQueryType | HunterQueryType[], options?: HunterOptionsType) => Promise<any>;
19
- export { ApiError } from './errors/ApiError';
44
+ export declare const query: (url: string, body: string, options?: HunterOptionsType) => Promise<any>;
45
+ export declare const mutation: (url: string, body: string, options?: HunterOptionsType) => Promise<any>;
46
+ export declare const subscribeSSE: (url: string, callbacks: HunterSSECallbackType, options?: HunterSSEOptionsType) => (() => void);
47
+ export { ApiError } from './errors/ApiError.js';
package/lib/index.js CHANGED
@@ -1,185 +1,2 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
- var src_exports = {};
29
- __export(src_exports, {
30
- ApiError: () => import_ApiError2.ApiError,
31
- ajax: () => ajax,
32
- del: () => del,
33
- get: () => get,
34
- graphqlQuery: () => graphqlQuery,
35
- post: () => post,
36
- put: () => put,
37
- queryString: () => queryString,
38
- removeSpaces: () => removeSpaces,
39
- toGql: () => toGql
40
- });
41
- module.exports = __toCommonJS(src_exports);
42
- var import_isArray = __toESM(require("lodash/isArray"));
43
- var import_isEmpty = __toESM(require("lodash/isEmpty"));
44
- var import_isNull = __toESM(require("lodash/isNull"));
45
- var import_isPlainObject = __toESM(require("lodash/isPlainObject"));
46
- var import_isString = __toESM(require("lodash/isString"));
47
- var import_isUndefined = __toESM(require("lodash/isUndefined"));
48
- var import_omit = __toESM(require("lodash/omit"));
49
- var import_ApiError = require("./errors/ApiError");
50
- var import_ApiError2 = require("./errors/ApiError");
51
- if (typeof window === "undefined") {
52
- require("cross-fetch/polyfill");
53
- }
54
- const removeSpaces = (str) => str.replace(/\s+(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/gm, "");
55
- const queryString = (json) => Object.keys(json).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(json[key])}`).join("&");
56
- const ajax = (url, method, params, options = {}) => {
57
- const { headers, token } = options;
58
- let formatUrl = (url || "").trim();
59
- const formatToken = (token || "").trim();
60
- const formatHeaders = headers || new Headers();
61
- const formatMethod = (method || "GET").toUpperCase();
62
- let formatParams;
63
- if (params && formatMethod === "GET") {
64
- formatUrl = `${formatUrl}?${queryString(params)}`;
65
- formatParams = null;
66
- } else if (params) {
67
- formatHeaders.set("Accept", "application/json");
68
- formatHeaders.set("Content-Type", "application/json");
69
- formatParams = JSON.stringify(params);
70
- } else {
71
- formatParams = params;
72
- }
73
- if (!(0, import_isEmpty.default)(formatToken)) {
74
- formatHeaders.set("Authorization", `Bearer ${formatToken}`);
75
- }
76
- let isResponseJson;
77
- return fetch(formatUrl, { body: formatParams, headers: formatHeaders, method: formatMethod }).then((response) => {
78
- const regex = /application\/json/i;
79
- isResponseJson = regex.test(response.headers.get("Content-Type") || "");
80
- if (isResponseJson) {
81
- return response.json();
82
- }
83
- return response.text();
84
- }).then((results) => {
85
- if (isResponseJson) {
86
- return results;
87
- }
88
- return results;
89
- }).catch((error) => {
90
- if ((error || {}).message === "only absolute urls are supported") {
91
- return Promise.reject(new import_ApiError.ApiError([{ message: "invalid_url" }], error));
92
- }
93
- return Promise.reject(new import_ApiError.ApiError([{ message: "network_error" }], error));
94
- });
95
- };
96
- const get = (url, params, options) => ajax(url, "GET", params, options);
97
- const post = (url, params, options) => ajax(url, "POST", params, options);
98
- const put = (url, params, options) => ajax(url, "PUT", params, options);
99
- const del = (url, params, options) => ajax(url, "DELETE", params, options);
100
- const toGql = (obj) => {
101
- if ((0, import_isString.default)(obj)) {
102
- return JSON.stringify(obj);
103
- } else if ((0, import_isPlainObject.default)(obj)) {
104
- let cleanObj = (0, import_omit.default)(obj, import_isUndefined.default);
105
- cleanObj = (0, import_omit.default)(cleanObj, import_isNull.default);
106
- const gqlProps = Object.keys(cleanObj).reduce((props, key) => {
107
- const item = obj[key];
108
- if ((0, import_isPlainObject.default)(item)) {
109
- props.push(toGql(item));
110
- } else if ((0, import_isArray.default)(item)) {
111
- const list = item.map((listItem) => toGql(listItem));
112
- props.push(`${key}: [${list.join(", ")}]`);
113
- } else {
114
- const val = JSON.stringify(item);
115
- if (val) {
116
- props.push(`${key}: ${val}`);
117
- }
118
- }
119
- return props;
120
- }, []);
121
- const values = gqlProps.join(", ");
122
- if (values === "") {
123
- return '""';
124
- }
125
- return `{${gqlProps.join(", ")}}`;
126
- } else if ((0, import_isArray.default)(obj)) {
127
- return `[${obj.map((objItem) => toGql(objItem)).toString()}]`;
128
- }
129
- return obj;
130
- };
131
- const graphqlQuery = (url, query, options = {}) => {
132
- const { headers, token } = options;
133
- const formatUrl = url ? url.trim() : "";
134
- const formatToken = (token || "").trim();
135
- const formatHeaders = headers || new Headers({ "Content-Type": "application/json" });
136
- if (formatToken !== "") {
137
- formatHeaders.set("Authorization", `Bearer ${formatToken}`);
138
- }
139
- return fetch(formatUrl, { body: JSON.stringify(query), headers: formatHeaders, method: "post" }).then((response) => {
140
- const regex = /application\/json/i;
141
- const isJson = regex.test(response.headers.get("Content-Type") || "");
142
- if (isJson && response.body) {
143
- return response.json();
144
- }
145
- return null;
146
- }).catch((error) => {
147
- if ((error || {}).message === "only absolute urls are supported") {
148
- return Promise.reject(new import_ApiError.ApiError([{ message: "invalid_url" }], error));
149
- }
150
- return Promise.reject(new import_ApiError.ApiError([{ message: "network_error" }], error));
151
- }).then((json) => {
152
- let updatedJson = {};
153
- if (!json || json.errors) {
154
- if (!json) {
155
- return Promise.reject(new import_ApiError.ApiError([{ message: "api_error" }], new Error()));
156
- } else if ((json.errors || []).some((error) => error.message === "Must provide query string.")) {
157
- return Promise.reject(new import_ApiError.ApiError([{ message: "required_query" }], new Error()));
158
- }
159
- return json.errors ? Promise.reject(new import_ApiError.ApiError(json.errors, new Error())) : updatedJson;
160
- } else if (json) {
161
- updatedJson = { ...json };
162
- }
163
- return updatedJson.data || {};
164
- }).catch((error) => {
165
- let updatedError = error;
166
- if (!error.source) {
167
- updatedError = new import_ApiError.ApiError([{ message: "network_error" }], error);
168
- }
169
- return Promise.reject(updatedError);
170
- });
171
- };
172
- // Annotate the CommonJS export names for ESM import in node:
173
- 0 && (module.exports = {
174
- ApiError,
175
- ajax,
176
- del,
177
- get,
178
- graphqlQuery,
179
- post,
180
- put,
181
- queryString,
182
- removeSpaces,
183
- toGql
184
- });
185
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IGlzQXJyYXkgZnJvbSAnbG9kYXNoL2lzQXJyYXknO1xuaW1wb3J0IGlzRW1wdHkgZnJvbSAnbG9kYXNoL2lzRW1wdHknO1xuaW1wb3J0IGlzTnVsbCBmcm9tICdsb2Rhc2gvaXNOdWxsJztcbmltcG9ydCBpc1BsYWluT2JqZWN0IGZyb20gJ2xvZGFzaC9pc1BsYWluT2JqZWN0JztcbmltcG9ydCBpc1N0cmluZyBmcm9tICdsb2Rhc2gvaXNTdHJpbmcnO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gJ2xvZGFzaC9pc1VuZGVmaW5lZCc7XG5pbXBvcnQgb21pdCBmcm9tICdsb2Rhc2gvb21pdCc7XG5cbmltcG9ydCB7QXBpRXJyb3J9IGZyb20gJy4vZXJyb3JzL0FwaUVycm9yJztcblxuaWYodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgcmVxdWlyZSgnY3Jvc3MtZmV0Y2gvcG9seWZpbGwnKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJPcHRpb25zVHlwZSB7XG4gIHJlYWRvbmx5IGhlYWRlcnM/OiBIZWFkZXJzO1xuICByZWFkb25seSB0b2tlbj86IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyaWFibGVzPzogYW55O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlclF1ZXJ5VHlwZSB7XG4gIHJlYWRvbmx5IHF1ZXJ5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcmlhYmxlcz86IGFueTtcbn1cblxuLyoqXG4gKiBKUyB1dGlsaXRpZXMgZm9yIEdyYXBoUUxcbiAqL1xuZXhwb3J0IGNvbnN0IHJlbW92ZVNwYWNlcyA9IChzdHI6IHN0cmluZyk6IHN0cmluZyA9PiBzdHIucmVwbGFjZSgvXFxzKyg/PSg/OlteJ1wiXSpbJ1wiXVteJ1wiXSpbJ1wiXSkqW14nXCJdKiQpL2dtLCAnJyk7XG5cbmV4cG9ydCBjb25zdCBxdWVyeVN0cmluZyA9IChqc29uOiBhbnkpOiBzdHJpbmcgPT4gT2JqZWN0XG4gIC5rZXlzKGpzb24pXG4gIC5tYXAoKGtleTogc3RyaW5nKSA9PiBgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQoanNvbltrZXldKX1gKS5qb2luKCcmJyk7XG5cbi8vIEFKQVhcbmV4cG9ydCBjb25zdCBhamF4ID0gKHVybDogc3RyaW5nLCBtZXRob2Q6IHN0cmluZywgcGFyYW1zPywgb3B0aW9uczogSHVudGVyT3B0aW9uc1R5cGUgPSB7fSk6IFByb21pc2U8YW55PiA9PiB7XG4gIGNvbnN0IHtoZWFkZXJzLCB0b2tlbn0gPSBvcHRpb25zO1xuXG4gIGxldCBmb3JtYXRVcmw6IHN0cmluZyA9ICh1cmwgfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0VG9rZW46IHN0cmluZyA9ICh0b2tlbiB8fCAnJykudHJpbSgpO1xuICBjb25zdCBmb3JtYXRIZWFkZXJzOiBIZWFkZXJzID0gaGVhZGVycyB8fCBuZXcgSGVhZGVycygpO1xuXG4gIC8vIE1ldGhvZFxuICBjb25zdCBmb3JtYXRNZXRob2Q6IHN0cmluZyA9IChtZXRob2QgfHwgJ0dFVCcpLnRvVXBwZXJDYXNlKCk7XG4gIGxldCBmb3JtYXRQYXJhbXM7XG5cbiAgLy8gUGFyYW1ldGVyc1xuICBpZihwYXJhbXMgJiYgZm9ybWF0TWV0aG9kID09PSAnR0VUJykge1xuICAgIGZvcm1hdFVybCA9IGAke2Zvcm1hdFVybH0/JHtxdWVyeVN0cmluZyhwYXJhbXMpfWA7XG4gICAgZm9ybWF0UGFyYW1zID0gbnVsbDtcbiAgfSBlbHNlIGlmKHBhcmFtcykge1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdBY2NlcHQnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIGZvcm1hdFBhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gIH0gZWxzZSB7XG4gICAgZm9ybWF0UGFyYW1zID0gcGFyYW1zO1xuICB9XG5cbiAgLy8gQXV0aGVudGljYXRpb24gdG9rZW5cbiAgaWYoIWlzRW1wdHkoZm9ybWF0VG9rZW4pKSB7XG4gICAgZm9ybWF0SGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7Zm9ybWF0VG9rZW59YCk7XG4gIH1cblxuICBsZXQgaXNSZXNwb25zZUpzb246IGJvb2xlYW47XG5cbiAgcmV0dXJuIGZldGNoKGZvcm1hdFVybCwge2JvZHk6IGZvcm1hdFBhcmFtcywgaGVhZGVyczogZm9ybWF0SGVhZGVycywgbWV0aG9kOiBmb3JtYXRNZXRob2R9KVxuICAgIC50aGVuKChyZXNwb25zZTogUmVzcG9uc2UpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gL2FwcGxpY2F0aW9uXFwvanNvbi9pO1xuXG4gICAgICAvLyBDaGVjayBpZiByZXNwb25zZSBpcyBqc29uXG4gICAgICBpc1Jlc3BvbnNlSnNvbiA9IHJlZ2V4LnRlc3QocmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnKTtcblxuICAgICAgaWYoaXNSZXNwb25zZUpzb24pIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcbiAgICB9KVxuICAgIC50aGVuKChyZXN1bHRzKSA9PiB7XG4gICAgICBpZihpc1Jlc3BvbnNlSnNvbikge1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpZigoZXJyb3IgfHwge30pLm1lc3NhZ2UgPT09ICdvbmx5IGFic29sdXRlIHVybHMgYXJlIHN1cHBvcnRlZCcpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICdpbnZhbGlkX3VybCd9XSwgZXJyb3IpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICduZXR3b3JrX2Vycm9yJ31dLCBlcnJvcikpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldCA9ICh1cmw6IHN0cmluZywgcGFyYW1zPywgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnR0VUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IHBvc3QgPSAodXJsOiBzdHJpbmcsIHBhcmFtcz8sIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZSk6IFByb21pc2U8YW55PiA9PiBhamF4KHVybCwgJ1BPU1QnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG5leHBvcnQgY29uc3QgcHV0ID0gKHVybDogc3RyaW5nLCBwYXJhbXM/LCBvcHRpb25zPzogSHVudGVyT3B0aW9uc1R5cGUpOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdQVVQnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG5leHBvcnQgY29uc3QgZGVsID0gKHVybDogc3RyaW5nLCBwYXJhbXM/LCBvcHRpb25zPzogSHVudGVyT3B0aW9uc1R5cGUpOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdERUxFVEUnLCBwYXJhbXMsIG9wdGlvbnMpO1xuXG4vLyBHcmFwaFFMXG5leHBvcnQgY29uc3QgdG9HcWwgPSAob2JqOiBhbnkpOiBzdHJpbmcgPT4ge1xuICBpZihpc1N0cmluZyhvYmopKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9iaik7XG4gIH0gZWxzZSBpZihpc1BsYWluT2JqZWN0KG9iaikpIHtcbiAgICBsZXQgY2xlYW5PYmogPSBvbWl0KG9iaiwgaXNVbmRlZmluZWQpO1xuICAgIGNsZWFuT2JqID0gb21pdChjbGVhbk9iaiwgaXNOdWxsKTtcblxuICAgIGNvbnN0IGdxbFByb3BzOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKGNsZWFuT2JqKS5yZWR1Y2UoKHByb3BzOiBzdHJpbmdbXSwga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBvYmpba2V5XTtcblxuICAgICAgaWYoaXNQbGFpbk9iamVjdChpdGVtKSkge1xuICAgICAgICBwcm9wcy5wdXNoKHRvR3FsKGl0ZW0pKTtcbiAgICAgIH0gZWxzZSBpZihpc0FycmF5KGl0ZW0pKSB7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBpdGVtLm1hcCgobGlzdEl0ZW0pID0+IHRvR3FsKGxpc3RJdGVtKSk7XG4gICAgICAgIHByb3BzLnB1c2goYCR7a2V5fTogWyR7bGlzdC5qb2luKCcsICcpfV1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IEpTT04uc3RyaW5naWZ5KGl0ZW0pO1xuXG4gICAgICAgIGlmKHZhbCkge1xuICAgICAgICAgIHByb3BzLnB1c2goYCR7a2V5fTogJHt2YWx9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByb3BzO1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IHZhbHVlcyA9IGdxbFByb3BzLmpvaW4oJywgJyk7XG5cbiAgICBpZih2YWx1ZXMgPT09ICcnKSB7XG4gICAgICByZXR1cm4gJ1wiXCInO1xuICAgIH1cblxuICAgIHJldHVybiBgeyR7Z3FsUHJvcHMuam9pbignLCAnKX19YDtcbiAgfSBlbHNlIGlmKGlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBgWyR7b2JqLm1hcCgob2JqSXRlbSkgPT4gdG9HcWwob2JqSXRlbSkpLnRvU3RyaW5nKCl9XWA7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufTtcblxuZXhwb3J0IGNvbnN0IGdyYXBocWxRdWVyeSA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHF1ZXJ5OiBIdW50ZXJRdWVyeVR5cGUgfCBIdW50ZXJRdWVyeVR5cGVbXSxcbiAgb3B0aW9uczogSHVudGVyT3B0aW9uc1R5cGUgPSB7fVxuKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgY29uc3Qge2hlYWRlcnMsIHRva2VufSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZvcm1hdFVybDogc3RyaW5nID0gdXJsID8gdXJsLnRyaW0oKSA6ICcnO1xuICBjb25zdCBmb3JtYXRUb2tlbjogc3RyaW5nID0gKHRva2VuIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdEhlYWRlcnM6IEhlYWRlcnMgPSBoZWFkZXJzIHx8IG5ldyBIZWFkZXJzKHsnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nfSk7XG5cbiAgaWYoZm9ybWF0VG9rZW4gIT09ICcnKSB7XG4gICAgZm9ybWF0SGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7Zm9ybWF0VG9rZW59YCk7XG4gIH1cblxuICByZXR1cm4gZmV0Y2goZm9ybWF0VXJsLCB7Ym9keTogSlNPTi5zdHJpbmdpZnkocXVlcnkpLCBoZWFkZXJzOiBmb3JtYXRIZWFkZXJzLCBtZXRob2Q6ICdwb3N0J30pXG4gICAgLnRoZW4oKHJlc3BvbnNlOiBSZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgcmVnZXg6IFJlZ0V4cCA9IC9hcHBsaWNhdGlvblxcL2pzb24vaTtcbiAgICAgIGNvbnN0IGlzSnNvbjogYm9vbGVhbiA9IHJlZ2V4LnRlc3QocmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnKTtcblxuICAgICAgaWYoaXNKc29uICYmIHJlc3BvbnNlLmJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7IC8vIHtkYXRhOiB7fX07XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpZigoZXJyb3IgfHwge30pLm1lc3NhZ2UgPT09ICdvbmx5IGFic29sdXRlIHVybHMgYXJlIHN1cHBvcnRlZCcpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICdpbnZhbGlkX3VybCd9XSwgZXJyb3IpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICduZXR3b3JrX2Vycm9yJ31dLCBlcnJvcikpO1xuICAgIH0pXG4gICAgLnRoZW4oKGpzb24pID0+IHtcbiAgICAgIGxldCB1cGRhdGVkSnNvbjogYW55ID0ge307XG5cbiAgICAgIGlmKCFqc29uIHx8IGpzb24uZXJyb3JzKSB7XG4gICAgICAgIGlmKCFqc29uKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICdhcGlfZXJyb3InfV0sIG5ldyBFcnJvcigpKSk7XG4gICAgICAgIH0gZWxzZSBpZigoanNvbi5lcnJvcnMgfHwgW10pLnNvbWUoKGVycm9yKSA9PiBlcnJvci5tZXNzYWdlID09PSAnTXVzdCBwcm92aWRlIHF1ZXJ5IHN0cmluZy4nKSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAncmVxdWlyZWRfcXVlcnknfV0sIG5ldyBFcnJvcigpKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ganNvbi5lcnJvcnMgPyBQcm9taXNlLnJlamVjdChuZXcgQXBpRXJyb3IoanNvbi5lcnJvcnMsIG5ldyBFcnJvcigpKSkgOiB1cGRhdGVkSnNvbjtcbiAgICAgIH0gZWxzZSBpZihqc29uKSB7XG4gICAgICAgIHVwZGF0ZWRKc29uID0gey4uLmpzb259O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZEpzb24uZGF0YSB8fCB7fTtcbiAgICB9KVxuICAgIC5jYXRjaCgoZXJyb3I6IEFwaUVycm9yKSA9PiB7XG4gICAgICBsZXQgdXBkYXRlZEVycm9yID0gZXJyb3I7XG5cbiAgICAgIGlmKCFlcnJvci5zb3VyY2UpIHtcbiAgICAgICAgdXBkYXRlZEVycm9yID0gbmV3IEFwaUVycm9yKFt7bWVzc2FnZTogJ25ldHdvcmtfZXJyb3InfV0sIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHVwZGF0ZWRFcnJvcik7XG4gICAgfSk7XG59O1xuXG5leHBvcnQge0FwaUVycm9yfSBmcm9tICcuL2Vycm9ycy9BcGlFcnJvcic7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBSUEscUJBQW9CO0FBQ3BCLHFCQUFvQjtBQUNwQixvQkFBbUI7QUFDbkIsMkJBQTBCO0FBQzFCLHNCQUFxQjtBQUNyQix5QkFBd0I7QUFDeEIsa0JBQWlCO0FBRWpCLHNCQUF1QjtBQW1NdkIsSUFBQUEsbUJBQXVCO0FBak12QixJQUFHLE9BQU8sV0FBVyxhQUFhO0FBQ2hDLFVBQVEsc0JBQXNCO0FBQ2hDO0FBZ0JPLE1BQU0sZUFBZSxDQUFDLFFBQXdCLElBQUksUUFBUSw2Q0FBNkMsRUFBRTtBQUV6RyxNQUFNLGNBQWMsQ0FBQyxTQUFzQixPQUMvQyxLQUFLLElBQUksRUFDVCxJQUFJLENBQUMsUUFBZ0IsR0FBRyxtQkFBbUIsR0FBRyxDQUFDLElBQUksbUJBQW1CLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssR0FBRztBQUd4RixNQUFNLE9BQU8sQ0FBQyxLQUFhLFFBQWdCLFFBQVMsVUFBNkIsQ0FBQyxNQUFvQjtBQUMzRyxRQUFNLEVBQUMsU0FBUyxNQUFLLElBQUk7QUFFekIsTUFBSSxhQUFxQixPQUFPLElBQUksS0FBSztBQUN6QyxR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
1
+ import{ApiError as l}from"./errors/ApiError.js";import{ApiError as B}from"./errors/ApiError.js";const v=e=>Array.isArray(e),q=e=>typeof e=="string",P=e=>e!==null&&typeof e=="object"&&!v(e),H=e=>e==null||e==="",C=e=>e===null,R=e=>e===void 0,w=/application\/json/i,S=new Map,A=e=>e.replace(/\s+(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/gm,""),J=e=>Object.keys(e).map(r=>`${encodeURIComponent(r)}=${encodeURIComponent(e[r])}`).join("&"),x=e=>new Promise((r,t)=>setTimeout(()=>t(new Error("Request timeout")),e)),O=(e,r,t,i)=>{const a=JSON.stringify({method:r,options:i,params:t,url:e});return btoa(a).slice(0,50)},N=(e,r)=>{if(typeof EventSource<"u")return new EventSource(e);throw new Error('EventSource not available in this environment. For Node.js support, install the "eventsource" package and import it manually.')},T=(e,r,t,i={})=>{const{headers:a,token:c,timeout:m=3e4,cache:f=!1}=i;let p=(e||"").trim();const d=(c||"").trim(),n=a||new Headers,u=(r||"GET").toUpperCase();let s;if(t&&u==="GET"?(p=`${p}?${J(t)}`,s=null):t?(n.set("Accept","application/json"),n.set("Content-Type","application/json"),s=JSON.stringify(t)):s=t,H(d)||n.set("Authorization",`Bearer ${d}`),f&&u==="GET"){const o=O(p,u,t,i),E=S.get(o);if(E)return E}const y=fetch(p,{body:s,headers:n,method:u}).then(o=>w.test(o.headers.get("Content-Type")||"")?o.json():o.text()).then(o=>o).catch(o=>(o||{}).message==="only absolute urls are supported"?Promise.reject(new l([{message:"invalid_url"}],o)):Promise.reject(new l([{message:"network_error"}],o))),g=m>0?Promise.race([y,x(m)]):y;if(f&&u==="GET"){const o=O(p,u,t,i);S.set(o,g),setTimeout(()=>S.delete(o),3e5)}return g},j=(e,r,t)=>T(e,"GET",r,t),b=(e,r,t)=>T(e,"POST",r,t),U=(e,r,t)=>T(e,"PUT",r,t),G=(e,r,t)=>T(e,"DELETE",r,t),h=e=>{if(q(e))return JSON.stringify(e);if(P(e)){const r=[];for(const i in e)if(e.hasOwnProperty(i)){const a=e[i];if(R(a)||C(a))continue;if(P(a))r.push(`${i}: ${h(a)}`);else if(v(a)){const c=a.map(m=>h(m));r.push(`${i}: [${c.join(", ")}]`)}else{const c=JSON.stringify(a);c&&r.push(`${i}: ${c}`)}}return r.join(", ")===""?'""':`{${r.join(", ")}}`}else if(v(e))return`[${e.map(r=>h(r)).join(", ")}]`;return String(e)},$=(e,r,t={})=>{const{headers:i,token:a,timeout:c=3e4}=t,m=e?e.trim():"",f=(a||"").trim(),p=i||new Headers({"Content-Type":"application/json"});H(f)||p.set("Authorization",`Bearer ${f}`);const d=fetch(m,{body:JSON.stringify(r),headers:p,method:"post"}).then(n=>w.test(n.headers.get("Content-Type")||"")&&n.body?n.json():null).catch(n=>(n||{}).message==="only absolute urls are supported"?Promise.reject(new l([{message:"invalid_url"}],n)):Promise.reject(new l([{message:"network_error"}],n))).then(n=>{if(!n||n.errors){if(n){if((n.errors||[]).some(u=>u.message==="Must provide query string."))return Promise.reject(new l([{message:"required_query"}],new Error))}else return Promise.reject(new l([{message:"api_error"}],new Error));return n.errors?Promise.reject(new l(n.errors,new Error)):{}}return n.data||{}}).catch(n=>Promise.reject(n.source?n:new l([{message:"network_error"}],n)));return c>0?Promise.race([d,x(c)]):d},I=(e,r,t={})=>$(e,{query:r},t),M=(e,r,t={})=>$(e,{query:r},t),Q=(e,r,t={})=>{const{headers:i,token:a,timeout:c=3e4,retryInterval:m=1e3,maxRetries:f=5}=t,p=(e||"").trim(),d=(a||"").trim(),n=i||new Headers;H(d)||n.set("Authorization",`Bearer ${d}`);let u=0,s=null,y=null;const g=()=>{try{s=N(p,{headers:n}),c>0&&(y=setTimeout(()=>{s&&(s.close(),r.onError&&r.onError(new Error("SSE connection timeout")))},c)),s.onopen=o=>{y&&(clearTimeout(y),y=null),u=0,r.onOpen&&r.onOpen(o)},s.onmessage=o=>{if(r.onMessage){const E={data:o.data,id:o.lastEventId,retry:o.data.includes("retry:")?parseInt(o.data.split("retry:")[1]):void 0,type:o.type};r.onMessage(E)}},s.onerror=o=>{y&&(clearTimeout(y),y=null),s&&s.readyState===EventSource.CLOSED?u<f?(u++,r.onRetry&&r.onRetry(u,m),setTimeout(g,m)):r.onError&&r.onError(new Error("SSE connection failed after max retries")):r.onError&&r.onError(o)}}catch(o){r.onError&&r.onError(o instanceof Error?o:new Error("Failed to create SSE connection"))}};return g(),()=>{y&&(clearTimeout(y),y=null),s&&(s.close(),s=null)}};export{B as ApiError,T as ajax,G as del,j as get,$ as graphqlQuery,M as mutation,b as post,U as put,I as query,J as queryString,A as removeSpaces,Q as subscribeSSE,h as toGql};
2
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuXG5pbXBvcnQge0FwaUVycm9yfSBmcm9tICcuL2Vycm9ycy9BcGlFcnJvci5qcyc7XG5cbmNvbnN0IGlzQXJyYXkgPSAodmFsdWU6IGFueSk6IHZhbHVlIGlzIGFueVtdID0+IEFycmF5LmlzQXJyYXkodmFsdWUpO1xuY29uc3QgaXNTdHJpbmcgPSAodmFsdWU6IGFueSk6IHZhbHVlIGlzIHN0cmluZyA9PiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnO1xuY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWx1ZTogYW55KTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgYW55PiA9PlxuICB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICFpc0FycmF5KHZhbHVlKTtcbmNvbnN0IGlzRW1wdHkgPSAodmFsdWU6IGFueSk6IGJvb2xlYW4gPT5cbiAgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJyc7XG5jb25zdCBpc051bGwgPSAodmFsdWU6IGFueSk6IGJvb2xlYW4gPT4gdmFsdWUgPT09IG51bGw7XG5jb25zdCBpc1VuZGVmaW5lZCA9ICh2YWx1ZTogYW55KTogYm9vbGVhbiA9PiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuXG4vLyBDYWNoZSBmb3IgY29tcGlsZWQgcmVnZXggcGF0dGVybnNcbmNvbnN0IEpTT05fQ09OVEVOVF9UWVBFX1JFR0VYID0gL2FwcGxpY2F0aW9uXFwvanNvbi9pO1xuXG4vLyBSZXF1ZXN0IGNhY2hlIGZvciBkZWR1cGxpY2F0aW9uXG5jb25zdCByZXF1ZXN0Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxhbnk+PigpO1xuXG5leHBvcnQgaW50ZXJmYWNlIEh1bnRlck9wdGlvbnNUeXBlIHtcbiAgcmVhZG9ubHkgaGVhZGVycz86IEhlYWRlcnM7XG4gIHJlYWRvbmx5IHRva2VuPzogc3RyaW5nO1xuICByZWFkb25seSB2YXJpYWJsZXM/OiBhbnk7XG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNhY2hlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJRdWVyeVR5cGUge1xuICByZWFkb25seSBxdWVyeTogc3RyaW5nO1xuICByZWFkb25seSB2YXJpYWJsZXM/OiBhbnk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSHVudGVyU1NFT3B0aW9uc1R5cGUge1xuICByZWFkb25seSBoZWFkZXJzPzogSGVhZGVycztcbiAgcmVhZG9ubHkgdG9rZW4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHJldHJ5SW50ZXJ2YWw/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heFJldHJpZXM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSHVudGVyU1NFRXZlbnRUeXBlIHtcbiAgcmVhZG9ubHkgZGF0YTogc3RyaW5nO1xuICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuICByZWFkb25seSByZXRyeT86IG51bWJlciB8IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIdW50ZXJTU0VDYWxsYmFja1R5cGUge1xuICBvbk1lc3NhZ2U/OiAoZXZlbnQ6IEh1bnRlclNTRUV2ZW50VHlwZSkgPT4gdm9pZDtcbiAgb25PcGVuPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcbiAgb25FcnJvcj86IChlcnJvcjogRXJyb3IgfCBFdmVudCkgPT4gdm9pZDtcbiAgb25SZXRyeT86IChhdHRlbXB0OiBudW1iZXIsIGRlbGF5OiBudW1iZXIpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCByZW1vdmVTcGFjZXMgPSAoc3RyOiBzdHJpbmcpOiBzdHJpbmcgPT5cbiAgc3RyLnJlcGxhY2UoL1xccysoPz0oPzpbXidcIl0qWydcIl1bXidcIl0qWydcIl0pKlteJ1wiXSokKS9nbSwgJycpO1xuXG5leHBvcnQgY29uc3QgcXVlcnlTdHJpbmcgPSAoanNvbjogYW55KTogc3RyaW5nID0+XG4gIE9iamVjdC5rZXlzKGpzb24pXG4gICAgLm1hcChcbiAgICAgIChrZXk6IHN0cmluZykgPT5cbiAgICAgICAgYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KGpzb25ba2V5XSl9YFxuICAgIClcbiAgICAuam9pbignJicpO1xuXG4vLyBDcmVhdGUgYSB0aW1lb3V0IHByb21pc2VcbmNvbnN0IGNyZWF0ZVRpbWVvdXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8bmV2ZXI+ID0+XG4gIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+XG4gICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKCdSZXF1ZXN0IHRpbWVvdXQnKSksIG1zKVxuICApO1xuXG4vLyBHZW5lcmF0ZSBjYWNoZSBrZXkgZm9yIHJlcXVlc3QgZGVkdXBsaWNhdGlvblxuY29uc3QgZ2VuZXJhdGVDYWNoZUtleSA9ICh1cmw6IHN0cmluZywgbWV0aG9kOiBzdHJpbmcsIHBhcmFtcz86IGFueSwgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlKTogc3RyaW5nID0+IHtcbiAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkoe21ldGhvZCwgb3B0aW9ucywgcGFyYW1zLCB1cmx9KTtcbiAgcmV0dXJuIGJ0b2Eoa2V5KS5zbGljZSgwLCA1MCk7IC8vIFRydW5jYXRlIHRvIHJlYXNvbmFibGUgbGVuZ3RoXG59O1xuXG4vLyBTU0UgRXZlbnRTb3VyY2UgcG9seWZpbGwgZm9yIE5vZGUuanNcbmNvbnN0IGNyZWF0ZUV2ZW50U291cmNlID0gKHVybDogc3RyaW5nLCBvcHRpb25zPzogSHVudGVyU1NFT3B0aW9uc1R5cGUpOiBFdmVudFNvdXJjZSA9PiB7XG4gIGlmKHR5cGVvZiBFdmVudFNvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbmV3IEV2ZW50U291cmNlKHVybCk7XG4gIH1cblxuICAvLyBGb3IgTm9kZS5qcywgd2UnbGwgdGhyb3cgYW4gZXJyb3Igc3VnZ2VzdGluZyB0aGUgdXNlciBpbnN0YWxsIGV2ZW50c291cmNlXG4gIHRocm93IG5ldyBFcnJvcignRXZlbnRTb3VyY2Ugbm90IGF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50LiBGb3IgTm9kZS5qcyBzdXBwb3J0LCBpbnN0YWxsIHRoZSBcImV2ZW50c291cmNlXCIgcGFja2FnZSBhbmQgaW1wb3J0IGl0IG1hbnVhbGx5LicpO1xufTtcblxuLy8gQUpBWFxuZXhwb3J0IGNvbnN0IGFqYXggPSAoXG4gIHVybDogc3RyaW5nLFxuICBtZXRob2Q6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9uczogSHVudGVyT3B0aW9uc1R5cGUgPSB7fVxuKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgY29uc3Qge2hlYWRlcnMsIHRva2VuLCB0aW1lb3V0ID0gMzAwMDAsIGNhY2hlID0gZmFsc2V9ID0gb3B0aW9ucztcblxuICBsZXQgZm9ybWF0VXJsOiBzdHJpbmcgPSAodXJsIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdFRva2VuOiBzdHJpbmcgPSAodG9rZW4gfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0SGVhZGVyczogSGVhZGVycyA9IGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoKTtcblxuICAvLyBNZXRob2RcbiAgY29uc3QgZm9ybWF0TWV0aG9kOiBzdHJpbmcgPSAobWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpO1xuICBsZXQgZm9ybWF0UGFyYW1zO1xuXG4gIC8vIFBhcmFtZXRlcnNcbiAgaWYocGFyYW1zICYmIGZvcm1hdE1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICBmb3JtYXRVcmwgPSBgJHtmb3JtYXRVcmx9PyR7cXVlcnlTdHJpbmcocGFyYW1zKX1gO1xuICAgIGZvcm1hdFBhcmFtcyA9IG51bGw7XG4gIH0gZWxzZSBpZihwYXJhbXMpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICBmb3JtYXRQYXJhbXMgPSBKU09OLnN0cmluZ2lmeShwYXJhbXMpO1xuICB9IGVsc2Uge1xuICAgIGZvcm1hdFBhcmFtcyA9IHBhcmFtcztcbiAgfVxuXG4gIC8vIEF1dGhlbnRpY2F0aW9uIHRva2VuXG4gIGlmKCFpc0VtcHR5KGZvcm1hdFRva2VuKSkge1xuICAgIGZvcm1hdEhlYWRlcnMuc2V0KCdBdXRob3JpemF0aW9uJywgYEJlYXJlciAke2Zvcm1hdFRva2VufWApO1xuICB9XG5cbiAgLy8gQ2hlY2sgY2FjaGUgZm9yIEdFVCByZXF1ZXN0c1xuICBpZihjYWNoZSAmJiBmb3JtYXRNZXRob2QgPT09ICdHRVQnKSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBnZW5lcmF0ZUNhY2hlS2V5KGZvcm1hdFVybCwgZm9ybWF0TWV0aG9kLCBwYXJhbXMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGNhY2hlZCA9IHJlcXVlc3RDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIGlmKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgdGhlIHJlcXVlc3QgcHJvbWlzZVxuICBjb25zdCByZXF1ZXN0UHJvbWlzZSA9IGZldGNoKGZvcm1hdFVybCwge1xuICAgIGJvZHk6IGZvcm1hdFBhcmFtcyxcbiAgICBoZWFkZXJzOiBmb3JtYXRIZWFkZXJzLFxuICAgIG1ldGhvZDogZm9ybWF0TWV0aG9kXG4gIH0pXG4gICAgLnRoZW4oKHJlc3BvbnNlOiBSZXNwb25zZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgcmVzcG9uc2UgaXMganNvbiB1c2luZyBjYWNoZWQgcmVnZXhcbiAgICAgIGNvbnN0IGlzUmVzcG9uc2VKc29uID0gSlNPTl9DT05URU5UX1RZUEVfUkVHRVgudGVzdChcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpIHx8ICcnXG4gICAgICApO1xuXG4gICAgICBpZihpc1Jlc3BvbnNlSnNvbikge1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKHJlc3VsdHMpID0+IHJlc3VsdHMpIC8vIFNpbXBsaWZpZWQgLSBubyBuZWVkIGZvciByZWR1bmRhbnQgY2hlY2tcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpZigoZXJyb3IgfHwge30pLm1lc3NhZ2UgPT09ICdvbmx5IGFic29sdXRlIHVybHMgYXJlIHN1cHBvcnRlZCcpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgIG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICdpbnZhbGlkX3VybCd9XSwgZXJyb3IpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IEFwaUVycm9yKFt7bWVzc2FnZTogJ25ldHdvcmtfZXJyb3InfV0sIGVycm9yKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAvLyBBZGQgdGltZW91dCBpZiBzcGVjaWZpZWRcbiAgY29uc3QgZmluYWxQcm9taXNlID0gdGltZW91dCA+IDBcbiAgICA/IFByb21pc2UucmFjZShbcmVxdWVzdFByb21pc2UsIGNyZWF0ZVRpbWVvdXQodGltZW91dCldKVxuICAgIDogcmVxdWVzdFByb21pc2U7XG5cbiAgLy8gQ2FjaGUgdGhlIHByb21pc2UgZm9yIEdFVCByZXF1ZXN0c1xuICBpZihjYWNoZSAmJiBmb3JtYXRNZXRob2QgPT09ICdHRVQnKSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBnZW5lcmF0ZUNhY2hlS2V5KGZvcm1hdFVybCwgZm9ybWF0TWV0aG9kLCBwYXJhbXMsIG9wdGlvbnMpO1xuICAgIHJlcXVlc3RDYWNoZS5zZXQoY2FjaGVLZXksIGZpbmFsUHJvbWlzZSk7XG5cbiAgICAvLyBDbGVhbiB1cCBjYWNoZSBhZnRlciA1IG1pbnV0ZXNcbiAgICBzZXRUaW1lb3V0KCgpID0+IHJlcXVlc3RDYWNoZS5kZWxldGUoY2FjaGVLZXkpLCAzMDAwMDApO1xuICB9XG5cbiAgcmV0dXJuIGZpbmFsUHJvbWlzZTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXQgPSAoXG4gIHVybDogc3RyaW5nLFxuICBwYXJhbXM/LFxuICBvcHRpb25zPzogSHVudGVyT3B0aW9uc1R5cGVcbik6IFByb21pc2U8YW55PiA9PiBhamF4KHVybCwgJ0dFVCcsIHBhcmFtcywgb3B0aW9ucyk7XG5cbmV4cG9ydCBjb25zdCBwb3N0ID0gKFxuICB1cmw6IHN0cmluZyxcbiAgcGFyYW1zPyxcbiAgb3B0aW9ucz86IEh1bnRlck9wdGlvbnNUeXBlXG4pOiBQcm9taXNlPGFueT4gPT4gYWpheCh1cmwsICdQT1NUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IHB1dCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHBhcmFtcz8sXG4gIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZVxuKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnUFVUJywgcGFyYW1zLCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IGRlbCA9IChcbiAgdXJsOiBzdHJpbmcsXG4gIHBhcmFtcz8sXG4gIG9wdGlvbnM/OiBIdW50ZXJPcHRpb25zVHlwZVxuKTogUHJvbWlzZTxhbnk+ID0+IGFqYXgodXJsLCAnREVMRVRFJywgcGFyYW1zLCBvcHRpb25zKTtcblxuLy8gT3B0aW1pemVkIHRvR3FsIGZ1bmN0aW9uXG5leHBvcnQgY29uc3QgdG9HcWwgPSAob2JqOiBhbnkpOiBzdHJpbmcgPT4ge1xuICBpZihpc1N0cmluZyhvYmopKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9iaik7XG4gIH0gZWxzZSBpZihpc1BsYWluT2JqZWN0KG9iaikpIHtcbiAgICAvLyBGaWx0ZXIgb3V0IHVuZGVmaW5lZCBhbmQgbnVsbCB2YWx1ZXMgaW4gb25lIHBhc3NcbiAgICBjb25zdCBncWxQcm9wczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvcihjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgICBpZihvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBjb25zdCBpdGVtID0gb2JqW2tleV07XG5cbiAgICAgICAgLy8gU2tpcCB1bmRlZmluZWQgYW5kIG51bGwgdmFsdWVzXG4gICAgICAgIGlmKGlzVW5kZWZpbmVkKGl0ZW0pIHx8IGlzTnVsbChpdGVtKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoaXNQbGFpbk9iamVjdChpdGVtKSkge1xuICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogJHt0b0dxbChpdGVtKX1gKTtcbiAgICAgICAgfSBlbHNlIGlmKGlzQXJyYXkoaXRlbSkpIHtcbiAgICAgICAgICBjb25zdCBsaXN0ID0gaXRlbS5tYXAoKGxpc3RJdGVtKSA9PiB0b0dxbChsaXN0SXRlbSkpO1xuICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogWyR7bGlzdC5qb2luKCcsICcpfV1gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB2YWwgPSBKU09OLnN0cmluZ2lmeShpdGVtKTtcbiAgICAgICAgICBpZih2YWwpIHtcbiAgICAgICAgICAgIGdxbFByb3BzLnB1c2goYCR7a2V5fTogJHt2YWx9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gZ3FsUHJvcHMuam9pbignLCAnKTtcbiAgICByZXR1cm4gdmFsdWVzID09PSAnJyA/ICdcIlwiJyA6IGB7JHtncWxQcm9wcy5qb2luKCcsICcpfX1gO1xuICB9IGVsc2UgaWYoaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIGBbJHtvYmoubWFwKChvYmpJdGVtKSA9PiB0b0dxbChvYmpJdGVtKSkuam9pbignLCAnKX1dYDtcbiAgfVxuXG4gIHJldHVybiBTdHJpbmcob2JqKTtcbn07XG5cbmV4cG9ydCBjb25zdCBncmFwaHFsUXVlcnkgPSAoXG4gIHVybDogc3RyaW5nLFxuICBxdWVyeTogSHVudGVyUXVlcnlUeXBlIHwgSHVudGVyUXVlcnlUeXBlW10sXG4gIG9wdGlvbnM6IEh1bnRlck9wdGlvbnNUeXBlID0ge31cbik6IFByb21pc2U8YW55PiA9PiB7XG4gIGNvbnN0IHtoZWFkZXJzLCB0b2tlbiwgdGltZW91dCA9IDMwMDAwfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGZvcm1hdFVybDogc3RyaW5nID0gdXJsID8gdXJsLnRyaW0oKSA6ICcnO1xuICBjb25zdCBmb3JtYXRUb2tlbjogc3RyaW5nID0gKHRva2VuIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdEhlYWRlcnM6IEhlYWRlcnMgPVxuICAgIGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoeydDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbid9KTtcblxuICBpZighaXNFbXB0eShmb3JtYXRUb2tlbikpIHtcbiAgICBmb3JtYXRIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHtmb3JtYXRUb2tlbn1gKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3RQcm9taXNlID0gZmV0Y2goZm9ybWF0VXJsLCB7XG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkocXVlcnkpLFxuICAgIGhlYWRlcnM6IGZvcm1hdEhlYWRlcnMsXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgfSlcbiAgICAudGhlbigocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCBpc0pzb246IGJvb2xlYW4gPSBKU09OX0NPTlRFTlRfVFlQRV9SRUdFWC50ZXN0KFxuICAgICAgICByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJykgfHwgJydcbiAgICAgICk7XG5cbiAgICAgIGlmKGlzSnNvbiAmJiByZXNwb25zZS5ib2R5KSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgaWYoKGVycm9yIHx8IHt9KS5tZXNzYWdlID09PSAnb25seSBhYnNvbHV0ZSB1cmxzIGFyZSBzdXBwb3J0ZWQnKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnaW52YWxpZF91cmwnfV0sIGVycm9yKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIG5ldyBBcGlFcnJvcihbe21lc3NhZ2U6ICduZXR3b3JrX2Vycm9yJ31dLCBlcnJvcilcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbigoanNvbikgPT4ge1xuICAgICAgaWYoIWpzb24gfHwganNvbi5lcnJvcnMpIHtcbiAgICAgICAgaWYoIWpzb24pIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnYXBpX2Vycm9yJ31dLCBuZXcgRXJyb3IoKSlcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYoXG4gICAgICAgICAgKGpzb24uZXJyb3JzIHx8IFtdKS5zb21lKFxuICAgICAgICAgICAgKGVycm9yKSA9PiBlcnJvci5tZXNzYWdlID09PSAnTXVzdCBwcm92aWRlIHF1ZXJ5IHN0cmluZy4nXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAncmVxdWlyZWRfcXVlcnknfV0sIG5ldyBFcnJvcigpKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ganNvbi5lcnJvcnNcbiAgICAgICAgICA/IFByb21pc2UucmVqZWN0KG5ldyBBcGlFcnJvcihqc29uLmVycm9ycywgbmV3IEVycm9yKCkpKVxuICAgICAgICAgIDoge307XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBqc29uLmRhdGEgfHwge307XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yOiBBcGlFcnJvcikgPT5cbiAgICAgIC8vIFNpbXBsaWZpZWQgZXJyb3IgaGFuZGxpbmcgLSBubyBuZWVkIHRvIGNyZWF0ZSBuZXcgZXJyb3IgaWYgc291cmNlIGV4aXN0c1xuICAgICAgUHJvbWlzZS5yZWplY3QoZXJyb3Iuc291cmNlID8gZXJyb3IgOiBuZXcgQXBpRXJyb3IoW3ttZXNzYWdlOiAnbmV0d29ya19lcnJvcid9XSwgZXJyb3IpKVxuICAgICk7XG5cbiAgLy8gQWRkIHRpbWVvdXQgaWYgc3BlY2lmaWVkXG4gIHJldHVybiB0aW1lb3V0ID4gMFxuICAgID8gUHJvbWlzZS5yYWNlKFtyZXF1ZXN0UHJvbWlzZSwgY3JlYXRlVGltZW91dCh0aW1lb3V0KV0pXG4gICAgOiByZXF1ZXN0UHJvbWlzZTtcbn07XG5cbi8vIEFkZCBxdWVyeSBhbmQgbXV0YXRpb24gZnVuY3Rpb25zIGZvciBiZXR0ZXIgQVBJIGNvbnNpc3RlbmN5XG5leHBvcnQgY29uc3QgcXVlcnkgPSAoXG4gIHVybDogc3RyaW5nLFxuICBib2R5OiBzdHJpbmcsXG4gIG9wdGlvbnM6IEh1bnRlck9wdGlvbnNUeXBlID0ge31cbik6IFByb21pc2U8YW55PiA9PiBncmFwaHFsUXVlcnkodXJsLCB7cXVlcnk6IGJvZHl9LCBvcHRpb25zKTtcblxuZXhwb3J0IGNvbnN0IG11dGF0aW9uID0gKFxuICB1cmw6IHN0cmluZyxcbiAgYm9keTogc3RyaW5nLFxuICBvcHRpb25zOiBIdW50ZXJPcHRpb25zVHlwZSA9IHt9XG4pOiBQcm9taXNlPGFueT4gPT4gZ3JhcGhxbFF1ZXJ5KHVybCwge3F1ZXJ5OiBib2R5fSwgb3B0aW9ucyk7XG5cbi8vIFNTRSBTdXBwb3J0XG5leHBvcnQgY29uc3Qgc3Vic2NyaWJlU1NFID0gKFxuICB1cmw6IHN0cmluZyxcbiAgY2FsbGJhY2tzOiBIdW50ZXJTU0VDYWxsYmFja1R5cGUsXG4gIG9wdGlvbnM6IEh1bnRlclNTRU9wdGlvbnNUeXBlID0ge31cbik6ICgoKSA9PiB2b2lkKSA9PiB7XG4gIGNvbnN0IHtoZWFkZXJzLCB0b2tlbiwgdGltZW91dCA9IDMwMDAwLCByZXRyeUludGVydmFsID0gMTAwMCwgbWF4UmV0cmllcyA9IDV9ID0gb3B0aW9ucztcbiAgY29uc3QgZm9ybWF0VXJsOiBzdHJpbmcgPSAodXJsIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IGZvcm1hdFRva2VuOiBzdHJpbmcgPSAodG9rZW4gfHwgJycpLnRyaW0oKTtcbiAgY29uc3QgZm9ybWF0SGVhZGVyczogSGVhZGVycyA9IGhlYWRlcnMgfHwgbmV3IEhlYWRlcnMoKTtcblxuICAvLyBBZGQgYXV0aG9yaXphdGlvbiBoZWFkZXIgaWYgdG9rZW4gcHJvdmlkZWRcbiAgaWYoIWlzRW1wdHkoZm9ybWF0VG9rZW4pKSB7XG4gICAgZm9ybWF0SGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCBgQmVhcmVyICR7Zm9ybWF0VG9rZW59YCk7XG4gIH1cblxuICBsZXQgcmV0cnlDb3VudCA9IDA7XG4gIGxldCBldmVudFNvdXJjZTogRXZlbnRTb3VyY2UgfCBudWxsID0gbnVsbDtcbiAgbGV0IHRpbWVvdXRJZDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcblxuICBjb25zdCBjb25uZWN0ID0gKCk6IHZvaWQgPT4ge1xuICAgIHRyeSB7XG4gICAgICBldmVudFNvdXJjZSA9IGNyZWF0ZUV2ZW50U291cmNlKGZvcm1hdFVybCwge2hlYWRlcnM6IGZvcm1hdEhlYWRlcnN9KTtcblxuICAgICAgLy8gU2V0IHVwIHRpbWVvdXRcbiAgICAgIGlmKHRpbWVvdXQgPiAwKSB7XG4gICAgICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlmKGV2ZW50U291cmNlKSB7XG4gICAgICAgICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTU0UgY29ubmVjdGlvbiB0aW1lb3V0JykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgdGltZW91dCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV2ZW50IGhhbmRsZXJzXG4gICAgICBldmVudFNvdXJjZS5vbm9wZW4gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYodGltZW91dElkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgICAgdGltZW91dElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXRyeUNvdW50ID0gMDsgLy8gUmVzZXQgcmV0cnkgY291bnQgb24gc3VjY2Vzc2Z1bCBjb25uZWN0aW9uXG4gICAgICAgIGlmKGNhbGxiYWNrcy5vbk9wZW4pIHtcbiAgICAgICAgICBjYWxsYmFja3Mub25PcGVuKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgZXZlbnRTb3VyY2Uub25tZXNzYWdlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmKGNhbGxiYWNrcy5vbk1lc3NhZ2UpIHtcbiAgICAgICAgICBjb25zdCBzc2VFdmVudDogSHVudGVyU1NFRXZlbnRUeXBlID0ge1xuICAgICAgICAgICAgZGF0YTogZXZlbnQuZGF0YSxcbiAgICAgICAgICAgIGlkOiBldmVudC5sYXN0RXZlbnRJZCxcbiAgICAgICAgICAgIHJldHJ5OiBldmVudC5kYXRhLmluY2x1ZGVzKCdyZXRyeTonKSA/IHBhcnNlSW50KGV2ZW50LmRhdGEuc3BsaXQoJ3JldHJ5OicpWzFdKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGVcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNhbGxiYWNrcy5vbk1lc3NhZ2Uoc3NlRXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBldmVudFNvdXJjZS5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmKHRpbWVvdXRJZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZihldmVudFNvdXJjZSAmJiBldmVudFNvdXJjZS5yZWFkeVN0YXRlID09PSBFdmVudFNvdXJjZS5DTE9TRUQpIHtcbiAgICAgICAgICAvLyBDb25uZWN0aW9uIGNsb3NlZCwgYXR0ZW1wdCByZXRyeSBpZiB3aXRoaW4gbGltaXRzXG4gICAgICAgICAgaWYocmV0cnlDb3VudCA8IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgIHJldHJ5Q291bnQrKztcbiAgICAgICAgICAgIGlmKGNhbGxiYWNrcy5vblJldHJ5KSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrcy5vblJldHJ5KHJldHJ5Q291bnQsIHJldHJ5SW50ZXJ2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2V0VGltZW91dChjb25uZWN0LCByZXRyeUludGVydmFsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTU0UgY29ubmVjdGlvbiBmYWlsZWQgYWZ0ZXIgbWF4IHJldHJpZXMnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgIGNhbGxiYWNrcy5vbkVycm9yKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBTU0UgY29ubmVjdGlvbicpKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gU3RhcnQgdGhlIGNvbm5lY3Rpb25cbiAgY29ubmVjdCgpO1xuXG4gIC8vIFJldHVybiBjbGVhbnVwIGZ1bmN0aW9uXG4gIHJldHVybiAoKSA9PiB7XG4gICAgaWYodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgfVxuICAgIGlmKGV2ZW50U291cmNlKSB7XG4gICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgZXZlbnRTb3VyY2UgPSBudWxsO1xuICAgIH1cbiAgfTtcbn07XG5cbmV4cG9ydCB7QXBpRXJyb3J9IGZyb20gJy4vZXJyb3JzL0FwaUVycm9yLmpzJztcbiJdLAogICJtYXBwaW5ncyI6ICJBQUtBLE9BQVEsWUFBQUEsTUFBZSx1QkFxYnZCLE9BQVEsWUFBQUEsTUFBZSx1QkFuYnZCLE1BQU1DLEVBQVdDLEdBQStCLE1BQU0sUUFBUUEsQ0FBSyxFQUM3REMsRUFBWUQsR0FBZ0MsT0FBT0EsR0FBVSxTQUM3REUsRUFBaUJGLEdBQ3JCQSxJQUFVLE1BQVEsT0FBT0EsR0FBVSxVQUFZLENBQUNELEVBQVFDLENBQUssRUFDekRHLEVBQVdILEdBQ2ZB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QUFRRyxFQUFZRixDQUFhLEVBRTdDLFdBQVdLLEVBQVNMLENBQWEsR0FFOUJELEVBQVUsU0FDWEEsRUFBVSxRQUFRLElBQUksTUFBTSx5Q0FBeUMsQ0FBQyxFQUl2RUEsRUFBVSxTQUNYQSxFQUFVLFFBQVFPLENBQUssQ0FHN0IsQ0FDRixPQUFRMUIsRUFBTyxDQUNWbUIsRUFBVSxTQUNYQSxFQUFVLFFBQVFuQixhQUFpQixNQUFRQSxFQUFRLElBQUksTUFBTSxpQ0FBaUMsQ0FBQyxDQUVuRyxDQUNGLEVBR0EsT0FBQXlCLEVBQVEsRUFHRCxJQUFNLENBQ1JELElBQ0QsYUFBYUEsQ0FBUyxFQUN0QkEsRUFBWSxNQUVYRCxJQUNEQSxFQUFZLE1BQU0sRUFDbEJBLEVBQWMsS0FFbEIsQ0FDRiIsCiAgIm5hbWVzIjogWyJBcGlFcnJvciIsICJpc0FycmF5IiwgInZhbHVlIiwgImlzU3RyaW5nIiwgImlzUGxhaW5PYmplY3QiLCAiaXNFbXB0eSIsICJpc051bGwiLCAiaXNVbmRlZmluZWQiLCAiSlNPTl9DT05URU5UX1RZUEVfUkVHRVgiLCAicmVxdWVzdENhY2hlIiwgInJlbW92ZVNwYWNlcyIsICJzdHIiLCAicXVlcnlTdHJpbmciLCAianNvbiIsICJrZXkiLCAiY3JlYXRlVGltZW91dCIsICJtcyIsICJfIiwgInJlamVjdCIsICJnZW5lcmF0ZUNhY2hlS2V5IiwgInVybCIsICJtZXRob2QiLCAicGFyYW1zIiwgIm9wdGlvbnMiLCAiY3JlYXRlRXZlbnRTb3VyY2UiLCAiYWpheCIsICJoZWFkZXJzIiwgInRva2VuIiwgInRpbWVvdXQiLCAiY2FjaGUiLCAiZm9ybWF0VXJsIiwgImZvcm1hdFRva2VuIiwgImZvcm1hdEhlYWRlcnMiLCAiZm9ybWF0TWV0aG9kIiwgImZvcm1hdFBhcmFtcyIsICJjYWNoZUtleSIsICJjYWNoZWQiLCAicmVxdWVzdFByb21pc2UiLCAicmVzcG9uc2UiLCAicmVzdWx0cyIsICJlcnJvciIsICJmaW5hbFByb21pc2UiLCAiZ2V0IiwgInBvc3QiLCAicHV0IiwgImRlbCIsICJ0b0dxbCIsICJvYmoiLCAiZ3FsUHJvcHMiLCAiaXRlbSIsICJsaXN0IiwgImxpc3RJdGVtIiwgInZhbCIsICJvYmpJdGVtIiwgImdyYXBocWxRdWVyeSIsICJxdWVyeSIsICJib2R5IiwgIm11dGF0aW9uIiwgInN1YnNjcmliZVNTRSIsICJjYWxsYmFja3MiLCAicmV0cnlJbnRlcnZhbCIsICJtYXhSZXRyaWVzIiwgInJldHJ5Q291bnQiLCAiZXZlbnRTb3VyY2UiLCAidGltZW91dElkIiwgImNvbm5lY3QiLCAiZXZlbnQiLCAic3NlRXZlbnQiXQp9Cg==
package/package.json CHANGED
@@ -1,11 +1,29 @@
1
1
  {
2
2
  "name": "@nlabs/rip-hunter",
3
- "version": "2.6.4",
3
+ "version": "3.0.2",
4
4
  "description": "JS utilities for AJAX and GraphQL",
5
5
  "license": "MIT",
6
+ "type": "module",
6
7
  "main": "./lib/index.js",
7
8
  "module": "./lib/index.js",
8
9
  "types": "./lib/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./lib/index.d.ts",
13
+ "import": "./lib/index.js",
14
+ "require": "./lib/index.js"
15
+ },
16
+ "./errors": {
17
+ "types": "./lib/errors/ApiError.d.ts",
18
+ "import": "./lib/errors/ApiError.js",
19
+ "require": "./lib/errors/ApiError.js"
20
+ },
21
+ "./errors/ApiError": {
22
+ "types": "./lib/errors/ApiError.d.ts",
23
+ "import": "./lib/errors/ApiError.js",
24
+ "require": "./lib/errors/ApiError.js"
25
+ }
26
+ },
9
27
  "keywords": [
10
28
  "ajax",
11
29
  "api",
@@ -33,7 +51,7 @@
33
51
  "scripts": {
34
52
  "build": "lex compile --remove",
35
53
  "clean": "lex clean",
36
- "lint": "eslint ./src --ext .ts,.tsx",
54
+ "lint": "lex lint --fix",
37
55
  "prepublishOnly": "npm run lint && npm run test && npm run build",
38
56
  "pretest": "stage=test npm run lint",
39
57
  "publish:major": "npm version major && npm run publish:tags && npm publish",
@@ -42,18 +60,18 @@
42
60
  "publish:tags": "git push --tags && git push origin HEAD",
43
61
  "test": "lex test",
44
62
  "update": "lex update --interactive",
45
- "watch": "lex compile --remove -watch"
63
+ "watch": "lex compile --remove -watch",
64
+ "benchmark": "node --experimental-modules ./benchmark.js"
46
65
  },
47
- "dependencies": {
48
- "cross-fetch": "4.0.0",
49
- "lodash": "4.17.21"
66
+ "optionalDependencies": {
67
+ "eventsource": "^2.0.2"
50
68
  },
51
69
  "devDependencies": {
70
+ "@jest/globals": "30.0.4",
71
+ "@nlabs/lex": "1.47.2",
52
72
  "@nlabs/fetch-mock": "1.0.2",
53
- "@types/jest": "29.5.11",
54
- "@types/node": "20.11.8",
55
- "eslint": "8.56.0",
56
- "eslint-config-styleguidejs": "3.2.1",
57
- "typescript": "5.3.3"
73
+ "@types/jest": "30.0.0",
74
+ "@types/node": "24.0.12",
75
+ "typescript": "5.8.3"
58
76
  }
59
77
  }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "skipLibCheck": true
5
+ },
6
+ "include": [
7
+ "./src/**/*.ts",
8
+ "./src/**/*.tsx"
9
+ ],
10
+ "exclude": [
11
+ "lib",
12
+ "./node_modules",
13
+ "./src/**/*.test.ts",
14
+ "./src/**/*.test.tsx"
15
+ ]
16
+ }
package/tsconfig.json CHANGED
@@ -5,40 +5,51 @@
5
5
  "declaration": true,
6
6
  "emitDeclarationOnly": true,
7
7
  "esModuleInterop": true,
8
+ "exactOptionalPropertyTypes": true,
9
+ "forceConsistentCasingInFileNames": true,
8
10
  "inlineSourceMap": true,
11
+ "isolatedModules": true,
12
+ "jsx": "react-jsx",
9
13
  "lib": [
14
+ "esnext",
10
15
  "dom",
11
- "es2015",
12
- "es5",
13
- "es6",
14
- "es7",
15
- "esnext"
16
+ "dom.iterable"
16
17
  ],
17
- "module": "commonjs",
18
+ "module": "esnext",
18
19
  "moduleResolution": "node",
20
+ "noImplicitAny": false,
21
+ "noImplicitOverride": false,
19
22
  "noImplicitReturns": true,
20
23
  "noImplicitThis": true,
24
+ "noUncheckedIndexedAccess": false,
21
25
  "noUnusedLocals": true,
22
- "outDir": "./lib",
23
- "removeComments": true,
24
- "skipLibCheck": true,
25
- "target": "ES5",
26
+ "outDir": "lib",
27
+ "pretty": true,
28
+ "resolveJsonModule": true,
29
+ "skipLibCheck": false,
30
+ "strict": false,
31
+ "strictFunctionTypes": true,
32
+ "strictNullChecks": true,
33
+ "target": "ES2022",
26
34
  "typeRoots": [
35
+ "../../node_modules/@types",
27
36
  "node_modules/@types",
28
37
  "node_modules/json-d-ts"
29
38
  ],
30
39
  "types": [
31
40
  "jest",
32
41
  "node"
33
- ]
42
+ ],
43
+ "useDefineForClassFields": true,
44
+ "verbatimModuleSyntax": true
34
45
  },
35
- "include": [
36
- "./src/**/*"
37
- ],
38
46
  "exclude": [
39
- "**/*.test.*",
40
- "./lib",
41
- "./node_modules",
42
- "./test"
47
+ "node_modules",
48
+ "lib",
49
+ "benchmark.js",
50
+ "index.js"
51
+ ],
52
+ "include": [
53
+ "src/**/*"
43
54
  ]
44
55
  }
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noImplicitAny": false,
5
+ "noImplicitThis": false,
6
+ "noUncheckedIndexedAccess": false,
7
+ "noUnusedLocals": false,
8
+ "skipLibCheck": false,
9
+ "strict": false,
10
+ "types": [
11
+ "jest",
12
+ "node"
13
+ ],
14
+ },
15
+ "include": [
16
+ "./src/**/*.ts",
17
+ "./src/**/*.tsx",
18
+ "./src/**/*.test.ts",
19
+ "./src/**/*.test.tsx"
20
+ ],
21
+ "exclude": [
22
+ "lib",
23
+ "./node_modules"
24
+ ]
25
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": [
4
+ "src/**/*.test.ts",
5
+ "src/**/*.test.tsx",
6
+ "src/**/*.spec.ts",
7
+ "src/**/*.spec.tsx"
8
+ ],
9
+ "compilerOptions": {
10
+ "types": [
11
+ "jest"
12
+ ]
13
+ }
14
+ }
package/.eslintrc DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "extends": [
3
- "styleguidejs/typescript"
4
- ]
5
- }