@nlabs/rip-hunter 2.6.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,211 +1,351 @@
1
- ![rip-hunter](https://nitrogenlabs.com/logos/gh-rip-hunter.png "rip-hunter")
1
+ # rip-hunter
2
2
 
3
- #### JS utilities for GraphQL
3
+ **Universal REST & GraphQL Client for Modern JavaScript/TypeScript Projects**
4
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.
5
+ ---
6
+
7
+ **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.
7
8
 
8
9
  [![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
10
  [![npm downloads](https://img.shields.io/npm/dm/rip-hunter.svg?style=flat-square)](https://www.npmjs.com/package/rip-hunter)
11
- [![Issues](http://img.shields.io/github/issues/nitrogenlabs/rip-hunter.svg?style=flat-square)](https://github.com/nitrogenlabs/rip-hunter/issues)
12
11
  [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](http://opensource.org/licenses/MIT)
13
12
 
14
- ### Installation
13
+ ---
14
+
15
+ ## 🚀 Why rip-hunter?
16
+
17
+ - **Unified API**: One package for both REST and GraphQL endpoints
18
+ - **ESM & TypeScript Native**: Modern, type-safe, and tree-shakable
19
+ - **Works Everywhere**: Node, browser, serverless—no config needed
20
+ - **Built-in Auth & Headers**: Effortlessly add tokens and custom headers
21
+ - **Automatic Error Handling**: Consistent, developer-friendly errors
22
+ - **Tiny & Fast**: Minimal dependencies, zero bloat
23
+ - **Request Caching**: Built-in caching for GET requests
24
+ - **Timeout Support**: Configurable request timeouts
25
+ - **Request Deduplication**: Prevents duplicate requests
26
+ - **Real-time Updates**: Server-Sent Events (SSE) support
27
+
28
+ ---
29
+
30
+ ## 📦 Installation
31
+
32
+ ```bash
33
+ npm install @nlabs/rip-hunter
34
+ # or
35
+ yarn add @nlabs/rip-hunter
36
+
37
+ # For Node.js SSE support (optional)
38
+ npm install eventsource
39
+ ```
15
40
 
16
- Using [npm](https://www.npmjs.com/):
41
+ ---
17
42
 
18
- $ npm install @nlabs/rip-hunter
43
+ ## Quick Start
19
44
 
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:
45
+ ### REST Example
22
46
 
23
47
  ```js
24
- import {query} from '@nlabs/rip-hunter';
48
+ import { get, post } from '@nlabs/rip-hunter';
49
+
50
+ const url = 'https://api.example.com/data';
51
+
52
+ // GET request with caching
53
+ const data = await get(url, { userId: 123 }, { cache: true });
54
+
55
+ // POST request with auth token and timeout
56
+ const result = await post(url, { name: 'Rip Hunter' }, {
57
+ token: 'your_jwt_token',
58
+ timeout: 5000
59
+ });
25
60
  ```
26
61
 
27
- ### How to use
62
+ ### GraphQL Example
63
+
64
+ ```js
65
+ import { query, mutation, toGql } from '@nlabs/rip-hunter';
66
+
67
+ const url = 'https://api.example.com/graphql';
68
+ const gql = '{ user { id name } }';
28
69
 
29
- **Example:**
70
+ // Query with timeout
71
+ const userData = await query(url, gql, { timeout: 10000 });
72
+
73
+ // Mutation with variables
74
+ const input = { name: 'Rip Hunter' };
75
+ const mutationGql = `mutation { createUser(input: ${toGql(input)}) { id name } }`;
76
+ const created = await mutation(url, mutationGql, { timeout: 5000 });
77
+ ```
78
+
79
+ ### SSE Example
30
80
 
31
81
  ```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
- },
82
+ import { subscribeSSE } from '@nlabs/rip-hunter';
51
83
 
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
- });
84
+ // Subscribe to real-time updates
85
+ const unsubscribe = subscribeSSE('https://api.example.com/stream', {
86
+ onMessage: (event) => {
87
+ console.log('Received:', event.data);
88
+ },
89
+ onError: (error) => {
90
+ console.error('SSE Error:', error);
91
+ },
92
+ onOpen: () => {
93
+ console.log('SSE connection opened');
68
94
  }
69
- }
70
-
95
+ }, {
96
+ token: 'your_jwt_token',
97
+ timeout: 30000,
98
+ retryInterval: 1000,
99
+ maxRetries: 5
100
+ });
101
+
102
+ // Later, to stop listening:
103
+ unsubscribe();
71
104
  ```
72
105
 
73
- ## API
106
+ ---
74
107
 
75
- ### Formatting
108
+ ## 🛠️ API Reference
76
109
 
77
- #### `toGql(data)`
110
+ ### REST Functions
111
+
112
+ #### `ajax(url, method, params?, options?)`
113
+
114
+ Low-level HTTP request for any method.
78
115
 
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.
116
+ - **url**: `string` Absolute URL
117
+ - **method**: `string` HTTP method (GET, POST, etc.)
118
+ - **params**: `object` – Data to send (query for GET, body for others)
119
+ - **options**: `{ headers?, token?, timeout?, cache? }`
120
+ - **Returns**: `Promise<any>`
81
121
 
82
- * [`data`] \(* Any *): An immutable object, JSON object, string or number to format for use with a GQL request.
122
+ #### `get(url, params?, options?)`
83
123
 
84
- ##### Returns
124
+ HTTP GET request.
85
125
 
86
- A string formatted for use with GQL.
126
+ - **url**: `string`
127
+ - **params**: `object`
128
+ - **options**: `{ headers?, token?, timeout?, cache? }`
129
+ - **Returns**: `Promise<any>`
87
130
 
131
+ #### `post(url, params?, options?)`
88
132
 
89
- ### Events
133
+ HTTP POST request.
90
134
 
91
- #### `on(eventType, data)`
135
+ - **url**: `string`
136
+ - **params**: `object`
137
+ - **options**: `{ headers?, token?, timeout? }`
138
+ - **Returns**: `Promise<any>`
92
139
 
93
- Adds an event listener. The only event emitted is when an error occurs. The error event is _rip_hunter_error_.
140
+ #### `put(url, params?, options?)`
94
141
 
95
- * [`eventType`] \(*String*): Event to subscribe for store updates.
96
- * [`listener`] \(*Function*): The callback to be invoked any time an action has been dispatched.
142
+ HTTP PUT request.
97
143
 
98
- #### `off(eventType, data)`
144
+ - **url**: `string`
145
+ - **params**: `object`
146
+ - **options**: `{ headers?, token?, timeout? }`
147
+ - **Returns**: `Promise<any>`
99
148
 
100
- Removes an event listener.
149
+ #### `del(url, params?, options?)`
101
150
 
102
- * [`eventType`] \(*String*): Event to unsubscribe.
103
- * [`listener`] \(*Function*): The callback associated with the subscribed event.
151
+ HTTP DELETE request.
104
152
 
153
+ - **url**: `string`
154
+ - **params**: `object`
155
+ - **options**: `{ headers?, token?, timeout? }`
156
+ - **Returns**: `Promise<any>`
105
157
 
106
- ### AJAX
158
+ ---
107
159
 
108
- #### `ajax(url, method, params, options)`
160
+ ### GraphQL Functions
109
161
 
110
- AJAX request.
162
+ #### `query(url, body, options?)`
111
163
 
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]_.
164
+ Send a GraphQL query.
118
165
 
119
- ##### Returns
166
+ - **url**: `string` – GraphQL endpoint
167
+ - **body**: `string` – GraphQL query string
168
+ - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }`
169
+ - **Returns**: `Promise<any>`
120
170
 
121
- A promise with either the response data or ApiError.
171
+ #### `mutation(url, body, options?)`
172
+
173
+ Send a GraphQL mutation.
174
+
175
+ - **url**: `string`
176
+ - **body**: `string`
177
+ - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }`
178
+ - **Returns**: `Promise<any>`
179
+
180
+ #### `graphqlQuery(url, query, options?)`
181
+
182
+ Low-level GraphQL request.
183
+
184
+ - **url**: `string` – GraphQL endpoint
185
+ - **query**: `HunterQueryType | HunterQueryType[]` – Query object(s)
186
+ - **options**: `{ headers?, token?, timeout? }`
187
+ - **Returns**: `Promise<any>`
188
+
189
+ #### `toGql(data)`
122
190
 
123
- #### `get(url, params, options)`
191
+ Convert JS objects, arrays, or primitives to GraphQL input strings.
124
192
 
125
- Server request using HTTP GET.
193
+ - **data**: `any`
194
+ - **Returns**: `string`
195
+ - **Example**:
126
196
 
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]_.
197
+ ```js
198
+ toGql({ name: 'Rip', age: 42 }) // => '{name: "Rip", age: 42}'
199
+ ```
132
200
 
133
- ##### Returns
201
+ ---
134
202
 
135
- A promise with either the response data or ApiError.
203
+ ### SSE Functions
136
204
 
137
- #### `post(url, params, options)`
205
+ #### `subscribeSSE(url, callbacks, options?)`
138
206
 
139
- Server request using HTTP POST.
207
+ Subscribe to Server-Sent Events.
140
208
 
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]_.
209
+ - **url**: `string` SSE endpoint URL
210
+ - **callbacks**: `HunterSSECallbackType` Event handlers
211
+ - `onMessage?: (event: HunterSSEEventType) => void`
212
+ - `onOpen?: (event: Event) => void`
213
+ - `onError?: (error: Error | Event) => void`
214
+ - `onRetry?: (attempt: number, delay: number) => void`
215
+ - **options**: `HunterSSEOptionsType` – Connection options
216
+ - `headers?: Headers`
217
+ - `token?: string`
218
+ - `timeout?: number` (default: 30000)
219
+ - `retryInterval?: number` (default: 1000)
220
+ - `maxRetries?: number` (default: 5)
221
+ - **Returns**: `() => void` – Cleanup function
146
222
 
147
- ##### Returns
223
+ #### `HunterSSEEventType`
148
224
 
149
- A promise with either the response data or ApiError.
225
+ SSE event object with:
150
226
 
151
- #### `put(url, params, options)`
227
+ - `data: string` – Event data
228
+ - `type: string` – Event type
229
+ - `id?: string` – Event ID
230
+ - `retry?: number` – Retry interval (if specified by server)
152
231
 
153
- Server request using HTTP PUT.
232
+ ---
154
233
 
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]_.
234
+ ### Events & Error Handling
160
235
 
161
- ##### Returns
236
+ #### `on(eventType, listener)`
162
237
 
163
- A promise with either the response data or ApiError.
238
+ Subscribe to events (e.g., error events).
164
239
 
165
- #### `del(url, params, options)`
240
+ - **eventType**: `string` (e.g., 'rip_hunter_error')
241
+ - **listener**: `Function`
166
242
 
167
- Server request using HTTP DEL.
243
+ #### `off(eventType, listener)`
168
244
 
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]_.
245
+ Unsubscribe from events.
246
+
247
+ #### `ApiError`
248
+
249
+ All errors are wrapped in a consistent `ApiError` object for easy handling.
250
+
251
+ - **.errors**: `string[]` – List of error messages
252
+ - **.source**: `Error` – Original error object
253
+
254
+ ---
255
+
256
+ ## 💡 Advanced Usage
257
+
258
+ ### Request Caching
259
+
260
+ ```js
261
+ // Cache GET requests for 5 minutes
262
+ const data = await get('/api/users', {}, { cache: true });
263
+ ```
264
+
265
+ ### Timeout Handling
266
+
267
+ ```js
268
+ // Set 10 second timeout
269
+ const result = await post('/api/data', payload, { timeout: 10000 });
270
+ ```
271
+
272
+ ### Custom Headers
273
+
274
+ ```js
275
+ const headers = new Headers({
276
+ 'X-Custom-Header': 'value',
277
+ 'Content-Type': 'application/json'
278
+ });
279
+
280
+ const data = await get('/api/data', {}, { headers });
281
+ ```
282
+
283
+ ### GraphQL Variables
284
+
285
+ ```js
286
+ const query = `
287
+ query GetUser($id: ID!) {
288
+ user(id: $id) { name email }
289
+ }
290
+ `;
291
+
292
+ const variables = { id: '123' };
293
+ const user = await query('/graphql', query, { variables });
294
+ ```
295
+
296
+ ### SSE with Authentication
297
+
298
+ ```js
299
+ const headers = new Headers({
300
+ 'Authorization': 'Bearer your-token',
301
+ 'Accept': 'text/event-stream'
302
+ });
303
+
304
+ const unsubscribe = subscribeSSE('/api/notifications', {
305
+ onMessage: (event) => {
306
+ const notification = JSON.parse(event.data);
307
+ console.log('New notification:', notification);
308
+ },
309
+ onError: (error) => {
310
+ console.error('SSE error:', error);
311
+ }
312
+ }, {
313
+ headers,
314
+ timeout: 60000,
315
+ maxRetries: 10
316
+ });
317
+ ```
174
318
 
175
- ##### Returns
319
+ ---
176
320
 
177
- A promise with either the response data or ApiError.
321
+ ## 🚀 Performance Features
178
322
 
179
- ### GraphQL
323
+ - **Request Deduplication**: Prevents duplicate requests to the same endpoint
324
+ - **Built-in Caching**: Automatic caching for GET requests with 5-minute TTL
325
+ - **Timeout Support**: Configurable request timeouts (default: 30s)
326
+ - **Optimized Functions**: Lightweight utility functions for better performance
327
+ - **Memory Efficient**: Minimal object creation and garbage collection
328
+ - **SSE Reconnection**: Automatic retry with exponential backoff for SSE connections
180
329
 
181
- #### `query(url, body, options)`
330
+ ---
182
331
 
183
- Queries a GraphQL server.
332
+ ## 🌐 Environment Support
184
333
 
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: {}.
334
+ - **Browser**: Full support for all features including SSE
335
+ - **Node.js**: Full REST/GraphQL support, SSE requires `eventsource` package
336
+ - **Serverless**: REST/GraphQL support (SSE not recommended in serverless)
192
337
 
193
- ##### Returns
338
+ ---
194
339
 
195
- A promise with either the response data or ApiError.
340
+ ## 🤝 Contributing
196
341
 
197
- #### `mutation(url, body, token, headers)`
342
+ PRs and issues welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
198
343
 
199
- Modifies data on a GraphQL server.
344
+ ## 📄 License
200
345
 
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: {}.
346
+ MIT © Nitrogen Labs, Inc.
208
347
 
209
- ##### Returns
348
+ ## 🔗 Links
210
349
 
211
- A promise with either the response data or ApiError.
350
+ - [GitHub](https://github.com/nitrogenlabs/rip-hunter)
351
+ - [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>;
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);
19
47
  export { ApiError } from './errors/ApiError';
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";import{ApiError as B}from"./errors/ApiError";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,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxNy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuXG5pbXBvcnQge0FwaUVycm9yfSBmcm9tICcuL2Vycm9ycy9BcGlFcnJvcic7XG5cbmNvbnN0IGlzQXJyYXkgPSAodmFsdWU6IGFueSk6IHZhbHVlIGlzIGFueVtdID0+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/IHBhcnNlSW50KGV2ZW50LmRhdGEuc3BsaXQoJ3JldHJ5OicpWzFdKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGVcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNhbGxiYWNrcy5vbk1lc3NhZ2Uoc3NlRXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBldmVudFNvdXJjZS5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmKHRpbWVvdXRJZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZihldmVudFNvdXJjZSAmJiBldmVudFNvdXJjZS5yZWFkeVN0YXRlID09PSBFdmVudFNvdXJjZS5DTE9TRUQpIHtcbiAgICAgICAgICAvLyBDb25uZWN0aW9uIGNsb3NlZCwgYXR0ZW1wdCByZXRyeSBpZiB3aXRoaW4gbGltaXRzXG4gICAgICAgICAgaWYocmV0cnlDb3VudCA8IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgIHJldHJ5Q291bnQrKztcbiAgICAgICAgICAgIGlmKGNhbGxiYWNrcy5vblJldHJ5KSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrcy5vblJldHJ5KHJldHJ5Q291bnQsIHJldHJ5SW50ZXJ2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2V0VGltZW91dChjb25uZWN0LCByZXRyeUludGVydmFsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYoY2FsbGJhY2tzLm9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzLm9uRXJyb3IobmV3IEVycm9yKCdTU0UgY29ubmVjdGlvbiBmYWlsZWQgYWZ0ZXIgbWF4IHJldHJpZXMnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgICAgICBjYWxsYmFja3Mub25FcnJvcihldmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGlmKGNhbGxiYWNrcy5vbkVycm9yKSB7XG4gICAgICAgIGNhbGxiYWNrcy5vbkVycm9yKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBTU0UgY29ubmVjdGlvbicpKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gU3RhcnQgdGhlIGNvbm5lY3Rpb25cbiAgY29ubmVjdCgpO1xuXG4gIC8vIFJldHVybiBjbGVhbnVwIGZ1bmN0aW9uXG4gIHJldHVybiAoKSA9PiB7XG4gICAgaWYodGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIHRpbWVvdXRJZCA9IG51bGw7XG4gICAgfVxuICAgIGlmKGV2ZW50U291cmNlKSB7XG4gICAgICBldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgZXZlbnRTb3VyY2UgPSBudWxsO1xuICAgIH1cbiAgfTtcbn07XG5cbmV4cG9ydCB7QXBpRXJyb3J9IGZyb20gJy4vZXJyb3JzL0FwaUVycm9yJztcbiJdLAogICJtYXBwaW5ncyI6ICJBQUtBLE9BQVEsWUFBQUEsTUFBZSxvQkFxYnZCLE9BQVEsWUFBQUEsTUFBZSxvQkFuYnZCLE1BQU1DLEVBQVdDLEdBQStCLE1BQU0sUUFBUUEsQ0FBSyxFQUM3REMsRUFBWUQsR0FBZ0MsT0FBT0EsR0FBVSxTQUM3REUsRUFBaUJGLEdBQ3JCQSxJQUFVLE1BQVEsT0FBT0EsR0FBVSxVQUFZLENBQUNELEVBQVFDLENBQUssRUFDekRHLEVBQVdILEdBQ2ZBLEdBQVUs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QUFZRixDQUFhLEVBRTdDLFdBQVdLLEVBQVNMLENBQWEsR0FFOUJELEVBQVUsU0FDWEEsRUFBVSxRQUFRLElBQUksTUFBTSx5Q0FBeUMsQ0FBQyxFQUl2RUEsRUFBVSxTQUNYQSxFQUFVLFFBQVFPLENBQUssQ0FHN0IsQ0FDRixPQUFRMUIsRUFBTyxDQUNWbUIsRUFBVSxTQUNYQSxFQUFVLFFBQVFuQixhQUFpQixNQUFRQSxFQUFRLElBQUksTUFBTSxpQ0FBaUMsQ0FBQyxDQUVuRyxDQUNGLEVBR0EsT0FBQXlCLEVBQVEsRUFHRCxJQUFNLENBQ1JELElBQ0QsYUFBYUEsQ0FBUyxFQUN0QkEsRUFBWSxNQUVYRCxJQUNEQSxFQUFZLE1BQU0sRUFDbEJBLEVBQWMsS0FFbEIsQ0FDRiIsCiAgIm5hbWVzIjogWyJBcGlFcnJvciIsICJpc0FycmF5IiwgInZhbHVlIiwgImlzU3RyaW5nIiwgImlzUGxhaW5PYmplY3QiLCAiaXNFbXB0eSIsICJpc051bGwiLCAiaXNVbmRlZmluZWQiLCAiSlNPTl9DT05URU5UX1RZUEVfUkVHRVgiLCAicmVxdWVzdENhY2hlIiwgInJlbW92ZVNwYWNlcyIsICJzdHIiLCAicXVlcnlTdHJpbmciLCAianNvbiIsICJrZXkiLCAiY3JlYXRlVGltZW91dCIsICJtcyIsICJfIiwgInJlamVjdCIsICJnZW5lcmF0ZUNhY2hlS2V5IiwgInVybCIsICJtZXRob2QiLCAicGFyYW1zIiwgIm9wdGlvbnMiLCAiY3JlYXRlRXZlbnRTb3VyY2UiLCAiYWpheCIsICJoZWFkZXJzIiwgInRva2VuIiwgInRpbWVvdXQiLCAiY2FjaGUiLCAiZm9ybWF0VXJsIiwgImZvcm1hdFRva2VuIiwgImZvcm1hdEhlYWRlcnMiLCAiZm9ybWF0TWV0aG9kIiwgImZvcm1hdFBhcmFtcyIsICJjYWNoZUtleSIsICJjYWNoZWQiLCAicmVxdWVzdFByb21pc2UiLCAicmVzcG9uc2UiLCAicmVzdWx0cyIsICJlcnJvciIsICJmaW5hbFByb21pc2UiLCAiZ2V0IiwgInBvc3QiLCAicHV0IiwgImRlbCIsICJ0b0dxbCIsICJvYmoiLCAiZ3FsUHJvcHMiLCAiaXRlbSIsICJsaXN0IiwgImxpc3RJdGVtIiwgInZhbCIsICJvYmpJdGVtIiwgImdyYXBocWxRdWVyeSIsICJxdWVyeSIsICJib2R5IiwgIm11dGF0aW9uIiwgInN1YnNjcmliZVNTRSIsICJjYWxsYmFja3MiLCAicmV0cnlJbnRlcnZhbCIsICJtYXhSZXRyaWVzIiwgInJldHJ5Q291bnQiLCAiZXZlbnRTb3VyY2UiLCAidGltZW91dElkIiwgImNvbm5lY3QiLCAiZXZlbnQiLCAic3NlRXZlbnQiXQp9Cg==
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@nlabs/rip-hunter",
3
- "version": "2.6.4",
3
+ "version": "3.0.0",
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",
@@ -33,7 +34,7 @@
33
34
  "scripts": {
34
35
  "build": "lex compile --remove",
35
36
  "clean": "lex clean",
36
- "lint": "eslint ./src --ext .ts,.tsx",
37
+ "lint": "lex lint --fix",
37
38
  "prepublishOnly": "npm run lint && npm run test && npm run build",
38
39
  "pretest": "stage=test npm run lint",
39
40
  "publish:major": "npm version major && npm run publish:tags && npm publish",
@@ -42,18 +43,18 @@
42
43
  "publish:tags": "git push --tags && git push origin HEAD",
43
44
  "test": "lex test",
44
45
  "update": "lex update --interactive",
45
- "watch": "lex compile --remove -watch"
46
+ "watch": "lex compile --remove -watch",
47
+ "benchmark": "node --experimental-modules ./benchmark.js"
46
48
  },
47
- "dependencies": {
48
- "cross-fetch": "4.0.0",
49
- "lodash": "4.17.21"
49
+ "optionalDependencies": {
50
+ "eventsource": "^2.0.2"
50
51
  },
51
52
  "devDependencies": {
53
+ "@jest/globals": "30.0.4",
54
+ "@nlabs/lex": "1.47.2",
52
55
  "@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"
56
+ "@types/jest": "30.0.0",
57
+ "@types/node": "24.0.12",
58
+ "typescript": "5.8.3"
58
59
  }
59
60
  }
@@ -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
- }