@discordeno/rest 21.0.1-next.fca0b40 → 22.0.0-beta.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/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/invalidBucket.d.ts.map +1 -0
- package/dist/invalidBucket.js +82 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +1844 -0
- package/dist/{types/queue.d.ts → queue.d.ts} +2 -2
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +190 -0
- package/dist/routes.d.ts +9 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +674 -0
- package/dist/{types/types.d.ts → types.d.ts} +462 -193
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/{types/typings → typings}/routes.d.ts +19 -1
- package/dist/typings/routes.d.ts.map +1 -0
- package/dist/typings/routes.js +3 -0
- package/package.json +27 -37
- package/dist/cjs/index.cjs +0 -25
- package/dist/cjs/invalidBucket.cjs +0 -86
- package/dist/cjs/manager.cjs +0 -1665
- package/dist/cjs/queue.cjs +0 -164
- package/dist/cjs/routes.cjs +0 -631
- package/dist/cjs/types.cjs +0 -6
- package/dist/cjs/typings/routes.cjs +0 -6
- package/dist/esm/index.js +0 -8
- package/dist/esm/invalidBucket.js +0 -82
- package/dist/esm/manager.js +0 -1623
- package/dist/esm/queue.js +0 -154
- package/dist/esm/routes.js +0 -621
- package/dist/esm/types.js +0 -3
- package/dist/esm/typings/routes.js +0 -3
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/invalidBucket.d.ts.map +0 -1
- package/dist/types/manager.d.ts.map +0 -1
- package/dist/types/queue.d.ts.map +0 -1
- package/dist/types/routes.d.ts +0 -3
- package/dist/types/routes.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/typings/routes.d.ts.map +0 -1
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/invalidBucket.d.ts → invalidBucket.d.ts} +0 -0
- /package/dist/{types/manager.d.ts → manager.d.ts} +0 -0
|
@@ -38,8 +38,8 @@ export declare class Queue {
|
|
|
38
38
|
constructor(rest: RestManager, options: QueueOptions);
|
|
39
39
|
/** Check if there is any remaining requests that are allowed. */
|
|
40
40
|
isRequestAllowed(): boolean;
|
|
41
|
-
/** Pauses the execution until a request is allowed to be made. */
|
|
42
|
-
waitUntilRequestAvailable(): Promise<void>;
|
|
41
|
+
/** Pauses the execution until a request is allowed to be made, or until the given signal aborts. */
|
|
42
|
+
waitUntilRequestAvailable(signal?: AbortSignal): Promise<void>;
|
|
43
43
|
/** Process the queue of requests waiting to be handled. */
|
|
44
44
|
processWaiting(): Promise<void>;
|
|
45
45
|
/** Process the queue of all requests pending to be sent. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAElE,qBAAa,KAAK;IAChB,uBAAuB;IACvB,IAAI,EAAE,WAAW,CAAC;IAClB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAK;IACtB,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAK;IAChB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAK;IACrB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC;IACtC,+CAA+C;IAC/C,OAAO,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAM;IAC/D,+CAA+C;IAC/C,OAAO,EAAE,kBAAkB,EAAE,CAAM;IACnC,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAS;IAC5B,8DAA8D;IAC9D,iBAAiB,EAAE,OAAO,CAAS;IACnC,4CAA4C;IAC5C,YAAY,EAAE,OAAO,CAAS;IAC9B,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAK;IACrB,iHAAiH;IACjH,gBAAgB,EAAE,MAAM,CAAS;IACjC,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACpC;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;gBAEP,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY;IAYpD,iEAAiE;IACjE,gBAAgB,IAAI,OAAO;IAI3B,oGAAoG;IAC9F,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBpE,2DAA2D;IACrD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBrC,4DAA4D;IACtD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAiErC,sBAAsB,CAAC,OAAO,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAkB9F,2HAA2H;IACrH,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe7D,gFAAgF;IAChF,OAAO,IAAI,IAAI;IA8Bf,mFAAmF;IACnF,gBAAgB,IAAI,OAAO;IAU3B,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF;AAED,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,iHAAiH;IACjH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/dist/queue.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { setTimeout } from 'node:timers';
|
|
2
|
+
import { delay } from '@discordeno/utils';
|
|
3
|
+
export class Queue {
|
|
4
|
+
constructor(rest, options){
|
|
5
|
+
/** Amount of requests that have are remaining. Defaults to 1. */ this.remaining = 1;
|
|
6
|
+
/** Max requests for this this. Defaults to 1. */ this.max = 1;
|
|
7
|
+
/** The time that discord allows to make the max number of requests. Defaults to 0 */ this.interval = 0;
|
|
8
|
+
/** The requests that are currently pending. */ this.waiting = [];
|
|
9
|
+
/** The requests that are currently pending. */ this.pending = [];
|
|
10
|
+
/** Whether or not the waiting queue is already processing. */ this.processing = false;
|
|
11
|
+
/** Whether or not the pending queue is already processing. */ this.processingPending = false;
|
|
12
|
+
/** Whether the first request is pending. */ this.firstRequest = false;
|
|
13
|
+
/** When requests started being made to determine when the interval will reset it. */ this.frozenAt = 0;
|
|
14
|
+
/** The time in milliseconds to wait before deleting this queue if it is empty. Defaults to 60000(one minute). */ this.deleteQueueDelay = 60000;
|
|
15
|
+
this.rest = rest;
|
|
16
|
+
this.url = options.url;
|
|
17
|
+
this.identifier = options.identifier;
|
|
18
|
+
if (options.interval) this.interval = options.interval;
|
|
19
|
+
if (options.max) this.max = options.max;
|
|
20
|
+
if (options.remaining) this.remaining = options.remaining;
|
|
21
|
+
if (options.timeoutId) this.timeoutId = options.timeoutId;
|
|
22
|
+
if (options.deleteQueueDelay) this.deleteQueueDelay = options.deleteQueueDelay;
|
|
23
|
+
}
|
|
24
|
+
/** Check if there is any remaining requests that are allowed. */ isRequestAllowed() {
|
|
25
|
+
return this.remaining > 0;
|
|
26
|
+
}
|
|
27
|
+
/** Pauses the execution until a request is allowed to be made, or until the given signal aborts. */ async waitUntilRequestAvailable(signal) {
|
|
28
|
+
return await new Promise(async (resolve)=>{
|
|
29
|
+
// If whatever amount of requests is left is more than the safety margin, allow the request
|
|
30
|
+
if (this.isRequestAllowed()) {
|
|
31
|
+
// this.remaining++;
|
|
32
|
+
resolve();
|
|
33
|
+
} else {
|
|
34
|
+
const stopWaiting = ()=>{
|
|
35
|
+
signal?.removeEventListener('abort', onAbort);
|
|
36
|
+
resolve();
|
|
37
|
+
};
|
|
38
|
+
// A caller that gives up is taken back out of the queue right away, so its request and body aren't kept alive until the queue resumes.
|
|
39
|
+
const onAbort = ()=>{
|
|
40
|
+
const index = this.waiting.indexOf(stopWaiting);
|
|
41
|
+
if (index !== -1) this.waiting.splice(index, 1);
|
|
42
|
+
stopWaiting();
|
|
43
|
+
};
|
|
44
|
+
this.waiting.push(stopWaiting);
|
|
45
|
+
signal?.addEventListener('abort', onAbort, {
|
|
46
|
+
once: true
|
|
47
|
+
});
|
|
48
|
+
await this.processWaiting();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/** Process the queue of requests waiting to be handled. */ async processWaiting() {
|
|
53
|
+
// If already processing, that loop will handle all waiting requests.
|
|
54
|
+
if (this.processing) return;
|
|
55
|
+
// Mark as processing so other loops don't start
|
|
56
|
+
this.processing = true;
|
|
57
|
+
while(this.waiting.length > 0){
|
|
58
|
+
this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url} process waiting while loop ran.`);
|
|
59
|
+
if (this.isRequestAllowed()) {
|
|
60
|
+
// Resolve the next item in the queue
|
|
61
|
+
this.waiting.shift()?.();
|
|
62
|
+
} else {
|
|
63
|
+
await delay(1000);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Mark as false so next pending request can be triggered by new loop.
|
|
67
|
+
this.processing = false;
|
|
68
|
+
// The waiting list can empty out without anything moving on to the pending one, when every request in it was cancelled, and nothing would
|
|
69
|
+
// look at this queue again.
|
|
70
|
+
this.cleanup();
|
|
71
|
+
}
|
|
72
|
+
/** Process the queue of all requests pending to be sent. */ async processPending() {
|
|
73
|
+
// If already processing, that loop will handle all pending requests.
|
|
74
|
+
if (this.processingPending || !this.pending.length) return;
|
|
75
|
+
// Mark as processing so other loops don't start
|
|
76
|
+
this.processingPending = true;
|
|
77
|
+
while(this.pending.length > 0){
|
|
78
|
+
this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop ran with ${this.pending.length}.`);
|
|
79
|
+
// Drop the requests whose caller gave up, they were rejected the moment their signal fired. This happens before anything is spent on
|
|
80
|
+
// them: sending them would use up a rate limit slot and delay the requests that are still wanted, and fetch refuses them anyway.
|
|
81
|
+
if (this.pending[0]?.requestBodyOptions?.signal?.aborted) {
|
|
82
|
+
this.pending.shift();
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (!this.firstRequest && !this.isRequestAllowed()) {
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
const future = this.frozenAt + this.interval;
|
|
88
|
+
await delay(future > now ? future - now : 1000);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const request = this.pending[0];
|
|
92
|
+
if (request) {
|
|
93
|
+
const basicURL = this.rest.simplifyUrl(request.route, request.method);
|
|
94
|
+
// If this url is still rate limited, try again
|
|
95
|
+
const urlResetIn = this.rest.checkRateLimits(basicURL, this.identifier);
|
|
96
|
+
if (urlResetIn) await delay(urlResetIn);
|
|
97
|
+
// IF A BUCKET EXISTS, CHECK THE BUCKET'S RATE LIMITS
|
|
98
|
+
const bucketResetIn = request.bucketId ? this.rest.checkRateLimits(request.bucketId, this.identifier) : false;
|
|
99
|
+
if (bucketResetIn) await delay(bucketResetIn);
|
|
100
|
+
this.firstRequest = false;
|
|
101
|
+
this.remaining--;
|
|
102
|
+
if (this.remaining === 0 && this.interval !== 0) {
|
|
103
|
+
this.timeoutId ??= setTimeout(()=>{
|
|
104
|
+
this.remaining = this.max;
|
|
105
|
+
this.timeoutId = undefined;
|
|
106
|
+
}, this.interval).unref();
|
|
107
|
+
}
|
|
108
|
+
// Remove from queue, we are executing it.
|
|
109
|
+
this.pending.shift();
|
|
110
|
+
// Check if this request is able to be made globally
|
|
111
|
+
await this.rest.invalidBucket.waitUntilRequestAvailable();
|
|
112
|
+
await this.rest.sendRequest(request).catch((e)=>{
|
|
113
|
+
this.rest.logger.debug(`Queue ${this.queueType} ${this.url} encountered an error when sending a request.`, e);
|
|
114
|
+
request.reject({
|
|
115
|
+
ok: false,
|
|
116
|
+
status: 999,
|
|
117
|
+
error: 'The queue encontered an unexpected error sending a request.',
|
|
118
|
+
errorObject: e
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop exited with ${this.pending.length}.`);
|
|
124
|
+
// Mark as false so next pending request can be triggered by new loop.
|
|
125
|
+
this.processingPending = false;
|
|
126
|
+
this.cleanup();
|
|
127
|
+
}
|
|
128
|
+
handleCompletedRequest(headers) {
|
|
129
|
+
if (headers.max === 0) {
|
|
130
|
+
this.remaining++;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!this.frozenAt) this.frozenAt = Date.now();
|
|
134
|
+
if (headers.interval !== undefined) this.interval = headers.interval;
|
|
135
|
+
if (headers.remaining !== undefined) this.remaining = headers.remaining;
|
|
136
|
+
if (this.remaining <= 1) {
|
|
137
|
+
this.timeoutId ??= setTimeout(()=>{
|
|
138
|
+
this.remaining = this.max;
|
|
139
|
+
this.timeoutId = undefined;
|
|
140
|
+
}, headers.interval).unref();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Checks if a request is available and adds it to the queue. Also triggers queue processing if not already processing. */ async makeRequest(options) {
|
|
144
|
+
const signal = options.requestBodyOptions?.signal;
|
|
145
|
+
await this.waitUntilRequestAvailable(signal);
|
|
146
|
+
// The caller gave up while this was waiting for a slot, it has already been rejected and there is nothing left to send.
|
|
147
|
+
if (signal?.aborted) {
|
|
148
|
+
this.cleanup();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.pending.push(options);
|
|
152
|
+
this.processPending();
|
|
153
|
+
}
|
|
154
|
+
/** Cleans up the queue by checking if there is nothing left and removing it. */ cleanup() {
|
|
155
|
+
if (!this.isQueueClearable()) {
|
|
156
|
+
this.processPending();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Delaying delete for ${this.deleteQueueDelay}ms`);
|
|
160
|
+
// Delete in a minute giving a bit of time to allow new requests that may reuse this queue
|
|
161
|
+
clearTimeout(this.deleteQueueTimeout);
|
|
162
|
+
this.deleteQueueTimeout = setTimeout(()=>{
|
|
163
|
+
if (!this.isQueueClearable()) {
|
|
164
|
+
this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. is not clearable. Restarting processing of queue.`);
|
|
165
|
+
this.processPending();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Deleting`);
|
|
169
|
+
if (this.timeoutId) clearTimeout(this.timeoutId);
|
|
170
|
+
// No requests have been requested for this queue so we nuke this queue
|
|
171
|
+
this.rest.queues.delete(`${this.identifier}${this.url}`);
|
|
172
|
+
this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Deleted! Remaining: (${this.rest.queues.size})`, [
|
|
173
|
+
...this.rest.queues.values()
|
|
174
|
+
].map((queue)=>`${queue.queueType}${queue.url}`));
|
|
175
|
+
}, this.deleteQueueDelay).unref();
|
|
176
|
+
}
|
|
177
|
+
/** Simply checks if the queue is able to be cleared or it has requests pending. */ isQueueClearable() {
|
|
178
|
+
if (this.firstRequest) return false;
|
|
179
|
+
if (this.waiting.length > 0) return false;
|
|
180
|
+
if (this.pending.length > 0) return false;
|
|
181
|
+
if (this.processing) return false;
|
|
182
|
+
if (this.processingPending) return false;
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
get queueType() {
|
|
186
|
+
return this.identifier.slice(0, this.identifier.indexOf(' '));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9xdWV1ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzZXRUaW1lb3V0IH0gZnJvbSAnbm9kZTp0aW1lcnMnO1xuaW1wb3J0IHsgZGVsYXkgfSBmcm9tICdAZGlzY29yZGVuby91dGlscyc7XG5pbXBvcnQgdHlwZSB7IFJlc3RNYW5hZ2VyLCBTZW5kUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFF1ZXVlIHtcbiAgLyoqIFRoZSByZXN0IG1hbmFnZXIgKi9cbiAgcmVzdDogUmVzdE1hbmFnZXI7XG4gIC8qKiBBbW91bnQgb2YgcmVxdWVzdHMgdGhhdCBoYXZlIGFyZSByZW1haW5pbmcuIERlZmF1bHRzIHRvIDEuICovXG4gIHJlbWFpbmluZzogbnVtYmVyID0gMTtcbiAgLyoqIE1heCByZXF1ZXN0cyBmb3IgdGhpcyB0aGlzLiBEZWZhdWx0cyB0byAxLiAqL1xuICBtYXg6IG51bWJlciA9IDE7XG4gIC8qKiBUaGUgdGltZSB0aGF0IGRpc2NvcmQgYWxsb3dzIHRvIG1ha2UgdGhlIG1heCBudW1iZXIgb2YgcmVxdWVzdHMuIERlZmF1bHRzIHRvIDAgKi9cbiAgaW50ZXJ2YWw6IG51bWJlciA9IDA7XG4gIC8qKiB0aW1lciB0byByZXNldCB0byAwICovXG4gIHRpbWVvdXRJZDogTm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWQ7XG4gIC8qKiBUaGUgcmVxdWVzdHMgdGhhdCBhcmUgY3VycmVudGx5IHBlbmRpbmcuICovXG4gIHdhaXRpbmc6IEFycmF5PCh2YWx1ZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+KSA9PiB2b2lkPiA9IFtdO1xuICAvKiogVGhlIHJlcXVlc3RzIHRoYXQgYXJlIGN1cnJlbnRseSBwZW5kaW5nLiAqL1xuICBwZW5kaW5nOiBTZW5kUmVxdWVzdE9wdGlvbnNbXSA9IFtdO1xuICAvKiogV2hldGhlciBvciBub3QgdGhlIHdhaXRpbmcgcXVldWUgaXMgYWxyZWFkeSBwcm9jZXNzaW5nLiAqL1xuICBwcm9jZXNzaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIG9yIG5vdCB0aGUgcGVuZGluZyBxdWV1ZSBpcyBhbHJlYWR5IHByb2Nlc3NpbmcuICovXG4gIHByb2Nlc3NpbmdQZW5kaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBXaGV0aGVyIHRoZSBmaXJzdCByZXF1ZXN0IGlzIHBlbmRpbmcuICovXG4gIGZpcnN0UmVxdWVzdDogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogVGhlIHVybCB0aGF0IGFsbCB0aGUgcmVxdWVzdHMgaW4gdGhpcyBxdWV1ZSBhcmUgc2VudCB0by4gKi9cbiAgdXJsOiBzdHJpbmc7XG4gIC8qKiBXaGVuIHJlcXVlc3RzIHN0YXJ0ZWQgYmVpbmcgbWFkZSB0byBkZXRlcm1pbmUgd2hlbiB0aGUgaW50ZXJ2YWwgd2lsbCByZXNldCBpdC4gKi9cbiAgZnJvemVuQXQ6IG51bWJlciA9IDA7XG4gIC8qKiBUaGUgdGltZSBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBiZWZvcmUgZGVsZXRpbmcgdGhpcyBxdWV1ZSBpZiBpdCBpcyBlbXB0eS4gRGVmYXVsdHMgdG8gNjAwMDAob25lIG1pbnV0ZSkuICovXG4gIGRlbGV0ZVF1ZXVlRGVsYXk6IG51bWJlciA9IDYwMDAwO1xuICAvKiogVGhlIHRpbWVvdXQgZm9yIHRoZSBkZWxldGlvbiBvZiB0aGlzIHF1ZXVlICovXG4gIGRlbGV0ZVF1ZXVlVGltZW91dD86IE5vZGVKUy5UaW1lb3V0O1xuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgZm9yIHRoaXMgcmVxdWVzdCwgbWF5IGJlIHRoZSByZXF1ZXN0IGF1dGhvcml6YXRpb24gb3IgZmFsbGJhY2sgdG8gdGhlIGJvdCBhdXRoXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIFRoaXMgaXMgdXNlZCB0byBnZXQgdGhlIGlkZW50aWZ5IHRoaXMgcXVldWUgZnJvbSB0aGUgcXVldWUgbWFwcGluZyBvZiB0aGUgcmVzdCBtYW5hZ2VyXG4gICAqL1xuICBpZGVudGlmaWVyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocmVzdDogUmVzdE1hbmFnZXIsIG9wdGlvbnM6IFF1ZXVlT3B0aW9ucykge1xuICAgIHRoaXMucmVzdCA9IHJlc3Q7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybDtcbiAgICB0aGlzLmlkZW50aWZpZXIgPSBvcHRpb25zLmlkZW50aWZpZXI7XG5cbiAgICBpZiAob3B0aW9ucy5pbnRlcnZhbCkgdGhpcy5pbnRlcnZhbCA9IG9wdGlvbnMuaW50ZXJ2YWw7XG4gICAgaWYgKG9wdGlvbnMubWF4KSB0aGlzLm1heCA9IG9wdGlvbnMubWF4O1xuICAgIGlmIChvcHRpb25zLnJlbWFpbmluZykgdGhpcy5yZW1haW5pbmcgPSBvcHRpb25zLnJlbWFpbmluZztcbiAgICBpZiAob3B0aW9ucy50aW1lb3V0SWQpIHRoaXMudGltZW91dElkID0gb3B0aW9ucy50aW1lb3V0SWQ7XG4gICAgaWYgKG9wdGlvbnMuZGVsZXRlUXVldWVEZWxheSkgdGhpcy5kZWxldGVRdWV1ZURlbGF5ID0gb3B0aW9ucy5kZWxldGVRdWV1ZURlbGF5O1xuICB9XG5cbiAgLyoqIENoZWNrIGlmIHRoZXJlIGlzIGFueSByZW1haW5pbmcgcmVxdWVzdHMgdGhhdCBhcmUgYWxsb3dlZC4gKi9cbiAgaXNSZXF1ZXN0QWxsb3dlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZW1haW5pbmcgPiAwO1xuICB9XG5cbiAgLyoqIFBhdXNlcyB0aGUgZXhlY3V0aW9uIHVudGlsIGEgcmVxdWVzdCBpcyBhbGxvd2VkIHRvIGJlIG1hZGUsIG9yIHVudGlsIHRoZSBnaXZlbiBzaWduYWwgYWJvcnRzLiAqL1xuICBhc3luYyB3YWl0VW50aWxSZXF1ZXN0QXZhaWxhYmxlKHNpZ25hbD86IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlKSA9PiB7XG4gICAgICAvLyBJZiB3aGF0ZXZlciBhbW91bnQgb2YgcmVxdWVzdHMgaXMgbGVmdCBpcyBtb3JlIHRoYW4gdGhlIHNhZmV0eSBtYXJnaW4sIGFsbG93IHRoZSByZXF1ZXN0XG4gICAgICBpZiAodGhpcy5pc1JlcXVlc3RBbGxvd2VkKCkpIHtcbiAgICAgICAgLy8gdGhpcy5yZW1haW5pbmcrKztcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc3RvcFdhaXRpbmcgPSAoKSA9PiB7XG4gICAgICAgICAgc2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gQSBjYWxsZXIgdGhhdCBnaXZlcyB1cCBpcyB0YWtlbiBiYWNrIG91dCBvZiB0aGUgcXVldWUgcmlnaHQgYXdheSwgc28gaXRzIHJlcXVlc3QgYW5kIGJvZHkgYXJlbid0IGtlcHQgYWxpdmUgdW50aWwgdGhlIHF1ZXVlIHJlc3VtZXMuXG4gICAgICAgIGNvbnN0IG9uQWJvcnQgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLndhaXRpbmcuaW5kZXhPZihzdG9wV2FpdGluZyk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkgdGhpcy53YWl0aW5nLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgc3RvcFdhaXRpbmcoKTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLndhaXRpbmcucHVzaChzdG9wV2FpdGluZyk7XG4gICAgICAgIHNpZ25hbD8uYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc1dhaXRpbmcoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBQcm9jZXNzIHRoZSBxdWV1ZSBvZiByZXF1ZXN0cyB3YWl0aW5nIHRvIGJlIGhhbmRsZWQuICovXG4gIGFzeW5jIHByb2Nlc3NXYWl0aW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIElmIGFscmVhZHkgcHJvY2Vzc2luZywgdGhhdCBsb29wIHdpbGwgaGFuZGxlIGFsbCB3YWl0aW5nIHJlcXVlc3RzLlxuICAgIGlmICh0aGlzLnByb2Nlc3NpbmcpIHJldHVybjtcbiAgICAvLyBNYXJrIGFzIHByb2Nlc3Npbmcgc28gb3RoZXIgbG9vcHMgZG9uJ3Qgc3RhcnRcbiAgICB0aGlzLnByb2Nlc3NpbmcgPSB0cnVlO1xuXG4gICAgd2hpbGUgKHRoaXMud2FpdGluZy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnJlc3QubG9nZ2VyLmRlYnVnKGBbUXVldWVdICR7dGhpcy5xdWV1ZVR5cGV9ICR7dGhpcy51cmx9IHByb2Nlc3Mgd2FpdGluZyB3aGlsZSBsb29wIHJhbi5gKTtcbiAgICAgIGlmICh0aGlzLmlzUmVxdWVzdEFsbG93ZWQoKSkge1xuICAgICAgICAvLyBSZXNvbHZlIHRoZSBuZXh0IGl0ZW0gaW4gdGhlIHF1ZXVlXG4gICAgICAgIHRoaXMud2FpdGluZy5zaGlmdCgpPy4oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGRlbGF5KDEwMDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE1hcmsgYXMgZmFsc2Ugc28gbmV4dCBwZW5kaW5nIHJlcXVlc3QgY2FuIGJlIHRyaWdnZXJlZCBieSBuZXcgbG9vcC5cbiAgICB0aGlzLnByb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAvLyBUaGUgd2FpdGluZyBsaXN0IGNhbiBlbXB0eSBvdXQgd2l0aG91dCBhbnl0aGluZyBtb3Zpbmcgb24gdG8gdGhlIHBlbmRpbmcgb25lLCB3aGVuIGV2ZXJ5IHJlcXVlc3QgaW4gaXQgd2FzIGNhbmNlbGxlZCwgYW5kIG5vdGhpbmcgd291bGRcbiAgICAvLyBsb29rIGF0IHRoaXMgcXVldWUgYWdhaW4uXG4gICAgdGhpcy5jbGVhbnVwKCk7XG4gIH1cblxuICAvKiogUHJvY2VzcyB0aGUgcXVldWUgb2YgYWxsIHJlcXVlc3RzIHBlbmRpbmcgdG8gYmUgc2VudC4gKi9cbiAgYXN5bmMgcHJvY2Vzc1BlbmRpbmcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gSWYgYWxyZWFkeSBwcm9jZXNzaW5nLCB0aGF0IGxvb3Agd2lsbCBoYW5kbGUgYWxsIHBlbmRpbmcgcmVxdWVzdHMuXG4gICAgaWYgKHRoaXMucHJvY2Vzc2luZ1BlbmRpbmcgfHwgIXRoaXMucGVuZGluZy5sZW5ndGgpIHJldHVybjtcblxuICAgIC8vIE1hcmsgYXMgcHJvY2Vzc2luZyBzbyBvdGhlciBsb29wcyBkb24ndCBzdGFydFxuICAgIHRoaXMucHJvY2Vzc2luZ1BlbmRpbmcgPSB0cnVlO1xuXG4gICAgd2hpbGUgKHRoaXMucGVuZGluZy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnJlc3QubG9nZ2VyLmRlYnVnKGBRdWV1ZSAke3RoaXMucXVldWVUeXBlfSAke3RoaXMudXJsfSBwcm9jZXNzIHBlbmRpbmcgd2hpbGUgbG9vcCByYW4gd2l0aCAke3RoaXMucGVuZGluZy5sZW5ndGh9LmApO1xuXG4gICAgICAvLyBEcm9wIHRoZSByZXF1ZXN0cyB3aG9zZSBjYWxsZXIgZ2F2ZSB1cCwgdGhleSB3ZXJlIHJlamVjdGVkIHRoZSBtb21lbnQgdGhlaXIgc2lnbmFsIGZpcmVkLiBUaGlzIGhhcHBlbnMgYmVmb3JlIGFueXRoaW5nIGlzIHNwZW50IG9uXG4gICAgICAvLyB0aGVtOiBzZW5kaW5nIHRoZW0gd291bGQgdXNlIHVwIGEgcmF0ZSBsaW1pdCBzbG90IGFuZCBkZWxheSB0aGUgcmVxdWVzdHMgdGhhdCBhcmUgc3RpbGwgd2FudGVkLCBhbmQgZmV0Y2ggcmVmdXNlcyB0aGVtIGFueXdheS5cbiAgICAgIGlmICh0aGlzLnBlbmRpbmdbMF0/LnJlcXVlc3RCb2R5T3B0aW9ucz8uc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgIHRoaXMucGVuZGluZy5zaGlmdCgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLmZpcnN0UmVxdWVzdCAmJiAhdGhpcy5pc1JlcXVlc3RBbGxvd2VkKCkpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgZnV0dXJlID0gdGhpcy5mcm96ZW5BdCArIHRoaXMuaW50ZXJ2YWw7XG4gICAgICAgIGF3YWl0IGRlbGF5KGZ1dHVyZSA+IG5vdyA/IGZ1dHVyZSAtIG5vdyA6IDEwMDApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVxdWVzdCA9IHRoaXMucGVuZGluZ1swXTtcbiAgICAgIGlmIChyZXF1ZXN0KSB7XG4gICAgICAgIGNvbnN0IGJhc2ljVVJMID0gdGhpcy5yZXN0LnNpbXBsaWZ5VXJsKHJlcXVlc3Qucm91dGUsIHJlcXVlc3QubWV0aG9kKTtcblxuICAgICAgICAvLyBJZiB0aGlzIHVybCBpcyBzdGlsbCByYXRlIGxpbWl0ZWQsIHRyeSBhZ2FpblxuICAgICAgICBjb25zdCB1cmxSZXNldEluID0gdGhpcy5yZXN0LmNoZWNrUmF0ZUxpbWl0cyhiYXNpY1VSTCwgdGhpcy5pZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKHVybFJlc2V0SW4pIGF3YWl0IGRlbGF5KHVybFJlc2V0SW4pO1xuXG4gICAgICAgIC8vIElGIEEgQlVDS0VUIEVYSVNUUywgQ0hFQ0sgVEhFIEJVQ0tFVCdTIFJBVEUgTElNSVRTXG4gICAgICAgIGNvbnN0IGJ1Y2tldFJlc2V0SW4gPSByZXF1ZXN0LmJ1Y2tldElkID8gdGhpcy5yZXN0LmNoZWNrUmF0ZUxpbWl0cyhyZXF1ZXN0LmJ1Y2tldElkLCB0aGlzLmlkZW50aWZpZXIpIDogZmFsc2U7XG4gICAgICAgIGlmIChidWNrZXRSZXNldEluKSBhd2FpdCBkZWxheShidWNrZXRSZXNldEluKTtcblxuICAgICAgICB0aGlzLmZpcnN0UmVxdWVzdCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlbWFpbmluZy0tO1xuXG4gICAgICAgIGlmICh0aGlzLnJlbWFpbmluZyA9PT0gMCAmJiB0aGlzLmludGVydmFsICE9PSAwKSB7XG4gICAgICAgICAgdGhpcy50aW1lb3V0SWQgPz89IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1haW5pbmcgPSB0aGlzLm1heDtcbiAgICAgICAgICAgIHRoaXMudGltZW91dElkID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH0sIHRoaXMuaW50ZXJ2YWwpLnVucmVmKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBxdWV1ZSwgd2UgYXJlIGV4ZWN1dGluZyBpdC5cbiAgICAgICAgdGhpcy5wZW5kaW5nLnNoaWZ0KCk7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoaXMgcmVxdWVzdCBpcyBhYmxlIHRvIGJlIG1hZGUgZ2xvYmFsbHlcbiAgICAgICAgYXdhaXQgdGhpcy5yZXN0LmludmFsaWRCdWNrZXQud2FpdFVudGlsUmVxdWVzdEF2YWlsYWJsZSgpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucmVzdC5zZW5kUmVxdWVzdChyZXF1ZXN0KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgIHRoaXMucmVzdC5sb2dnZXIuZGVidWcoYFF1ZXVlICR7dGhpcy5xdWV1ZVR5cGV9ICR7dGhpcy51cmx9IGVuY291bnRlcmVkIGFuIGVycm9yIHdoZW4gc2VuZGluZyBhIHJlcXVlc3QuYCwgZSk7XG4gICAgICAgICAgcmVxdWVzdC5yZWplY3QoeyBvazogZmFsc2UsIHN0YXR1czogOTk5LCBlcnJvcjogJ1RoZSBxdWV1ZSBlbmNvbnRlcmVkIGFuIHVuZXhwZWN0ZWQgZXJyb3Igc2VuZGluZyBhIHJlcXVlc3QuJywgZXJyb3JPYmplY3Q6IGUgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucmVzdC5sb2dnZXIuZGVidWcoYFF1ZXVlICR7dGhpcy5xdWV1ZVR5cGV9ICR7dGhpcy51cmx9IHByb2Nlc3MgcGVuZGluZyB3aGlsZSBsb29wIGV4aXRlZCB3aXRoICR7dGhpcy5wZW5kaW5nLmxlbmd0aH0uYCk7XG5cbiAgICAvLyBNYXJrIGFzIGZhbHNlIHNvIG5leHQgcGVuZGluZyByZXF1ZXN0IGNhbiBiZSB0cmlnZ2VyZWQgYnkgbmV3IGxvb3AuXG4gICAgdGhpcy5wcm9jZXNzaW5nUGVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuY2xlYW51cCgpO1xuICB9XG5cbiAgaGFuZGxlQ29tcGxldGVkUmVxdWVzdChoZWFkZXJzOiB7IG1heD86IG51bWJlcjsgaW50ZXJ2YWw/OiBudW1iZXI7IHJlbWFpbmluZz86IG51bWJlciB9KTogdm9pZCB7XG4gICAgaWYgKGhlYWRlcnMubWF4ID09PSAwKSB7XG4gICAgICB0aGlzLnJlbWFpbmluZysrO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5mcm96ZW5BdCkgdGhpcy5mcm96ZW5BdCA9IERhdGUubm93KCk7XG4gICAgaWYgKGhlYWRlcnMuaW50ZXJ2YWwgIT09IHVuZGVmaW5lZCkgdGhpcy5pbnRlcnZhbCA9IGhlYWRlcnMuaW50ZXJ2YWw7XG4gICAgaWYgKGhlYWRlcnMucmVtYWluaW5nICE9PSB1bmRlZmluZWQpIHRoaXMucmVtYWluaW5nID0gaGVhZGVycy5yZW1haW5pbmc7XG5cbiAgICBpZiAodGhpcy5yZW1haW5pbmcgPD0gMSkge1xuICAgICAgdGhpcy50aW1lb3V0SWQgPz89IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbWFpbmluZyA9IHRoaXMubWF4O1xuICAgICAgICB0aGlzLnRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICAgIH0sIGhlYWRlcnMuaW50ZXJ2YWwpLnVucmVmKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENoZWNrcyBpZiBhIHJlcXVlc3QgaXMgYXZhaWxhYmxlIGFuZCBhZGRzIGl0IHRvIHRoZSBxdWV1ZS4gQWxzbyB0cmlnZ2VycyBxdWV1ZSBwcm9jZXNzaW5nIGlmIG5vdCBhbHJlYWR5IHByb2Nlc3NpbmcuICovXG4gIGFzeW5jIG1ha2VSZXF1ZXN0KG9wdGlvbnM6IFNlbmRSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNpZ25hbCA9IG9wdGlvbnMucmVxdWVzdEJvZHlPcHRpb25zPy5zaWduYWw7XG5cbiAgICBhd2FpdCB0aGlzLndhaXRVbnRpbFJlcXVlc3RBdmFpbGFibGUoc2lnbmFsKTtcblxuICAgIC8vIFRoZSBjYWxsZXIgZ2F2ZSB1cCB3aGlsZSB0aGlzIHdhcyB3YWl0aW5nIGZvciBhIHNsb3QsIGl0IGhhcyBhbHJlYWR5IGJlZW4gcmVqZWN0ZWQgYW5kIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCB0byBzZW5kLlxuICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucGVuZGluZy5wdXNoKG9wdGlvbnMpO1xuICAgIHRoaXMucHJvY2Vzc1BlbmRpbmcoKTtcbiAgfVxuXG4gIC8qKiBDbGVhbnMgdXAgdGhlIHF1ZXVlIGJ5IGNoZWNraW5nIGlmIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCBhbmQgcmVtb3ZpbmcgaXQuICovXG4gIGNsZWFudXAoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzUXVldWVDbGVhcmFibGUoKSkge1xuICAgICAgdGhpcy5wcm9jZXNzUGVuZGluZygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucmVzdC5sb2dnZXIuZGVidWcoYFtRdWV1ZV0gJHt0aGlzLnF1ZXVlVHlwZX0gJHt0aGlzLnVybH0uIERlbGF5aW5nIGRlbGV0ZSBmb3IgJHt0aGlzLmRlbGV0ZVF1ZXVlRGVsYXl9bXNgKTtcblxuICAgIC8vIERlbGV0ZSBpbiBhIG1pbnV0ZSBnaXZpbmcgYSBiaXQgb2YgdGltZSB0byBhbGxvdyBuZXcgcmVxdWVzdHMgdGhhdCBtYXkgcmV1c2UgdGhpcyBxdWV1ZVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmRlbGV0ZVF1ZXVlVGltZW91dCk7XG4gICAgdGhpcy5kZWxldGVRdWV1ZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5pc1F1ZXVlQ2xlYXJhYmxlKCkpIHtcbiAgICAgICAgdGhpcy5yZXN0LmxvZ2dlci5kZWJ1ZyhgW1F1ZXVlXSAke3RoaXMucXVldWVUeXBlfSAke3RoaXMudXJsfS4gaXMgbm90IGNsZWFyYWJsZS4gUmVzdGFydGluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlLmApO1xuICAgICAgICB0aGlzLnByb2Nlc3NQZW5kaW5nKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZXN0LmxvZ2dlci5kZWJ1ZyhgW1F1ZXVlXSAke3RoaXMucXVldWVUeXBlfSAke3RoaXMudXJsfS4gRGVsZXRpbmdgKTtcblxuICAgICAgaWYgKHRoaXMudGltZW91dElkKSBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0SWQpO1xuXG4gICAgICAvLyBObyByZXF1ZXN0cyBoYXZlIGJlZW4gcmVxdWVzdGVkIGZvciB0aGlzIHF1ZXVlIHNvIHdlIG51a2UgdGhpcyBxdWV1ZVxuICAgICAgdGhpcy5yZXN0LnF1ZXVlcy5kZWxldGUoYCR7dGhpcy5pZGVudGlmaWVyfSR7dGhpcy51cmx9YCk7XG4gICAgICB0aGlzLnJlc3QubG9nZ2VyLmRlYnVnKFxuICAgICAgICBgW1F1ZXVlXSAke3RoaXMucXVldWVUeXBlfSAke3RoaXMudXJsfS4gRGVsZXRlZCEgUmVtYWluaW5nOiAoJHt0aGlzLnJlc3QucXVldWVzLnNpemV9KWAsXG4gICAgICAgIFsuLi50aGlzLnJlc3QucXVldWVzLnZhbHVlcygpXS5tYXAoKHF1ZXVlKSA9PiBgJHtxdWV1ZS5xdWV1ZVR5cGV9JHtxdWV1ZS51cmx9YCksXG4gICAgICApO1xuICAgIH0sIHRoaXMuZGVsZXRlUXVldWVEZWxheSkudW5yZWYoKTtcbiAgfVxuXG4gIC8qKiBTaW1wbHkgY2hlY2tzIGlmIHRoZSBxdWV1ZSBpcyBhYmxlIHRvIGJlIGNsZWFyZWQgb3IgaXQgaGFzIHJlcXVlc3RzIHBlbmRpbmcuICovXG4gIGlzUXVldWVDbGVhcmFibGUoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuZmlyc3RSZXF1ZXN0KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRoaXMud2FpdGluZy5sZW5ndGggPiAwKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRoaXMucGVuZGluZy5sZW5ndGggPiAwKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRoaXMucHJvY2Vzc2luZykgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0aGlzLnByb2Nlc3NpbmdQZW5kaW5nKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldCBxdWV1ZVR5cGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pZGVudGlmaWVyLnNsaWNlKDAsIHRoaXMuaWRlbnRpZmllci5pbmRleE9mKCcgJykpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVldWVPcHRpb25zIHtcbiAgLyoqIEhvdyBtYW55IHJlcXVlc3RzIGFyZSByZW1haW5pbmcuIERlZmF1bHRzIHRvIDEgKi9cbiAgcmVtYWluaW5nPzogbnVtYmVyO1xuICAvKiogTWF4IG51bWJlciBvZiByZXF1ZXN0cyBhbGxvd2VkIGluIHRoaXMgdGhpcy4gRGVmYXVsdHMgdG8gMS4gKi9cbiAgbWF4PzogbnVtYmVyO1xuICAvKiogVGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHRoYXQgZGlzY29yZCBhbGxvd3MgdG8gbWFrZSB0aGUgbWF4IG51bWJlciBvZiBpbnZhbGlkIHJlcXVlc3RzLiBEZWZhdWx0cyB0byAwICovXG4gIGludGVydmFsPzogbnVtYmVyO1xuICAvKiogdGltZXIgdG8gcmVzZXQgdG8gMCAqL1xuICB0aW1lb3V0SWQ/OiBOb2RlSlMuVGltZW91dDtcbiAgLyoqIFRoZSB1cmwgdGhpcyBxdWV1ZSB3aWxsIGJlIGhhbmRsaW5nLiAqL1xuICB1cmw6IHN0cmluZztcbiAgLyoqIFRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBkZWxldGluZyB0aGlzIHF1ZXVlIGlmIGl0IGlzIGVtcHR5LiBEZWZhdWx0cyB0byA2MDAwMChvbmUgbWludXRlKS4gKi9cbiAgZGVsZXRlUXVldWVEZWxheT86IG51bWJlcjtcbiAgLyoqIFRoZSBiYXNlIGtleSB0aGF0IGlkZW50aWZpZXMgdGhpcyBxdWV1ZSBpbiB0aGUgcmVzdCBtYW5hZ2VyICovXG4gIGlkZW50aWZpZXI6IHN0cmluZztcbn1cbiJdLCJuYW1lcyI6WyJzZXRUaW1lb3V0IiwiZGVsYXkiLCJRdWV1ZSIsInJlc3QiLCJvcHRpb25zIiwicmVtYWluaW5nIiwibWF4IiwiaW50ZXJ2YWwiLCJ3YWl0aW5nIiwicGVuZGluZyIsInByb2Nlc3NpbmciLCJwcm9jZXNzaW5nUGVuZGluZyIsImZpcnN0UmVxdWVzdCIsImZyb3plbkF0IiwiZGVsZXRlUXVldWVEZWxheSIsInVybCIsImlkZW50aWZpZXIiLCJ0aW1lb3V0SWQiLCJpc1JlcXVlc3RBbGxvd2VkIiwid2FpdFVudGlsUmVxdWVzdEF2YWlsYWJsZSIsInNpZ25hbCIsIlByb21pc2UiLCJyZXNvbHZlIiwic3RvcFdhaXRpbmciLCJyZW1vdmVFdmVudExpc3RlbmVyIiwib25BYm9ydCIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsInB1c2giLCJhZGRFdmVudExpc3RlbmVyIiwib25jZSIsInByb2Nlc3NXYWl0aW5nIiwibGVuZ3RoIiwibG9nZ2VyIiwiZGVidWciLCJxdWV1ZVR5cGUiLCJzaGlmdCIsImNsZWFudXAiLCJwcm9jZXNzUGVuZGluZyIsInJlcXVlc3RCb2R5T3B0aW9ucyIsImFib3J0ZWQiLCJub3ciLCJEYXRlIiwiZnV0dXJlIiwicmVxdWVzdCIsImJhc2ljVVJMIiwic2ltcGxpZnlVcmwiLCJyb3V0ZSIsIm1ldGhvZCIsInVybFJlc2V0SW4iLCJjaGVja1JhdGVMaW1pdHMiLCJidWNrZXRSZXNldEluIiwiYnVja2V0SWQiLCJ1bmRlZmluZWQiLCJ1bnJlZiIsImludmFsaWRCdWNrZXQiLCJzZW5kUmVxdWVzdCIsImNhdGNoIiwiZSIsInJlamVjdCIsIm9rIiwic3RhdHVzIiwiZXJyb3IiLCJlcnJvck9iamVjdCIsImhhbmRsZUNvbXBsZXRlZFJlcXVlc3QiLCJoZWFkZXJzIiwibWFrZVJlcXVlc3QiLCJpc1F1ZXVlQ2xlYXJhYmxlIiwiY2xlYXJUaW1lb3V0IiwiZGVsZXRlUXVldWVUaW1lb3V0IiwicXVldWVzIiwiZGVsZXRlIiwic2l6ZSIsInZhbHVlcyIsIm1hcCIsInF1ZXVlIiwic2xpY2UiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFVBQVUsUUFBUSxjQUFjO0FBQ3pDLFNBQVNDLEtBQUssUUFBUSxvQkFBb0I7QUFHMUMsT0FBTyxNQUFNQztJQXFDWCxZQUFZQyxJQUFpQixFQUFFQyxPQUFxQixDQUFFO1FBbEN0RCwrREFBK0QsUUFDL0RDLFlBQW9CO1FBQ3BCLCtDQUErQyxRQUMvQ0MsTUFBYztRQUNkLG1GQUFtRixRQUNuRkMsV0FBbUI7UUFHbkIsNkNBQTZDLFFBQzdDQyxVQUE0RCxFQUFFO1FBQzlELDZDQUE2QyxRQUM3Q0MsVUFBZ0MsRUFBRTtRQUNsQyw0REFBNEQsUUFDNURDLGFBQXNCO1FBQ3RCLDREQUE0RCxRQUM1REMsb0JBQTZCO1FBQzdCLDBDQUEwQyxRQUMxQ0MsZUFBd0I7UUFHeEIsbUZBQW1GLFFBQ25GQyxXQUFtQjtRQUNuQiwrR0FBK0csUUFDL0dDLG1CQUEyQjtRQVl6QixJQUFJLENBQUNYLElBQUksR0FBR0E7UUFDWixJQUFJLENBQUNZLEdBQUcsR0FBR1gsUUFBUVcsR0FBRztRQUN0QixJQUFJLENBQUNDLFVBQVUsR0FBR1osUUFBUVksVUFBVTtRQUVwQyxJQUFJWixRQUFRRyxRQUFRLEVBQUUsSUFBSSxDQUFDQSxRQUFRLEdBQUdILFFBQVFHLFFBQVE7UUFDdEQsSUFBSUgsUUFBUUUsR0FBRyxFQUFFLElBQUksQ0FBQ0EsR0FBRyxHQUFHRixRQUFRRSxHQUFHO1FBQ3ZDLElBQUlGLFFBQVFDLFNBQVMsRUFBRSxJQUFJLENBQUNBLFNBQVMsR0FBR0QsUUFBUUMsU0FBUztRQUN6RCxJQUFJRCxRQUFRYSxT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
|
package/dist/routes.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RestRoutes } from './typings/routes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the available discord API routes
|
|
4
|
+
*
|
|
5
|
+
* @param disableURIEncode Don't encode strings, except where required - Danger: disabling URI encoding may lead to path traversal if unsafe strings are used
|
|
6
|
+
* @returns The available discord API routes
|
|
7
|
+
*/
|
|
8
|
+
export declare function createRoutes(disableURIEncode?: boolean): RestRoutes;
|
|
9
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,GAAE,OAAe,GAAG,UAAU,CAgwB1E"}
|