@h3ravel/http 11.4.3 → 11.5.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/app.globals.d.ts +10 -0
- package/dist/index.cjs +1329 -30
- package/dist/index.d.cts +825 -20
- package/dist/index.d.ts +824 -19
- package/dist/index.js +1318 -30
- package/package.json +7 -6
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-BncF-t-1.cjs');
|
|
2
|
+
let fs_promises = require("fs/promises");
|
|
3
|
+
fs_promises = require_chunk.__toESM(fs_promises);
|
|
4
|
+
let __h3ravel_support = require("@h3ravel/support");
|
|
5
|
+
__h3ravel_support = require_chunk.__toESM(__h3ravel_support);
|
|
2
6
|
let __h3ravel_musket = require("@h3ravel/musket");
|
|
3
7
|
__h3ravel_musket = require_chunk.__toESM(__h3ravel_musket);
|
|
4
8
|
let __h3ravel_shared = require("@h3ravel/shared");
|
|
@@ -35,9 +39,696 @@ let node_buffer = require("node:buffer");
|
|
|
35
39
|
node_buffer = require_chunk.__toESM(node_buffer);
|
|
36
40
|
let h3 = require("h3");
|
|
37
41
|
h3 = require_chunk.__toESM(h3);
|
|
38
|
-
let __h3ravel_support = require("@h3ravel/support");
|
|
39
|
-
__h3ravel_support = require_chunk.__toESM(__h3ravel_support);
|
|
40
42
|
|
|
43
|
+
//#region src/Exceptions/BadRequestException.ts
|
|
44
|
+
var BadRequestException = class extends Error {
|
|
45
|
+
constructor(message) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "BadRequestException";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/Exceptions/UnexpectedValueException.ts
|
|
53
|
+
var UnexpectedValueException = class extends Error {
|
|
54
|
+
constructor(message) {
|
|
55
|
+
super(message);
|
|
56
|
+
this.name = "UnexpectedValueException";
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/Bags/ParamBag.ts
|
|
62
|
+
/**
|
|
63
|
+
* ParamBag is a container for key/value pairs
|
|
64
|
+
* for Node/H3 environments.
|
|
65
|
+
*/
|
|
66
|
+
var ParamBag = class {
|
|
67
|
+
constructor(parameters = {}, event) {
|
|
68
|
+
this.parameters = parameters;
|
|
69
|
+
this.event = event;
|
|
70
|
+
this.parameters = { ...parameters };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns the parameters.
|
|
74
|
+
* @
|
|
75
|
+
* @param key The name of the parameter to return or null to get them all
|
|
76
|
+
*
|
|
77
|
+
* @throws BadRequestException if the value is not an array
|
|
78
|
+
*/
|
|
79
|
+
all(key) {
|
|
80
|
+
if (key === null) return { ...this.parameters };
|
|
81
|
+
const value = key ? this.parameters[key] : void 0;
|
|
82
|
+
if (value && typeof value !== "object") throw new BadRequestException(`Unexpected value for parameter "${key}": expected object, got ${typeof value}`);
|
|
83
|
+
return value || {};
|
|
84
|
+
}
|
|
85
|
+
get(key, defaultValue) {
|
|
86
|
+
return key in this.parameters ? this.parameters[key] : defaultValue;
|
|
87
|
+
}
|
|
88
|
+
set(key, value) {
|
|
89
|
+
this.parameters[key] = value;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Returns true if the parameter is defined.
|
|
93
|
+
*
|
|
94
|
+
* @param key
|
|
95
|
+
*/
|
|
96
|
+
has(key) {
|
|
97
|
+
return Object.prototype.hasOwnProperty.call(this.parameters, key);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Removes a parameter.
|
|
101
|
+
*
|
|
102
|
+
* @param key
|
|
103
|
+
*/
|
|
104
|
+
remove(key) {
|
|
105
|
+
delete this.parameters[key];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* Returns the parameter as string.
|
|
110
|
+
*
|
|
111
|
+
* @param key
|
|
112
|
+
* @param defaultValue
|
|
113
|
+
* @throws UnexpectedValueException if the value cannot be converted to string
|
|
114
|
+
* @returns
|
|
115
|
+
*/
|
|
116
|
+
getString(key, defaultValue = "") {
|
|
117
|
+
const value = this.get(key, defaultValue);
|
|
118
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
|
|
119
|
+
throw new UnexpectedValueException(`Parameter "${key}" cannot be converted to string`);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Returns the parameter value converted to integer.
|
|
123
|
+
*
|
|
124
|
+
* @param key
|
|
125
|
+
* @param defaultValue
|
|
126
|
+
* @throws UnexpectedValueException if the value cannot be converted to integer
|
|
127
|
+
*/
|
|
128
|
+
getInt(key, defaultValue = 0) {
|
|
129
|
+
const value = parseInt(this.get(key, defaultValue), 10);
|
|
130
|
+
if (isNaN(value)) throw new Error(`Parameter "${key}" is not an integer`);
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Returns the parameter value converted to boolean.
|
|
135
|
+
*
|
|
136
|
+
* @param key
|
|
137
|
+
* @param defaultValue
|
|
138
|
+
* @throws UnexpectedValueException if the value cannot be converted to a boolean
|
|
139
|
+
*/
|
|
140
|
+
getBoolean(key, defaultValue = false) {
|
|
141
|
+
const value = this.get(key, defaultValue);
|
|
142
|
+
if (typeof value === "boolean") return value;
|
|
143
|
+
if ([
|
|
144
|
+
"1",
|
|
145
|
+
"true",
|
|
146
|
+
"yes"
|
|
147
|
+
].includes(String(value).toLowerCase())) return true;
|
|
148
|
+
if ([
|
|
149
|
+
"0",
|
|
150
|
+
"false",
|
|
151
|
+
"no"
|
|
152
|
+
].includes(String(value).toLowerCase())) return false;
|
|
153
|
+
throw new Error(`Parameter "${key}" cannot be converted to boolean`);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns the alphabetic characters of the parameter value.
|
|
157
|
+
*
|
|
158
|
+
* @param key
|
|
159
|
+
* @param defaultValue
|
|
160
|
+
* @throws UnexpectedValueException if the value cannot be converted to string
|
|
161
|
+
*/
|
|
162
|
+
getAlpha(key, defaultValue = "") {
|
|
163
|
+
return this.getString(key, defaultValue).replace(/[^a-z]/gi, "");
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns the alphabetic characters and digits of the parameter value.
|
|
167
|
+
*
|
|
168
|
+
* @param key
|
|
169
|
+
* @param defaultValue
|
|
170
|
+
* @throws UnexpectedValueException if the value cannot be converted to string
|
|
171
|
+
*/
|
|
172
|
+
getAlnum(key, defaultValue = "") {
|
|
173
|
+
return this.getString(key, defaultValue).replace(/[^a-z0-9]/gi, "");
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Returns the digits of the parameter value.
|
|
177
|
+
*
|
|
178
|
+
* @param key
|
|
179
|
+
* @param defaultValue
|
|
180
|
+
* @throws UnexpectedValueException if the value cannot be converted to string
|
|
181
|
+
* @returns
|
|
182
|
+
**/
|
|
183
|
+
getDigits(key, defaultValue = "") {
|
|
184
|
+
return this.getString(key, defaultValue).replace(/\D/g, "");
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Returns the parameter keys.
|
|
188
|
+
*/
|
|
189
|
+
keys() {
|
|
190
|
+
return Object.keys(this.parameters);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Replaces the current parameters by a new set.
|
|
194
|
+
*/
|
|
195
|
+
replace(parameters = {}) {
|
|
196
|
+
this.parameters = { ...parameters };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Adds parameters.
|
|
200
|
+
*/
|
|
201
|
+
add(parameters = {}) {
|
|
202
|
+
this.parameters = {
|
|
203
|
+
...this.parameters,
|
|
204
|
+
...parameters
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Returns the number of parameters.
|
|
209
|
+
*/
|
|
210
|
+
count() {
|
|
211
|
+
return Object.keys(this.parameters).length;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns an iterator for parameters.
|
|
215
|
+
*
|
|
216
|
+
* @returns
|
|
217
|
+
*/
|
|
218
|
+
[Symbol.iterator]() {
|
|
219
|
+
return Object.entries(this.parameters)[Symbol.iterator]();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/UploadedFile.ts
|
|
225
|
+
var UploadedFile = class UploadedFile {
|
|
226
|
+
constructor(originalName, mimeType, size, content) {
|
|
227
|
+
this.originalName = originalName;
|
|
228
|
+
this.mimeType = mimeType;
|
|
229
|
+
this.size = size;
|
|
230
|
+
this.content = content;
|
|
231
|
+
}
|
|
232
|
+
static createFromBase(file) {
|
|
233
|
+
return new UploadedFile(file.name, file.type, file.size, file);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Save to disk (Node environment only)
|
|
237
|
+
*/
|
|
238
|
+
async moveTo(destination) {
|
|
239
|
+
await (0, fs_promises.writeFile)(destination, Buffer.from(await this.content.arrayBuffer()));
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/Bags/FileBag.ts
|
|
245
|
+
/**
|
|
246
|
+
* FileBag is a container for uploaded files
|
|
247
|
+
* for Node/H3 environments.
|
|
248
|
+
*/
|
|
249
|
+
var FileBag = class extends ParamBag {
|
|
250
|
+
parameters = {};
|
|
251
|
+
constructor(parameters = {}, event) {
|
|
252
|
+
super(parameters, event);
|
|
253
|
+
this.replace(parameters);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Replace all stored files.
|
|
257
|
+
*/
|
|
258
|
+
replace(files = {}) {
|
|
259
|
+
this.parameters = {};
|
|
260
|
+
this.add(files);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Set a file or array of files.
|
|
264
|
+
*/
|
|
265
|
+
set(key, value) {
|
|
266
|
+
if (Array.isArray(value)) this.parameters[key] = value.map((v) => v ? this.convertFileInformation(v) : null).filter(Boolean);
|
|
267
|
+
else if (value) this.parameters[key] = this.convertFileInformation(value);
|
|
268
|
+
else this.parameters[key] = null;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Add multiple files.
|
|
272
|
+
*/
|
|
273
|
+
add(files = {}) {
|
|
274
|
+
for (const [key, file] of Object.entries(files)) this.set(key, file);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get all stored files.
|
|
278
|
+
*/
|
|
279
|
+
all() {
|
|
280
|
+
return this.parameters;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Normalize file input into UploadedFile instances.
|
|
284
|
+
*/
|
|
285
|
+
convertFileInformation(file) {
|
|
286
|
+
if (!file) return null;
|
|
287
|
+
if (file instanceof UploadedFile) return file;
|
|
288
|
+
if (file instanceof File) return UploadedFile.createFromBase(file);
|
|
289
|
+
throw new TypeError("Invalid file input — expected File or UploadedFile instance.");
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/Bags/HeaderBag.ts
|
|
295
|
+
/**
|
|
296
|
+
* HeaderBag — A container for HTTP headers
|
|
297
|
+
* for Node/H3 environments.
|
|
298
|
+
*/
|
|
299
|
+
var HeaderBag = class HeaderBag {
|
|
300
|
+
static UPPER = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
301
|
+
static LOWER = "-abcdefghijklmnopqrstuvwxyz";
|
|
302
|
+
headers = {};
|
|
303
|
+
cacheControl = {};
|
|
304
|
+
constructor(headers = {}) {
|
|
305
|
+
for (const [key, values] of Object.entries(headers)) this.set(key, values);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Returns all headers as string (for debugging / toString)
|
|
309
|
+
*
|
|
310
|
+
* @returns
|
|
311
|
+
*/
|
|
312
|
+
toString() {
|
|
313
|
+
const headers = this.all();
|
|
314
|
+
if (!Object.keys(headers).length) return "";
|
|
315
|
+
const sortedKeys = Object.keys(headers).sort();
|
|
316
|
+
const max = Math.max(...sortedKeys.map((k) => k.length)) + 1;
|
|
317
|
+
let content = "";
|
|
318
|
+
for (const name of sortedKeys) {
|
|
319
|
+
const values = headers[name] ?? [];
|
|
320
|
+
const displayName = name.split("-").map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("-");
|
|
321
|
+
for (const value of values) content += `${displayName + ":"}`.padEnd(max + 1, " ") + `${value ?? ""}\r\n`;
|
|
322
|
+
}
|
|
323
|
+
return content;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Returns all headers or specific header list
|
|
327
|
+
*
|
|
328
|
+
* @param key
|
|
329
|
+
* @returns
|
|
330
|
+
*/
|
|
331
|
+
all(key) {
|
|
332
|
+
if (key !== void 0) return this.headers[this.normalizeKey(key)] ?? [];
|
|
333
|
+
return this.headers;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Returns header keys
|
|
337
|
+
*
|
|
338
|
+
* @returns
|
|
339
|
+
*/
|
|
340
|
+
keys() {
|
|
341
|
+
return Object.keys(this.headers);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Replace all headers with new set
|
|
345
|
+
*
|
|
346
|
+
* @param headers
|
|
347
|
+
*/
|
|
348
|
+
replace(headers = {}) {
|
|
349
|
+
this.headers = {};
|
|
350
|
+
this.add(headers);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Add multiple headers
|
|
354
|
+
*
|
|
355
|
+
* @param headers
|
|
356
|
+
*/
|
|
357
|
+
add(headers) {
|
|
358
|
+
for (const [key, values] of Object.entries(headers)) this.set(key, values);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Returns first header value by name or default
|
|
362
|
+
*
|
|
363
|
+
* @param key
|
|
364
|
+
* @param defaultValue
|
|
365
|
+
* @returns
|
|
366
|
+
*/
|
|
367
|
+
get(key, defaultValue = null) {
|
|
368
|
+
const headers = this.all(key);
|
|
369
|
+
if (!headers.length) return defaultValue;
|
|
370
|
+
return headers[0];
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Sets a header by name.
|
|
374
|
+
*
|
|
375
|
+
* @param replace Whether to replace existing values (default true)
|
|
376
|
+
*/
|
|
377
|
+
set(key, values, replace = true) {
|
|
378
|
+
const normalized = this.normalizeKey(key);
|
|
379
|
+
if (Array.isArray(values)) {
|
|
380
|
+
const valList = values.map((v) => v === void 0 ? null : v);
|
|
381
|
+
if (replace || !this.headers[normalized]) this.headers[normalized] = valList;
|
|
382
|
+
else this.headers[normalized].push(...valList);
|
|
383
|
+
} else {
|
|
384
|
+
const val = values === void 0 ? null : values;
|
|
385
|
+
if (replace || !this.headers[normalized]) this.headers[normalized] = [val];
|
|
386
|
+
else this.headers[normalized].push(val);
|
|
387
|
+
}
|
|
388
|
+
if (normalized === "cache-control") this.cacheControl = this.parseCacheControl((this.headers[normalized] ?? []).join(", "));
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Returns true if header exists
|
|
392
|
+
*
|
|
393
|
+
* @param key
|
|
394
|
+
* @returns
|
|
395
|
+
*/
|
|
396
|
+
has(key) {
|
|
397
|
+
return Object.prototype.hasOwnProperty.call(this.headers, this.normalizeKey(key));
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Returns true if header contains value
|
|
401
|
+
*
|
|
402
|
+
* @param key
|
|
403
|
+
* @param value
|
|
404
|
+
* @returns
|
|
405
|
+
*/
|
|
406
|
+
contains(key, value) {
|
|
407
|
+
return this.all(key).includes(value);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Removes a header
|
|
411
|
+
*
|
|
412
|
+
* @param key
|
|
413
|
+
*/
|
|
414
|
+
remove(key) {
|
|
415
|
+
const normalized = this.normalizeKey(key);
|
|
416
|
+
delete this.headers[normalized];
|
|
417
|
+
if (normalized === "cache-control") this.cacheControl = {};
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Returns parsed date from header
|
|
421
|
+
*
|
|
422
|
+
* @param key
|
|
423
|
+
* @param defaultValue
|
|
424
|
+
* @returns
|
|
425
|
+
*/
|
|
426
|
+
getDate(key, defaultValue = null) {
|
|
427
|
+
const value = this.get(key);
|
|
428
|
+
if (!value) return defaultValue ? new Date(defaultValue) : null;
|
|
429
|
+
const parsed = new Date(value);
|
|
430
|
+
if (isNaN(parsed.getTime())) throw new Error(`The "${key}" HTTP header is not parseable (${value}).`);
|
|
431
|
+
return parsed;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Adds a Cache-Control directive
|
|
435
|
+
*
|
|
436
|
+
* @param key
|
|
437
|
+
* @param value
|
|
438
|
+
*/
|
|
439
|
+
addCacheControlDirective(key, value = true) {
|
|
440
|
+
this.cacheControl[key] = value;
|
|
441
|
+
this.set("Cache-Control", this.getCacheControlHeader());
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Returns true if Cache-Control directive is defined
|
|
445
|
+
*
|
|
446
|
+
* @param key
|
|
447
|
+
* @returns
|
|
448
|
+
*/
|
|
449
|
+
hasCacheControlDirective(key) {
|
|
450
|
+
return Object.prototype.hasOwnProperty.call(this.cacheControl, key);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Returns a Cache-Control directive value by name
|
|
454
|
+
*
|
|
455
|
+
* @param key
|
|
456
|
+
* @returns
|
|
457
|
+
*/
|
|
458
|
+
getCacheControlDirective(key) {
|
|
459
|
+
return this.cacheControl[key] ?? null;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Removes a Cache-Control directive
|
|
463
|
+
*
|
|
464
|
+
* @param key
|
|
465
|
+
* @returns
|
|
466
|
+
*/
|
|
467
|
+
removeCacheControlDirective(key) {
|
|
468
|
+
delete this.cacheControl[key];
|
|
469
|
+
this.set("Cache-Control", this.getCacheControlHeader());
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Number of headers
|
|
473
|
+
*
|
|
474
|
+
* @param key
|
|
475
|
+
* @returns
|
|
476
|
+
*/
|
|
477
|
+
count() {
|
|
478
|
+
return Object.keys(this.headers).length;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Normalize header name to lowercase with hyphens
|
|
482
|
+
*
|
|
483
|
+
* @param key
|
|
484
|
+
* @returns
|
|
485
|
+
*/
|
|
486
|
+
normalizeKey(key) {
|
|
487
|
+
return key.replace(/[A-Z_]/g, (ch) => {
|
|
488
|
+
const idx = HeaderBag.UPPER.indexOf(ch);
|
|
489
|
+
return idx === -1 ? ch : HeaderBag.LOWER[idx];
|
|
490
|
+
}).toLowerCase();
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Generates Cache-Control header string
|
|
494
|
+
*
|
|
495
|
+
* @param header
|
|
496
|
+
* @returns
|
|
497
|
+
*/
|
|
498
|
+
getCacheControlHeader() {
|
|
499
|
+
return Object.entries(this.cacheControl).sort(([a$1], [b]) => a$1.localeCompare(b)).map(([k, v]) => v === true ? k : v === false ? "" : `${k}=${v}`).filter(Boolean).join(", ");
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Parses Cache-Control header
|
|
503
|
+
*
|
|
504
|
+
* @param header
|
|
505
|
+
* @returns
|
|
506
|
+
*/
|
|
507
|
+
parseCacheControl(header) {
|
|
508
|
+
const directives = {};
|
|
509
|
+
const parts = header.split(",").map((p) => p.trim()).filter(Boolean);
|
|
510
|
+
for (const part of parts) {
|
|
511
|
+
const [key, val] = part.split("=", 2);
|
|
512
|
+
directives[key.trim()] = val !== void 0 ? val.trim() : true;
|
|
513
|
+
}
|
|
514
|
+
return directives;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Iterator support
|
|
518
|
+
* @returns
|
|
519
|
+
*/
|
|
520
|
+
[Symbol.iterator]() {
|
|
521
|
+
return Object.entries(this.headers)[Symbol.iterator]();
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
//#endregion
|
|
526
|
+
//#region src/Bags/InputBag.ts
|
|
527
|
+
/**
|
|
528
|
+
* InputBag is a container for user input values
|
|
529
|
+
* (e.g., query params, body, cookies)
|
|
530
|
+
* for Node/H3 environments.
|
|
531
|
+
*/
|
|
532
|
+
var InputBag = class extends ParamBag {
|
|
533
|
+
constructor(inputs = {}, event) {
|
|
534
|
+
super(inputs, event);
|
|
535
|
+
this.add(inputs);
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Returns a scalar input value by name.
|
|
539
|
+
*
|
|
540
|
+
* @param key
|
|
541
|
+
* @param defaultValue
|
|
542
|
+
* @throws BadRequestException if the input contains a non-scalar value
|
|
543
|
+
* @returns
|
|
544
|
+
*/
|
|
545
|
+
get(key, defaultValue = null) {
|
|
546
|
+
if (defaultValue !== null && typeof defaultValue !== "string" && typeof defaultValue !== "number" && typeof defaultValue !== "boolean") throw new TypeError(`Expected a scalar value as 2nd argument to get(), got ${typeof defaultValue}`);
|
|
547
|
+
const value = __h3ravel_support.Obj.get(this.parameters, key, defaultValue);
|
|
548
|
+
if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") throw new BadRequestException(`Input value "${key}" contains a non-scalar value.`);
|
|
549
|
+
return value;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Replaces all current input values.
|
|
553
|
+
*
|
|
554
|
+
* @param inputs
|
|
555
|
+
* @returns
|
|
556
|
+
*/
|
|
557
|
+
replace(inputs = {}) {
|
|
558
|
+
this.parameters = {};
|
|
559
|
+
this.add(inputs);
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Adds multiple input values.
|
|
563
|
+
*
|
|
564
|
+
* @param inputs
|
|
565
|
+
* @returns
|
|
566
|
+
*/
|
|
567
|
+
add(inputs = {}) {
|
|
568
|
+
Object.entries(inputs).forEach(([key, value]) => this.set(key, value));
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Sets an input by name.
|
|
572
|
+
*
|
|
573
|
+
* @param key
|
|
574
|
+
* @param value
|
|
575
|
+
* @throws TypeError if value is not scalar or array
|
|
576
|
+
* @returns
|
|
577
|
+
*/
|
|
578
|
+
set(key, value) {
|
|
579
|
+
if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean" && !Array.isArray(value) && typeof value !== "object") throw new TypeError(`Expected scalar, array, object, or null as value for set(), got ${typeof value}`);
|
|
580
|
+
this.parameters[key] = value;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Returns true if a key exists.
|
|
584
|
+
*
|
|
585
|
+
* @param key
|
|
586
|
+
* @returns
|
|
587
|
+
*/
|
|
588
|
+
has(key) {
|
|
589
|
+
return Object.prototype.hasOwnProperty.call(this.parameters, key);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Returns all parameters.
|
|
593
|
+
*
|
|
594
|
+
* @returns
|
|
595
|
+
*/
|
|
596
|
+
all() {
|
|
597
|
+
return { ...this.parameters };
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Converts a parameter value to string.
|
|
601
|
+
*
|
|
602
|
+
* @param key
|
|
603
|
+
* @param defaultValue
|
|
604
|
+
* @throws BadRequestException if input contains a non-scalar value
|
|
605
|
+
* @returns
|
|
606
|
+
*/
|
|
607
|
+
getString(key, defaultValue = "") {
|
|
608
|
+
const value = this.get(key, defaultValue);
|
|
609
|
+
return String(value ?? "");
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Filters input value with a predicate.
|
|
613
|
+
* Mimics PHP’s filter_var() in spirit, but simpler.
|
|
614
|
+
*
|
|
615
|
+
* @param key
|
|
616
|
+
* @param defaultValue
|
|
617
|
+
* @param filterFn
|
|
618
|
+
* @throws BadRequestException if validation fails
|
|
619
|
+
* @returns
|
|
620
|
+
*/
|
|
621
|
+
filter(key, defaultValue = null, filterFn) {
|
|
622
|
+
const value = this.has(key) ? this.parameters[key] : defaultValue;
|
|
623
|
+
if (Array.isArray(value)) throw new BadRequestException(`Input value "${key}" contains an array, but array filtering not allowed.`);
|
|
624
|
+
if (filterFn && !filterFn(value)) throw new BadRequestException(`Input value "${key}" is invalid and did not pass filter.`);
|
|
625
|
+
return value;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Returns an enum value by key.
|
|
629
|
+
*
|
|
630
|
+
* @param key
|
|
631
|
+
* @param EnumClass
|
|
632
|
+
* @param defaultValue
|
|
633
|
+
* @throws BadRequestException if conversion fails
|
|
634
|
+
* @returns
|
|
635
|
+
*/
|
|
636
|
+
getEnum(key, EnumClass, defaultValue = null) {
|
|
637
|
+
const value = this.get(key, defaultValue);
|
|
638
|
+
if (value === null) return defaultValue;
|
|
639
|
+
if (!Object.values(EnumClass).includes(value)) throw new BadRequestException(`Input "${key}" cannot be converted to enum.`);
|
|
640
|
+
return value;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Removes a key.
|
|
644
|
+
*
|
|
645
|
+
* @param key
|
|
646
|
+
*/
|
|
647
|
+
remove(key) {
|
|
648
|
+
delete this.parameters[key];
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Returns all keys.
|
|
652
|
+
*
|
|
653
|
+
* @returns
|
|
654
|
+
*/
|
|
655
|
+
keys() {
|
|
656
|
+
return Object.keys(this.parameters);
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Returns number of parameters.
|
|
660
|
+
*
|
|
661
|
+
* @returns
|
|
662
|
+
*/
|
|
663
|
+
count() {
|
|
664
|
+
return this.keys().length;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/Bags/ServerBag.ts
|
|
670
|
+
/**
|
|
671
|
+
* ServerBag — a simplified version of Symfony's ServerBag
|
|
672
|
+
* for Node/H3 environments.
|
|
673
|
+
*
|
|
674
|
+
* Responsible for extracting and normalizing HTTP headers
|
|
675
|
+
* from the incoming request.
|
|
676
|
+
*/
|
|
677
|
+
var ServerBag = class extends ParamBag {
|
|
678
|
+
constructor(parameters = {}, event) {
|
|
679
|
+
super(Object.fromEntries(Object.entries(parameters).map(([k, v]) => [k.toLowerCase(), v])), event);
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Returns all request headers, normalized to uppercase with underscores.
|
|
683
|
+
* Example: content-type → CONTENT_TYPE
|
|
684
|
+
*/
|
|
685
|
+
getHeaders() {
|
|
686
|
+
const headers = {};
|
|
687
|
+
for (const [key, value] of Object.entries(this.parameters)) {
|
|
688
|
+
if (value === void 0 || value === "") continue;
|
|
689
|
+
switch (key) {
|
|
690
|
+
case "accept":
|
|
691
|
+
case "content-type":
|
|
692
|
+
case "content-length":
|
|
693
|
+
case "content-md5":
|
|
694
|
+
case "authorization":
|
|
695
|
+
headers[key.toUpperCase().replace(/-/g, "_")] = value;
|
|
696
|
+
break;
|
|
697
|
+
default: headers[`HTTP_${key.toUpperCase().replace(/-/g, "_")}`] = value;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
if (headers["HTTP_AUTHORIZATION"] || headers["AUTHORIZATION"]) {
|
|
701
|
+
const auth = headers["HTTP_AUTHORIZATION"] || headers["AUTHORIZATION"] || "";
|
|
702
|
+
if (auth.toLowerCase().startsWith("basic ")) {
|
|
703
|
+
const [user, pass] = Buffer.from(auth.slice(6), "base64").toString().split(":", 2);
|
|
704
|
+
headers["AUTH_TYPE"] = "Basic";
|
|
705
|
+
headers["AUTH_USER"] = user;
|
|
706
|
+
headers["AUTH_PASS"] = pass;
|
|
707
|
+
} else if (auth.toLowerCase().startsWith("bearer ")) {
|
|
708
|
+
headers["AUTH_TYPE"] = "Bearer";
|
|
709
|
+
headers["AUTH_TOKEN"] = auth.slice(7);
|
|
710
|
+
} else if (auth.toLowerCase().startsWith("digest ")) {
|
|
711
|
+
headers["AUTH_TYPE"] = "Digest";
|
|
712
|
+
headers["AUTH_DIGEST"] = auth;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return headers;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Returns a specific header by name, case-insensitive.
|
|
719
|
+
*/
|
|
720
|
+
get(name) {
|
|
721
|
+
return this.parameters[name.toLowerCase()];
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Returns true if a header exists.
|
|
725
|
+
*/
|
|
726
|
+
has(name) {
|
|
727
|
+
return name.toLowerCase() in this.parameters;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
//#endregion
|
|
41
732
|
//#region ../../node_modules/.pnpm/is-plain-obj@4.1.0/node_modules/is-plain-obj/index.js
|
|
42
733
|
function isPlainObject(value) {
|
|
43
734
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -10246,8 +10937,8 @@ var require_graceful_fs = /* @__PURE__ */ require_chunk.__commonJS({ "../../node
|
|
|
10246
10937
|
}
|
|
10247
10938
|
}
|
|
10248
10939
|
var fs$writeFile = fs$9.writeFile;
|
|
10249
|
-
fs$9.writeFile = writeFile;
|
|
10250
|
-
function writeFile(path$16, data, options, cb) {
|
|
10940
|
+
fs$9.writeFile = writeFile$1;
|
|
10941
|
+
function writeFile$1(path$16, data, options, cb) {
|
|
10251
10942
|
if (typeof options === "function") cb = options, options = null;
|
|
10252
10943
|
return go$writeFile(path$16, data, options, cb);
|
|
10253
10944
|
function go$writeFile(path$17, data$1, options$1, cb$1, startTime) {
|
|
@@ -18058,7 +18749,7 @@ var require_dumper = /* @__PURE__ */ require_chunk.__commonJS({ "../../node_modu
|
|
|
18058
18749
|
}
|
|
18059
18750
|
}
|
|
18060
18751
|
}
|
|
18061
|
-
function dump(input, options) {
|
|
18752
|
+
function dump$1(input, options) {
|
|
18062
18753
|
options = options || {};
|
|
18063
18754
|
var state = new State(options);
|
|
18064
18755
|
if (!state.noRefs) getDuplicateReferences(input, state);
|
|
@@ -18066,9 +18757,9 @@ var require_dumper = /* @__PURE__ */ require_chunk.__commonJS({ "../../node_modu
|
|
|
18066
18757
|
return "";
|
|
18067
18758
|
}
|
|
18068
18759
|
function safeDump(input, options) {
|
|
18069
|
-
return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
|
|
18760
|
+
return dump$1(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
|
|
18070
18761
|
}
|
|
18071
|
-
module.exports.dump = dump;
|
|
18762
|
+
module.exports.dump = dump$1;
|
|
18072
18763
|
module.exports.safeDump = safeDump;
|
|
18073
18764
|
}) });
|
|
18074
18765
|
|
|
@@ -18279,6 +18970,68 @@ var FireCommand = class extends __h3ravel_musket.Command {
|
|
|
18279
18970
|
}
|
|
18280
18971
|
};
|
|
18281
18972
|
|
|
18973
|
+
//#endregion
|
|
18974
|
+
//#region src/Exceptions/SuspiciousOperationException.ts
|
|
18975
|
+
var SuspiciousOperationException = class extends Error {
|
|
18976
|
+
constructor(message) {
|
|
18977
|
+
super(message);
|
|
18978
|
+
this.name = "SuspiciousOperationException";
|
|
18979
|
+
}
|
|
18980
|
+
};
|
|
18981
|
+
|
|
18982
|
+
//#endregion
|
|
18983
|
+
//#region src/FormRequest.ts
|
|
18984
|
+
var FormRequest = class {
|
|
18985
|
+
dataset;
|
|
18986
|
+
constructor(data) {
|
|
18987
|
+
this.initialize(data);
|
|
18988
|
+
}
|
|
18989
|
+
/**
|
|
18990
|
+
* Initialize the data
|
|
18991
|
+
* @param data
|
|
18992
|
+
*/
|
|
18993
|
+
initialize(data) {
|
|
18994
|
+
this.dataset = {
|
|
18995
|
+
files: {},
|
|
18996
|
+
input: {}
|
|
18997
|
+
};
|
|
18998
|
+
for (const [rawKey, value] of data.entries()) {
|
|
18999
|
+
const key = rawKey.endsWith("[]") ? rawKey.slice(0, -2) : rawKey;
|
|
19000
|
+
if (value instanceof File) {
|
|
19001
|
+
const uploaded = value instanceof UploadedFile ? value : UploadedFile.createFromBase(value);
|
|
19002
|
+
if (this.dataset.files[key]) {
|
|
19003
|
+
const existing = this.dataset.files[key];
|
|
19004
|
+
if (Array.isArray(existing)) existing.push(uploaded);
|
|
19005
|
+
else this.dataset.files[key] = [existing, uploaded];
|
|
19006
|
+
} else this.dataset.files[key] = uploaded;
|
|
19007
|
+
} else if (this.dataset.input[key]) {
|
|
19008
|
+
const existing = this.dataset.input[key];
|
|
19009
|
+
if (Array.isArray(existing)) existing.push(value);
|
|
19010
|
+
else this.dataset.input[key] = [existing, value];
|
|
19011
|
+
} else this.dataset.input[key] = value;
|
|
19012
|
+
}
|
|
19013
|
+
}
|
|
19014
|
+
/**
|
|
19015
|
+
* Get all uploaded files
|
|
19016
|
+
*/
|
|
19017
|
+
files() {
|
|
19018
|
+
return this.dataset.files;
|
|
19019
|
+
}
|
|
19020
|
+
/**
|
|
19021
|
+
* Get all input fields
|
|
19022
|
+
*/
|
|
19023
|
+
input() {
|
|
19024
|
+
return this.dataset.input;
|
|
19025
|
+
}
|
|
19026
|
+
/**
|
|
19027
|
+
* Get combined input and files
|
|
19028
|
+
* File entries take precedence if names overlap.
|
|
19029
|
+
*/
|
|
19030
|
+
all() {
|
|
19031
|
+
return Object.assign({}, this.dataset.input, this.dataset.files);
|
|
19032
|
+
}
|
|
19033
|
+
};
|
|
19034
|
+
|
|
18282
19035
|
//#endregion
|
|
18283
19036
|
//#region src/Middleware.ts
|
|
18284
19037
|
var Middleware = class {};
|
|
@@ -18325,50 +19078,586 @@ var HttpServiceProvider = class {
|
|
|
18325
19078
|
|
|
18326
19079
|
//#endregion
|
|
18327
19080
|
//#region src/Request.ts
|
|
18328
|
-
var Request = class {
|
|
19081
|
+
var Request = class Request {
|
|
19082
|
+
/**
|
|
19083
|
+
* Parsed request body
|
|
19084
|
+
*/
|
|
19085
|
+
body;
|
|
19086
|
+
/**
|
|
19087
|
+
* The decoded JSON content for the request.
|
|
19088
|
+
*/
|
|
19089
|
+
#json;
|
|
19090
|
+
#uri;
|
|
19091
|
+
#method = void 0;
|
|
18329
19092
|
/**
|
|
18330
19093
|
* Gets route parameters.
|
|
18331
19094
|
* @returns An object containing route parameters.
|
|
18332
19095
|
*/
|
|
18333
19096
|
params;
|
|
18334
19097
|
/**
|
|
18335
|
-
*
|
|
18336
|
-
|
|
19098
|
+
* All of the converted files for the request.
|
|
19099
|
+
*/
|
|
19100
|
+
convertedFiles;
|
|
19101
|
+
/**
|
|
19102
|
+
* Form data from incoming request.
|
|
19103
|
+
* @returns The FormRequest object.
|
|
19104
|
+
*/
|
|
19105
|
+
formData;
|
|
19106
|
+
/**
|
|
19107
|
+
* Request body parameters (POST).
|
|
19108
|
+
*
|
|
19109
|
+
* @see getPayload() for portability between content types
|
|
19110
|
+
*/
|
|
19111
|
+
request;
|
|
19112
|
+
/**
|
|
19113
|
+
* Query string parameters (GET).
|
|
18337
19114
|
*/
|
|
18338
19115
|
query;
|
|
18339
19116
|
/**
|
|
19117
|
+
* Uploaded files (FILES).
|
|
19118
|
+
*/
|
|
19119
|
+
files;
|
|
19120
|
+
/**
|
|
19121
|
+
* Server and execution environment parameters
|
|
19122
|
+
*/
|
|
19123
|
+
server;
|
|
19124
|
+
/**
|
|
19125
|
+
* Cookies
|
|
19126
|
+
*/
|
|
19127
|
+
cookies;
|
|
19128
|
+
/**
|
|
19129
|
+
* The request attributes (parameters parsed from the PATH_INFO, ...).
|
|
19130
|
+
*/
|
|
19131
|
+
attributes;
|
|
19132
|
+
/**
|
|
18340
19133
|
* Gets the request headers.
|
|
18341
19134
|
* @returns An object containing request headers.
|
|
18342
19135
|
*/
|
|
18343
19136
|
headers;
|
|
19137
|
+
content = void 0;
|
|
19138
|
+
static formats = void 0;
|
|
19139
|
+
static httpMethodParameterOverride = false;
|
|
18344
19140
|
/**
|
|
18345
|
-
*
|
|
19141
|
+
* List of Acceptable Content Types
|
|
18346
19142
|
*/
|
|
18347
|
-
|
|
19143
|
+
acceptableContentTypes = [];
|
|
18348
19144
|
constructor(event, app) {
|
|
18349
|
-
this.app = app;
|
|
18350
19145
|
this.event = event;
|
|
18351
|
-
this.
|
|
19146
|
+
this.app = app;
|
|
19147
|
+
}
|
|
19148
|
+
/**
|
|
19149
|
+
* Factory method to create a Request instance from an H3Event.
|
|
19150
|
+
*/
|
|
19151
|
+
static async create(event, app) {
|
|
19152
|
+
const instance = new Request(event, app);
|
|
19153
|
+
await instance.setBody();
|
|
19154
|
+
await instance.initialize();
|
|
19155
|
+
globalThis.request = () => instance;
|
|
19156
|
+
return instance;
|
|
19157
|
+
}
|
|
19158
|
+
/**
|
|
19159
|
+
* Sets the parameters for this request.
|
|
19160
|
+
*
|
|
19161
|
+
* This method also re-initializes all properties.
|
|
19162
|
+
*
|
|
19163
|
+
* @param attributes
|
|
19164
|
+
* @param cookies The COOKIE parameters
|
|
19165
|
+
* @param files The FILES parameters
|
|
19166
|
+
* @param server The SERVER parameters
|
|
19167
|
+
* @param content The raw body data
|
|
19168
|
+
*/
|
|
19169
|
+
async initialize() {
|
|
18352
19170
|
this.params = (0, h3.getRouterParams)(this.event);
|
|
18353
|
-
this.
|
|
19171
|
+
this.request = new InputBag(this.formData ? this.formData.input() : {}, this.event);
|
|
19172
|
+
this.query = new InputBag((0, h3.getQuery)(this.event), this.event);
|
|
19173
|
+
this.attributes = new ParamBag((0, h3.getRouterParams)(this.event), this.event);
|
|
19174
|
+
this.cookies = new InputBag((0, h3.parseCookies)(this.event), this.event);
|
|
19175
|
+
this.files = new FileBag(this.formData ? this.formData.files() : {}, this.event);
|
|
19176
|
+
this.server = new ServerBag(Object.fromEntries(this.event.req.headers.entries()), this.event);
|
|
19177
|
+
this.headers = new HeaderBag(this.server.getHeaders());
|
|
19178
|
+
this.acceptableContentTypes = [];
|
|
19179
|
+
this.#method = void 0;
|
|
19180
|
+
this.#uri = (await import(String("@h3ravel/url"))).Url.of((0, h3.getRequestURL)(this.event).toString(), this.app);
|
|
19181
|
+
}
|
|
19182
|
+
async setBody() {
|
|
19183
|
+
const type = this.event.req.headers.get("content-type") || "";
|
|
19184
|
+
if (this.body) return;
|
|
19185
|
+
if (type.includes("application/json")) {
|
|
19186
|
+
this.body = await this.event.req.json().catch(() => ({}));
|
|
19187
|
+
this.content = this.body;
|
|
19188
|
+
} else if (type.includes("form-data") || type.includes("x-www-form-urlencoded")) {
|
|
19189
|
+
this.formData = new FormRequest(await this.event.req.formData());
|
|
19190
|
+
this.body = this.formData.all();
|
|
19191
|
+
this.content = JSON.stringify(this.formData.input());
|
|
19192
|
+
} else if (type.startsWith("text/")) {
|
|
19193
|
+
this.body = await this.event.req.text();
|
|
19194
|
+
this.content = this.body;
|
|
19195
|
+
} else {
|
|
19196
|
+
const content = this.event.req.body;
|
|
19197
|
+
this.content = content;
|
|
19198
|
+
if (content instanceof ReadableStream) {
|
|
19199
|
+
const reader = content.getReader();
|
|
19200
|
+
const chunks = [];
|
|
19201
|
+
let done = false;
|
|
19202
|
+
while (!done) {
|
|
19203
|
+
const { value, done: isDone } = await reader.read();
|
|
19204
|
+
if (value) chunks.push(value);
|
|
19205
|
+
done = isDone;
|
|
19206
|
+
}
|
|
19207
|
+
this.body = new TextDecoder().decode(new Uint8Array(chunks.flatMap((chunk) => Array.from(chunk))));
|
|
19208
|
+
} else this.body = content;
|
|
19209
|
+
}
|
|
18354
19210
|
}
|
|
18355
19211
|
/**
|
|
18356
|
-
*
|
|
19212
|
+
* Retrieve all data from the instance (query + body).
|
|
19213
|
+
*/
|
|
19214
|
+
all(keys) {
|
|
19215
|
+
const input = __h3ravel_support.Obj.deepMerge({}, this.input(), this.allFiles());
|
|
19216
|
+
if (!keys) return input;
|
|
19217
|
+
const results = {};
|
|
19218
|
+
const list = Array.isArray(keys) ? keys : [keys];
|
|
19219
|
+
for (const key of list) (0, __h3ravel_support.data_set)(results, key, __h3ravel_support.Obj.get(input, key));
|
|
19220
|
+
return results;
|
|
19221
|
+
}
|
|
19222
|
+
/**
|
|
19223
|
+
* Retrieve an input item from the request.
|
|
19224
|
+
*
|
|
19225
|
+
* @param key
|
|
19226
|
+
* @param defaultValue
|
|
19227
|
+
* @returns
|
|
18357
19228
|
*/
|
|
18358
|
-
|
|
18359
|
-
|
|
18360
|
-
...(
|
|
18361
|
-
...
|
|
19229
|
+
input(key, defaultValue) {
|
|
19230
|
+
const source = {
|
|
19231
|
+
...this.getInputSource().all(),
|
|
19232
|
+
...this.query.all()
|
|
18362
19233
|
};
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
19234
|
+
return key ? (0, __h3ravel_support.data_get)(source, key, defaultValue) : __h3ravel_support.Arr.except(source, ["_method"]);
|
|
19235
|
+
}
|
|
19236
|
+
/**
|
|
19237
|
+
* Retrieve a file from the request.
|
|
19238
|
+
*
|
|
19239
|
+
* @param key
|
|
19240
|
+
* @param defaultValue
|
|
19241
|
+
* @returns
|
|
19242
|
+
*/
|
|
19243
|
+
file(key, defaultValue) {
|
|
19244
|
+
const source = this.allFiles();
|
|
19245
|
+
return key ? (0, __h3ravel_support.data_get)(source, key, defaultValue) : source;
|
|
19246
|
+
}
|
|
19247
|
+
/**
|
|
19248
|
+
* Get an array of all of the files on the request.
|
|
19249
|
+
*/
|
|
19250
|
+
allFiles() {
|
|
19251
|
+
if (this.convertedFiles) return this.convertedFiles;
|
|
19252
|
+
const entries = Object.entries(this.files.all()).filter((e) => e[1] != null);
|
|
19253
|
+
const files = Object.fromEntries(entries);
|
|
19254
|
+
this.convertedFiles = this.convertUploadedFiles(files);
|
|
19255
|
+
return this.convertedFiles;
|
|
19256
|
+
}
|
|
19257
|
+
/**
|
|
19258
|
+
* Extract and convert uploaded files from FormData.
|
|
19259
|
+
*/
|
|
19260
|
+
convertUploadedFiles(files) {
|
|
19261
|
+
if (!this.formData) return files;
|
|
19262
|
+
for (const [key, value] of Object.entries(this.formData.files())) {
|
|
19263
|
+
if (!(value instanceof File)) continue;
|
|
19264
|
+
if (key.endsWith("[]")) {
|
|
19265
|
+
const normalizedKey = key.slice(0, -2);
|
|
19266
|
+
if (!files[normalizedKey]) files[normalizedKey] = [];
|
|
19267
|
+
files[normalizedKey].push(UploadedFile.createFromBase(value));
|
|
19268
|
+
} else files[key] = UploadedFile.createFromBase(value);
|
|
19269
|
+
}
|
|
19270
|
+
return files;
|
|
19271
|
+
}
|
|
19272
|
+
/**
|
|
19273
|
+
* Determine if the data contains a given key.
|
|
19274
|
+
*
|
|
19275
|
+
* @param keys
|
|
19276
|
+
* @returns
|
|
19277
|
+
*/
|
|
19278
|
+
has(keys) {
|
|
19279
|
+
return __h3ravel_support.Obj.has(this.all(), keys);
|
|
19280
|
+
}
|
|
19281
|
+
/**
|
|
19282
|
+
* Determine if the instance is missing a given key.
|
|
19283
|
+
*/
|
|
19284
|
+
missing(key) {
|
|
19285
|
+
const keys = Array.isArray(key) ? key : [key];
|
|
19286
|
+
return !this.has(keys);
|
|
19287
|
+
}
|
|
19288
|
+
/**
|
|
19289
|
+
* Get a subset containing the provided keys with values from the instance data.
|
|
19290
|
+
*
|
|
19291
|
+
* @param keys
|
|
19292
|
+
* @returns
|
|
19293
|
+
*/
|
|
19294
|
+
only(keys) {
|
|
19295
|
+
const data = Object.entries(this.all()).filter(([key]) => keys.includes(key));
|
|
19296
|
+
return Object.fromEntries(data);
|
|
19297
|
+
}
|
|
19298
|
+
/**
|
|
19299
|
+
* Get all of the data except for a specified array of items.
|
|
19300
|
+
*
|
|
19301
|
+
* @param keys
|
|
19302
|
+
* @returns
|
|
19303
|
+
*/
|
|
19304
|
+
except(keys) {
|
|
19305
|
+
const data = Object.entries(this.all()).filter(([key]) => !keys.includes(key));
|
|
19306
|
+
return Object.fromEntries(data);
|
|
19307
|
+
}
|
|
19308
|
+
/**
|
|
19309
|
+
* Merges new input data into the current request's input source.
|
|
19310
|
+
*
|
|
19311
|
+
* @param input - An object containing key-value pairs to merge.
|
|
19312
|
+
* @returns this - For fluent chaining.
|
|
19313
|
+
*/
|
|
19314
|
+
merge(input) {
|
|
19315
|
+
const source = this.getInputSource();
|
|
19316
|
+
for (const [key, value] of Object.entries(input)) source.set(key, value);
|
|
19317
|
+
return this;
|
|
19318
|
+
}
|
|
19319
|
+
/**
|
|
19320
|
+
* Merge new input into the request's input, but only when that key is missing from the request.
|
|
19321
|
+
*
|
|
19322
|
+
* @param input
|
|
19323
|
+
*/
|
|
19324
|
+
mergeIfMissing(input) {
|
|
19325
|
+
return this.merge(Object.fromEntries(Object.entries(input).filter(([key]) => this.missing(key))));
|
|
19326
|
+
}
|
|
19327
|
+
/**
|
|
19328
|
+
* Get the keys for all of the input and files.
|
|
19329
|
+
*/
|
|
19330
|
+
keys() {
|
|
19331
|
+
return [...Object.keys(this.input()), ...this.files.keys()];
|
|
19332
|
+
}
|
|
19333
|
+
/**
|
|
19334
|
+
* Determine if the request is sending JSON.
|
|
19335
|
+
*
|
|
19336
|
+
* @return bool
|
|
19337
|
+
*/
|
|
19338
|
+
isJson() {
|
|
19339
|
+
return __h3ravel_support.Str.contains(this.getHeader("CONTENT_TYPE") ?? "", ["/json", "+json"]);
|
|
19340
|
+
}
|
|
19341
|
+
/**
|
|
19342
|
+
* Determine if the current request probably expects a JSON response.
|
|
19343
|
+
*
|
|
19344
|
+
* @returns
|
|
19345
|
+
*/
|
|
19346
|
+
expectsJson() {
|
|
19347
|
+
return __h3ravel_support.Str.contains(this.getHeader("Accept") ?? "", "application/json");
|
|
19348
|
+
}
|
|
19349
|
+
/**
|
|
19350
|
+
* Determine if the current request is asking for JSON.
|
|
19351
|
+
*
|
|
19352
|
+
* @returns
|
|
19353
|
+
*/
|
|
19354
|
+
wantsJson() {
|
|
19355
|
+
const acceptable = this.getAcceptableContentTypes();
|
|
19356
|
+
return !!acceptable[0] && __h3ravel_support.Str.contains(acceptable[0].toLowerCase(), ["/json", "+json"]);
|
|
19357
|
+
}
|
|
19358
|
+
/**
|
|
19359
|
+
* Gets a list of content types acceptable by the client browser in preferable order.
|
|
19360
|
+
* @returns {string[]}
|
|
19361
|
+
*/
|
|
19362
|
+
getAcceptableContentTypes() {
|
|
19363
|
+
if (this.acceptableContentTypes.length > 0) return this.acceptableContentTypes;
|
|
19364
|
+
const accept = this.getHeader("accept");
|
|
19365
|
+
if (!accept) return [];
|
|
19366
|
+
return this.acceptableContentTypes = accept.split(",").map((type) => type.trim()).map((type) => type.split(";")[0]).filter(Boolean);
|
|
19367
|
+
}
|
|
19368
|
+
/**
|
|
19369
|
+
* Determine if the request is the result of a PJAX call.
|
|
19370
|
+
*
|
|
19371
|
+
* @return bool
|
|
19372
|
+
*/
|
|
19373
|
+
pjax() {
|
|
19374
|
+
return this.headers.get("X-PJAX") == true;
|
|
19375
|
+
}
|
|
19376
|
+
/**
|
|
19377
|
+
* Returns true if the request is an XMLHttpRequest (AJAX).
|
|
19378
|
+
*
|
|
19379
|
+
* @alias isXmlHttpRequest()
|
|
19380
|
+
* @returns {boolean}
|
|
19381
|
+
*/
|
|
19382
|
+
ajax() {
|
|
19383
|
+
return this.isXmlHttpRequest();
|
|
19384
|
+
}
|
|
19385
|
+
/**
|
|
19386
|
+
* Returns true if the request is an XMLHttpRequest (AJAX).
|
|
19387
|
+
*/
|
|
19388
|
+
isXmlHttpRequest() {
|
|
19389
|
+
return "XMLHttpRequest" === this.getHeader("X-Requested-With");
|
|
19390
|
+
}
|
|
19391
|
+
/**
|
|
19392
|
+
* Returns the value of the requested header.
|
|
19393
|
+
*/
|
|
19394
|
+
getHeader(name) {
|
|
19395
|
+
return this.headers.get(name);
|
|
19396
|
+
}
|
|
19397
|
+
/**
|
|
19398
|
+
* Checks if the request method is of specified type.
|
|
19399
|
+
*
|
|
19400
|
+
* @param method Uppercase request method (GET, POST etc)
|
|
19401
|
+
*/
|
|
19402
|
+
isMethod(method) {
|
|
19403
|
+
return this.getMethod() === method.toUpperCase();
|
|
19404
|
+
}
|
|
19405
|
+
/**
|
|
19406
|
+
* Checks whether or not the method is safe.
|
|
19407
|
+
*
|
|
19408
|
+
* @see https://tools.ietf.org/html/rfc7231#section-4.2.1
|
|
19409
|
+
*/
|
|
19410
|
+
isMethodSafe() {
|
|
19411
|
+
return [
|
|
19412
|
+
"GET",
|
|
19413
|
+
"HEAD",
|
|
19414
|
+
"OPTIONS",
|
|
19415
|
+
"TRACE"
|
|
19416
|
+
].includes(this.getMethod());
|
|
19417
|
+
}
|
|
19418
|
+
/**
|
|
19419
|
+
* Checks whether or not the method is idempotent.
|
|
19420
|
+
*/
|
|
19421
|
+
isMethodIdempotent() {
|
|
19422
|
+
return [
|
|
19423
|
+
"HEAD",
|
|
19424
|
+
"GET",
|
|
19425
|
+
"PUT",
|
|
19426
|
+
"DELETE",
|
|
19427
|
+
"TRACE",
|
|
19428
|
+
"OPTIONS",
|
|
19429
|
+
"PURGE"
|
|
19430
|
+
].includes(this.getMethod());
|
|
19431
|
+
}
|
|
19432
|
+
/**
|
|
19433
|
+
* Checks whether the method is cacheable or not.
|
|
19434
|
+
*
|
|
19435
|
+
* @see https://tools.ietf.org/html/rfc7231#section-4.2.3
|
|
19436
|
+
*/
|
|
19437
|
+
isMethodCacheable() {
|
|
19438
|
+
return ["GET", "HEAD"].includes(this.getMethod());
|
|
19439
|
+
}
|
|
19440
|
+
/**
|
|
19441
|
+
* Initializes HTTP request formats.
|
|
19442
|
+
*/
|
|
19443
|
+
static initializeFormats() {
|
|
19444
|
+
this.formats = {
|
|
19445
|
+
html: ["text/html", "application/xhtml+xml"],
|
|
19446
|
+
txt: ["text/plain"],
|
|
19447
|
+
js: [
|
|
19448
|
+
"application/javascript",
|
|
19449
|
+
"application/x-javascript",
|
|
19450
|
+
"text/javascript"
|
|
19451
|
+
],
|
|
19452
|
+
css: ["text/css"],
|
|
19453
|
+
json: ["application/json", "application/x-json"],
|
|
19454
|
+
jsonld: ["application/ld+json"],
|
|
19455
|
+
xml: [
|
|
19456
|
+
"text/xml",
|
|
19457
|
+
"application/xml",
|
|
19458
|
+
"application/x-xml"
|
|
19459
|
+
],
|
|
19460
|
+
rdf: ["application/rdf+xml"],
|
|
19461
|
+
atom: ["application/atom+xml"],
|
|
19462
|
+
rss: ["application/rss+xml"],
|
|
19463
|
+
form: ["application/x-www-form-urlencoded", "multipart/form-data"]
|
|
19464
|
+
};
|
|
19465
|
+
}
|
|
19466
|
+
/**
|
|
19467
|
+
* Gets the request "intended" method.
|
|
19468
|
+
*
|
|
19469
|
+
* If the X-HTTP-Method-Override header is set, and if the method is a POST,
|
|
19470
|
+
* then it is used to determine the "real" intended HTTP method.
|
|
19471
|
+
*
|
|
19472
|
+
* The _method request parameter can also be used to determine the HTTP method,
|
|
19473
|
+
* but only if enableHttpMethodParameterOverride() has been called.
|
|
19474
|
+
*
|
|
19475
|
+
* The method is always an uppercased string.
|
|
19476
|
+
*
|
|
19477
|
+
* @see getRealMethod()
|
|
19478
|
+
*/
|
|
19479
|
+
getMethod() {
|
|
19480
|
+
if (this.#method) return this.#method;
|
|
19481
|
+
this.#method = this.getRealMethod();
|
|
19482
|
+
if ("POST" !== this.#method) return this.#method;
|
|
19483
|
+
let method = this.event.req.headers.get("X-HTTP-METHOD-OVERRIDE");
|
|
19484
|
+
if (!method && Request.httpMethodParameterOverride) method = this.request.get("_method", this.query.get("_method", "POST"));
|
|
19485
|
+
if (typeof method !== "string") return this.#method;
|
|
19486
|
+
method = method.toUpperCase();
|
|
19487
|
+
if ([
|
|
19488
|
+
"GET",
|
|
19489
|
+
"HEAD",
|
|
19490
|
+
"POST",
|
|
19491
|
+
"PUT",
|
|
19492
|
+
"DELETE",
|
|
19493
|
+
"CONNECT",
|
|
19494
|
+
"OPTIONS",
|
|
19495
|
+
"PATCH",
|
|
19496
|
+
"PURGE",
|
|
19497
|
+
"TRACE"
|
|
19498
|
+
].includes(method)) {
|
|
19499
|
+
this.#method = method;
|
|
19500
|
+
return this.#method;
|
|
19501
|
+
}
|
|
19502
|
+
if (!/^[A-Z]+$/.test(method)) throw new SuspiciousOperationException("Invalid HTTP method override.");
|
|
19503
|
+
this.#method = method;
|
|
19504
|
+
return this.#method;
|
|
19505
|
+
}
|
|
19506
|
+
/**
|
|
19507
|
+
* Gets the "real" request method.
|
|
19508
|
+
*
|
|
19509
|
+
* @see getMethod()
|
|
19510
|
+
*/
|
|
19511
|
+
getRealMethod() {
|
|
19512
|
+
return this.event.req.method.toUpperCase();
|
|
19513
|
+
}
|
|
19514
|
+
/**
|
|
19515
|
+
* Get the client IP address.
|
|
19516
|
+
*/
|
|
19517
|
+
ip() {
|
|
19518
|
+
return (0, h3.getRequestIP)(this.event);
|
|
19519
|
+
}
|
|
19520
|
+
/**
|
|
19521
|
+
* Get a URI instance for the request.
|
|
19522
|
+
*/
|
|
19523
|
+
uri() {
|
|
19524
|
+
return this.#uri;
|
|
19525
|
+
}
|
|
19526
|
+
/**
|
|
19527
|
+
* Get the full URL for the request.
|
|
19528
|
+
*/
|
|
19529
|
+
fullUrl() {
|
|
19530
|
+
return this.event.req.url;
|
|
19531
|
+
}
|
|
19532
|
+
/**
|
|
19533
|
+
* Return the Request instance.
|
|
19534
|
+
*/
|
|
19535
|
+
instance() {
|
|
19536
|
+
return this;
|
|
19537
|
+
}
|
|
19538
|
+
/**
|
|
19539
|
+
* Get the request method.
|
|
19540
|
+
*/
|
|
19541
|
+
method() {
|
|
19542
|
+
return this.getMethod();
|
|
19543
|
+
}
|
|
19544
|
+
/**
|
|
19545
|
+
* Get the JSON payload for the request.
|
|
19546
|
+
*
|
|
19547
|
+
* @param key
|
|
19548
|
+
* @param defaultValue
|
|
19549
|
+
* @return {InputBag}
|
|
19550
|
+
*/
|
|
19551
|
+
json(key, defaultValue) {
|
|
19552
|
+
if (!this.#json) {
|
|
19553
|
+
let json = this.getContent();
|
|
19554
|
+
if (typeof json == "string") json = JSON.parse(json || "{}");
|
|
19555
|
+
this.#json = new InputBag(json, this.event);
|
|
19556
|
+
}
|
|
19557
|
+
if (!key) return this.#json;
|
|
19558
|
+
return __h3ravel_support.Obj.get(this.#json.all(), key, defaultValue);
|
|
19559
|
+
}
|
|
19560
|
+
/**
|
|
19561
|
+
* Get the input source for the request.
|
|
19562
|
+
*
|
|
19563
|
+
* @return {InputBag}
|
|
19564
|
+
*/
|
|
19565
|
+
getInputSource() {
|
|
19566
|
+
if (this.isJson()) return this.json();
|
|
19567
|
+
return ["GET", "HEAD"].includes(this.getRealMethod()) ? this.query : this.request;
|
|
19568
|
+
}
|
|
19569
|
+
/**
|
|
19570
|
+
* Returns the request body content.
|
|
19571
|
+
*
|
|
19572
|
+
* @param asStream If true, returns a ReadableStream instead of the parsed string
|
|
19573
|
+
* @return {string | ReadableStream | Promise<string | ReadableStream>}
|
|
19574
|
+
*/
|
|
19575
|
+
getContent(asStream = false) {
|
|
19576
|
+
let content = this.body;
|
|
19577
|
+
if (content !== void 0 && content !== null) {
|
|
19578
|
+
if (asStream) {
|
|
19579
|
+
if (content instanceof ReadableStream) return content;
|
|
19580
|
+
const encoder = new TextEncoder();
|
|
19581
|
+
return new ReadableStream({ start(controller) {
|
|
19582
|
+
controller.enqueue(encoder.encode(String(content)));
|
|
19583
|
+
controller.close();
|
|
19584
|
+
} });
|
|
19585
|
+
}
|
|
19586
|
+
if (typeof content === "string") return content;
|
|
19587
|
+
}
|
|
19588
|
+
if (asStream) return this.content;
|
|
19589
|
+
content = this.content;
|
|
19590
|
+
this.body = content;
|
|
19591
|
+
return content;
|
|
19592
|
+
}
|
|
19593
|
+
/**
|
|
19594
|
+
* Determine if the uploaded data contains a file.
|
|
19595
|
+
*
|
|
19596
|
+
* @param key
|
|
19597
|
+
* @return boolean
|
|
19598
|
+
*/
|
|
19599
|
+
hasFile(key) {
|
|
19600
|
+
let files = this.file(key);
|
|
19601
|
+
if (!Array.isArray(files)) files = [files];
|
|
19602
|
+
return files.some((e) => this.isValidFile(e));
|
|
19603
|
+
}
|
|
19604
|
+
/**
|
|
19605
|
+
* Check that the given file is a valid file instance.
|
|
19606
|
+
*
|
|
19607
|
+
* @param file
|
|
19608
|
+
* @return boolean
|
|
19609
|
+
*/
|
|
19610
|
+
isValidFile(file) {
|
|
19611
|
+
return file.content instanceof File && file.size > 0;
|
|
18366
19612
|
}
|
|
18367
19613
|
/**
|
|
18368
|
-
*
|
|
19614
|
+
* Gets a "parameter" value from any bag.
|
|
19615
|
+
*
|
|
19616
|
+
* This method is mainly useful for libraries that want to provide some flexibility. If you don't need the
|
|
19617
|
+
* flexibility in controllers, it is better to explicitly get request parameters from the appropriate
|
|
19618
|
+
* public property instead (attributes, query, request).
|
|
19619
|
+
*
|
|
19620
|
+
* Order of precedence: PATH (routing placeholders or custom attributes), GET, POST
|
|
19621
|
+
*
|
|
19622
|
+
* @internal use explicit input sources instead
|
|
19623
|
+
*/
|
|
19624
|
+
get(key, defaultValue) {
|
|
19625
|
+
const result = this.attributes.get(key, this);
|
|
19626
|
+
if (this !== result) return result;
|
|
19627
|
+
if (this.query.has(key)) return this.query.all()[key];
|
|
19628
|
+
if (this.request.has(key)) return this.request.all()[key];
|
|
19629
|
+
return defaultValue;
|
|
19630
|
+
}
|
|
19631
|
+
/**
|
|
19632
|
+
* Enables support for the _method request parameter to determine the intended HTTP method.
|
|
19633
|
+
*
|
|
19634
|
+
* Be warned that enabling this feature might lead to CSRF issues in your code.
|
|
19635
|
+
* Check that you are using CSRF tokens when required.
|
|
19636
|
+
* If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
|
|
19637
|
+
* and used to send a "PUT" or "DELETE" request via the _method request parameter.
|
|
19638
|
+
* If these methods are not protected against CSRF, this presents a possible vulnerability.
|
|
19639
|
+
*
|
|
19640
|
+
* The HTTP method can only be overridden when the real HTTP method is POST.
|
|
18369
19641
|
*/
|
|
18370
|
-
|
|
18371
|
-
|
|
19642
|
+
static enableHttpMethodParameterOverride() {
|
|
19643
|
+
this.httpMethodParameterOverride = true;
|
|
19644
|
+
}
|
|
19645
|
+
/**
|
|
19646
|
+
* Checks whether support for the _method request parameter is enabled.
|
|
19647
|
+
*/
|
|
19648
|
+
static getHttpMethodParameterOverride() {
|
|
19649
|
+
return this.httpMethodParameterOverride;
|
|
19650
|
+
}
|
|
19651
|
+
/**
|
|
19652
|
+
* Dump the items.
|
|
19653
|
+
*
|
|
19654
|
+
* @param keys
|
|
19655
|
+
* @return this
|
|
19656
|
+
*/
|
|
19657
|
+
dump(...keys) {
|
|
19658
|
+
if (keys.length > 0) this.only(keys).then(dump);
|
|
19659
|
+
else this.all().then(dump);
|
|
19660
|
+
return this;
|
|
18372
19661
|
}
|
|
18373
19662
|
getEvent(key) {
|
|
18374
19663
|
return (0, __h3ravel_support.safeDot)(this.event, key);
|
|
@@ -18553,7 +19842,7 @@ var Response = class {
|
|
|
18553
19842
|
}
|
|
18554
19843
|
html(content) {
|
|
18555
19844
|
this.applyHeaders();
|
|
18556
|
-
return (0, h3.html)(
|
|
19845
|
+
return (0, h3.html)(content);
|
|
18557
19846
|
}
|
|
18558
19847
|
/**
|
|
18559
19848
|
* Send a JSON response.
|
|
@@ -18574,9 +19863,9 @@ var Response = class {
|
|
|
18574
19863
|
/**
|
|
18575
19864
|
* Redirect to another URL.
|
|
18576
19865
|
*/
|
|
18577
|
-
redirect(
|
|
19866
|
+
redirect(location, status = 302, statusText) {
|
|
18578
19867
|
this.setStatusCode(status);
|
|
18579
|
-
return (0, h3.redirect)(
|
|
19868
|
+
return (0, h3.redirect)(location, this.statusCode, statusText);
|
|
18580
19869
|
}
|
|
18581
19870
|
/**
|
|
18582
19871
|
* Apply headers before sending response.
|
|
@@ -18593,7 +19882,11 @@ var Response = class {
|
|
|
18593
19882
|
|
|
18594
19883
|
//#endregion
|
|
18595
19884
|
exports.ApiResource = ApiResource;
|
|
19885
|
+
exports.BadRequestException = BadRequestException;
|
|
19886
|
+
exports.FileBag = FileBag;
|
|
18596
19887
|
exports.FireCommand = FireCommand;
|
|
19888
|
+
exports.FormRequest = FormRequest;
|
|
19889
|
+
exports.HeaderBag = HeaderBag;
|
|
18597
19890
|
Object.defineProperty(exports, 'HttpContext', {
|
|
18598
19891
|
enumerable: true,
|
|
18599
19892
|
get: function () {
|
|
@@ -18601,8 +19894,14 @@ Object.defineProperty(exports, 'HttpContext', {
|
|
|
18601
19894
|
}
|
|
18602
19895
|
});
|
|
18603
19896
|
exports.HttpServiceProvider = HttpServiceProvider;
|
|
19897
|
+
exports.InputBag = InputBag;
|
|
18604
19898
|
exports.JsonResource = JsonResource;
|
|
18605
19899
|
exports.LogRequests = LogRequests;
|
|
18606
19900
|
exports.Middleware = Middleware;
|
|
19901
|
+
exports.ParamBag = ParamBag;
|
|
18607
19902
|
exports.Request = Request;
|
|
18608
|
-
exports.Response = Response;
|
|
19903
|
+
exports.Response = Response;
|
|
19904
|
+
exports.ServerBag = ServerBag;
|
|
19905
|
+
exports.SuspiciousOperationException = SuspiciousOperationException;
|
|
19906
|
+
exports.UnexpectedValueException = UnexpectedValueException;
|
|
19907
|
+
exports.UploadedFile = UploadedFile;
|