@chainfuse/helpers 2.4.2 → 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/dist/discord.d.mts +22 -3
- package/dist/discord.mjs +419 -66
- package/dist/net.d.mts +163 -7
- package/dist/net.mjs +335 -115
- package/package.json +8 -6
package/dist/net.mjs
CHANGED
|
@@ -1,112 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum representing HTTP request methods.
|
|
3
|
+
*
|
|
4
|
+
* Each member of the enum corresponds to a standard HTTP method, which can be used to specify the desired action to be performed on a given resource.
|
|
5
|
+
*/
|
|
6
|
+
export var Methods;
|
|
7
|
+
(function (Methods) {
|
|
8
|
+
Methods["GET"] = "GET";
|
|
9
|
+
Methods["HEAD"] = "HEAD";
|
|
10
|
+
Methods["POST"] = "POST";
|
|
11
|
+
Methods["PUT"] = "PUT";
|
|
12
|
+
Methods["DELETE"] = "DELETE";
|
|
13
|
+
Methods["CONNECT"] = "CONNECT";
|
|
14
|
+
Methods["OPTIONS"] = "OPTIONS";
|
|
15
|
+
Methods["TRACE"] = "TRACE";
|
|
16
|
+
Methods["PATCH"] = "PATCH";
|
|
17
|
+
})(Methods || (Methods = {}));
|
|
1
18
|
export class NetHelpers {
|
|
19
|
+
static cfApiLogging() {
|
|
20
|
+
return import('zod').then(({ z }) => z
|
|
21
|
+
.union([
|
|
22
|
+
z.object({
|
|
23
|
+
level: z.literal(0),
|
|
24
|
+
}),
|
|
25
|
+
z.object({
|
|
26
|
+
level: z.coerce.number().int().min(1).max(3),
|
|
27
|
+
color: z.boolean().default(true),
|
|
28
|
+
custom: z
|
|
29
|
+
.function()
|
|
30
|
+
.args()
|
|
31
|
+
.returns(z.union([z.void(), z.promise(z.void())]))
|
|
32
|
+
.optional(),
|
|
33
|
+
}),
|
|
34
|
+
])
|
|
35
|
+
.default({
|
|
36
|
+
level: 0,
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
2
39
|
/**
|
|
3
|
-
*
|
|
40
|
+
* Creates an instance of the Cloudflare API client with enhanced logging capabilities.
|
|
41
|
+
*
|
|
42
|
+
* @param apiKey - The API token used to authenticate with the Cloudflare API.
|
|
43
|
+
* @param logging - The logging configuration object, parsed using the `cfApiLogging` parser.
|
|
44
|
+
*
|
|
45
|
+
* @returns A promise that resolves to an instance of the Cloudflare API client.
|
|
4
46
|
*
|
|
5
|
-
*
|
|
47
|
+
* The logging configuration supports the following properties:
|
|
48
|
+
* - `level`: The logging level. If set to `1`, it is internally treated as `2` to include headers for the `cf-ray` ID, but reset back to 1 for the returned logs.
|
|
49
|
+
* - `color`: Optional. If `true`, enables colored output using the `chalk` library.
|
|
50
|
+
* - `custom`: Optional. A custom logging function that receives detailed request and response information.
|
|
6
51
|
*
|
|
7
|
-
*
|
|
52
|
+
* The function also enhances logging by:
|
|
53
|
+
* - Extracting and displaying the `cf-ray` ID from response headers.
|
|
54
|
+
* - Formatting and coloring log output for better readability.
|
|
55
|
+
* - Stripping redundant parts of URLs and wrapping unique IDs in brackets with color coding.
|
|
8
56
|
*/
|
|
9
|
-
static
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
static stripSensitiveHeaders(originalHeaders = new Headers()) {
|
|
16
|
-
const mutableHeaders = new Headers(originalHeaders);
|
|
17
|
-
mutableHeaders.delete('Set-Cookie');
|
|
18
|
-
mutableHeaders.delete('Authorization');
|
|
19
|
-
return mutableHeaders;
|
|
20
|
-
}
|
|
21
|
-
static cfApi(apiKey, logger = false) {
|
|
22
|
-
return import('cloudflare').then(({ Cloudflare }) => new Cloudflare({
|
|
57
|
+
static cfApi(apiKey, logging) {
|
|
58
|
+
return Promise.all([
|
|
59
|
+
//
|
|
60
|
+
import('cloudflare'),
|
|
61
|
+
NetHelpers.cfApiLogging().then((parser) => parser.parseAsync(logging)),
|
|
62
|
+
]).then(([{ Cloudflare }, logging]) => new Cloudflare({
|
|
23
63
|
apiToken: apiKey,
|
|
24
64
|
fetch: async (info, init) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
const loggingFetchInit = {
|
|
66
|
+
...init,
|
|
67
|
+
logging: {
|
|
68
|
+
// Fake level 1 as 2 to get headers for ray-id
|
|
69
|
+
level: logging.level === 1 ? 2 : logging.level,
|
|
70
|
+
...('color' in logging && { color: logging.color }),
|
|
71
|
+
...(logging.level > 0 && {
|
|
72
|
+
custom: async (...args) => {
|
|
73
|
+
const [, id, , url, headers] = args;
|
|
74
|
+
const customUrl = new URL(url);
|
|
75
|
+
const customHeaders = new Headers(headers);
|
|
76
|
+
if (customHeaders.has('cf-ray')) {
|
|
77
|
+
args.splice(3, 0, customHeaders.get('cf-ray'));
|
|
78
|
+
}
|
|
79
|
+
if ('color' in logging && logging.color) {
|
|
80
|
+
await import('chalk')
|
|
81
|
+
.then(({ Chalk }) => {
|
|
82
|
+
const chalk = new Chalk({ level: 2 });
|
|
83
|
+
if (customHeaders.has('cf-ray')) {
|
|
84
|
+
args.splice(3, 1, chalk.rgb(255, 102, 51)(customHeaders.get('cf-ray')));
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
88
|
+
.catch(() => { });
|
|
89
|
+
}
|
|
90
|
+
if ('custom' in logging && logging.custom) {
|
|
91
|
+
// We faked level 1 as 2 to get headers for ray-id
|
|
92
|
+
if (logging.level === 1) {
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
94
|
+
return logging.custom(...args.slice(0, -1));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
98
|
+
return logging.custom(...args);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
await Promise.all([import('strip-ansi'), import('chalk'), import("./index.mjs")]).then(([{ default: stripAnsi }, { Chalk }, { Helpers }]) => {
|
|
103
|
+
const chalk = new Chalk({ level: 2 });
|
|
104
|
+
// We faked level 1 as 2 to get headers for ray-id
|
|
105
|
+
if (logging.level === 1) {
|
|
106
|
+
console.info('CF Rest',
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
108
|
+
...args
|
|
109
|
+
.slice(0, -1)
|
|
110
|
+
// Convert date to ISO string
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
112
|
+
.map((value) => (value instanceof Date && !isNaN(value.getTime()) ? value.toISOString() : value))
|
|
113
|
+
// Wrap id in brackets
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
115
|
+
.map((value) => (value === id ? chalk.rgb(...Helpers.uniqueIdColor(stripAnsi(id)))(`[${stripAnsi(id)}]`) : value))
|
|
116
|
+
// Strip out redundant parts of url
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
118
|
+
.map((value) => (value === url ? `${customUrl.pathname}${customUrl.search}${customUrl.hash}` : value)));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.info('CF Rest',
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
123
|
+
...args
|
|
124
|
+
// Convert date to ISO string
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
126
|
+
.map((value) => (value instanceof Date && !isNaN(value.getTime()) ? value.toISOString() : value))
|
|
127
|
+
// Wrap id in brackets
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
129
|
+
.map((value) => (value === id ? chalk.rgb(...Helpers.uniqueIdColor(stripAnsi(id)))(`[${stripAnsi(id)}]`) : value))
|
|
130
|
+
// Strip out redundant parts of url
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
132
|
+
.map((value) => (value === url ? `${customUrl.pathname}${customUrl.search}${customUrl.hash}` : value)));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
return this.loggingFetch(info, loggingFetchInit);
|
|
50
141
|
},
|
|
51
142
|
}));
|
|
52
143
|
}
|
|
53
|
-
static
|
|
54
|
-
|
|
55
|
-
|
|
144
|
+
static loggingFetchInit() {
|
|
145
|
+
return Promise.all([import('zod'), this.loggingFetchInitLogging()]).then(([{ z }, logging]) => z.object({
|
|
146
|
+
logging,
|
|
147
|
+
}));
|
|
56
148
|
}
|
|
57
|
-
static
|
|
58
|
-
return import(
|
|
149
|
+
static loggingFetchInitLogging() {
|
|
150
|
+
return import('zod').then(({ z }) => z
|
|
151
|
+
.union([
|
|
152
|
+
z.object({
|
|
153
|
+
level: z.literal(0),
|
|
154
|
+
}),
|
|
155
|
+
z.object({
|
|
156
|
+
level: z.coerce.number().int().min(1).max(3),
|
|
157
|
+
color: z.boolean().default(true),
|
|
158
|
+
custom: z
|
|
159
|
+
.function()
|
|
160
|
+
// .args()
|
|
161
|
+
.returns(z.union([z.void(), z.promise(z.void())]))
|
|
162
|
+
.optional(),
|
|
163
|
+
}),
|
|
164
|
+
])
|
|
165
|
+
.default({
|
|
166
|
+
level: 0,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A utility function that wraps the native `fetch` API with enhanced capabilities.
|
|
171
|
+
* This function allows for customizable logging of request and response details, including headers, body, and status, with support for colorized output and custom logging handlers.
|
|
172
|
+
*
|
|
173
|
+
* @template RI - The type of the `RequestInit` object, defaulting to `RequestInit`. Intended for cloudflare's `RequestInit` variation.
|
|
174
|
+
*
|
|
175
|
+
* @param info - The input to the `fetch` function, which can be a `Request` object or a URL string.
|
|
176
|
+
* @param init - An optional configuration object extending `RequestInit` with additional options.
|
|
177
|
+
*
|
|
178
|
+
* @returns A promise that resolves to the `Response` object returned by the `fetch` call.
|
|
179
|
+
*
|
|
180
|
+
* ### Logging Levels:
|
|
181
|
+
* - `level >= 1`: Logs basic request details (timestamp, unique ID, method, and URL).
|
|
182
|
+
* - `level >= 2`: Logs request headers (with sensitive headers stripped).
|
|
183
|
+
* - `level >= 3`: Logs request body (if available) and response body (if available).
|
|
184
|
+
*
|
|
185
|
+
* ### Logging Options:
|
|
186
|
+
* - `logging.level`: The verbosity level of logging (1, 2, or 3).
|
|
187
|
+
* - `logging.color`: A boolean indicating whether to use colorized output.
|
|
188
|
+
* - `logging.custom`: An optional custom logging function to handle the log output.
|
|
189
|
+
*
|
|
190
|
+
* ### Features:
|
|
191
|
+
* - Automatically generates a unique ID for each request.
|
|
192
|
+
* - Strips sensitive headers from logs to ensure security.
|
|
193
|
+
* - Supports JSON and stream-based request/response bodies.
|
|
194
|
+
* - Allows for colorized output using the `chalk` library.
|
|
195
|
+
* - Provides hooks for custom logging implementations.
|
|
196
|
+
*/
|
|
197
|
+
static loggingFetch(info, init) {
|
|
198
|
+
return NetHelpers.loggingFetchInit()
|
|
199
|
+
.then((parser) => parser.passthrough().parseAsync(init))
|
|
200
|
+
.then((parsed) => parsed)
|
|
201
|
+
.then((init) => import("./crypto.mjs")
|
|
59
202
|
.then(({ CryptoHelpers }) => CryptoHelpers.base62secret(8))
|
|
60
203
|
.then(async (id) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
204
|
+
if (init.logging.level) {
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
206
|
+
const loggingItems = [new Date(), id, init?.method ?? Methods.GET, this.isRequestLike(info) ? info.url : info.toString()];
|
|
207
|
+
if (init.logging.level >= 2) {
|
|
208
|
+
loggingItems.push(Object.fromEntries(this.stripSensitiveHeaders(new Headers(init?.headers)).entries()));
|
|
65
209
|
}
|
|
66
|
-
|
|
67
|
-
|
|
210
|
+
if (init.logging.level >= 3 && init?.body) {
|
|
211
|
+
if (init.body instanceof ReadableStream) {
|
|
212
|
+
loggingItems.push(Array.from(new Uint8Array(await new Response(init.body).arrayBuffer())));
|
|
213
|
+
}
|
|
214
|
+
else if (new Headers(init.headers).get('Content-Type')?.toLowerCase().startsWith('application/json')) {
|
|
215
|
+
loggingItems.push(JSON.parse(init.body));
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
loggingItems.push(init.body);
|
|
219
|
+
}
|
|
68
220
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
case 'PUT':
|
|
86
|
-
loggingItems.splice(2, 1, chalk.hex('#fca130')(initMethod));
|
|
87
|
-
break;
|
|
88
|
-
case 'DELETE':
|
|
89
|
-
loggingItems.splice(2, 1, chalk.hex('#f93e3e')(initMethod));
|
|
90
|
-
break;
|
|
91
|
-
case 'HEAD':
|
|
92
|
-
loggingItems.splice(2, 1, chalk.hex('#9012fe')(initMethod));
|
|
93
|
-
break;
|
|
94
|
-
case 'PATCH':
|
|
95
|
-
loggingItems.splice(2, 1, chalk.hex('#50e3c2')(initMethod));
|
|
96
|
-
break;
|
|
221
|
+
if ('color' in init.logging && init.logging.color) {
|
|
222
|
+
await Promise.all([import('chalk'), import("./index.mjs")])
|
|
223
|
+
.then(([{ Chalk }, { Helpers }]) => {
|
|
224
|
+
const chalk = new Chalk({ level: 2 });
|
|
225
|
+
loggingItems.splice(1, 1, chalk.rgb(...Helpers.uniqueIdColor(id))(id));
|
|
226
|
+
})
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
228
|
+
.catch(() => { });
|
|
229
|
+
await this.methodColors(loggingItems[2])
|
|
230
|
+
.then((color) => {
|
|
231
|
+
if (color) {
|
|
232
|
+
loggingItems.splice(2, 1, color(loggingItems[2]));
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
236
|
+
.catch(() => { });
|
|
97
237
|
}
|
|
98
|
-
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
100
|
-
.catch(() => { });
|
|
101
|
-
if (typeof logger === 'boolean') {
|
|
102
|
-
if (logger) {
|
|
238
|
+
if ('custom' in init.logging && init.logging.custom) {
|
|
103
239
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
104
|
-
|
|
240
|
+
await init.logging.custom(...loggingItems);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
console.info(
|
|
244
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
245
|
+
...loggingItems
|
|
246
|
+
// Convert date to ISO string
|
|
247
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
248
|
+
.map((value) => (value instanceof Date && !isNaN(value.getTime()) ? value.toISOString() : value))
|
|
249
|
+
// Wrap id in brackets
|
|
250
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
251
|
+
.map((value) => (typeof value === 'string' && value.includes(id) ? value.replace(id, `[${id}]`) : value)));
|
|
105
252
|
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
109
|
-
await logger(...loggingItems);
|
|
110
253
|
}
|
|
111
254
|
return id;
|
|
112
255
|
})
|
|
@@ -114,37 +257,114 @@ export class NetHelpers {
|
|
|
114
257
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
115
258
|
new Promise((resolve, reject) => fetch(info, init)
|
|
116
259
|
.then(async (response) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
if (
|
|
121
|
-
loggingItems.push(
|
|
260
|
+
if (init.logging.level) {
|
|
261
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
262
|
+
const loggingItems = [new Date(), id, response.status, response.url];
|
|
263
|
+
if (init.logging.level >= 2) {
|
|
264
|
+
loggingItems.push(Object.fromEntries(this.stripSensitiveHeaders(response.headers).entries()));
|
|
122
265
|
}
|
|
123
|
-
|
|
124
|
-
|
|
266
|
+
if (init.logging.level >= 3 && init?.body) {
|
|
267
|
+
const loggingClone = response.clone();
|
|
268
|
+
if (response.headers.get('Content-Type')?.toLowerCase().startsWith('application/json')) {
|
|
269
|
+
loggingItems.push(await loggingClone.json());
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
loggingItems.push(await loggingClone.text());
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* @todo @demosjarco detect if the body is a stream and convert it to an array
|
|
276
|
+
*/
|
|
125
277
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (
|
|
278
|
+
if ('color' in init.logging && init.logging.color) {
|
|
279
|
+
await Promise.all([import('chalk'), import("./index.mjs")])
|
|
280
|
+
.then(([{ Chalk }, { Helpers }]) => {
|
|
281
|
+
const chalk = new Chalk({ level: 2 });
|
|
282
|
+
loggingItems.splice(1, 1, chalk.rgb(...Helpers.uniqueIdColor(id))(id));
|
|
283
|
+
loggingItems.splice(2, 1, response.ok ? chalk.green(response.status) : chalk.red(response.status));
|
|
284
|
+
})
|
|
285
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
286
|
+
.catch(() => { });
|
|
287
|
+
}
|
|
288
|
+
if ('custom' in init.logging && init.logging.custom) {
|
|
137
289
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
138
|
-
|
|
290
|
+
await init.logging.custom(...loggingItems);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
console.info(
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
295
|
+
...loggingItems
|
|
296
|
+
// Convert date to ISO string
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
298
|
+
.map((value) => (value instanceof Date && !isNaN(value.getTime()) ? value.toISOString() : value))
|
|
299
|
+
// Wrap id in brackets
|
|
300
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
301
|
+
.map((value) => (typeof value === 'string' && value.includes(id) ? value.replace(id, `[${id}]`) : value)));
|
|
139
302
|
}
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
143
|
-
await logger(...loggingItems);
|
|
144
303
|
}
|
|
145
304
|
resolve(response);
|
|
146
305
|
})
|
|
147
|
-
.catch(reject)));
|
|
306
|
+
.catch(reject))));
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Removes sensitive headers from the provided `Headers` object. Specifically, it deletes the `Set-Cookie` and `Authorization` headers.
|
|
310
|
+
*
|
|
311
|
+
* @param originalHeaders - The original `Headers` object to sanitize. Defaults to an empty `Headers` object if not provided.
|
|
312
|
+
* @returns A new `Headers` object with the sensitive headers removed.
|
|
313
|
+
*/
|
|
314
|
+
static stripSensitiveHeaders(originalHeaders = new Headers()) {
|
|
315
|
+
const mutableHeaders = new Headers(originalHeaders);
|
|
316
|
+
mutableHeaders.delete('Set-Cookie');
|
|
317
|
+
mutableHeaders.delete('Authorization');
|
|
318
|
+
return mutableHeaders;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Determines if the given object is a `Request`-like object.
|
|
322
|
+
*
|
|
323
|
+
* This function checks if the provided object has a `url` property of type `string`,
|
|
324
|
+
* which is a characteristic of the `Request` object used in the Fetch API.
|
|
325
|
+
*
|
|
326
|
+
* @param obj - The object to check, typically the first parameter of the `fetch` function.
|
|
327
|
+
* @returns A boolean indicating whether the object is a `Request` instance.
|
|
328
|
+
*/
|
|
329
|
+
static isRequestLike(obj) {
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
331
|
+
return typeof obj?.url === 'string';
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Returns a promise that resolves to a `chalk` instance with a color corresponding to the provided HTTP method.
|
|
335
|
+
*
|
|
336
|
+
* The colors are based on the Swagger UI method colors:
|
|
337
|
+
* @link https://github.com/swagger-api/swagger-ui/blob/master/src/style/_variables.scss#L48-L55
|
|
338
|
+
*
|
|
339
|
+
* @param method - The HTTP method for which to retrieve the color.
|
|
340
|
+
* @returns A promise that resolves to a `chalk` instance with the color corresponding to the provided HTTP method.
|
|
341
|
+
* @throws An error if the provided method is unsupported.
|
|
342
|
+
*/
|
|
343
|
+
static methodColors(method) {
|
|
344
|
+
return import('chalk').then(({ Chalk }) => {
|
|
345
|
+
const chalk = new Chalk({ level: 2 });
|
|
346
|
+
/**
|
|
347
|
+
* @link https://github.com/swagger-api/swagger-ui/blob/master/src/style/_variables.scss#L48-L55
|
|
348
|
+
*/
|
|
349
|
+
switch (method) {
|
|
350
|
+
case Methods.GET:
|
|
351
|
+
return chalk.hex('#61affe');
|
|
352
|
+
case Methods.HEAD:
|
|
353
|
+
return chalk.hex('#9012fe');
|
|
354
|
+
case Methods.POST:
|
|
355
|
+
return chalk.hex('#49cc90');
|
|
356
|
+
case Methods.PUT:
|
|
357
|
+
return chalk.hex('#fca130');
|
|
358
|
+
case Methods.DELETE:
|
|
359
|
+
return chalk.hex('#f93e3e');
|
|
360
|
+
case Methods.OPTIONS:
|
|
361
|
+
return chalk.hex('#0d5aa7');
|
|
362
|
+
case Methods.PATCH:
|
|
363
|
+
return chalk.hex('#50e3c2');
|
|
364
|
+
default:
|
|
365
|
+
throw new Error(`Unsupported method: ${method}`);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
148
368
|
}
|
|
149
369
|
/**
|
|
150
370
|
* Parses the Server-Timing header and returns an object with the metrics.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chainfuse/helpers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "ChainFuse",
|
|
6
6
|
"homepage": "https://github.com/ChainFuse/packages/tree/main/packages/helpers#readme",
|
|
@@ -51,12 +51,14 @@
|
|
|
51
51
|
"@discordjs/rest": "^2.4.3",
|
|
52
52
|
"chalk": "^5.4.1",
|
|
53
53
|
"cloudflare": "^4.2.0",
|
|
54
|
-
"
|
|
54
|
+
"strip-ansi": "^7.1.0",
|
|
55
|
+
"uuid": "^11.1.0",
|
|
56
|
+
"zod": "^3.24.3"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
|
-
"@chainfuse/types": "^2.10.
|
|
58
|
-
"@cloudflare/workers-types": "^4.
|
|
59
|
-
"@types/node": "^22.14.
|
|
59
|
+
"@chainfuse/types": "^2.10.1",
|
|
60
|
+
"@cloudflare/workers-types": "^4.20250417.0",
|
|
61
|
+
"@types/node": "^22.14.1"
|
|
60
62
|
},
|
|
61
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "ed937523841735fb5d944dfe1a5bc8d396a601c5"
|
|
62
64
|
}
|