@orieljs/framework 0.1.0-alpha.3 → 0.1.0-alpha.4
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/{chunk-WEGTH46M.js → chunk-3DETYZMZ.js} +3 -3
- package/dist/{chunk-IRHK7GH7.js → chunk-DCI2T7WJ.js} +24 -3
- package/dist/chunk-DCI2T7WJ.js.map +1 -0
- package/dist/{chunk-I2OMKIQZ.js → chunk-SBZQ6L3Z.js} +2213 -137
- package/dist/chunk-SBZQ6L3Z.js.map +1 -0
- package/dist/{chunk-3ZRPBRAE.js → chunk-WSGWYXAO.js} +3 -1
- package/dist/chunk-WSGWYXAO.js.map +1 -0
- package/dist/contracts.d.ts +155 -132
- package/dist/contracts.js +3 -1
- package/dist/index.d.ts +543 -285
- package/dist/index.js +805 -2053
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/{testing--F6FODc_.d.ts → testing-D3dCOkTm.d.ts} +208 -86
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +3 -3
- package/package.json +30 -30
- package/dist/chunk-3ZRPBRAE.js.map +0 -1
- package/dist/chunk-HU43NADT.js +0 -745
- package/dist/chunk-HU43NADT.js.map +0 -1
- package/dist/chunk-I2OMKIQZ.js.map +0 -1
- package/dist/chunk-IRHK7GH7.js.map +0 -1
- package/dist/chunk-S7YC43IH.js +0 -93
- package/dist/chunk-S7YC43IH.js.map +0 -1
- package/dist/chunk-TIE5OAMF.js +0 -474
- package/dist/chunk-TIE5OAMF.js.map +0 -1
- package/dist/chunk-UPZAML2Q.js +0 -3653
- package/dist/chunk-UPZAML2Q.js.map +0 -1
- package/dist/jsx-runtime-CZ6JqBQo.d.ts +0 -345
- /package/dist/{chunk-WEGTH46M.js.map → chunk-3DETYZMZ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -22,18 +22,32 @@ import {
|
|
|
22
22
|
renderToString,
|
|
23
23
|
styleString,
|
|
24
24
|
view
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-3DETYZMZ.js";
|
|
26
26
|
import {
|
|
27
|
+
API_ROUTES_STUB,
|
|
27
28
|
Application as Application2,
|
|
28
29
|
ApplicationBuilder,
|
|
29
30
|
BusFake,
|
|
30
31
|
ClosureKernel,
|
|
31
32
|
Component,
|
|
32
33
|
Computed,
|
|
34
|
+
ConvertEmptyStringsToNull,
|
|
33
35
|
CorruptComponentPayloadError,
|
|
34
36
|
ErrorBag,
|
|
37
|
+
ErrorHandler,
|
|
35
38
|
EventFake,
|
|
39
|
+
ExceptionsConfiguration,
|
|
40
|
+
FormUploadedFile,
|
|
41
|
+
HttpException,
|
|
42
|
+
HttpRedirectResponse,
|
|
43
|
+
HttpRedirector,
|
|
44
|
+
HttpResponseException,
|
|
45
|
+
HttpResponseFactory,
|
|
46
|
+
HttpServerError,
|
|
47
|
+
HttpServiceProvider,
|
|
48
|
+
IncomingRequest,
|
|
36
49
|
InvalidLiveRequestError,
|
|
50
|
+
Kernel,
|
|
37
51
|
Live,
|
|
38
52
|
LiveComponentManager,
|
|
39
53
|
LiveComponentNotFoundError,
|
|
@@ -42,8 +56,10 @@ import {
|
|
|
42
56
|
Locked,
|
|
43
57
|
MailFake,
|
|
44
58
|
MethodNotCallableError,
|
|
59
|
+
MiddlewareConfiguration,
|
|
45
60
|
NotificationFake,
|
|
46
61
|
On,
|
|
62
|
+
PERSISTENT_MIDDLEWARE,
|
|
47
63
|
PendingEvent,
|
|
48
64
|
PropertyNotUpdatableError,
|
|
49
65
|
ProviderBootError,
|
|
@@ -51,18 +67,69 @@ import {
|
|
|
51
67
|
QueueFake,
|
|
52
68
|
Repository,
|
|
53
69
|
StorageFake,
|
|
70
|
+
TestRequestScope,
|
|
54
71
|
Testable,
|
|
72
|
+
TrimStrings,
|
|
55
73
|
UPDATE_URI,
|
|
56
74
|
Vite,
|
|
57
75
|
ViteError,
|
|
58
76
|
ViteHtml,
|
|
77
|
+
abort,
|
|
78
|
+
abortIf,
|
|
79
|
+
abortUnless,
|
|
80
|
+
addApiRouting,
|
|
81
|
+
applyExceptionCallbacks,
|
|
82
|
+
applyMiddlewareCallbacks,
|
|
83
|
+
back,
|
|
84
|
+
bunRuntime,
|
|
85
|
+
clientAddress,
|
|
59
86
|
componentName,
|
|
87
|
+
contentDisposition,
|
|
88
|
+
currentRequest,
|
|
60
89
|
currentVite,
|
|
90
|
+
debugPage,
|
|
91
|
+
detectRuntime,
|
|
61
92
|
env,
|
|
93
|
+
escapeHtml,
|
|
94
|
+
exceedsJsonDepth,
|
|
95
|
+
extensionFromMime,
|
|
96
|
+
filterRouteList,
|
|
97
|
+
formatRouteList,
|
|
98
|
+
fromEntries,
|
|
99
|
+
ipMatches,
|
|
100
|
+
isBlank,
|
|
62
101
|
live,
|
|
102
|
+
mergeRecursive,
|
|
103
|
+
minimalPage,
|
|
104
|
+
normalizeLists,
|
|
105
|
+
optionalCookieJar,
|
|
106
|
+
optionalSession,
|
|
107
|
+
parseBracketKey,
|
|
108
|
+
persistentMiddleware,
|
|
109
|
+
redirect,
|
|
110
|
+
registerHttpCommands,
|
|
111
|
+
request,
|
|
112
|
+
requestScope,
|
|
113
|
+
response,
|
|
114
|
+
route,
|
|
115
|
+
routeListRows,
|
|
116
|
+
sanitize,
|
|
117
|
+
serve,
|
|
118
|
+
serveBun,
|
|
119
|
+
serveNode,
|
|
120
|
+
servePublicFile,
|
|
121
|
+
setClientAddress,
|
|
122
|
+
stackFrames,
|
|
123
|
+
statusFor,
|
|
124
|
+
statusText,
|
|
125
|
+
summarizeValidation,
|
|
126
|
+
toWebRequest,
|
|
127
|
+
transformLeaves,
|
|
128
|
+
url,
|
|
63
129
|
vite,
|
|
64
|
-
viteReactRefresh
|
|
65
|
-
|
|
130
|
+
viteReactRefresh,
|
|
131
|
+
writeResponse
|
|
132
|
+
} from "./chunk-SBZQ6L3Z.js";
|
|
66
133
|
import {
|
|
67
134
|
Arr,
|
|
68
135
|
BindingResolutionError,
|
|
@@ -74,6 +141,7 @@ import {
|
|
|
74
141
|
LazyCollection,
|
|
75
142
|
ServiceProvider,
|
|
76
143
|
Str,
|
|
144
|
+
__,
|
|
77
145
|
app,
|
|
78
146
|
collect,
|
|
79
147
|
config,
|
|
@@ -84,7 +152,7 @@ import {
|
|
|
84
152
|
retry,
|
|
85
153
|
tap,
|
|
86
154
|
value
|
|
87
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-DCI2T7WJ.js";
|
|
88
156
|
import {
|
|
89
157
|
Application,
|
|
90
158
|
AuthFactory,
|
|
@@ -100,25 +168,22 @@ import {
|
|
|
100
168
|
DatabaseManager,
|
|
101
169
|
Encrypter,
|
|
102
170
|
EventDispatcher,
|
|
103
|
-
ExceptionCallbacks,
|
|
104
171
|
ExceptionHandler,
|
|
105
172
|
FailedJobProvider,
|
|
106
173
|
FilesystemManager,
|
|
107
174
|
Gate,
|
|
108
175
|
Hasher,
|
|
109
|
-
HttpKernel,
|
|
110
176
|
HttpRequest,
|
|
111
177
|
InertiaFactory,
|
|
112
178
|
InertiaSsrGateway,
|
|
113
179
|
LogManager,
|
|
114
180
|
MailManager,
|
|
115
|
-
MiddlewareCallbacks,
|
|
116
181
|
NotificationDispatcher,
|
|
117
182
|
PasswordBroker,
|
|
118
183
|
PipelineFactory,
|
|
119
184
|
QueueManager,
|
|
185
|
+
RateLimiter,
|
|
120
186
|
Redirector,
|
|
121
|
-
ResponseFactory,
|
|
122
187
|
RouteModelResolver,
|
|
123
188
|
Router,
|
|
124
189
|
RoutingPaths,
|
|
@@ -128,12 +193,14 @@ import {
|
|
|
128
193
|
ValidationFactory,
|
|
129
194
|
ViewFactory,
|
|
130
195
|
token
|
|
131
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-WSGWYXAO.js";
|
|
132
197
|
|
|
133
198
|
// ../Auth/dist/index.js
|
|
134
|
-
import { timingSafeEqual } from "crypto";
|
|
135
199
|
import { createHash } from "crypto";
|
|
136
200
|
import { createHash as createHash2 } from "crypto";
|
|
201
|
+
import { timingSafeEqual } from "crypto";
|
|
202
|
+
import { createHash as createHash3 } from "crypto";
|
|
203
|
+
import { createHash as createHash4 } from "crypto";
|
|
137
204
|
import { createHmac } from "crypto";
|
|
138
205
|
import { readdir } from "fs/promises";
|
|
139
206
|
import { join } from "path";
|
|
@@ -213,6 +280,24 @@ var PasswordReset = class {
|
|
|
213
280
|
}
|
|
214
281
|
user;
|
|
215
282
|
};
|
|
283
|
+
var Registered = class {
|
|
284
|
+
constructor(user) {
|
|
285
|
+
this.user = user;
|
|
286
|
+
}
|
|
287
|
+
user;
|
|
288
|
+
};
|
|
289
|
+
var Verified = class {
|
|
290
|
+
constructor(user) {
|
|
291
|
+
this.user = user;
|
|
292
|
+
}
|
|
293
|
+
user;
|
|
294
|
+
};
|
|
295
|
+
var Lockout = class {
|
|
296
|
+
constructor(request2) {
|
|
297
|
+
this.request = request2;
|
|
298
|
+
}
|
|
299
|
+
request;
|
|
300
|
+
};
|
|
216
301
|
var createUrlCallback;
|
|
217
302
|
var toMailCallback;
|
|
218
303
|
var ResetPassword = class {
|
|
@@ -261,6 +346,83 @@ var ResetPassword = class {
|
|
|
261
346
|
return `/reset-password/${encodeURIComponent(this.token)}?email=${encodeURIComponent(email)}`;
|
|
262
347
|
}
|
|
263
348
|
};
|
|
349
|
+
var createUrlCallback2;
|
|
350
|
+
var toMailCallback2;
|
|
351
|
+
var VerifyEmail = class {
|
|
352
|
+
/** Build the verification URL yourself (e.g. for a SPA front end). */
|
|
353
|
+
static createUrlUsing(callback) {
|
|
354
|
+
createUrlCallback2 = callback;
|
|
355
|
+
}
|
|
356
|
+
/** Build the mail yourself (e.g. a MailMessage from the Notifications component). */
|
|
357
|
+
static toMailUsing(callback) {
|
|
358
|
+
toMailCallback2 = callback;
|
|
359
|
+
}
|
|
360
|
+
via() {
|
|
361
|
+
return ["mail"];
|
|
362
|
+
}
|
|
363
|
+
toMail(notifiable) {
|
|
364
|
+
const user = notifiable;
|
|
365
|
+
const url2 = this.verificationUrl(user);
|
|
366
|
+
if (toMailCallback2 !== void 0) return toMailCallback2(user, url2);
|
|
367
|
+
const mail = {
|
|
368
|
+
subject: "Verify Email Address",
|
|
369
|
+
lines: ["Please click the button below to verify your email address."],
|
|
370
|
+
actionText: "Verify Email Address",
|
|
371
|
+
actionUrl: url2,
|
|
372
|
+
outroLines: ["If you did not create an account, no further action is required."]
|
|
373
|
+
};
|
|
374
|
+
return mail;
|
|
375
|
+
}
|
|
376
|
+
verificationUrl(notifiable) {
|
|
377
|
+
if (createUrlCallback2 !== void 0) return createUrlCallback2(notifiable);
|
|
378
|
+
const container = currentContainer();
|
|
379
|
+
if (container === void 0 || !container.bound(UrlGenerator)) {
|
|
380
|
+
throw new Error("VerifyEmail needs the UrlGenerator (Routing) to sign the verification link.");
|
|
381
|
+
}
|
|
382
|
+
const config2 = container.bound(ConfigRepository) ? container.make(ConfigRepository) : void 0;
|
|
383
|
+
const minutes = Number(config2?.get("auth.verification.expire", 60) ?? 60);
|
|
384
|
+
const id = typeof notifiable.getKey === "function" ? notifiable.getKey() : notifiable.getAuthIdentifier?.();
|
|
385
|
+
const hash2 = createHash("sha1").update(notifiable.getEmailForVerification()).digest("hex");
|
|
386
|
+
return container.make(UrlGenerator).temporarySignedRoute("verification.verify", minutes * 60, { id, hash: hash2 });
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
var SendEmailVerificationNotification = class {
|
|
390
|
+
async handle(event2) {
|
|
391
|
+
const user = event2.user;
|
|
392
|
+
if (typeof user.hasVerifiedEmail !== "function" || typeof user.sendEmailVerificationNotification !== "function") return;
|
|
393
|
+
if (!user.hasVerifiedEmail()) await user.sendEmailVerificationNotification();
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
function equals(known, user) {
|
|
397
|
+
const a = Buffer.from(known);
|
|
398
|
+
const b = Buffer.from(user);
|
|
399
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
400
|
+
}
|
|
401
|
+
var EmailVerificationRequest = class {
|
|
402
|
+
static async validate() {
|
|
403
|
+
if (!await new this().authorize()) throw new AuthorizationError();
|
|
404
|
+
return {};
|
|
405
|
+
}
|
|
406
|
+
authorize() {
|
|
407
|
+
const request2 = inject(HttpRequest);
|
|
408
|
+
const user = request2.user();
|
|
409
|
+
if (user === void 0 || user === null) return false;
|
|
410
|
+
const key = typeof user.getKey === "function" ? user.getKey() : user.getAuthIdentifier();
|
|
411
|
+
const hash2 = createHash2("sha1").update(user.getEmailForVerification()).digest("hex");
|
|
412
|
+
return equals(String(key), String(request2.route("id") ?? "")) && equals(hash2, String(request2.route("hash") ?? ""));
|
|
413
|
+
}
|
|
414
|
+
rules() {
|
|
415
|
+
return {};
|
|
416
|
+
}
|
|
417
|
+
/** Marks the signed-in user's email as verified and fires Verified, unless it already was. */
|
|
418
|
+
async fulfill() {
|
|
419
|
+
const user = inject(HttpRequest).user();
|
|
420
|
+
if (user === void 0 || user === null || user.hasVerifiedEmail()) return;
|
|
421
|
+
await user.markEmailAsVerified();
|
|
422
|
+
const container = currentContainer();
|
|
423
|
+
if (container?.bound(EventDispatcher)) await container.make(EventDispatcher).dispatch(new Verified(user));
|
|
424
|
+
}
|
|
425
|
+
};
|
|
264
426
|
var verificationSender;
|
|
265
427
|
function sendEmailVerificationUsing(callback) {
|
|
266
428
|
verificationSender = callback;
|
|
@@ -316,19 +478,13 @@ function AuthenticatableModel(Base) {
|
|
|
316
478
|
getEmailForVerification() {
|
|
317
479
|
return String(this.getAttribute("email") ?? "");
|
|
318
480
|
}
|
|
481
|
+
/** Sends the VerifyEmail notification (a signed link), or what sendEmailVerificationUsing() configured. */
|
|
319
482
|
async sendEmailVerificationNotification() {
|
|
320
|
-
if (verificationSender
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
await verificationSender(this);
|
|
483
|
+
if (verificationSender !== void 0) return verificationSender(this);
|
|
484
|
+
return sendNotification(this, new VerifyEmail());
|
|
324
485
|
}
|
|
325
486
|
};
|
|
326
487
|
}
|
|
327
|
-
function equals(known, user) {
|
|
328
|
-
const a = Buffer.from(known);
|
|
329
|
-
const b = Buffer.from(user);
|
|
330
|
-
return a.length === b.length && timingSafeEqual(a, b);
|
|
331
|
-
}
|
|
332
488
|
var EloquentUserProvider = class {
|
|
333
489
|
constructor(hasher, model) {
|
|
334
490
|
this.hasher = hasher;
|
|
@@ -384,7 +540,7 @@ var EloquentUserProvider = class {
|
|
|
384
540
|
return this.model;
|
|
385
541
|
}
|
|
386
542
|
};
|
|
387
|
-
var GUARD_HASH =
|
|
543
|
+
var GUARD_HASH = createHash3("sha1").update("Oriel\\Auth\\SessionGuard").digest("hex");
|
|
388
544
|
var SessionGuard = class {
|
|
389
545
|
constructor(name, provider, container, options = {}) {
|
|
390
546
|
this.name = name;
|
|
@@ -531,8 +687,8 @@ var SessionGuard = class {
|
|
|
531
687
|
const session2 = this.#session();
|
|
532
688
|
if (session2 === void 0) return;
|
|
533
689
|
session2.put(this.getName(), id);
|
|
534
|
-
const
|
|
535
|
-
if (typeof
|
|
690
|
+
const store = session2;
|
|
691
|
+
if (typeof store.migrate === "function") await store.migrate(true);
|
|
536
692
|
else await session2.regenerate(true);
|
|
537
693
|
}
|
|
538
694
|
async #cycleRememberToken(user) {
|
|
@@ -579,7 +735,7 @@ function parseStoredDate(value2) {
|
|
|
579
735
|
}
|
|
580
736
|
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
581
737
|
}
|
|
582
|
-
var sha256 = (value2) =>
|
|
738
|
+
var sha256 = (value2) => createHash4("sha256").update(value2).digest("hex");
|
|
583
739
|
function tokenableType(user) {
|
|
584
740
|
const container = currentContainer();
|
|
585
741
|
const cls = user.constructor;
|
|
@@ -647,7 +803,7 @@ var TokenRepository = class {
|
|
|
647
803
|
clock;
|
|
648
804
|
async create(user, name, abilities = ["*"], expiresAt) {
|
|
649
805
|
const secret = Str.random(40);
|
|
650
|
-
const
|
|
806
|
+
const now5 = this.clock();
|
|
651
807
|
const attributes = {
|
|
652
808
|
tokenable_type: tokenableType(user),
|
|
653
809
|
tokenable_id: user.getAuthIdentifier(),
|
|
@@ -656,8 +812,8 @@ var TokenRepository = class {
|
|
|
656
812
|
abilities: JSON.stringify(abilities),
|
|
657
813
|
last_used_at: null,
|
|
658
814
|
expires_at: expiresAt ?? null,
|
|
659
|
-
created_at:
|
|
660
|
-
updated_at:
|
|
815
|
+
created_at: now5,
|
|
816
|
+
updated_at: now5
|
|
661
817
|
};
|
|
662
818
|
const id = await this.#query().insertGetId(attributes);
|
|
663
819
|
return { accessToken: new PersonalAccessToken({ id, ...attributes }, this), plainTextToken: `${id}|${secret}` };
|
|
@@ -678,9 +834,9 @@ var TokenRepository = class {
|
|
|
678
834
|
}
|
|
679
835
|
/** Records the token's use (last_used_at). */
|
|
680
836
|
async touch(token2) {
|
|
681
|
-
const
|
|
682
|
-
token2.attributes.last_used_at =
|
|
683
|
-
await this.#query().where("id", token2.id).update({ last_used_at:
|
|
837
|
+
const now5 = this.clock();
|
|
838
|
+
token2.attributes.last_used_at = now5;
|
|
839
|
+
await this.#query().where("id", token2.id).update({ last_used_at: now5 });
|
|
684
840
|
}
|
|
685
841
|
async tokensFor(user) {
|
|
686
842
|
const rows = await this.#query().where("tokenable_type", tokenableType(user)).where("tokenable_id", user.getAuthIdentifier()).get();
|
|
@@ -790,15 +946,15 @@ var TokenGuard = class {
|
|
|
790
946
|
return { user, token: token2 };
|
|
791
947
|
}
|
|
792
948
|
#isValid(token2) {
|
|
793
|
-
const
|
|
949
|
+
const now5 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))().getTime();
|
|
794
950
|
const expiresAt = token2.expiresAt;
|
|
795
951
|
const rawExpiresAt = token2.attributes.expires_at;
|
|
796
952
|
if (rawExpiresAt !== null && rawExpiresAt !== void 0 && expiresAt === void 0) return false;
|
|
797
|
-
if (expiresAt !== void 0 && expiresAt.getTime() <=
|
|
953
|
+
if (expiresAt !== void 0 && expiresAt.getTime() <= now5) return false;
|
|
798
954
|
const expiration = this.options.expiration;
|
|
799
955
|
if (typeof expiration === "number") {
|
|
800
956
|
const createdAt = token2.createdAt;
|
|
801
|
-
if (createdAt === void 0 || createdAt.getTime() + expiration * 6e4 <=
|
|
957
|
+
if (createdAt === void 0 || createdAt.getTime() + expiration * 6e4 <= now5) return false;
|
|
802
958
|
}
|
|
803
959
|
return true;
|
|
804
960
|
}
|
|
@@ -1496,6 +1652,7 @@ var AuthServiceProvider = class extends ServiceProvider {
|
|
|
1496
1652
|
if (this.app.bound(Router)) {
|
|
1497
1653
|
this.app.make(Router).aliasMiddleware("auth", Authenticate).aliasMiddleware("guest", RedirectIfAuthenticated).aliasMiddleware("can", Authorize).aliasMiddleware("verified", EnsureEmailIsVerified);
|
|
1498
1654
|
}
|
|
1655
|
+
if (this.app.bound(EventDispatcher)) this.app.make(EventDispatcher).listen(Registered, SendEmailVerificationNotification);
|
|
1499
1656
|
await discoverPolicies(this.app.appPath("Policies"), this.app.make(Gate));
|
|
1500
1657
|
}
|
|
1501
1658
|
};
|
|
@@ -1568,11 +1725,11 @@ var UniqueLock = class _UniqueLock {
|
|
|
1568
1725
|
async acquire(job) {
|
|
1569
1726
|
const members = job;
|
|
1570
1727
|
const uniqueFor = typeof members.uniqueFor === "function" ? members.uniqueFor.call(job) : members.uniqueFor ?? 0;
|
|
1571
|
-
const
|
|
1728
|
+
const store = members.uniqueVia?.call(job);
|
|
1572
1729
|
const key = _UniqueLock.key(job);
|
|
1573
|
-
if (!await this.store(
|
|
1730
|
+
if (!await this.store(store).lock(key, uniqueFor > 0 ? uniqueFor : void 0).get()) return void 0;
|
|
1574
1731
|
const spec = { key, untilProcessing: members.uniqueUntilProcessing === true };
|
|
1575
|
-
if (
|
|
1732
|
+
if (store !== void 0) spec.store = store;
|
|
1576
1733
|
return spec;
|
|
1577
1734
|
}
|
|
1578
1735
|
async release(spec) {
|
|
@@ -1918,7 +2075,7 @@ var BusServiceProvider = class extends ServiceProvider {
|
|
|
1918
2075
|
|
|
1919
2076
|
// ../Cache/dist/index.js
|
|
1920
2077
|
import { setTimeout as sleep } from "timers/promises";
|
|
1921
|
-
import { createHash as
|
|
2078
|
+
import { createHash as createHash5 } from "crypto";
|
|
1922
2079
|
import { link, mkdir, readFile, rename, rm, stat, writeFile } from "fs/promises";
|
|
1923
2080
|
import { dirname, join as join2 } from "path";
|
|
1924
2081
|
import { setTimeout as sleep2 } from "timers/promises";
|
|
@@ -1939,8 +2096,8 @@ var TagsNotSupportedError = class extends Error {
|
|
|
1939
2096
|
kind = "Server";
|
|
1940
2097
|
status = 500;
|
|
1941
2098
|
name = "TagsNotSupportedError";
|
|
1942
|
-
constructor(
|
|
1943
|
-
super(`The [${
|
|
2099
|
+
constructor(store) {
|
|
2100
|
+
super(`The [${store}] cache store does not support tags. Only the redis store does.`);
|
|
1944
2101
|
}
|
|
1945
2102
|
};
|
|
1946
2103
|
var UnknownCacheStoreError = class extends Error {
|
|
@@ -1974,8 +2131,8 @@ function roundTrip(value2) {
|
|
|
1974
2131
|
return JSON.parse(serialize(value2));
|
|
1975
2132
|
}
|
|
1976
2133
|
var GenericLock = class {
|
|
1977
|
-
constructor(
|
|
1978
|
-
this.store =
|
|
2134
|
+
constructor(store, name, seconds, owner, pollMs = 50) {
|
|
2135
|
+
this.store = store;
|
|
1979
2136
|
this.name = name;
|
|
1980
2137
|
this.seconds = seconds;
|
|
1981
2138
|
this.pollMs = pollMs;
|
|
@@ -2022,10 +2179,10 @@ var GenericLock = class {
|
|
|
2022
2179
|
await this.store.forget(this.name);
|
|
2023
2180
|
}
|
|
2024
2181
|
};
|
|
2025
|
-
var defaultLockFactory = (
|
|
2182
|
+
var defaultLockFactory = (store, name, seconds, owner) => new GenericLock(store, name, seconds, owner);
|
|
2026
2183
|
var Repository2 = class {
|
|
2027
|
-
constructor(
|
|
2028
|
-
this.store =
|
|
2184
|
+
constructor(store, lockFactory = defaultLockFactory) {
|
|
2185
|
+
this.store = store;
|
|
2029
2186
|
this.lockFactory = lockFactory;
|
|
2030
2187
|
}
|
|
2031
2188
|
store;
|
|
@@ -2195,7 +2352,7 @@ var FileStore = class {
|
|
|
2195
2352
|
directory;
|
|
2196
2353
|
keyPrefix;
|
|
2197
2354
|
path(key) {
|
|
2198
|
-
const hash2 =
|
|
2355
|
+
const hash2 = createHash5("sha1").update(this.keyPrefix + key).digest("hex");
|
|
2199
2356
|
return join2(this.directory, hash2.slice(0, 2), hash2.slice(2, 4), hash2);
|
|
2200
2357
|
}
|
|
2201
2358
|
tempPath(path) {
|
|
@@ -2366,8 +2523,8 @@ var FileStore = class {
|
|
|
2366
2523
|
};
|
|
2367
2524
|
async function insertOrTakeOver(connection, table, row) {
|
|
2368
2525
|
if (await connection.table(table).insertOrIgnore(row) === 1) return true;
|
|
2369
|
-
const
|
|
2370
|
-
return await connection.table(table).where("key", row.key).where("expiration", "<=",
|
|
2526
|
+
const now5 = Math.floor(Date.now() / 1e3);
|
|
2527
|
+
return await connection.table(table).where("key", row.key).where("expiration", "<=", now5).update(row) > 0;
|
|
2371
2528
|
}
|
|
2372
2529
|
var FOREVER_SECONDS = 31536e4;
|
|
2373
2530
|
var now22 = () => Math.floor(Date.now() / 1e3);
|
|
@@ -2799,8 +2956,8 @@ var CacheManager2 = class {
|
|
|
2799
2956
|
const table = cfg.table ?? "cache";
|
|
2800
2957
|
const lockTable = cfg.lockTable ?? "cache_locks";
|
|
2801
2958
|
const prefix = this.str(cfg.prefix);
|
|
2802
|
-
const
|
|
2803
|
-
return new Repository2(
|
|
2959
|
+
const store = new DatabaseStore(connection, table, prefix);
|
|
2960
|
+
return new Repository2(store, (_store, name, seconds, owner) => new DatabaseLock(connection, lockTable, prefix + name, seconds, owner));
|
|
2804
2961
|
}
|
|
2805
2962
|
buildRedisStore(cfg) {
|
|
2806
2963
|
const resolved = resolveRedisConfig(
|
|
@@ -2808,8 +2965,8 @@ var CacheManager2 = class {
|
|
|
2808
2965
|
(connectionName) => this.container.make(ConfigRepository).get(`database.redis.${connectionName}`, {})
|
|
2809
2966
|
);
|
|
2810
2967
|
const redis = makeRedisClient(resolved);
|
|
2811
|
-
const
|
|
2812
|
-
return new RedisRepository(
|
|
2968
|
+
const store = new RedisStore(redis, this.str(cfg.prefix));
|
|
2969
|
+
return new RedisRepository(store, redis);
|
|
2813
2970
|
}
|
|
2814
2971
|
store(name) {
|
|
2815
2972
|
const cacheConfig = this.cacheConfig();
|
|
@@ -2878,7 +3035,54 @@ var CacheManager2 = class {
|
|
|
2878
3035
|
return this.store().tags(names);
|
|
2879
3036
|
}
|
|
2880
3037
|
};
|
|
3038
|
+
var now4 = () => Math.floor(Date.now() / 1e3);
|
|
3039
|
+
var CacheRateLimiter = class {
|
|
3040
|
+
constructor(store) {
|
|
3041
|
+
this.store = store;
|
|
3042
|
+
}
|
|
3043
|
+
store;
|
|
3044
|
+
async tooManyAttempts(key, maxAttempts) {
|
|
3045
|
+
const clean = this.cleanKey(key);
|
|
3046
|
+
if (await this.#attempts(clean) >= maxAttempts) {
|
|
3047
|
+
if (await this.store().has(`${clean}:timer`)) return true;
|
|
3048
|
+
await this.store().forget(clean);
|
|
3049
|
+
}
|
|
3050
|
+
return false;
|
|
3051
|
+
}
|
|
3052
|
+
async hit(key, decaySeconds = 60) {
|
|
3053
|
+
const clean = this.cleanKey(key);
|
|
3054
|
+
const cache2 = this.store();
|
|
3055
|
+
await cache2.add(`${clean}:timer`, now4() + decaySeconds, decaySeconds);
|
|
3056
|
+
const added = await cache2.add(clean, 0, decaySeconds);
|
|
3057
|
+
const hits = await cache2.increment(clean);
|
|
3058
|
+
if (!added && hits === 1) await cache2.put(clean, 1, decaySeconds);
|
|
3059
|
+
return hits;
|
|
3060
|
+
}
|
|
3061
|
+
attempts(key) {
|
|
3062
|
+
return this.#attempts(this.cleanKey(key));
|
|
3063
|
+
}
|
|
3064
|
+
async remaining(key, maxAttempts) {
|
|
3065
|
+
return Math.max(0, maxAttempts - await this.#attempts(this.cleanKey(key)));
|
|
3066
|
+
}
|
|
3067
|
+
async availableIn(key) {
|
|
3068
|
+
const timer = await this.store().get(`${this.cleanKey(key)}:timer`);
|
|
3069
|
+
return timer === void 0 ? 0 : Math.max(0, Number(timer) - now4());
|
|
3070
|
+
}
|
|
3071
|
+
async clear(key) {
|
|
3072
|
+
const clean = this.cleanKey(key);
|
|
3073
|
+
await this.store().forget(clean);
|
|
3074
|
+
await this.store().forget(`${clean}:timer`);
|
|
3075
|
+
}
|
|
3076
|
+
/** Laravel's cleanRateLimiterKey(): accented letters become their plain letter ('zoë' and 'zoe' share a key). */
|
|
3077
|
+
cleanKey(key) {
|
|
3078
|
+
return key.normalize("NFKD").replace(/[̀-ͯ]/g, "");
|
|
3079
|
+
}
|
|
3080
|
+
async #attempts(clean) {
|
|
3081
|
+
return Number(await this.store().get(clean) ?? 0);
|
|
3082
|
+
}
|
|
3083
|
+
};
|
|
2881
3084
|
var Cache = facade(CacheManager);
|
|
3085
|
+
var RateLimiter2 = facade(RateLimiter);
|
|
2882
3086
|
function cache(arg, ttlSeconds) {
|
|
2883
3087
|
const manager2 = inject(CacheManager);
|
|
2884
3088
|
if (arg === void 0) return manager2;
|
|
@@ -2906,6 +3110,12 @@ var CacheServiceProvider = class extends ServiceProvider {
|
|
|
2906
3110
|
"cache"
|
|
2907
3111
|
);
|
|
2908
3112
|
this.app.singleton(CacheManager, (container) => new CacheManager2(container));
|
|
3113
|
+
this.app.singleton(RateLimiter, (container) => {
|
|
3114
|
+
return new CacheRateLimiter(() => {
|
|
3115
|
+
const name = container.make(ConfigRepository).get("cache.limiter", void 0);
|
|
3116
|
+
return container.make(CacheManager).store(name === void 0 || name === "" ? void 0 : name);
|
|
3117
|
+
});
|
|
3118
|
+
});
|
|
2909
3119
|
}
|
|
2910
3120
|
};
|
|
2911
3121
|
|
|
@@ -2920,7 +3130,7 @@ import { start } from "repl";
|
|
|
2920
3130
|
import { existsSync as existsSync2, readdirSync } from "fs";
|
|
2921
3131
|
import { join as join4 } from "path";
|
|
2922
3132
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
2923
|
-
import { createHash as
|
|
3133
|
+
import { createHash as createHash6 } from "crypto";
|
|
2924
3134
|
import { CronExpressionParser } from "cron-parser";
|
|
2925
3135
|
var InvalidSignatureError = class extends Error {
|
|
2926
3136
|
name = "InvalidSignatureError";
|
|
@@ -2990,7 +3200,7 @@ var NodeConsoleInput = class {
|
|
|
2990
3200
|
const line = this.lines.shift();
|
|
2991
3201
|
if (line !== void 0) return line;
|
|
2992
3202
|
if (this.ended) throw new Error("Aborted.");
|
|
2993
|
-
return new Promise((
|
|
3203
|
+
return new Promise((resolve3, reject) => this.waiting.push({ resolve: resolve3, reject }));
|
|
2994
3204
|
}
|
|
2995
3205
|
close() {
|
|
2996
3206
|
const rl = this.rl;
|
|
@@ -3035,11 +3245,11 @@ var Command = class {
|
|
|
3035
3245
|
consoleOutput = new NodeConsoleOutput();
|
|
3036
3246
|
consoleInput = new NodeConsoleInput();
|
|
3037
3247
|
/** @internal Set by the kernel before handle() runs. */
|
|
3038
|
-
bind(args, options,
|
|
3248
|
+
bind(args, options, io) {
|
|
3039
3249
|
this.boundArguments = args;
|
|
3040
3250
|
this.boundOptions = options;
|
|
3041
|
-
this.consoleInput =
|
|
3042
|
-
this.consoleOutput =
|
|
3251
|
+
this.consoleInput = io.input;
|
|
3252
|
+
this.consoleOutput = io.output;
|
|
3043
3253
|
}
|
|
3044
3254
|
argument(name) {
|
|
3045
3255
|
return this.boundArguments[name];
|
|
@@ -4009,15 +4219,15 @@ var ScheduleListCommand = class extends Command {
|
|
|
4009
4219
|
function summaryOf(event2) {
|
|
4010
4220
|
return event2.getSummary();
|
|
4011
4221
|
}
|
|
4012
|
-
async function runDueEvents(events,
|
|
4222
|
+
async function runDueEvents(events, io, now5) {
|
|
4013
4223
|
const backgroundRuns = [];
|
|
4014
4224
|
for (const event2 of events) {
|
|
4015
|
-
|
|
4225
|
+
io.info(`Running scheduled task: ${summaryOf(event2)}`);
|
|
4016
4226
|
const attempt = async () => {
|
|
4017
4227
|
try {
|
|
4018
|
-
await event2.run(
|
|
4228
|
+
await event2.run(now5);
|
|
4019
4229
|
} catch (error) {
|
|
4020
|
-
|
|
4230
|
+
io.error(` Failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
4021
4231
|
}
|
|
4022
4232
|
};
|
|
4023
4233
|
if (event2.isBackground()) {
|
|
@@ -4032,13 +4242,13 @@ var ScheduleRunCommand = class extends Command {
|
|
|
4032
4242
|
signature = "schedule:run";
|
|
4033
4243
|
description = "Run the scheduled commands";
|
|
4034
4244
|
async handle() {
|
|
4035
|
-
const
|
|
4036
|
-
const due = inject(Schedule).dueEvents(
|
|
4245
|
+
const now5 = /* @__PURE__ */ new Date();
|
|
4246
|
+
const due = inject(Schedule).dueEvents(now5);
|
|
4037
4247
|
if (due.length === 0) {
|
|
4038
4248
|
this.info("No scheduled commands are ready to run.");
|
|
4039
4249
|
return 0;
|
|
4040
4250
|
}
|
|
4041
|
-
await runDueEvents(due, this,
|
|
4251
|
+
await runDueEvents(due, this, now5);
|
|
4042
4252
|
return 0;
|
|
4043
4253
|
}
|
|
4044
4254
|
};
|
|
@@ -4052,7 +4262,7 @@ var ScheduleWorkCommand = class extends Command {
|
|
|
4052
4262
|
description = "Start the schedule worker";
|
|
4053
4263
|
async handle() {
|
|
4054
4264
|
const schedule = inject(Schedule);
|
|
4055
|
-
const sleep5 = this.workOptions.sleep ?? ((ms) => new Promise((
|
|
4265
|
+
const sleep5 = this.workOptions.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
|
|
4056
4266
|
const clock = this.workOptions.now ?? Date.now;
|
|
4057
4267
|
this.info("Running scheduled tasks every minute.");
|
|
4058
4268
|
let lastMinute;
|
|
@@ -4061,8 +4271,8 @@ var ScheduleWorkCommand = class extends Command {
|
|
|
4061
4271
|
const minute = Math.floor(time / 6e4);
|
|
4062
4272
|
if (minute !== lastMinute) {
|
|
4063
4273
|
lastMinute = minute;
|
|
4064
|
-
const
|
|
4065
|
-
await runDueEvents(schedule.dueEvents(
|
|
4274
|
+
const now5 = new Date(time);
|
|
4275
|
+
await runDueEvents(schedule.dueEvents(now5), this, now5);
|
|
4066
4276
|
}
|
|
4067
4277
|
await sleep5(Math.max(0, (minute + 1) * 6e4 - clock()) + 10);
|
|
4068
4278
|
}
|
|
@@ -4085,13 +4295,13 @@ var TestCommand = class extends Command {
|
|
|
4085
4295
|
if (typeof filter === "string") args.push("--testNamePattern", filter);
|
|
4086
4296
|
const extra = this.argument("args");
|
|
4087
4297
|
if (Array.isArray(extra)) args.push(...extra);
|
|
4088
|
-
return new Promise((
|
|
4298
|
+
return new Promise((resolve3) => {
|
|
4089
4299
|
const child = this.spawner("npx", args);
|
|
4090
4300
|
child.on("error", (error) => {
|
|
4091
4301
|
this.error(error.message);
|
|
4092
|
-
|
|
4302
|
+
resolve3(1);
|
|
4093
4303
|
});
|
|
4094
|
-
child.on("exit", (code) =>
|
|
4304
|
+
child.on("exit", (code) => resolve3(code ?? 1));
|
|
4095
4305
|
});
|
|
4096
4306
|
}
|
|
4097
4307
|
};
|
|
@@ -4106,10 +4316,10 @@ var TinkerCommand = class extends Command {
|
|
|
4106
4316
|
handle() {
|
|
4107
4317
|
const app2 = inject(Application);
|
|
4108
4318
|
const startRepl = this.tinkerOptions.start ?? ((options) => start(options));
|
|
4109
|
-
return new Promise((
|
|
4319
|
+
return new Promise((resolve3) => {
|
|
4110
4320
|
const repl = startRepl({ prompt: "oriel> " });
|
|
4111
4321
|
repl.context.app = app2;
|
|
4112
|
-
repl.on("exit", () =>
|
|
4322
|
+
repl.on("exit", () => resolve3(0));
|
|
4113
4323
|
});
|
|
4114
4324
|
}
|
|
4115
4325
|
};
|
|
@@ -4201,11 +4411,11 @@ function parametersToInput(parameters, signature) {
|
|
|
4201
4411
|
}
|
|
4202
4412
|
return { arguments: args, options };
|
|
4203
4413
|
}
|
|
4204
|
-
var
|
|
4205
|
-
constructor(app2,
|
|
4414
|
+
var Kernel2 = class {
|
|
4415
|
+
constructor(app2, io = {}) {
|
|
4206
4416
|
this.app = app2;
|
|
4207
|
-
this.defaultInput =
|
|
4208
|
-
this.defaultOutput =
|
|
4417
|
+
this.defaultInput = io.input ?? new NodeConsoleInput();
|
|
4418
|
+
this.defaultOutput = io.output ?? new NodeConsoleOutput();
|
|
4209
4419
|
}
|
|
4210
4420
|
app;
|
|
4211
4421
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -4238,22 +4448,22 @@ var Kernel = class {
|
|
|
4238
4448
|
return code;
|
|
4239
4449
|
}
|
|
4240
4450
|
/** @internal Runs a command with the given I/O. Command.call() passes its own, so nested output isn't swallowed. */
|
|
4241
|
-
async callWithIo(command, parameters,
|
|
4451
|
+
async callWithIo(command, parameters, io) {
|
|
4242
4452
|
const instance = this.findOrThrow(command);
|
|
4243
4453
|
const signature = parseSignature(instance.signature);
|
|
4244
|
-
return this.execute(instance, signature, parametersToInput(parameters, signature),
|
|
4454
|
+
return this.execute(instance, signature, parametersToInput(parameters, signature), io);
|
|
4245
4455
|
}
|
|
4246
4456
|
async handle(argv) {
|
|
4247
|
-
const
|
|
4457
|
+
const io = { input: this.defaultInput, output: this.defaultOutput };
|
|
4248
4458
|
this.running++;
|
|
4249
4459
|
try {
|
|
4250
4460
|
const [name, ...rest] = this.normalizeTopLevel(argv);
|
|
4251
4461
|
const instance = this.findOrThrow(name);
|
|
4252
4462
|
const signature = parseSignature(instance.signature);
|
|
4253
4463
|
const input = parseArgv(rest, signature);
|
|
4254
|
-
return await this.execute(instance, signature, input,
|
|
4464
|
+
return await this.execute(instance, signature, input, io);
|
|
4255
4465
|
} catch (error) {
|
|
4256
|
-
return this.reportTopLevelError(error,
|
|
4466
|
+
return this.reportTopLevelError(error, io.output);
|
|
4257
4467
|
} finally {
|
|
4258
4468
|
if (--this.running === 0) this.defaultInput.close?.();
|
|
4259
4469
|
}
|
|
@@ -4295,10 +4505,10 @@ var Kernel = class {
|
|
|
4295
4505
|
throw new CommandNotFoundError(`Command "${name}" is not defined.`, suggest(name, [...this.commands.keys()]));
|
|
4296
4506
|
return instance;
|
|
4297
4507
|
}
|
|
4298
|
-
async execute(instance, signature, input,
|
|
4508
|
+
async execute(instance, signature, input, io) {
|
|
4299
4509
|
validateRequiredArguments(signature, input);
|
|
4300
4510
|
const run = Object.create(instance);
|
|
4301
|
-
run.bind?.(resolveArguments(signature, input), resolveOptions(signature, input),
|
|
4511
|
+
run.bind?.(resolveArguments(signature, input), resolveOptions(signature, input), io);
|
|
4302
4512
|
const scope = this.app.createScope();
|
|
4303
4513
|
scope.instance(ConsoleKernel, this);
|
|
4304
4514
|
return scope.run(async () => {
|
|
@@ -4331,7 +4541,7 @@ function parseTime(time) {
|
|
|
4331
4541
|
return [minute, hour];
|
|
4332
4542
|
}
|
|
4333
4543
|
function sha1(value2) {
|
|
4334
|
-
return
|
|
4544
|
+
return createHash6("sha1").update(value2).digest("hex");
|
|
4335
4545
|
}
|
|
4336
4546
|
var ScheduledEventImpl = class {
|
|
4337
4547
|
/**
|
|
@@ -4470,21 +4680,21 @@ var ScheduledEventImpl = class {
|
|
|
4470
4680
|
* Minute precision: `now` is truncated to the start of its minute, since cron-parser's includesDate() also
|
|
4471
4681
|
* compares seconds. Without timezone(), expressions are read in app.timezone (UTC by default), as in Laravel.
|
|
4472
4682
|
*/
|
|
4473
|
-
isDue(
|
|
4474
|
-
const minute = new Date(Math.floor(
|
|
4683
|
+
isDue(now5) {
|
|
4684
|
+
const minute = new Date(Math.floor(now5.getTime() / 6e4) * 6e4);
|
|
4475
4685
|
const parsed = CronExpressionParser.parse(this.cronExpression, { tz: this.zone() });
|
|
4476
4686
|
if (!parsed.includesDate(minute)) return false;
|
|
4477
|
-
return !this.betweenWindow || this.isWithinWindow(
|
|
4687
|
+
return !this.betweenWindow || this.isWithinWindow(now5);
|
|
4478
4688
|
}
|
|
4479
4689
|
zone() {
|
|
4480
4690
|
if (this.tz !== void 0) return this.tz;
|
|
4481
4691
|
const container = currentContainer();
|
|
4482
4692
|
return container?.bound(ConfigRepository) ? container.make(ConfigRepository).get("app.timezone", "UTC") : "UTC";
|
|
4483
4693
|
}
|
|
4484
|
-
isWithinWindow(
|
|
4694
|
+
isWithinWindow(now5) {
|
|
4485
4695
|
const { start: start2, end } = this.betweenWindow;
|
|
4486
4696
|
const format = (d) => d.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit", hour12: false, timeZone: this.zone() });
|
|
4487
|
-
const current = format(
|
|
4697
|
+
const current = format(now5);
|
|
4488
4698
|
return start2 <= end ? current >= start2 && current <= end : current >= start2 || current <= end;
|
|
4489
4699
|
}
|
|
4490
4700
|
/**
|
|
@@ -4574,8 +4784,8 @@ var ScheduleImpl = class {
|
|
|
4574
4784
|
events() {
|
|
4575
4785
|
return [...this.scheduledEvents];
|
|
4576
4786
|
}
|
|
4577
|
-
dueEvents(
|
|
4578
|
-
return this.scheduledEvents.filter((event2) => event2.isDue(
|
|
4787
|
+
dueEvents(now5) {
|
|
4788
|
+
return this.scheduledEvents.filter((event2) => event2.isDue(now5));
|
|
4579
4789
|
}
|
|
4580
4790
|
push(event2) {
|
|
4581
4791
|
this.scheduledEvents.push(event2);
|
|
@@ -4585,7 +4795,7 @@ var ScheduleImpl = class {
|
|
|
4585
4795
|
var ConsoleServiceProvider = class extends ServiceProvider {
|
|
4586
4796
|
register() {
|
|
4587
4797
|
this.mergeConfigFrom({ stubs: {} }, "console");
|
|
4588
|
-
this.app.singleton(ConsoleKernel, () => new
|
|
4798
|
+
this.app.singleton(ConsoleKernel, () => new Kernel2(this.app));
|
|
4589
4799
|
this.app.singleton(Schedule, () => new ScheduleImpl());
|
|
4590
4800
|
}
|
|
4591
4801
|
boot() {
|
|
@@ -4644,14 +4854,14 @@ async function runConsoleAndExit(app2, argv = process.argv.slice(2), exit = (cod
|
|
|
4644
4854
|
// ../Cookie/dist/index.js
|
|
4645
4855
|
import { createHmac as createHmac2, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
4646
4856
|
var SAME_SITE = { lax: "Lax", strict: "Strict", none: "None" };
|
|
4647
|
-
function serializeCookie(cookie2,
|
|
4857
|
+
function serializeCookie(cookie2, now5 = Date.now()) {
|
|
4648
4858
|
const parts = [];
|
|
4649
4859
|
if (cookie2.minutes < 0) {
|
|
4650
4860
|
parts.push(`${cookie2.name}=`, "Expires=Thu, 01 Jan 1970 00:00:00 GMT", "Max-Age=0");
|
|
4651
4861
|
} else {
|
|
4652
4862
|
parts.push(`${cookie2.name}=${encodeURIComponent(cookie2.value)}`);
|
|
4653
4863
|
if (cookie2.minutes > 0) {
|
|
4654
|
-
parts.push(`Expires=${new Date(
|
|
4864
|
+
parts.push(`Expires=${new Date(now5 + cookie2.minutes * 6e4).toUTCString()}`, `Max-Age=${cookie2.minutes * 60}`);
|
|
4655
4865
|
}
|
|
4656
4866
|
}
|
|
4657
4867
|
parts.push(`Path=${cookie2.path}`);
|
|
@@ -4774,14 +4984,14 @@ var AddQueuedCookiesToResponse = class {
|
|
|
4774
4984
|
}
|
|
4775
4985
|
};
|
|
4776
4986
|
var neverEncrypt = /* @__PURE__ */ new Set();
|
|
4777
|
-
function isDeletion(attributes,
|
|
4987
|
+
function isDeletion(attributes, now5 = Date.now()) {
|
|
4778
4988
|
for (const part of attributes.split(";")) {
|
|
4779
4989
|
const equals4 = part.indexOf("=");
|
|
4780
4990
|
if (equals4 === -1) continue;
|
|
4781
4991
|
const key = part.slice(0, equals4).trim().toLowerCase();
|
|
4782
4992
|
const value2 = part.slice(equals4 + 1).trim();
|
|
4783
4993
|
if (key === "max-age" && Number(value2) <= 0) return true;
|
|
4784
|
-
if (key === "expires" && Date.parse(value2) <=
|
|
4994
|
+
if (key === "expires" && Date.parse(value2) <= now5) return true;
|
|
4785
4995
|
}
|
|
4786
4996
|
return false;
|
|
4787
4997
|
}
|
|
@@ -8484,9 +8694,9 @@ var BelongsToMany = class extends Relation {
|
|
|
8484
8694
|
pivotRow(id, attributes, creating) {
|
|
8485
8695
|
const row = { ...attributes, [this.foreignPivotKey]: this.getParentKey(), [this.relatedPivotKey]: this.idOf(id) };
|
|
8486
8696
|
if (this.pivotTimestamps && creating) {
|
|
8487
|
-
const
|
|
8488
|
-
row[this.pivotTimestamps[0]] ??=
|
|
8489
|
-
row[this.pivotTimestamps[1]] ??=
|
|
8697
|
+
const now5 = formatDateTime(this.parent.freshTimestamp());
|
|
8698
|
+
row[this.pivotTimestamps[0]] ??= now5;
|
|
8699
|
+
row[this.pivotTimestamps[1]] ??= now5;
|
|
8490
8700
|
}
|
|
8491
8701
|
return row;
|
|
8492
8702
|
}
|
|
@@ -9876,9 +10086,9 @@ var Model = class _Model {
|
|
|
9876
10086
|
}
|
|
9877
10087
|
/** The current time, to the second (the storage precision). */
|
|
9878
10088
|
freshTimestamp() {
|
|
9879
|
-
const
|
|
9880
|
-
|
|
9881
|
-
return
|
|
10089
|
+
const now5 = /* @__PURE__ */ new Date();
|
|
10090
|
+
now5.setMilliseconds(0);
|
|
10091
|
+
return now5;
|
|
9882
10092
|
}
|
|
9883
10093
|
updateTimestamps() {
|
|
9884
10094
|
const time = this.freshTimestamp();
|
|
@@ -11243,7 +11453,7 @@ function databaseConfigDefaults(app2) {
|
|
|
11243
11453
|
}
|
|
11244
11454
|
};
|
|
11245
11455
|
}
|
|
11246
|
-
function
|
|
11456
|
+
function currentRequest2() {
|
|
11247
11457
|
const container = currentContainer();
|
|
11248
11458
|
if (!container?.bound(HttpRequest)) return void 0;
|
|
11249
11459
|
try {
|
|
@@ -11253,13 +11463,13 @@ function currentRequest() {
|
|
|
11253
11463
|
}
|
|
11254
11464
|
}
|
|
11255
11465
|
function usePaginationResolvers() {
|
|
11256
|
-
AbstractPaginator.currentPathResolver = () =>
|
|
11466
|
+
AbstractPaginator.currentPathResolver = () => currentRequest2()?.url() ?? "/";
|
|
11257
11467
|
AbstractPaginator.currentPageResolver = (pageName) => {
|
|
11258
|
-
const page = Number(
|
|
11468
|
+
const page = Number(currentRequest2()?.input(pageName));
|
|
11259
11469
|
return Number.isInteger(page) && page >= 1 ? page : 1;
|
|
11260
11470
|
};
|
|
11261
|
-
AbstractPaginator.queryStringResolver = () =>
|
|
11262
|
-
AbstractPaginator.currentCursorResolver = (cursorName) =>
|
|
11471
|
+
AbstractPaginator.queryStringResolver = () => currentRequest2()?.query() ?? {};
|
|
11472
|
+
AbstractPaginator.currentCursorResolver = (cursorName) => currentRequest2()?.input(cursorName);
|
|
11263
11473
|
}
|
|
11264
11474
|
var DatabaseServiceProvider = class extends ServiceProvider {
|
|
11265
11475
|
register() {
|
|
@@ -12679,1866 +12889,93 @@ var HashingServiceProvider = class extends ServiceProvider {
|
|
|
12679
12889
|
}
|
|
12680
12890
|
};
|
|
12681
12891
|
|
|
12682
|
-
// ../
|
|
12683
|
-
import { createReadStream as createReadStream2 } from "fs";
|
|
12684
|
-
import { stat as stat3 } from "fs/promises";
|
|
12685
|
-
import { basename as basename2 } from "path";
|
|
12686
|
-
import { Readable as Readable2 } from "stream";
|
|
12687
|
-
import { readFile as readFile4 } from "fs/promises";
|
|
12688
|
-
import { fileURLToPath } from "url";
|
|
12689
|
-
import { createReadStream as createReadStream22 } from "fs";
|
|
12690
|
-
import { stat as stat22 } from "fs/promises";
|
|
12691
|
-
import { Readable as Readable22 } from "stream";
|
|
12692
|
-
import { relative as relative5, resolve as resolve3, sep as sep4 } from "path";
|
|
12693
|
-
import { createServer } from "http";
|
|
12694
|
-
import { Readable as Readable3 } from "stream";
|
|
12695
|
-
import { pipeline as pipeline2 } from "stream/promises";
|
|
12892
|
+
// ../Inertia/dist/index.js
|
|
12696
12893
|
import { existsSync as existsSync7 } from "fs";
|
|
12697
|
-
import {
|
|
12698
|
-
import {
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12894
|
+
import { join as join10 } from "path";
|
|
12895
|
+
import { createHash as createHash7 } from "crypto";
|
|
12896
|
+
import { existsSync as existsSync23, readFileSync } from "fs";
|
|
12897
|
+
import { spawn as spawn2 } from "child_process";
|
|
12898
|
+
import { existsSync as existsSync33 } from "fs";
|
|
12899
|
+
import { mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
|
|
12900
|
+
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join24, relative as relative5 } from "path";
|
|
12901
|
+
import { existsSync as existsSync42, readFileSync as readFileSync2 } from "fs";
|
|
12902
|
+
var Header = {
|
|
12903
|
+
INERTIA: "X-Inertia",
|
|
12904
|
+
ERROR_BAG: "X-Inertia-Error-Bag",
|
|
12905
|
+
LOCATION: "X-Inertia-Location",
|
|
12906
|
+
REDIRECT: "X-Inertia-Redirect",
|
|
12907
|
+
VERSION: "X-Inertia-Version",
|
|
12908
|
+
PARTIAL_COMPONENT: "X-Inertia-Partial-Component",
|
|
12909
|
+
PARTIAL_ONLY: "X-Inertia-Partial-Data",
|
|
12910
|
+
PARTIAL_EXCEPT: "X-Inertia-Partial-Except",
|
|
12911
|
+
RESET: "X-Inertia-Reset",
|
|
12912
|
+
INFINITE_SCROLL_MERGE_INTENT: "X-Inertia-Infinite-Scroll-Merge-Intent",
|
|
12913
|
+
EXCEPT_ONCE_PROPS: "X-Inertia-Except-Once-Props"
|
|
12709
12914
|
};
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12915
|
+
function parseList(value2) {
|
|
12916
|
+
const items = (value2 ?? "").split(",").filter((item) => item !== "");
|
|
12917
|
+
return items.length === 0 ? void 0 : items;
|
|
12918
|
+
}
|
|
12919
|
+
var Prop = class {
|
|
12920
|
+
constructor(value2) {
|
|
12921
|
+
this.value = value2;
|
|
12715
12922
|
}
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
name = "HttpServerError";
|
|
12725
|
-
};
|
|
12726
|
-
async function readBody2(raw3, limit) {
|
|
12727
|
-
if (raw3.body === null) return new Uint8Array(0);
|
|
12728
|
-
const declared = Number(raw3.headers.get("content-length") ?? NaN);
|
|
12729
|
-
if (limit !== null && Number.isFinite(declared) && declared > limit) {
|
|
12730
|
-
await raw3.body.cancel();
|
|
12731
|
-
throw new HttpException(413, "Content Too Large");
|
|
12923
|
+
value;
|
|
12924
|
+
mergeState = { merge: false, deep: false, append: true, appendPaths: [], prependPaths: [], matchOn: [] };
|
|
12925
|
+
onceState = { once: false, fresh: false, key: void 0, ttlSeconds: void 0 };
|
|
12926
|
+
deferred = false;
|
|
12927
|
+
deferGroup;
|
|
12928
|
+
/** Calls the callback, if the value is one. */
|
|
12929
|
+
async resolve() {
|
|
12930
|
+
return typeof this.value === "function" ? await this.value() : this.value;
|
|
12732
12931
|
}
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
for (; ; ) {
|
|
12737
|
-
const { done, value: value2 } = await reader.read();
|
|
12738
|
-
if (done) break;
|
|
12739
|
-
size += value2.byteLength;
|
|
12740
|
-
if (limit !== null && size > limit) {
|
|
12741
|
-
await reader.cancel();
|
|
12742
|
-
throw new HttpException(413, "Content Too Large");
|
|
12743
|
-
}
|
|
12744
|
-
chunks.push(value2);
|
|
12932
|
+
/** Never sent on the first load (OptionalProp, DeferProp). */
|
|
12933
|
+
ignoresFirstLoad() {
|
|
12934
|
+
return false;
|
|
12745
12935
|
}
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
out.set(chunk, offset);
|
|
12750
|
-
offset += chunk.byteLength;
|
|
12936
|
+
/** Sent even when a partial reload didn't ask for it (AlwaysProp). */
|
|
12937
|
+
isAlways() {
|
|
12938
|
+
return false;
|
|
12751
12939
|
}
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
const container = currentContainer();
|
|
12756
|
-
return container !== void 0 && container.bound(HttpRequest) ? container : void 0;
|
|
12757
|
-
}
|
|
12758
|
-
function currentRequest2() {
|
|
12759
|
-
return requestScope()?.make(HttpRequest);
|
|
12760
|
-
}
|
|
12761
|
-
function optionalSession() {
|
|
12762
|
-
const scope = requestScope();
|
|
12763
|
-
return scope?.bound(Session) ? scope.make(Session) : void 0;
|
|
12764
|
-
}
|
|
12765
|
-
function optionalCookieJar() {
|
|
12766
|
-
const scope = requestScope();
|
|
12767
|
-
return scope?.bound(CookieJar) ? scope.make(CookieJar) : void 0;
|
|
12768
|
-
}
|
|
12769
|
-
function serializeCookie2(cookie2) {
|
|
12770
|
-
const parts = [`${encodeURIComponent(cookie2.name)}=${encodeURIComponent(cookie2.value)}`, `Path=${cookie2.path}`];
|
|
12771
|
-
if (cookie2.domain !== void 0) parts.push(`Domain=${cookie2.domain}`);
|
|
12772
|
-
if (cookie2.secure) parts.push("Secure");
|
|
12773
|
-
if (cookie2.httpOnly) parts.push("HttpOnly");
|
|
12774
|
-
parts.push(`SameSite=${cookie2.sameSite.charAt(0).toUpperCase()}${cookie2.sameSite.slice(1)}`);
|
|
12775
|
-
if (cookie2.minutes < 0) parts.push("Max-Age=0", "Expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
12776
|
-
else if (cookie2.minutes > 0) parts.push(`Max-Age=${Math.round(cookie2.minutes * 60)}`);
|
|
12777
|
-
return parts.join("; ");
|
|
12778
|
-
}
|
|
12779
|
-
var HttpRedirectResponse = class {
|
|
12780
|
-
constructor(targetUrl, status = 302, headers) {
|
|
12781
|
-
this.targetUrl = targetUrl;
|
|
12782
|
-
this.status = status;
|
|
12783
|
-
this.#headers = new Headers(headers);
|
|
12940
|
+
/** Errors are reported and the prop is left out, instead of failing the page (defer(..., { rescue: true })). */
|
|
12941
|
+
shouldRescue() {
|
|
12942
|
+
return false;
|
|
12784
12943
|
}
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
if (
|
|
12791
|
-
if (typeof key === "string") session2.flash(key, value2);
|
|
12792
|
-
else for (const [name, item] of Object.entries(key)) session2.flash(name, item);
|
|
12944
|
+
// Once (honoured by OptionalProp, DeferProp, MergeProp and OnceProp) ------------------------------------
|
|
12945
|
+
/** once(), once(false), once(true, { as: 'key', until: 3600 }). */
|
|
12946
|
+
once(value2 = true, options = {}) {
|
|
12947
|
+
this.onceState.once = value2;
|
|
12948
|
+
if (options.as !== void 0) this.onceState.key = options.as;
|
|
12949
|
+
if (options.until !== void 0) this.onceState.ttlSeconds = secondsUntil(options.until);
|
|
12793
12950
|
return this;
|
|
12794
12951
|
}
|
|
12795
|
-
/**
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
if (session2 === void 0) return this;
|
|
12799
|
-
const source = typeof errors2.toObject === "function" ? errors2.toObject() : errors2;
|
|
12800
|
-
const normalized = Object.fromEntries(
|
|
12801
|
-
Object.entries(source).map(([field, messages]) => [field, Array.isArray(messages) ? [...messages] : [messages]])
|
|
12802
|
-
);
|
|
12803
|
-
const existing = session2.get("errors", {});
|
|
12804
|
-
session2.flash("errors", { ...existing, [bag]: normalized });
|
|
12952
|
+
/** A custom once key, so pages can share the prop under different names. */
|
|
12953
|
+
as(key) {
|
|
12954
|
+
this.onceState.key = key;
|
|
12805
12955
|
return this;
|
|
12806
12956
|
}
|
|
12807
|
-
/**
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
if (session2 === void 0) return this;
|
|
12811
|
-
session2.flashInput(input ?? currentRequest2()?.input() ?? {});
|
|
12957
|
+
/** Send the prop again even though the client already has it. */
|
|
12958
|
+
fresh(value2 = true) {
|
|
12959
|
+
this.onceState.fresh = value2;
|
|
12812
12960
|
return this;
|
|
12813
12961
|
}
|
|
12814
|
-
/**
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
*/
|
|
12818
|
-
withCookie(name, value2, minutes = 0) {
|
|
12819
|
-
const jar = optionalCookieJar();
|
|
12820
|
-
const cookie2 = jar !== void 0 ? jar.make(name, value2, minutes) : { name, value: value2, minutes, path: "/", secure: false, httpOnly: true, sameSite: "lax" };
|
|
12821
|
-
this.#headers.append("Set-Cookie", serializeCookie2(cookie2));
|
|
12962
|
+
/** Expire after a number of seconds, or at a Date. */
|
|
12963
|
+
until(delay) {
|
|
12964
|
+
this.onceState.ttlSeconds = secondsUntil(delay);
|
|
12822
12965
|
return this;
|
|
12823
12966
|
}
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
return
|
|
12967
|
+
// Merging -------------------------------------------------------------------------------------------------
|
|
12968
|
+
isMergeable() {
|
|
12969
|
+
return false;
|
|
12827
12970
|
}
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
headers.set("Location", this.targetUrl);
|
|
12831
|
-
return new Response(null, { status: this.status, headers });
|
|
12971
|
+
shouldMerge() {
|
|
12972
|
+
return this.isMergeable() && this.mergeState.merge;
|
|
12832
12973
|
}
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
to(path, status = 302, headers) {
|
|
12836
|
-
return new HttpRedirectResponse(inject(UrlGenerator).to(path), status, headers);
|
|
12974
|
+
shouldDeepMerge() {
|
|
12975
|
+
return this.mergeState.deep;
|
|
12837
12976
|
}
|
|
12838
|
-
|
|
12839
|
-
return
|
|
12840
|
-
}
|
|
12841
|
-
back(fallback, status = 302) {
|
|
12842
|
-
return new HttpRedirectResponse(inject(UrlGenerator).previous(fallback), status);
|
|
12843
|
-
}
|
|
12844
|
-
/** Pulls url.intended from the session (put there by guest()), else goes to `fallback`. */
|
|
12845
|
-
intended(fallback = "/", status = 302) {
|
|
12846
|
-
const path = optionalSession()?.pull("url.intended") ?? fallback;
|
|
12847
|
-
return this.to(path, status);
|
|
12848
|
-
}
|
|
12849
|
-
away(url2, status = 302) {
|
|
12850
|
-
return new HttpRedirectResponse(url2, status);
|
|
12851
|
-
}
|
|
12852
|
-
/** Remembers where a guest was going (a GET page, else the previous URL), then redirects to `path`. */
|
|
12853
|
-
guest(path, status = 302) {
|
|
12854
|
-
const session2 = optionalSession();
|
|
12855
|
-
const request2 = currentRequest2();
|
|
12856
|
-
if (session2 !== void 0) {
|
|
12857
|
-
const intended = request2 !== void 0 && request2.method() === "GET" && !request2.expectsJson() ? request2.fullUrl() : inject(UrlGenerator).previous();
|
|
12858
|
-
session2.put("url.intended", intended);
|
|
12859
|
-
}
|
|
12860
|
-
return this.to(path, status);
|
|
12861
|
-
}
|
|
12862
|
-
setIntendedUrl(url2) {
|
|
12863
|
-
optionalSession()?.put("url.intended", url2);
|
|
12864
|
-
}
|
|
12865
|
-
refresh(status = 302) {
|
|
12866
|
-
return this.to(currentRequest2()?.fullUrl() ?? inject(UrlGenerator).current(), status);
|
|
12867
|
-
}
|
|
12868
|
-
};
|
|
12869
|
-
var KEY = /* @__PURE__ */ Symbol.for("oriel:http.client-address");
|
|
12870
|
-
var store = globalThis[KEY] ??= /* @__PURE__ */ new WeakMap();
|
|
12871
|
-
function setClientAddress(request2, address) {
|
|
12872
|
-
if (address !== void 0 && address !== "") store.set(request2, address);
|
|
12873
|
-
}
|
|
12874
|
-
function clientAddress(request2) {
|
|
12875
|
-
return store.get(request2);
|
|
12876
|
-
}
|
|
12877
|
-
var TYPES = {
|
|
12878
|
-
avif: "image/avif",
|
|
12879
|
-
css: "text/css",
|
|
12880
|
-
csv: "text/csv",
|
|
12881
|
-
doc: "application/msword",
|
|
12882
|
-
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
12883
|
-
gif: "image/gif",
|
|
12884
|
-
gz: "application/gzip",
|
|
12885
|
-
html: "text/html",
|
|
12886
|
-
ico: "image/vnd.microsoft.icon",
|
|
12887
|
-
jpg: "image/jpeg",
|
|
12888
|
-
js: "text/javascript",
|
|
12889
|
-
map: "application/json",
|
|
12890
|
-
json: "application/json",
|
|
12891
|
-
md: "text/markdown",
|
|
12892
|
-
mp3: "audio/mpeg",
|
|
12893
|
-
mp4: "video/mp4",
|
|
12894
|
-
otf: "font/otf",
|
|
12895
|
-
pdf: "application/pdf",
|
|
12896
|
-
png: "image/png",
|
|
12897
|
-
svg: "image/svg+xml",
|
|
12898
|
-
ttf: "font/ttf",
|
|
12899
|
-
txt: "text/plain",
|
|
12900
|
-
wasm: "application/wasm",
|
|
12901
|
-
webm: "video/webm",
|
|
12902
|
-
webp: "image/webp",
|
|
12903
|
-
woff: "font/woff",
|
|
12904
|
-
woff2: "font/woff2",
|
|
12905
|
-
xls: "application/vnd.ms-excel",
|
|
12906
|
-
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
12907
|
-
xml: "application/xml",
|
|
12908
|
-
zip: "application/zip"
|
|
12909
|
-
};
|
|
12910
|
-
var ALIASES = { jpeg: "jpg", htm: "html", mjs: "js", text: "txt" };
|
|
12911
|
-
var EXTENSIONS2 = Object.fromEntries(Object.entries(TYPES).map(([extension, type]) => [type, extension]));
|
|
12912
|
-
function mimeFromExtension2(pathOrExtension) {
|
|
12913
|
-
const extension = pathOrExtension.slice(pathOrExtension.lastIndexOf(".") + 1).toLowerCase();
|
|
12914
|
-
return TYPES[ALIASES[extension] ?? extension] ?? "application/octet-stream";
|
|
12915
|
-
}
|
|
12916
|
-
function extensionFromMime(type) {
|
|
12917
|
-
return EXTENSIONS2[type.split(";")[0].trim().toLowerCase()];
|
|
12918
|
-
}
|
|
12919
|
-
var FormUploadedFile = class {
|
|
12920
|
-
constructor(file) {
|
|
12921
|
-
this.file = file;
|
|
12922
|
-
this.clientName = file.name ?? "";
|
|
12923
|
-
this.mimeType = file.type === "" ? "application/octet-stream" : file.type;
|
|
12924
|
-
this.size = file.size;
|
|
12925
|
-
}
|
|
12926
|
-
file;
|
|
12927
|
-
clientName;
|
|
12928
|
-
mimeType;
|
|
12929
|
-
size;
|
|
12930
|
-
/** Guessed from the MIME type, falling back to the client's extension (Laravel's extension()). */
|
|
12931
|
-
extension() {
|
|
12932
|
-
return extensionFromMime(this.mimeType) ?? this.clientExtension();
|
|
12933
|
-
}
|
|
12934
|
-
clientExtension() {
|
|
12935
|
-
const dot = this.clientName.lastIndexOf(".");
|
|
12936
|
-
return dot === -1 ? "" : this.clientName.slice(dot + 1).toLowerCase();
|
|
12937
|
-
}
|
|
12938
|
-
/** A random 40-character name with the guessed extension. */
|
|
12939
|
-
hashName() {
|
|
12940
|
-
const extension = this.extension();
|
|
12941
|
-
return extension === "" ? Str.random(40) : `${Str.random(40)}.${extension}`;
|
|
12942
|
-
}
|
|
12943
|
-
arrayBuffer() {
|
|
12944
|
-
return this.file.arrayBuffer();
|
|
12945
|
-
}
|
|
12946
|
-
text() {
|
|
12947
|
-
return this.file.text();
|
|
12948
|
-
}
|
|
12949
|
-
stream() {
|
|
12950
|
-
return this.file.stream();
|
|
12951
|
-
}
|
|
12952
|
-
store(directory, disk) {
|
|
12953
|
-
return inject(FilesystemManager).disk(disk).putFile(directory, this);
|
|
12954
|
-
}
|
|
12955
|
-
storeAs(directory, name, disk) {
|
|
12956
|
-
return inject(FilesystemManager).disk(disk).putFileAs(directory, this, name);
|
|
12957
|
-
}
|
|
12958
|
-
};
|
|
12959
|
-
var FORBIDDEN = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
12960
|
-
var INTEGER_KEY = /^(?:0|[1-9]\d*)$/;
|
|
12961
|
-
var isPlainObject2 = (value2) => {
|
|
12962
|
-
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return false;
|
|
12963
|
-
const prototype = Object.getPrototypeOf(value2);
|
|
12964
|
-
return prototype === Object.prototype || prototype === null;
|
|
12965
|
-
};
|
|
12966
|
-
function parseBracketKey(name) {
|
|
12967
|
-
const open = name.indexOf("[");
|
|
12968
|
-
if (open <= 0 || !name.endsWith("]")) return [name];
|
|
12969
|
-
const segments = [name.slice(0, open)];
|
|
12970
|
-
const rest = name.slice(open);
|
|
12971
|
-
const matches = rest.match(/\[[^[\]]*\]/g);
|
|
12972
|
-
if (matches === null || matches.join("") !== rest) return [name];
|
|
12973
|
-
for (const match of matches) segments.push(match.slice(1, -1));
|
|
12974
|
-
return segments;
|
|
12975
|
-
}
|
|
12976
|
-
function normalizeLists(value2) {
|
|
12977
|
-
if (Array.isArray(value2)) return value2.map(normalizeLists);
|
|
12978
|
-
if (!isPlainObject2(value2)) return value2;
|
|
12979
|
-
const keys = Object.keys(value2);
|
|
12980
|
-
const out = {};
|
|
12981
|
-
for (const key of keys) out[key] = normalizeLists(value2[key]);
|
|
12982
|
-
if (keys.length > 0 && keys.every((key, index) => key === String(index))) return keys.map((key) => out[key]);
|
|
12983
|
-
return out;
|
|
12984
|
-
}
|
|
12985
|
-
function fromEntries(entries) {
|
|
12986
|
-
const root = {};
|
|
12987
|
-
const nextIndex = /* @__PURE__ */ new WeakMap();
|
|
12988
|
-
for (const [name, value2] of entries) {
|
|
12989
|
-
const segments = parseBracketKey(name);
|
|
12990
|
-
if (segments.some((segment) => FORBIDDEN.has(segment))) continue;
|
|
12991
|
-
let node = root;
|
|
12992
|
-
for (let i = 0; i < segments.length; i++) {
|
|
12993
|
-
let segment = segments[i];
|
|
12994
|
-
const next = nextIndex.get(node) ?? 0;
|
|
12995
|
-
if (segment === "") {
|
|
12996
|
-
segment = String(next);
|
|
12997
|
-
nextIndex.set(node, next + 1);
|
|
12998
|
-
} else if (INTEGER_KEY.test(segment) && Number(segment) >= next) {
|
|
12999
|
-
nextIndex.set(node, Number(segment) + 1);
|
|
13000
|
-
}
|
|
13001
|
-
if (i === segments.length - 1) {
|
|
13002
|
-
node[segment] = value2;
|
|
13003
|
-
break;
|
|
13004
|
-
}
|
|
13005
|
-
if (!isPlainObject2(node[segment])) node[segment] = {};
|
|
13006
|
-
node = node[segment];
|
|
13007
|
-
}
|
|
13008
|
-
}
|
|
13009
|
-
return normalizeLists(root);
|
|
13010
|
-
}
|
|
13011
|
-
function sanitize(value2) {
|
|
13012
|
-
if (Array.isArray(value2)) return value2.map(sanitize);
|
|
13013
|
-
if (!isPlainObject2(value2)) return value2;
|
|
13014
|
-
const out = {};
|
|
13015
|
-
for (const [key, item] of Object.entries(value2)) if (!FORBIDDEN.has(key)) out[key] = sanitize(item);
|
|
13016
|
-
return out;
|
|
13017
|
-
}
|
|
13018
|
-
function mergeRecursive(base, override) {
|
|
13019
|
-
const out = { ...base };
|
|
13020
|
-
for (const [key, value2] of Object.entries(override)) {
|
|
13021
|
-
if (FORBIDDEN.has(key)) continue;
|
|
13022
|
-
const current = out[key];
|
|
13023
|
-
out[key] = (isPlainObject2(current) || Array.isArray(current)) && (isPlainObject2(value2) || Array.isArray(value2)) ? normalizeLists(mergeRecursive({ ...current }, { ...value2 })) : value2;
|
|
13024
|
-
}
|
|
13025
|
-
return out;
|
|
13026
|
-
}
|
|
13027
|
-
function isBlank(value2) {
|
|
13028
|
-
if (value2 === null || value2 === void 0) return true;
|
|
13029
|
-
if (typeof value2 === "string") return value2.trim() === "";
|
|
13030
|
-
if (Array.isArray(value2)) return value2.length === 0;
|
|
13031
|
-
if (isPlainObject2(value2)) return Object.keys(value2).length === 0;
|
|
13032
|
-
return false;
|
|
13033
|
-
}
|
|
13034
|
-
function transformLeaves(tree, transform, prefix = "") {
|
|
13035
|
-
const out = {};
|
|
13036
|
-
for (const [key, value2] of Object.entries(tree)) out[key] = transformValue(`${prefix}${key}`, value2, transform);
|
|
13037
|
-
return out;
|
|
13038
|
-
}
|
|
13039
|
-
function transformValue(path, value2, transform) {
|
|
13040
|
-
if (Array.isArray(value2)) return value2.map((item, index) => transformValue(`${path}.${index}`, item, transform));
|
|
13041
|
-
if (isPlainObject2(value2)) return transformLeaves(value2, transform, `${path}.`);
|
|
13042
|
-
return transform(path, value2);
|
|
13043
|
-
}
|
|
13044
|
-
var TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true", "on", "yes"]);
|
|
13045
|
-
var normalizeIp = (ip) => ip.trim().replace(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i, "$1");
|
|
13046
|
-
function ipv4ToNumber(ip) {
|
|
13047
|
-
const parts = ip.split(".");
|
|
13048
|
-
if (parts.length !== 4 || parts.some((part) => !/^\d{1,3}$/.test(part) || Number(part) > 255)) return void 0;
|
|
13049
|
-
return parts.reduce((total, part) => total * 256 + Number(part), 0);
|
|
13050
|
-
}
|
|
13051
|
-
function ipMatches(ip, patterns) {
|
|
13052
|
-
const address = normalizeIp(ip);
|
|
13053
|
-
return patterns.some((pattern) => {
|
|
13054
|
-
if (pattern === "*") return true;
|
|
13055
|
-
if (!pattern.includes("/")) return normalizeIp(pattern) === address;
|
|
13056
|
-
const [range, bits] = pattern.split("/");
|
|
13057
|
-
const base = ipv4ToNumber(range);
|
|
13058
|
-
const value2 = ipv4ToNumber(address);
|
|
13059
|
-
const size = Number(bits);
|
|
13060
|
-
if (base === void 0 || value2 === void 0 || !(size >= 0 && size <= 32)) return false;
|
|
13061
|
-
const mask = size === 0 ? 0 : ~0 << 32 - size >>> 0;
|
|
13062
|
-
return (base & mask) >>> 0 === (value2 & mask) >>> 0;
|
|
13063
|
-
});
|
|
13064
|
-
}
|
|
13065
|
-
var IncomingRequest = class {
|
|
13066
|
-
constructor(raw3, options = {}) {
|
|
13067
|
-
this.raw = raw3;
|
|
13068
|
-
this.#url = new URL(raw3.url);
|
|
13069
|
-
this.#trustedProxies = options.trustedProxies ?? [];
|
|
13070
|
-
this.#maxBodySize = options.maxBodySize === void 0 ? 8 * 1024 * 1024 : options.maxBodySize;
|
|
13071
|
-
this.#query = fromEntries(this.#url.searchParams.entries());
|
|
13072
|
-
this.#method = raw3.method.toUpperCase();
|
|
13073
|
-
}
|
|
13074
|
-
raw;
|
|
13075
|
-
#url;
|
|
13076
|
-
#trustedProxies;
|
|
13077
|
-
#maxBodySize;
|
|
13078
|
-
#query;
|
|
13079
|
-
#body = {};
|
|
13080
|
-
#files = {};
|
|
13081
|
-
#content = "";
|
|
13082
|
-
#method;
|
|
13083
|
-
#cookies;
|
|
13084
|
-
#loading;
|
|
13085
|
-
#userResolver;
|
|
13086
|
-
/** Reads and parses the body (JSON, urlencoded or multipart) once, then applies method spoofing. */
|
|
13087
|
-
load() {
|
|
13088
|
-
return this.#loading ??= this.#load();
|
|
13089
|
-
}
|
|
13090
|
-
async #load() {
|
|
13091
|
-
const method = this.raw.method.toUpperCase();
|
|
13092
|
-
if (method !== "GET" && method !== "HEAD" && this.raw.body !== null) {
|
|
13093
|
-
const type = (this.raw.headers.get("content-type") ?? "").toLowerCase();
|
|
13094
|
-
const isJson = type.includes("/json") || type.includes("+json");
|
|
13095
|
-
const isUrlencoded = type.startsWith("application/x-www-form-urlencoded");
|
|
13096
|
-
const isMultipart = type.startsWith("multipart/form-data");
|
|
13097
|
-
if (isJson || isUrlencoded || isMultipart) {
|
|
13098
|
-
const bytes = await readBody2(this.raw, this.#maxBodySize);
|
|
13099
|
-
try {
|
|
13100
|
-
if (isJson) {
|
|
13101
|
-
this.#content = new TextDecoder().decode(bytes);
|
|
13102
|
-
this.#body = this.#parseJson(this.#content);
|
|
13103
|
-
} else if (isUrlencoded) {
|
|
13104
|
-
this.#content = new TextDecoder().decode(bytes);
|
|
13105
|
-
this.#body = fromEntries(new URLSearchParams(this.#content).entries());
|
|
13106
|
-
} else {
|
|
13107
|
-
this.#parseForm(await new Response(bytes, { headers: { "content-type": this.raw.headers.get("content-type") ?? "" } }).formData());
|
|
13108
|
-
}
|
|
13109
|
-
} catch {
|
|
13110
|
-
}
|
|
13111
|
-
}
|
|
13112
|
-
}
|
|
13113
|
-
if (method === "POST") {
|
|
13114
|
-
const override = this.raw.headers.get("x-http-method-override") ?? this.#string(this.#body._method) ?? this.#string(this.#query._method);
|
|
13115
|
-
const spoofed = override?.toUpperCase();
|
|
13116
|
-
if (spoofed !== void 0 && /^[A-Z]+$/.test(spoofed) && !["GET", "HEAD", "CONNECT", "TRACE"].includes(spoofed)) {
|
|
13117
|
-
this.#method = spoofed;
|
|
13118
|
-
}
|
|
13119
|
-
}
|
|
13120
|
-
return this;
|
|
13121
|
-
}
|
|
13122
|
-
#parseJson(text3) {
|
|
13123
|
-
let parsed;
|
|
13124
|
-
try {
|
|
13125
|
-
parsed = JSON.parse(text3);
|
|
13126
|
-
} catch {
|
|
13127
|
-
return {};
|
|
13128
|
-
}
|
|
13129
|
-
if (Array.isArray(parsed)) return sanitize({ ...parsed });
|
|
13130
|
-
return isPlainObject2(parsed) ? sanitize(parsed) : {};
|
|
13131
|
-
}
|
|
13132
|
-
#parseForm(form) {
|
|
13133
|
-
const fields = [];
|
|
13134
|
-
const files3 = [];
|
|
13135
|
-
for (const [name, value2] of form.entries()) {
|
|
13136
|
-
if (typeof value2 === "string") fields.push([name, value2]);
|
|
13137
|
-
else if (!((value2.name ?? "") === "" && value2.size === 0)) files3.push([name, new FormUploadedFile(value2)]);
|
|
13138
|
-
}
|
|
13139
|
-
this.#body = fromEntries(fields);
|
|
13140
|
-
this.#files = fromEntries(files3);
|
|
13141
|
-
}
|
|
13142
|
-
#string(value2) {
|
|
13143
|
-
return typeof value2 === "string" && value2 !== "" ? value2 : void 0;
|
|
13144
|
-
}
|
|
13145
|
-
method() {
|
|
13146
|
-
return this.#method;
|
|
13147
|
-
}
|
|
13148
|
-
isMethod(method) {
|
|
13149
|
-
return this.#method === method.toUpperCase();
|
|
13150
|
-
}
|
|
13151
|
-
/** The scheme and host, honouring X-Forwarded-Proto/Host from trusted proxies. */
|
|
13152
|
-
root() {
|
|
13153
|
-
const trusted = this.#fromTrustedProxy();
|
|
13154
|
-
const proto = trusted ? this.raw.headers.get("x-forwarded-proto")?.split(",")[0]?.trim() : void 0;
|
|
13155
|
-
const host = trusted ? this.raw.headers.get("x-forwarded-host")?.split(",")[0]?.trim() : void 0;
|
|
13156
|
-
const scheme = proto === "https" || proto === "http" ? proto : this.#url.protocol.slice(0, -1);
|
|
13157
|
-
return `${scheme}://${host !== void 0 && host !== "" ? host : this.#url.host}`;
|
|
13158
|
-
}
|
|
13159
|
-
/** The URL without the query string or a trailing slash. */
|
|
13160
|
-
url() {
|
|
13161
|
-
return `${this.root()}${this.#url.pathname}`.replace(/\/+$/, "");
|
|
13162
|
-
}
|
|
13163
|
-
fullUrl() {
|
|
13164
|
-
return this.#url.search === "" ? this.url() : `${this.url()}${this.#url.search}`;
|
|
13165
|
-
}
|
|
13166
|
-
/** 'posts/1', or '/' for the root. */
|
|
13167
|
-
path() {
|
|
13168
|
-
const trimmed = this.#url.pathname.replace(/^\/+|\/+$/g, "");
|
|
13169
|
-
return trimmed === "" ? "/" : trimmed;
|
|
13170
|
-
}
|
|
13171
|
-
decodedPath() {
|
|
13172
|
-
try {
|
|
13173
|
-
return decodeURIComponent(this.path());
|
|
13174
|
-
} catch {
|
|
13175
|
-
return this.path();
|
|
13176
|
-
}
|
|
13177
|
-
}
|
|
13178
|
-
secure() {
|
|
13179
|
-
return this.root().startsWith("https:");
|
|
13180
|
-
}
|
|
13181
|
-
/** request.is('admin/*'): wildcard match against the decoded path. */
|
|
13182
|
-
is(...patterns) {
|
|
13183
|
-
const path = this.decodedPath();
|
|
13184
|
-
return patterns.some((pattern) => {
|
|
13185
|
-
const trimmed = pattern.replace(/^\/+|\/+$/g, "");
|
|
13186
|
-
return Str.is(trimmed === "" ? "/" : trimmed, path);
|
|
13187
|
-
});
|
|
13188
|
-
}
|
|
13189
|
-
routeIs(...names) {
|
|
13190
|
-
const name = this.#currentRoute()?.route.getName();
|
|
13191
|
-
return name !== void 0 && names.some((pattern) => Str.is(pattern, name));
|
|
13192
|
-
}
|
|
13193
|
-
header(name, defaultValue) {
|
|
13194
|
-
return this.raw.headers.get(name) ?? defaultValue;
|
|
13195
|
-
}
|
|
13196
|
-
bearerToken() {
|
|
13197
|
-
const header = this.header("authorization", "");
|
|
13198
|
-
const position = header.toLowerCase().lastIndexOf("bearer ");
|
|
13199
|
-
if (position === -1) return void 0;
|
|
13200
|
-
const token2 = header.slice(position + 7).split(",")[0].trim();
|
|
13201
|
-
return token2 === "" ? void 0 : token2;
|
|
13202
|
-
}
|
|
13203
|
-
userAgent() {
|
|
13204
|
-
return this.header("user-agent");
|
|
13205
|
-
}
|
|
13206
|
-
/** The socket address, or the right-most untrusted X-Forwarded-For entry when the socket is a trusted proxy. */
|
|
13207
|
-
ip() {
|
|
13208
|
-
const socket = clientAddress(this.raw);
|
|
13209
|
-
if (socket === void 0) return void 0;
|
|
13210
|
-
const address = normalizeIp(socket);
|
|
13211
|
-
if (!this.#fromTrustedProxy()) return address;
|
|
13212
|
-
const chain = (this.raw.headers.get("x-forwarded-for") ?? "").split(",").map((entry) => normalizeIp(entry)).filter((entry) => entry !== "");
|
|
13213
|
-
for (let i = chain.length - 1; i >= 0; i--) if (!ipMatches(chain[i], this.#trustedProxies)) return chain[i];
|
|
13214
|
-
return chain[0] ?? address;
|
|
13215
|
-
}
|
|
13216
|
-
#fromTrustedProxy() {
|
|
13217
|
-
const socket = clientAddress(this.raw);
|
|
13218
|
-
return socket !== void 0 && this.#trustedProxies.length > 0 && ipMatches(socket, this.#trustedProxies);
|
|
13219
|
-
}
|
|
13220
|
-
ajax() {
|
|
13221
|
-
return this.header("x-requested-with") === "XMLHttpRequest";
|
|
13222
|
-
}
|
|
13223
|
-
pjax() {
|
|
13224
|
-
return this.header("x-pjax") === "true";
|
|
13225
|
-
}
|
|
13226
|
-
/** The first Accept type is JSON. */
|
|
13227
|
-
wantsJson() {
|
|
13228
|
-
const first = this.header("accept", "").split(",")[0].trim();
|
|
13229
|
-
return first.includes("/json") || first.includes("+json");
|
|
13230
|
-
}
|
|
13231
|
-
/** Laravel: (ajax and not pjax and accepts anything) or wantsJson. */
|
|
13232
|
-
expectsJson() {
|
|
13233
|
-
const first = this.header("accept", "").split(",")[0].split(";")[0].trim();
|
|
13234
|
-
const acceptsAny = first === "" || first === "*/*" || first === "*";
|
|
13235
|
-
return this.ajax() && !this.pjax() && acceptsAny || this.wantsJson();
|
|
13236
|
-
}
|
|
13237
|
-
/** The raw body text for JSON and urlencoded requests ('' otherwise; the raw stream stays unread for other types). */
|
|
13238
|
-
content() {
|
|
13239
|
-
return this.#content;
|
|
13240
|
-
}
|
|
13241
|
-
query(key, defaultValue) {
|
|
13242
|
-
return Arr.get(this.#query, key, defaultValue);
|
|
13243
|
-
}
|
|
13244
|
-
/** Body wins over the query string (PHP's $body + $query). Files are not input. */
|
|
13245
|
-
input(key, defaultValue) {
|
|
13246
|
-
return Arr.get({ ...this.#query, ...this.#body }, key, defaultValue);
|
|
13247
|
-
}
|
|
13248
|
-
/** Input plus files (array_replace_recursive). */
|
|
13249
|
-
all() {
|
|
13250
|
-
return mergeRecursive({ ...this.#query, ...this.#body }, this.#files);
|
|
13251
|
-
}
|
|
13252
|
-
only(...keys) {
|
|
13253
|
-
const all = this.all();
|
|
13254
|
-
const out = {};
|
|
13255
|
-
for (const key of keys.flat()) if (Arr.has(all, key)) Arr.set(out, key, Arr.get(all, key));
|
|
13256
|
-
return out;
|
|
13257
|
-
}
|
|
13258
|
-
except(...keys) {
|
|
13259
|
-
const all = structuredCloneInput(this.all());
|
|
13260
|
-
for (const key of keys.flat()) Arr.forget(all, key);
|
|
13261
|
-
return all;
|
|
13262
|
-
}
|
|
13263
|
-
has(...keys) {
|
|
13264
|
-
const all = this.all();
|
|
13265
|
-
return keys.flat().every((key) => Arr.has(all, key));
|
|
13266
|
-
}
|
|
13267
|
-
hasAny(...keys) {
|
|
13268
|
-
const all = this.all();
|
|
13269
|
-
return keys.flat().some((key) => Arr.has(all, key));
|
|
13270
|
-
}
|
|
13271
|
-
missing(...keys) {
|
|
13272
|
-
return !this.has(...keys);
|
|
13273
|
-
}
|
|
13274
|
-
filled(key) {
|
|
13275
|
-
return !isBlank(Arr.get(this.all(), key));
|
|
13276
|
-
}
|
|
13277
|
-
string(key, defaultValue = "") {
|
|
13278
|
-
const value2 = this.input(key);
|
|
13279
|
-
return value2 === void 0 || value2 === null ? defaultValue : String(value2);
|
|
13280
|
-
}
|
|
13281
|
-
/** PHP's FILTER_VALIDATE_BOOLEAN: '1', 'true', 'on', 'yes' (any case) and true are true. */
|
|
13282
|
-
boolean(key, defaultValue = false) {
|
|
13283
|
-
const value2 = this.input(key);
|
|
13284
|
-
if (value2 === void 0) return defaultValue;
|
|
13285
|
-
if (typeof value2 === "boolean") return value2;
|
|
13286
|
-
if (typeof value2 === "number") return value2 === 1;
|
|
13287
|
-
return typeof value2 === "string" && TRUE_VALUES.has(value2.trim().toLowerCase());
|
|
13288
|
-
}
|
|
13289
|
-
/** PHP's intval: leading digits, else 0. */
|
|
13290
|
-
integer(key, defaultValue = 0) {
|
|
13291
|
-
const value2 = this.input(key);
|
|
13292
|
-
if (value2 === void 0) return defaultValue;
|
|
13293
|
-
if (typeof value2 === "number") return Number.isFinite(value2) ? Math.trunc(value2) : 0;
|
|
13294
|
-
if (typeof value2 === "boolean") return value2 ? 1 : 0;
|
|
13295
|
-
const parsed = Number.parseInt(String(value2).trim(), 10);
|
|
13296
|
-
return Number.isNaN(parsed) ? 0 : parsed;
|
|
13297
|
-
}
|
|
13298
|
-
/** Adds or replaces top-level body values. */
|
|
13299
|
-
merge(values) {
|
|
13300
|
-
this.#body = { ...this.#body, ...sanitize(values) };
|
|
13301
|
-
return this;
|
|
13302
|
-
}
|
|
13303
|
-
/** Rewrites every scalar in the query and the body (TrimStrings and ConvertEmptyStringsToNull use this). */
|
|
13304
|
-
transformInput(transform) {
|
|
13305
|
-
this.#query = transformLeaves(this.#query, transform);
|
|
13306
|
-
this.#body = transformLeaves(this.#body, transform);
|
|
13307
|
-
return this;
|
|
13308
|
-
}
|
|
13309
|
-
file(key) {
|
|
13310
|
-
const value2 = Arr.get(this.#files, key);
|
|
13311
|
-
return value2 instanceof FormUploadedFile ? value2 : void 0;
|
|
13312
|
-
}
|
|
13313
|
-
hasFile(key) {
|
|
13314
|
-
const value2 = Arr.get(this.#files, key);
|
|
13315
|
-
return value2 instanceof FormUploadedFile || Array.isArray(value2) && value2.some((item) => item instanceof FormUploadedFile);
|
|
13316
|
-
}
|
|
13317
|
-
allFiles() {
|
|
13318
|
-
return { ...this.#files };
|
|
13319
|
-
}
|
|
13320
|
-
cookie(name) {
|
|
13321
|
-
return this.cookies()[name];
|
|
13322
|
-
}
|
|
13323
|
-
cookies() {
|
|
13324
|
-
if (this.#cookies === void 0) {
|
|
13325
|
-
const cookies = {};
|
|
13326
|
-
for (const part of (this.raw.headers.get("cookie") ?? "").split(";")) {
|
|
13327
|
-
const index = part.indexOf("=");
|
|
13328
|
-
if (index === -1) continue;
|
|
13329
|
-
const name = part.slice(0, index).trim();
|
|
13330
|
-
if (name === "" || Object.hasOwn(cookies, name)) continue;
|
|
13331
|
-
let value2 = part.slice(index + 1).trim();
|
|
13332
|
-
if (value2.startsWith('"') && value2.endsWith('"')) value2 = value2.slice(1, -1);
|
|
13333
|
-
try {
|
|
13334
|
-
cookies[name] = decodeURIComponent(value2);
|
|
13335
|
-
} catch {
|
|
13336
|
-
cookies[name] = value2;
|
|
13337
|
-
}
|
|
13338
|
-
}
|
|
13339
|
-
this.#cookies = cookies;
|
|
13340
|
-
}
|
|
13341
|
-
return { ...this.#cookies };
|
|
13342
|
-
}
|
|
13343
|
-
/** Replaces the parsed cookies (EncryptCookies calls this after decrypting). */
|
|
13344
|
-
setCookies(cookies) {
|
|
13345
|
-
this.#cookies = { ...cookies };
|
|
13346
|
-
}
|
|
13347
|
-
/** One route parameter (after model binding), or all of them. */
|
|
13348
|
-
route(key) {
|
|
13349
|
-
const parameters = this.#currentRoute()?.parameters ?? {};
|
|
13350
|
-
return key === void 0 ? { ...parameters } : parameters[key];
|
|
13351
|
-
}
|
|
13352
|
-
session() {
|
|
13353
|
-
return inject(Session);
|
|
13354
|
-
}
|
|
13355
|
-
user(guard2) {
|
|
13356
|
-
return this.#userResolver?.(guard2);
|
|
13357
|
-
}
|
|
13358
|
-
setUserResolver(resolver) {
|
|
13359
|
-
this.#userResolver = resolver;
|
|
13360
|
-
}
|
|
13361
|
-
/** Validates all() through the ValidationFactory; throws its Validation error on failure. */
|
|
13362
|
-
validate(rules, messages, attributes) {
|
|
13363
|
-
return inject(ValidationFactory).make(this.all(), rules, messages, attributes).validated();
|
|
13364
|
-
}
|
|
13365
|
-
#currentRoute() {
|
|
13366
|
-
const container = currentContainer();
|
|
13367
|
-
return container?.bound(CurrentRoute) ? container.make(CurrentRoute) : void 0;
|
|
13368
|
-
}
|
|
13369
|
-
};
|
|
13370
|
-
function structuredCloneInput(tree) {
|
|
13371
|
-
const out = {};
|
|
13372
|
-
for (const [key, value2] of Object.entries(tree)) {
|
|
13373
|
-
out[key] = isPlainObject2(value2) ? structuredCloneInput(value2) : Array.isArray(value2) ? [...value2] : value2;
|
|
13374
|
-
}
|
|
13375
|
-
return out;
|
|
13376
|
-
}
|
|
13377
|
-
function request(key, defaultValue) {
|
|
13378
|
-
const current = inject(HttpRequest);
|
|
13379
|
-
return key === void 0 ? current : current.input(key, defaultValue);
|
|
13380
|
-
}
|
|
13381
|
-
function response(content, status, headers) {
|
|
13382
|
-
const factory = inject(ResponseFactory);
|
|
13383
|
-
return content === void 0 ? factory : factory.make(content, status, headers);
|
|
13384
|
-
}
|
|
13385
|
-
function redirect(to, status) {
|
|
13386
|
-
const redirector = inject(Redirector);
|
|
13387
|
-
return to === void 0 ? redirector : redirector.to(to, status);
|
|
13388
|
-
}
|
|
13389
|
-
function back(fallback, status) {
|
|
13390
|
-
return inject(Redirector).back(fallback, status);
|
|
13391
|
-
}
|
|
13392
|
-
function url(path, query, absolute) {
|
|
13393
|
-
const generator = inject(UrlGenerator);
|
|
13394
|
-
return path === void 0 ? generator : generator.to(path, query, absolute);
|
|
13395
|
-
}
|
|
13396
|
-
function route(name, parameters, absolute) {
|
|
13397
|
-
return inject(UrlGenerator).route(name, parameters, absolute);
|
|
13398
|
-
}
|
|
13399
|
-
function abort(status, message = "", headers = {}) {
|
|
13400
|
-
if (status instanceof Response) throw new HttpResponseException(status);
|
|
13401
|
-
throw new HttpException(status, message, headers);
|
|
13402
|
-
}
|
|
13403
|
-
function abortIf(condition, status, message = "", headers = {}) {
|
|
13404
|
-
if (condition) abort(status, message, headers);
|
|
13405
|
-
}
|
|
13406
|
-
function abortUnless(condition, status, message = "", headers = {}) {
|
|
13407
|
-
if (!condition) abort(status, message, headers);
|
|
13408
|
-
}
|
|
13409
|
-
function contentDisposition(type, name) {
|
|
13410
|
-
const fallback = name.replace(/[^\x20-\x7e]/g, "_").replace(/["\\]/g, "\\$&");
|
|
13411
|
-
const header = `${type}; filename="${fallback}"`;
|
|
13412
|
-
return /^[\x20-\x7e]*$/.test(name) ? header : `${header}; filename*=UTF-8''${encodeURIComponent(name)}`;
|
|
13413
|
-
}
|
|
13414
|
-
var HttpResponseFactory = class {
|
|
13415
|
-
/** Strings default to text/html; charset=utf-8, as in Laravel. */
|
|
13416
|
-
make(content = null, status = 200, headers) {
|
|
13417
|
-
const merged = new Headers(headers);
|
|
13418
|
-
if (typeof content === "string" && !merged.has("content-type")) merged.set("content-type", "text/html; charset=utf-8");
|
|
13419
|
-
return new Response(content, { status, headers: merged });
|
|
13420
|
-
}
|
|
13421
|
-
json(data, status = 200, headers) {
|
|
13422
|
-
const merged = new Headers(headers);
|
|
13423
|
-
if (!merged.has("content-type")) merged.set("content-type", "application/json");
|
|
13424
|
-
return new Response(JSON.stringify(data === void 0 ? null : data), { status, headers: merged });
|
|
13425
|
-
}
|
|
13426
|
-
noContent(status = 204) {
|
|
13427
|
-
return new Response(null, { status });
|
|
13428
|
-
}
|
|
13429
|
-
/** Renders a view (through the ViewFactory) into an HTML response. */
|
|
13430
|
-
async view(name, data = {}, status = 200, headers) {
|
|
13431
|
-
const html2 = await inject(ViewFactory).make(name, data).render();
|
|
13432
|
-
return this.make(html2, status, headers);
|
|
13433
|
-
}
|
|
13434
|
-
/** Streams a file as an attachment. A missing file is a 404. */
|
|
13435
|
-
download(path, name = basename2(path), headers) {
|
|
13436
|
-
return this.#file(path, "attachment", name, headers);
|
|
13437
|
-
}
|
|
13438
|
-
/** Streams a file for the browser to display (Laravel's response()->file()). */
|
|
13439
|
-
file(path, headers) {
|
|
13440
|
-
return this.#file(path, "inline", basename2(path), headers);
|
|
13441
|
-
}
|
|
13442
|
-
stream(body, status = 200, headers) {
|
|
13443
|
-
return new Response(body, { status, headers });
|
|
13444
|
-
}
|
|
13445
|
-
async #file(path, disposition, name, headers) {
|
|
13446
|
-
const info = await stat3(path).catch(() => void 0);
|
|
13447
|
-
if (info === void 0 || !info.isFile()) throw new HttpException(404);
|
|
13448
|
-
const merged = new Headers(headers);
|
|
13449
|
-
if (!merged.has("content-type")) merged.set("content-type", mimeFromExtension2(name));
|
|
13450
|
-
merged.set("content-length", String(info.size));
|
|
13451
|
-
merged.set("content-disposition", contentDisposition(disposition, name));
|
|
13452
|
-
const body = Readable2.toWeb(createReadStream2(path));
|
|
13453
|
-
return new Response(body, { status: 200, headers: merged });
|
|
13454
|
-
}
|
|
13455
|
-
};
|
|
13456
|
-
var ConvertEmptyStringsToNull = class {
|
|
13457
|
-
async handle(request2, next) {
|
|
13458
|
-
if (request2 instanceof IncomingRequest) request2.transformInput((_key, value2) => value2 === "" ? null : value2);
|
|
13459
|
-
return next(request2);
|
|
13460
|
-
}
|
|
13461
|
-
};
|
|
13462
|
-
var TRIM = /^[\s\uFEFF\u200B\u200E]+|[\s\uFEFF\u200B\u200E]+$/g;
|
|
13463
|
-
var TrimStrings = class {
|
|
13464
|
-
/** Dotted input keys left untouched. Override in a subclass to change. */
|
|
13465
|
-
except = ["current_password", "password", "password_confirmation"];
|
|
13466
|
-
async handle(request2, next) {
|
|
13467
|
-
if (request2 instanceof IncomingRequest) {
|
|
13468
|
-
request2.transformInput(
|
|
13469
|
-
(key, value2) => typeof value2 === "string" && !this.except.includes(key) ? value2.replace(TRIM, "") : value2
|
|
13470
|
-
);
|
|
13471
|
-
}
|
|
13472
|
-
return next(request2);
|
|
13473
|
-
}
|
|
13474
|
-
};
|
|
13475
|
-
var plainServerError = () => new Response("Server Error", { status: 500, headers: { "content-type": "text/plain; charset=utf-8" } });
|
|
13476
|
-
var Kernel2 = class {
|
|
13477
|
-
constructor(app2) {
|
|
13478
|
-
this.app = app2;
|
|
13479
|
-
}
|
|
13480
|
-
app;
|
|
13481
|
-
#middleware = [TrimStrings, ConvertEmptyStringsToNull];
|
|
13482
|
-
#requests = /* @__PURE__ */ new WeakMap();
|
|
13483
|
-
getGlobalMiddleware() {
|
|
13484
|
-
return [...this.#middleware];
|
|
13485
|
-
}
|
|
13486
|
-
setGlobalMiddleware(middleware) {
|
|
13487
|
-
this.#middleware = [...middleware];
|
|
13488
|
-
return this;
|
|
13489
|
-
}
|
|
13490
|
-
appendMiddleware(...middleware) {
|
|
13491
|
-
for (const cls of middleware) if (!this.#middleware.includes(cls)) this.#middleware.push(cls);
|
|
13492
|
-
return this;
|
|
13493
|
-
}
|
|
13494
|
-
prependMiddleware(...middleware) {
|
|
13495
|
-
for (const cls of [...middleware].reverse()) if (!this.#middleware.includes(cls)) this.#middleware.unshift(cls);
|
|
13496
|
-
return this;
|
|
13497
|
-
}
|
|
13498
|
-
hasMiddleware(middleware) {
|
|
13499
|
-
return this.#middleware.includes(middleware);
|
|
13500
|
-
}
|
|
13501
|
-
/** Runs in the current request scope (Application.handle() opens one); called directly, it opens its own. */
|
|
13502
|
-
handle(raw3) {
|
|
13503
|
-
const current = currentContainer();
|
|
13504
|
-
const scope = current !== void 0 && current !== this.app ? current : this.app.createScope();
|
|
13505
|
-
return scope.run(() => this.#handle(raw3, scope));
|
|
13506
|
-
}
|
|
13507
|
-
async #handle(raw3, scope) {
|
|
13508
|
-
let request2;
|
|
13509
|
-
let response2;
|
|
13510
|
-
try {
|
|
13511
|
-
request2 = new IncomingRequest(raw3, { trustedProxies: this.#trustedProxies(), maxBodySize: this.#maxBodySize() });
|
|
13512
|
-
scope.instance(HttpRequest, request2);
|
|
13513
|
-
const state = { scope, request: request2, middleware: [] };
|
|
13514
|
-
this.#requests.set(raw3, state);
|
|
13515
|
-
await request2.load();
|
|
13516
|
-
response2 = await this.#sendThroughGlobal(state);
|
|
13517
|
-
} catch (error) {
|
|
13518
|
-
request2 ??= this.#bareRequest(scope, raw3);
|
|
13519
|
-
if (request2 !== void 0) {
|
|
13520
|
-
response2 = await this.#renderLast(scope, request2, error);
|
|
13521
|
-
} else {
|
|
13522
|
-
await this.#report(scope, error);
|
|
13523
|
-
response2 = plainServerError();
|
|
13524
|
-
}
|
|
13525
|
-
}
|
|
13526
|
-
if (raw3.method.toUpperCase() === "HEAD" && response2.body !== null) {
|
|
13527
|
-
await response2.body.cancel().catch(() => void 0);
|
|
13528
|
-
response2 = new Response(null, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
|
|
13529
|
-
}
|
|
13530
|
-
return response2;
|
|
13531
|
-
}
|
|
13532
|
-
/** The request without options, for rendering an error raised while the real one was being built. */
|
|
13533
|
-
#bareRequest(scope, raw3) {
|
|
13534
|
-
try {
|
|
13535
|
-
const request2 = new IncomingRequest(raw3);
|
|
13536
|
-
scope.instance(HttpRequest, request2);
|
|
13537
|
-
return request2;
|
|
13538
|
-
} catch {
|
|
13539
|
-
return void 0;
|
|
13540
|
-
}
|
|
13541
|
-
}
|
|
13542
|
-
/** Runs terminate() on the global and route middleware (inside the request's scope), then Application.terminate(), inside the same scope, so terminating callbacks see the request's bindings. */
|
|
13543
|
-
async terminate(raw3, response2) {
|
|
13544
|
-
const state = this.#requests.get(raw3);
|
|
13545
|
-
if (state !== void 0) {
|
|
13546
|
-
this.#requests.delete(raw3);
|
|
13547
|
-
await state.scope.run(async () => {
|
|
13548
|
-
const route2 = state.scope.bound(CurrentRoute) ? state.scope.make(CurrentRoute).middleware : [];
|
|
13549
|
-
for (const middleware of [...state.middleware, ...route2]) {
|
|
13550
|
-
if (typeof middleware.terminate !== "function") continue;
|
|
13551
|
-
try {
|
|
13552
|
-
await middleware.terminate(state.request, response2);
|
|
13553
|
-
} catch (error) {
|
|
13554
|
-
await this.#report(state.scope, error);
|
|
13555
|
-
}
|
|
13556
|
-
}
|
|
13557
|
-
await this.app.terminate();
|
|
13558
|
-
});
|
|
13559
|
-
return;
|
|
13560
|
-
}
|
|
13561
|
-
await this.app.terminate();
|
|
13562
|
-
}
|
|
13563
|
-
#sendThroughGlobal(state) {
|
|
13564
|
-
const { scope, request: request2 } = state;
|
|
13565
|
-
const pipes = this.#middleware.map((cls) => {
|
|
13566
|
-
const instance = scope.make(cls);
|
|
13567
|
-
state.middleware.push(instance);
|
|
13568
|
-
return (passable, next) => this.#guard(scope, passable, () => instance.handle(passable, next));
|
|
13569
|
-
});
|
|
13570
|
-
return scope.make(PipelineFactory).make().send(request2).through(pipes).then((passable) => this.#guard(scope, passable, () => this.#dispatch(scope, passable)));
|
|
13571
|
-
}
|
|
13572
|
-
#dispatch(scope, request2) {
|
|
13573
|
-
return scope.make(Router).dispatch(request2);
|
|
13574
|
-
}
|
|
13575
|
-
/** Converts a Responsable result, and renders a thrown error at this stage (Laravel's Routing\Pipeline). */
|
|
13576
|
-
async #guard(scope, request2, run) {
|
|
13577
|
-
try {
|
|
13578
|
-
const result = await run();
|
|
13579
|
-
if (result instanceof Response) return result;
|
|
13580
|
-
const responsable = result;
|
|
13581
|
-
if (typeof responsable?.toResponse === "function") return await responsable.toResponse(request2);
|
|
13582
|
-
throw new HttpServerError("Middleware must return a Response.");
|
|
13583
|
-
} catch (error) {
|
|
13584
|
-
if (!scope.bound(ExceptionHandler)) throw error;
|
|
13585
|
-
const handler3 = scope.make(ExceptionHandler);
|
|
13586
|
-
await handler3.report(error);
|
|
13587
|
-
return handler3.render(request2, error);
|
|
13588
|
-
}
|
|
13589
|
-
}
|
|
13590
|
-
/** Last resort: the handler failed or isn't bound. Never throws. */
|
|
13591
|
-
async #renderLast(scope, request2, error) {
|
|
13592
|
-
if (scope.bound(ExceptionHandler)) {
|
|
13593
|
-
try {
|
|
13594
|
-
const handler3 = scope.make(ExceptionHandler);
|
|
13595
|
-
await handler3.report(error);
|
|
13596
|
-
return await handler3.render(request2, error);
|
|
13597
|
-
} catch (renderError2) {
|
|
13598
|
-
console.error(renderError2);
|
|
13599
|
-
}
|
|
13600
|
-
} else {
|
|
13601
|
-
console.error(error);
|
|
13602
|
-
}
|
|
13603
|
-
return plainServerError();
|
|
13604
|
-
}
|
|
13605
|
-
async #report(scope, error) {
|
|
13606
|
-
try {
|
|
13607
|
-
if (scope.bound(ExceptionHandler)) await scope.make(ExceptionHandler).report(error);
|
|
13608
|
-
else console.error(error);
|
|
13609
|
-
} catch (reportError) {
|
|
13610
|
-
console.error(reportError);
|
|
13611
|
-
}
|
|
13612
|
-
}
|
|
13613
|
-
/** config('http.max_body_size'): bytes, or null for no limit. Anything else is a configuration error. */
|
|
13614
|
-
#maxBodySize() {
|
|
13615
|
-
if (!this.app.bound(ConfigRepository)) return 8 * 1024 * 1024;
|
|
13616
|
-
const value2 = this.app.make(ConfigRepository).get("http.max_body_size", 8 * 1024 * 1024);
|
|
13617
|
-
if (value2 === null) return null;
|
|
13618
|
-
if (typeof value2 === "number" && Number.isFinite(value2) && value2 >= 0) return value2;
|
|
13619
|
-
throw new HttpServerError(
|
|
13620
|
-
`Invalid http.max_body_size ${JSON.stringify(value2) ?? String(value2)}: use a number of bytes (0 or more), or null for no limit.`
|
|
13621
|
-
);
|
|
13622
|
-
}
|
|
13623
|
-
/** config('http.trusted_proxies'): an array, or a comma-separated string such as '*' or '10.0.0.0/8,::1'. */
|
|
13624
|
-
#trustedProxies() {
|
|
13625
|
-
if (!this.app.bound(ConfigRepository)) return [];
|
|
13626
|
-
const value2 = this.app.make(ConfigRepository).get("http.trusted_proxies", []);
|
|
13627
|
-
if (typeof value2 === "string") return value2.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "");
|
|
13628
|
-
return Array.isArray(value2) ? value2.map(String) : [];
|
|
13629
|
-
}
|
|
13630
|
-
};
|
|
13631
|
-
var MiddlewareConfiguration = class {
|
|
13632
|
-
constructor(kernel, router, config2) {
|
|
13633
|
-
this.kernel = kernel;
|
|
13634
|
-
this.router = router;
|
|
13635
|
-
this.config = config2;
|
|
13636
|
-
}
|
|
13637
|
-
kernel;
|
|
13638
|
-
router;
|
|
13639
|
-
config;
|
|
13640
|
-
append(...middleware) {
|
|
13641
|
-
this.kernel.appendMiddleware(...middleware);
|
|
13642
|
-
return this;
|
|
13643
|
-
}
|
|
13644
|
-
prepend(...middleware) {
|
|
13645
|
-
this.kernel.prependMiddleware(...middleware);
|
|
13646
|
-
return this;
|
|
13647
|
-
}
|
|
13648
|
-
web(options) {
|
|
13649
|
-
return this.#modifyGroup("web", options);
|
|
13650
|
-
}
|
|
13651
|
-
api(options) {
|
|
13652
|
-
return this.#modifyGroup("api", options);
|
|
13653
|
-
}
|
|
13654
|
-
alias(aliases2) {
|
|
13655
|
-
for (const [name, middleware] of Object.entries(aliases2)) this.router.aliasMiddleware(name, middleware);
|
|
13656
|
-
return this;
|
|
13657
|
-
}
|
|
13658
|
-
group(name, middleware) {
|
|
13659
|
-
this.router.middlewareGroup(name, middleware);
|
|
13660
|
-
return this;
|
|
13661
|
-
}
|
|
13662
|
-
/** Stored in config('http.csrf_except'), which the Session component's VerifyCsrfToken reads. */
|
|
13663
|
-
validateCsrfTokens(options) {
|
|
13664
|
-
const current = this.config?.get("http.csrf_except", []) ?? [];
|
|
13665
|
-
this.config?.set("http.csrf_except", [...current, ...options.except]);
|
|
13666
|
-
return this;
|
|
13667
|
-
}
|
|
13668
|
-
/** Stored in config('http.redirect_guests_to'), which the Auth middleware and the exception handler read. */
|
|
13669
|
-
redirectGuestsTo(url2) {
|
|
13670
|
-
this.config?.set("http.redirect_guests_to", url2);
|
|
13671
|
-
return this;
|
|
13672
|
-
}
|
|
13673
|
-
/** Laravel 11's redirectUsersTo(): stored in config('http.redirect_users_to') for Auth's RedirectIfAuthenticated. */
|
|
13674
|
-
redirectUsersTo(url2) {
|
|
13675
|
-
this.config?.set("http.redirect_users_to", url2);
|
|
13676
|
-
return this;
|
|
13677
|
-
}
|
|
13678
|
-
/** Laravel's order: prepends, then the group minus removals, then appends. */
|
|
13679
|
-
#modifyGroup(name, { append = [], prepend = [], remove = [] }) {
|
|
13680
|
-
const current = this.router.getMiddlewareGroups()[name] ?? [];
|
|
13681
|
-
const moved = /* @__PURE__ */ new Set([...append, ...prepend, ...remove]);
|
|
13682
|
-
this.router.middlewareGroup(name, [...prepend, ...current.filter((entry) => !moved.has(entry)), ...append]);
|
|
13683
|
-
return this;
|
|
13684
|
-
}
|
|
13685
|
-
};
|
|
13686
|
-
function applyMiddlewareCallbacks(app2, kernel) {
|
|
13687
|
-
if (!app2.bound(MiddlewareCallbacks)) return;
|
|
13688
|
-
const callbacks = app2.make(MiddlewareCallbacks);
|
|
13689
|
-
if (callbacks.length === 0) return;
|
|
13690
|
-
const config2 = app2.bound(ConfigRepository) ? app2.make(ConfigRepository) : void 0;
|
|
13691
|
-
const configurator = new MiddlewareConfiguration(kernel, app2.make(Router), config2);
|
|
13692
|
-
for (const callback of callbacks) callback(configurator);
|
|
13693
|
-
}
|
|
13694
|
-
var STATUS_TEXTS = {
|
|
13695
|
-
400: "Bad Request",
|
|
13696
|
-
401: "Unauthorized",
|
|
13697
|
-
402: "Payment Required",
|
|
13698
|
-
403: "Forbidden",
|
|
13699
|
-
404: "Not Found",
|
|
13700
|
-
405: "Method Not Allowed",
|
|
13701
|
-
408: "Request Timeout",
|
|
13702
|
-
409: "Conflict",
|
|
13703
|
-
410: "Gone",
|
|
13704
|
-
413: "Content Too Large",
|
|
13705
|
-
415: "Unsupported Media Type",
|
|
13706
|
-
419: "Page Expired",
|
|
13707
|
-
422: "Unprocessable Content",
|
|
13708
|
-
429: "Too Many Requests",
|
|
13709
|
-
500: "Server Error",
|
|
13710
|
-
502: "Bad Gateway",
|
|
13711
|
-
503: "Service Unavailable",
|
|
13712
|
-
504: "Gateway Timeout"
|
|
13713
|
-
};
|
|
13714
|
-
function statusText(status) {
|
|
13715
|
-
return STATUS_TEXTS[status] ?? (status >= 500 ? "Server Error" : "Error");
|
|
13716
|
-
}
|
|
13717
|
-
function escapeHtml(value2) {
|
|
13718
|
-
return value2.replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
|
|
13719
|
-
}
|
|
13720
|
-
function minimalPage(status, message) {
|
|
13721
|
-
const title = escapeHtml(message);
|
|
13722
|
-
return `<!DOCTYPE html>
|
|
13723
|
-
<html lang="en">
|
|
13724
|
-
<head>
|
|
13725
|
-
<meta charset="utf-8">
|
|
13726
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
13727
|
-
<title>${title}</title>
|
|
13728
|
-
<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f7fafc;color:#1a202c;display:flex;align-items:center;justify-content:center;min-height:100vh}.code{padding:0 1rem;border-right:1px solid #a0aec0;font-size:1.125rem}.message{padding:0 1rem;font-size:1.125rem;text-transform:uppercase;letter-spacing:.05em}</style>
|
|
13729
|
-
</head>
|
|
13730
|
-
<body><div class="code">${status}</div><div class="message">${title}</div></body>
|
|
13731
|
-
</html>`;
|
|
13732
|
-
}
|
|
13733
|
-
function stackFrames(error) {
|
|
13734
|
-
const frames = [];
|
|
13735
|
-
for (const raw3 of (error.stack ?? "").split("\n").slice(1)) {
|
|
13736
|
-
const text3 = raw3.trim();
|
|
13737
|
-
const match = /(?:\(|@|at )((?:file:\/\/)?(?:\/|[A-Za-z]:\\)[^()]*?):(\d+):(\d+)\)?$/.exec(text3);
|
|
13738
|
-
if (match === null) continue;
|
|
13739
|
-
const location = match[1];
|
|
13740
|
-
const file = location.startsWith("file://") ? fileURLToPath(location) : location;
|
|
13741
|
-
frames.push({ file, line: Number(match[2]), column: Number(match[3]), text: text3 });
|
|
13742
|
-
}
|
|
13743
|
-
return frames;
|
|
13744
|
-
}
|
|
13745
|
-
async function excerpt(frame, radius = 5) {
|
|
13746
|
-
const source = await readFile4(frame.file, "utf8").catch(() => void 0);
|
|
13747
|
-
if (source === void 0) return void 0;
|
|
13748
|
-
const lines = source.split("\n");
|
|
13749
|
-
const start2 = Math.max(1, frame.line - radius);
|
|
13750
|
-
const end = Math.min(lines.length, frame.line + radius);
|
|
13751
|
-
const rows = [];
|
|
13752
|
-
for (let number3 = start2; number3 <= end; number3++) {
|
|
13753
|
-
const current = number3 === frame.line ? ' class="current"' : "";
|
|
13754
|
-
rows.push(`<tr${current}><td class="n">${number3}</td><td><code>${escapeHtml(lines[number3 - 1] ?? "")}</code></td></tr>`);
|
|
13755
|
-
}
|
|
13756
|
-
return `<table class="source">${rows.join("")}</table>`;
|
|
13757
|
-
}
|
|
13758
|
-
async function debugPage(error, method, url2) {
|
|
13759
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
13760
|
-
const frames = stackFrames(err);
|
|
13761
|
-
const appFrame = frames.find((frame) => !frame.file.includes("node_modules") && !frame.file.startsWith("node:")) ?? frames[0];
|
|
13762
|
-
const source = appFrame === void 0 ? void 0 : await excerpt(appFrame);
|
|
13763
|
-
const causes = [];
|
|
13764
|
-
for (let cause = err.cause, depth = 0; cause !== void 0 && depth < 5; cause = cause.cause, depth++) {
|
|
13765
|
-
causes.push(`<li>${escapeHtml(cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause))}</li>`);
|
|
13766
|
-
}
|
|
13767
|
-
return `<!DOCTYPE html>
|
|
13768
|
-
<html lang="en">
|
|
13769
|
-
<head>
|
|
13770
|
-
<meta charset="utf-8">
|
|
13771
|
-
<title>${escapeHtml(err.message || err.name)}</title>
|
|
13772
|
-
<style>body{margin:0;font-family:ui-sans-serif,system-ui,sans-serif;background:#f3f4f6;color:#111827}main{max-width:1100px;margin:2rem auto;padding:0 1rem}header{background:#fff;border-radius:.5rem;padding:1.5rem;box-shadow:0 1px 3px #0001}.class{color:#dc2626;font-weight:600}.message{font-size:1.5rem;margin:.5rem 0}.request{color:#6b7280}section{background:#fff;border-radius:.5rem;padding:1rem;margin-top:1rem;box-shadow:0 1px 3px #0001;overflow:auto}.source td{padding:0 .5rem;white-space:pre;font-size:.85rem}.source .n{color:#9ca3af;text-align:right}.source .current{background:#fee2e2}ol{font-family:ui-monospace,monospace;font-size:.85rem}</style>
|
|
13773
|
-
</head>
|
|
13774
|
-
<body><main>
|
|
13775
|
-
<header><div class="class">${escapeHtml(err.name)}</div><div class="message">${escapeHtml(err.message)}</div><div class="request">${escapeHtml(method)} ${escapeHtml(url2)}</div></header>
|
|
13776
|
-
${appFrame === void 0 ? "" : `<section><div>${escapeHtml(appFrame.file)}:${appFrame.line}</div>${source ?? ""}</section>`}
|
|
13777
|
-
<section><ol>${frames.map((frame) => `<li>${escapeHtml(frame.text)}</li>`).join("")}</ol></section>
|
|
13778
|
-
${causes.length === 0 ? "" : `<section><div>Caused by</div><ul>${causes.join("")}</ul></section>`}
|
|
13779
|
-
</main></body>
|
|
13780
|
-
</html>`;
|
|
13781
|
-
}
|
|
13782
|
-
var NOT_REPORTED = /* @__PURE__ */ new Set(["Http", "ModelNotFound", "Validation", "Authentication", "Authorization", "TokenMismatch"]);
|
|
13783
|
-
var HTTP_KINDS = /* @__PURE__ */ new Set(["Http", "ModelNotFound", "Authorization", "TokenMismatch"]);
|
|
13784
|
-
var kindOf = (error) => typeof error === "object" && error !== null && typeof error.kind === "string" ? error.kind : void 0;
|
|
13785
|
-
function statusFor(error) {
|
|
13786
|
-
const status = error?.status;
|
|
13787
|
-
switch (kindOf(error)) {
|
|
13788
|
-
case "Http":
|
|
13789
|
-
return status ?? 500;
|
|
13790
|
-
case "ModelNotFound":
|
|
13791
|
-
return 404;
|
|
13792
|
-
case "Authorization":
|
|
13793
|
-
return status ?? 403;
|
|
13794
|
-
case "TokenMismatch":
|
|
13795
|
-
return 419;
|
|
13796
|
-
case "Authentication":
|
|
13797
|
-
return 401;
|
|
13798
|
-
case "Validation":
|
|
13799
|
-
return status ?? 422;
|
|
13800
|
-
case "Server":
|
|
13801
|
-
return status ?? 500;
|
|
13802
|
-
default:
|
|
13803
|
-
return 500;
|
|
13804
|
-
}
|
|
13805
|
-
}
|
|
13806
|
-
function summarizeValidation(errors2) {
|
|
13807
|
-
const messages = Object.values(errors2).flat();
|
|
13808
|
-
if (messages.length === 0) return "The given data was invalid.";
|
|
13809
|
-
const more = messages.length - 1;
|
|
13810
|
-
return more === 0 ? messages[0] : `${messages[0]} (and ${more} more ${more === 1 ? "error" : "errors"})`;
|
|
13811
|
-
}
|
|
13812
|
-
var isHttpLike = (error) => {
|
|
13813
|
-
const kind = kindOf(error);
|
|
13814
|
-
return kind !== void 0 && HTTP_KINDS.has(kind);
|
|
13815
|
-
};
|
|
13816
|
-
var ErrorHandler = class {
|
|
13817
|
-
constructor(app2) {
|
|
13818
|
-
this.app = app2;
|
|
13819
|
-
}
|
|
13820
|
-
app;
|
|
13821
|
-
/** Input keys never flashed back on a validation redirect. */
|
|
13822
|
-
dontFlash = ["current_password", "password", "password_confirmation"];
|
|
13823
|
-
#reportCallbacks = [];
|
|
13824
|
-
#renderCallbacks = [];
|
|
13825
|
-
#dontReport = [];
|
|
13826
|
-
#reported = /* @__PURE__ */ new WeakSet();
|
|
13827
|
-
reportUsing(callback) {
|
|
13828
|
-
this.#reportCallbacks.push(callback);
|
|
13829
|
-
}
|
|
13830
|
-
renderUsing(callback) {
|
|
13831
|
-
this.#renderCallbacks.push(callback);
|
|
13832
|
-
}
|
|
13833
|
-
ignore(...classes) {
|
|
13834
|
-
this.#dontReport.push(...classes);
|
|
13835
|
-
}
|
|
13836
|
-
shouldReport(error) {
|
|
13837
|
-
const kind = kindOf(error);
|
|
13838
|
-
if (kind !== void 0 && NOT_REPORTED.has(kind)) return false;
|
|
13839
|
-
return !this.#dontReport.some((cls) => error instanceof cls);
|
|
13840
|
-
}
|
|
13841
|
-
/** Report callbacks first (returning false stops the default log), then LogManager.error(), else console.error. Once per error. */
|
|
13842
|
-
async report(error) {
|
|
13843
|
-
if (!this.shouldReport(error)) return;
|
|
13844
|
-
if (typeof error === "object" && error !== null) {
|
|
13845
|
-
if (this.#reported.has(error)) return;
|
|
13846
|
-
this.#reported.add(error);
|
|
13847
|
-
}
|
|
13848
|
-
try {
|
|
13849
|
-
for (const callback of this.#reportCallbacks) if (await callback(error) === false) return;
|
|
13850
|
-
const container = this.#container();
|
|
13851
|
-
if (container.bound(LogManager)) {
|
|
13852
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
13853
|
-
container.make(LogManager).error(message, { exception: error });
|
|
13854
|
-
} else {
|
|
13855
|
-
console.error(error);
|
|
13856
|
-
}
|
|
13857
|
-
} catch (reportError) {
|
|
13858
|
-
console.error(reportError);
|
|
13859
|
-
}
|
|
13860
|
-
}
|
|
13861
|
-
async render(request2, error) {
|
|
13862
|
-
for (const callback of this.#renderCallbacks) {
|
|
13863
|
-
const response3 = await callback(error, request2);
|
|
13864
|
-
if (response3 instanceof Response) return response3;
|
|
13865
|
-
}
|
|
13866
|
-
if (error instanceof HttpResponseException) return error.response;
|
|
13867
|
-
const custom = await this.#renderCustom(request2, error);
|
|
13868
|
-
if (custom !== void 0) return custom;
|
|
13869
|
-
const http = this.#httpRequest(request2);
|
|
13870
|
-
const kind = kindOf(error);
|
|
13871
|
-
let response2;
|
|
13872
|
-
if (kind === "Validation") response2 = await this.#renderValidation(http, error);
|
|
13873
|
-
else if (kind === "Authentication") response2 = await this.#renderAuthentication(http, error);
|
|
13874
|
-
else if (http.expectsJson()) response2 = this.#renderJson(error);
|
|
13875
|
-
else response2 = await this.#renderHtml(http, error);
|
|
13876
|
-
const headers = error?.headers;
|
|
13877
|
-
if (headers !== void 0) for (const [name, value2] of Object.entries(headers)) response2.headers.set(name, value2);
|
|
13878
|
-
return response2;
|
|
13879
|
-
}
|
|
13880
|
-
/** An error with its own render(request) or toResponse(request) (Laravel's renderable exceptions / Responsable). */
|
|
13881
|
-
async #renderCustom(request2, error) {
|
|
13882
|
-
if (typeof error !== "object" || error === null) return void 0;
|
|
13883
|
-
const candidate = error;
|
|
13884
|
-
for (const method of [candidate.render, candidate.toResponse]) {
|
|
13885
|
-
if (typeof method !== "function") continue;
|
|
13886
|
-
const response2 = await method.call(error, request2);
|
|
13887
|
-
if (response2 instanceof Response) return response2;
|
|
13888
|
-
}
|
|
13889
|
-
return void 0;
|
|
13890
|
-
}
|
|
13891
|
-
async #renderValidation(request2, error) {
|
|
13892
|
-
if (request2.expectsJson()) {
|
|
13893
|
-
return this.#json({ message: summarizeValidation(error.errors), errors: error.errors }, statusFor(error));
|
|
13894
|
-
}
|
|
13895
|
-
const input = { ...request2.input() };
|
|
13896
|
-
for (const key of this.dontFlash) delete input[key];
|
|
13897
|
-
const container = this.#container();
|
|
13898
|
-
if (!container.bound(Redirector)) {
|
|
13899
|
-
return this.#redirect(error.redirectTo ?? request2.header("referer") ?? "/");
|
|
13900
|
-
}
|
|
13901
|
-
const redirector = container.make(Redirector);
|
|
13902
|
-
const redirect2 = error.redirectTo !== void 0 ? redirector.to(error.redirectTo) : redirector.back();
|
|
13903
|
-
const response2 = await redirect2.withInput(input).withErrors(error.errors, error.errorBag).toResponse(request2);
|
|
13904
|
-
return response2;
|
|
13905
|
-
}
|
|
13906
|
-
async #renderAuthentication(request2, error) {
|
|
13907
|
-
if (request2.expectsJson()) return this.#json({ message: error.message || "Unauthenticated." }, 401);
|
|
13908
|
-
const target = error.redirectTo ?? this.#guestRedirect(request2);
|
|
13909
|
-
const container = this.#container();
|
|
13910
|
-
if (!container.bound(Redirector)) return this.#redirect(target);
|
|
13911
|
-
const redirector = container.make(Redirector);
|
|
13912
|
-
const redirect2 = typeof redirector.guest === "function" ? redirector.guest(target) : redirector.to(target);
|
|
13913
|
-
return await redirect2.toResponse(request2);
|
|
13914
|
-
}
|
|
13915
|
-
/** config('http.redirect_guests_to'), then route('login'), then '/login'. */
|
|
13916
|
-
#guestRedirect(request2) {
|
|
13917
|
-
const configured = this.#config("http.redirect_guests_to", void 0);
|
|
13918
|
-
if (typeof configured === "function") return String(configured(request2));
|
|
13919
|
-
if (typeof configured === "string" && configured !== "") return configured;
|
|
13920
|
-
const container = this.#container();
|
|
13921
|
-
if (container.bound(UrlGenerator)) {
|
|
13922
|
-
const url2 = container.make(UrlGenerator);
|
|
13923
|
-
if (url2.hasRoute("login")) return url2.route("login");
|
|
13924
|
-
}
|
|
13925
|
-
return "/login";
|
|
13926
|
-
}
|
|
13927
|
-
#renderJson(error) {
|
|
13928
|
-
const status = statusFor(error);
|
|
13929
|
-
if (isHttpLike(error)) {
|
|
13930
|
-
const message = error instanceof Error && error.message !== "" ? error.message : statusText(status);
|
|
13931
|
-
return this.#json({ message }, status);
|
|
13932
|
-
}
|
|
13933
|
-
if (!this.#debug()) return this.#json({ message: "Server Error" }, status);
|
|
13934
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
13935
|
-
const [frame] = stackFrames(err);
|
|
13936
|
-
return this.#json(
|
|
13937
|
-
{
|
|
13938
|
-
message: err.message,
|
|
13939
|
-
exception: err.name,
|
|
13940
|
-
file: frame?.file,
|
|
13941
|
-
line: frame?.line,
|
|
13942
|
-
trace: stackFrames(err).map((entry) => entry.text)
|
|
13943
|
-
},
|
|
13944
|
-
status
|
|
13945
|
-
);
|
|
13946
|
-
}
|
|
13947
|
-
async #renderHtml(request2, error) {
|
|
13948
|
-
const status = statusFor(error);
|
|
13949
|
-
if (!isHttpLike(error) && this.#debug()) {
|
|
13950
|
-
return this.#html(await debugPage(error, request2.method(), request2.fullUrl()), status);
|
|
13951
|
-
}
|
|
13952
|
-
const message = status === 403 && error instanceof Error && error.message !== "" ? error.message : statusText(status);
|
|
13953
|
-
const view2 = await this.#errorView(status, error, message);
|
|
13954
|
-
return this.#html(view2 ?? minimalPage(status, message), status);
|
|
13955
|
-
}
|
|
13956
|
-
/** resources/views/errors/{status}.tsx, then errors/4xx or errors/5xx, through the ViewFactory. */
|
|
13957
|
-
async #errorView(status, error, message) {
|
|
13958
|
-
const container = this.#container();
|
|
13959
|
-
if (!container.bound(ViewFactory)) return void 0;
|
|
13960
|
-
const views = container.make(ViewFactory);
|
|
13961
|
-
for (const name of [`errors.${status}`, `errors.${Math.floor(status / 100)}xx`]) {
|
|
13962
|
-
if (!views.exists(name)) continue;
|
|
13963
|
-
try {
|
|
13964
|
-
return await views.make(name, { exception: error, status, message }).render();
|
|
13965
|
-
} catch (viewError) {
|
|
13966
|
-
await this.report(viewError);
|
|
13967
|
-
return void 0;
|
|
13968
|
-
}
|
|
13969
|
-
}
|
|
13970
|
-
return void 0;
|
|
13971
|
-
}
|
|
13972
|
-
#httpRequest(request2) {
|
|
13973
|
-
if (typeof request2 === "object" && request2 !== null && typeof request2.expectsJson === "function") {
|
|
13974
|
-
return request2;
|
|
13975
|
-
}
|
|
13976
|
-
return new IncomingRequest(request2 instanceof Request ? request2 : new Request("http://localhost/"));
|
|
13977
|
-
}
|
|
13978
|
-
#json(body, status) {
|
|
13979
|
-
return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" } });
|
|
13980
|
-
}
|
|
13981
|
-
#html(body, status) {
|
|
13982
|
-
return new Response(body, { status, headers: { "content-type": "text/html; charset=utf-8" } });
|
|
13983
|
-
}
|
|
13984
|
-
#redirect(location) {
|
|
13985
|
-
return new Response(null, { status: 302, headers: { Location: location } });
|
|
13986
|
-
}
|
|
13987
|
-
#debug() {
|
|
13988
|
-
return this.#config("app.debug", false) === true;
|
|
13989
|
-
}
|
|
13990
|
-
#config(key, fallback) {
|
|
13991
|
-
return this.app.bound(ConfigRepository) ? this.app.make(ConfigRepository).get(key, fallback) : fallback;
|
|
13992
|
-
}
|
|
13993
|
-
/** The request scope while handling a request (so scoped services resolve), else the application. */
|
|
13994
|
-
#container() {
|
|
13995
|
-
return currentContainer() ?? this.app;
|
|
13996
|
-
}
|
|
13997
|
-
};
|
|
13998
|
-
var ExceptionsConfiguration = class {
|
|
13999
|
-
constructor(handler3) {
|
|
14000
|
-
this.handler = handler3;
|
|
14001
|
-
}
|
|
14002
|
-
handler;
|
|
14003
|
-
report(callback) {
|
|
14004
|
-
this.handler.reportUsing(callback);
|
|
14005
|
-
return this;
|
|
14006
|
-
}
|
|
14007
|
-
render(callback) {
|
|
14008
|
-
this.handler.renderUsing(callback);
|
|
14009
|
-
return this;
|
|
14010
|
-
}
|
|
14011
|
-
dontReport(...classes) {
|
|
14012
|
-
this.handler.ignore(...classes);
|
|
14013
|
-
return this;
|
|
14014
|
-
}
|
|
14015
|
-
};
|
|
14016
|
-
function applyExceptionCallbacks(app2, handler3) {
|
|
14017
|
-
if (!app2.bound(ExceptionCallbacks)) return;
|
|
14018
|
-
const configurator = new ExceptionsConfiguration(handler3);
|
|
14019
|
-
for (const callback of app2.make(ExceptionCallbacks)) callback(configurator);
|
|
14020
|
-
}
|
|
14021
|
-
var HIDDEN_SEGMENT = /^\.|\.(ts|tsx|mts|cts)$|[. ]$/i;
|
|
14022
|
-
async function servePublicFile(publicPath, request2) {
|
|
14023
|
-
if (request2.method !== "GET" && request2.method !== "HEAD") return void 0;
|
|
14024
|
-
let pathname;
|
|
14025
|
-
try {
|
|
14026
|
-
pathname = decodeURIComponent(new URL(request2.url).pathname);
|
|
14027
|
-
} catch {
|
|
14028
|
-
return void 0;
|
|
14029
|
-
}
|
|
14030
|
-
if (pathname === "/" || pathname.includes("\0")) return void 0;
|
|
14031
|
-
const root = resolve3(publicPath);
|
|
14032
|
-
const file = resolve3(root, `.${pathname}`);
|
|
14033
|
-
if (!file.startsWith(root + sep4)) return void 0;
|
|
14034
|
-
if (relative5(root, file).split(/[\\/]/).some((segment) => HIDDEN_SEGMENT.test(segment))) return void 0;
|
|
14035
|
-
const info = await stat22(file).catch(() => void 0);
|
|
14036
|
-
if (info === void 0 || !info.isFile()) return void 0;
|
|
14037
|
-
const type = mimeFromExtension2(file);
|
|
14038
|
-
const headers = new Headers({
|
|
14039
|
-
"content-type": type.startsWith("text/") || type === "application/json" ? `${type}; charset=utf-8` : type,
|
|
14040
|
-
"content-length": String(info.size),
|
|
14041
|
-
"last-modified": info.mtime.toUTCString()
|
|
14042
|
-
});
|
|
14043
|
-
if (pathname.startsWith("/build/assets/")) headers.set("cache-control", "public, max-age=31536000, immutable");
|
|
14044
|
-
if (request2.method === "HEAD") return new Response(null, { status: 200, headers });
|
|
14045
|
-
const body = Readable22.toWeb(createReadStream22(file));
|
|
14046
|
-
return new Response(body, { status: 200, headers });
|
|
14047
|
-
}
|
|
14048
|
-
async function terminateRequest(app2, request2, response2) {
|
|
14049
|
-
try {
|
|
14050
|
-
if (app2.bound(HttpKernel)) await app2.make(HttpKernel).terminate?.(request2, response2);
|
|
14051
|
-
} catch (error) {
|
|
14052
|
-
console.error(error);
|
|
14053
|
-
}
|
|
14054
|
-
}
|
|
14055
|
-
async function handleSafely(app2, request2, publicPath) {
|
|
14056
|
-
try {
|
|
14057
|
-
if (publicPath !== void 0) {
|
|
14058
|
-
const file = await servePublicFile(publicPath, request2);
|
|
14059
|
-
if (file !== void 0) return file;
|
|
14060
|
-
}
|
|
14061
|
-
return await app2.handle(request2);
|
|
14062
|
-
} catch (error) {
|
|
14063
|
-
console.error(error);
|
|
14064
|
-
return plainServerError();
|
|
14065
|
-
}
|
|
14066
|
-
}
|
|
14067
|
-
function exitOnSignals(close, closed) {
|
|
14068
|
-
const onSignal = () => {
|
|
14069
|
-
void close().then(() => process.exit(0));
|
|
14070
|
-
};
|
|
14071
|
-
process.once("SIGINT", onSignal);
|
|
14072
|
-
process.once("SIGTERM", onSignal);
|
|
14073
|
-
void closed.then(() => {
|
|
14074
|
-
process.off("SIGINT", onSignal);
|
|
14075
|
-
process.off("SIGTERM", onSignal);
|
|
14076
|
-
});
|
|
14077
|
-
}
|
|
14078
|
-
var displayHost = (hostname) => hostname.includes(":") ? `[${hostname}]` : hostname;
|
|
14079
|
-
function bunRuntime() {
|
|
14080
|
-
return globalThis.Bun;
|
|
14081
|
-
}
|
|
14082
|
-
async function serveBun(app2, options) {
|
|
14083
|
-
const bun = bunRuntime();
|
|
14084
|
-
if (bun === void 0) throw new HttpServerError("Bun.serve is not available: the process is not running on Bun.");
|
|
14085
|
-
let markClosed = () => void 0;
|
|
14086
|
-
const closed = new Promise((resolve22) => markClosed = resolve22);
|
|
14087
|
-
const server = bun.serve({
|
|
14088
|
-
port: options.port,
|
|
14089
|
-
hostname: options.hostname,
|
|
14090
|
-
async fetch(request2, current) {
|
|
14091
|
-
setClientAddress(request2, current.requestIP(request2)?.address);
|
|
14092
|
-
const response2 = await handleSafely(app2, request2, options.publicPath);
|
|
14093
|
-
setTimeout(() => void terminateRequest(app2, request2, response2), 0);
|
|
14094
|
-
return response2;
|
|
14095
|
-
},
|
|
14096
|
-
error(error) {
|
|
14097
|
-
console.error(error);
|
|
14098
|
-
return plainServerError();
|
|
14099
|
-
}
|
|
14100
|
-
});
|
|
14101
|
-
let closing;
|
|
14102
|
-
const close = () => closing ??= (async () => {
|
|
14103
|
-
let timer;
|
|
14104
|
-
const forced = new Promise((resolve22) => {
|
|
14105
|
-
timer = setTimeout(() => void Promise.resolve(server.stop(true)).then(resolve22), options.shutdownTimeout);
|
|
14106
|
-
});
|
|
14107
|
-
await Promise.race([Promise.resolve(server.stop(false)), forced]);
|
|
14108
|
-
clearTimeout(timer);
|
|
14109
|
-
markClosed();
|
|
14110
|
-
})();
|
|
14111
|
-
if (options.signals) exitOnSignals(close, closed);
|
|
14112
|
-
return {
|
|
14113
|
-
runtime: "bun",
|
|
14114
|
-
hostname: options.hostname,
|
|
14115
|
-
port: server.port,
|
|
14116
|
-
url: `http://${displayHost(options.hostname)}:${server.port}`,
|
|
14117
|
-
close,
|
|
14118
|
-
closed
|
|
14119
|
-
};
|
|
14120
|
-
}
|
|
14121
|
-
function requestBody(req) {
|
|
14122
|
-
let finished = false;
|
|
14123
|
-
const detach = () => {
|
|
14124
|
-
finished = true;
|
|
14125
|
-
req.off("data", onData);
|
|
14126
|
-
req.off("end", onEnd);
|
|
14127
|
-
req.off("error", onError);
|
|
14128
|
-
req.off("close", onClose);
|
|
14129
|
-
};
|
|
14130
|
-
let controller;
|
|
14131
|
-
const onData = (chunk) => {
|
|
14132
|
-
if (finished) return;
|
|
14133
|
-
controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
|
14134
|
-
if ((controller.desiredSize ?? 0) <= 0) req.pause();
|
|
14135
|
-
};
|
|
14136
|
-
const onEnd = () => {
|
|
14137
|
-
if (finished) return;
|
|
14138
|
-
detach();
|
|
14139
|
-
controller.close();
|
|
14140
|
-
};
|
|
14141
|
-
const onError = (error) => {
|
|
14142
|
-
if (finished) return;
|
|
14143
|
-
detach();
|
|
14144
|
-
controller.error(error);
|
|
14145
|
-
};
|
|
14146
|
-
const onClose = () => {
|
|
14147
|
-
if (!finished && !req.complete) onError(new Error("The request was aborted."));
|
|
14148
|
-
};
|
|
14149
|
-
return new ReadableStream(
|
|
14150
|
-
{
|
|
14151
|
-
start(c) {
|
|
14152
|
-
controller = c;
|
|
14153
|
-
req.on("data", onData);
|
|
14154
|
-
req.on("end", onEnd);
|
|
14155
|
-
req.on("error", onError);
|
|
14156
|
-
req.on("close", onClose);
|
|
14157
|
-
req.pause();
|
|
14158
|
-
},
|
|
14159
|
-
pull() {
|
|
14160
|
-
req.resume();
|
|
14161
|
-
},
|
|
14162
|
-
cancel() {
|
|
14163
|
-
detach();
|
|
14164
|
-
}
|
|
14165
|
-
},
|
|
14166
|
-
{ highWaterMark: 0 }
|
|
14167
|
-
);
|
|
14168
|
-
}
|
|
14169
|
-
function toWebRequest(req, res, fallbackHost) {
|
|
14170
|
-
const target = req.url ?? "/";
|
|
14171
|
-
const url2 = new URL(`http://${req.headers.host ?? fallbackHost}${target.startsWith("/") ? target : `/${target}`}`);
|
|
14172
|
-
const headers = new Headers();
|
|
14173
|
-
for (let i = 0; i < req.rawHeaders.length; i += 2) {
|
|
14174
|
-
const name = req.rawHeaders[i];
|
|
14175
|
-
if (!name.startsWith(":")) headers.append(name, req.rawHeaders[i + 1]);
|
|
14176
|
-
}
|
|
14177
|
-
const method = (req.method ?? "GET").toUpperCase();
|
|
14178
|
-
const controller = new AbortController();
|
|
14179
|
-
res.once("close", () => {
|
|
14180
|
-
if (!res.writableFinished) controller.abort();
|
|
14181
|
-
});
|
|
14182
|
-
const init = { method, headers, signal: controller.signal };
|
|
14183
|
-
if (method !== "GET" && method !== "HEAD") {
|
|
14184
|
-
init.body = requestBody(req);
|
|
14185
|
-
init.duplex = "half";
|
|
14186
|
-
}
|
|
14187
|
-
return new Request(url2, init);
|
|
14188
|
-
}
|
|
14189
|
-
async function writeResponse(res, response2) {
|
|
14190
|
-
res.statusCode = response2.status;
|
|
14191
|
-
if (response2.statusText !== "") res.statusMessage = response2.statusText;
|
|
14192
|
-
response2.headers.forEach((value2, name) => {
|
|
14193
|
-
if (name !== "set-cookie") res.setHeader(name, value2);
|
|
14194
|
-
});
|
|
14195
|
-
const cookies = response2.headers.getSetCookie();
|
|
14196
|
-
if (cookies.length > 0) res.setHeader("set-cookie", cookies);
|
|
14197
|
-
if (response2.body === null) {
|
|
14198
|
-
res.end();
|
|
14199
|
-
return;
|
|
14200
|
-
}
|
|
14201
|
-
await pipeline2(Readable3.fromWeb(response2.body), res);
|
|
14202
|
-
}
|
|
14203
|
-
async function serveNode(app2, options) {
|
|
14204
|
-
const fallbackHost = `${displayHost(options.hostname)}:${options.port}`;
|
|
14205
|
-
const server = createServer((req, res) => {
|
|
14206
|
-
void (async () => {
|
|
14207
|
-
let request2;
|
|
14208
|
-
try {
|
|
14209
|
-
request2 = toWebRequest(req, res, fallbackHost);
|
|
14210
|
-
} catch {
|
|
14211
|
-
res.statusCode = 400;
|
|
14212
|
-
res.end("Bad Request");
|
|
14213
|
-
return;
|
|
14214
|
-
}
|
|
14215
|
-
setClientAddress(request2, req.socket.remoteAddress);
|
|
14216
|
-
const response2 = await handleSafely(app2, request2, options.publicPath);
|
|
14217
|
-
try {
|
|
14218
|
-
await writeResponse(res, response2);
|
|
14219
|
-
} catch {
|
|
14220
|
-
res.destroy();
|
|
14221
|
-
}
|
|
14222
|
-
await terminateRequest(app2, request2, response2);
|
|
14223
|
-
})();
|
|
14224
|
-
});
|
|
14225
|
-
await new Promise((resolve22, reject) => {
|
|
14226
|
-
server.once("error", reject);
|
|
14227
|
-
server.listen(options.port, options.hostname, () => {
|
|
14228
|
-
server.off("error", reject);
|
|
14229
|
-
resolve22();
|
|
14230
|
-
});
|
|
14231
|
-
});
|
|
14232
|
-
const address = server.address();
|
|
14233
|
-
const closed = new Promise((resolve22) => server.once("close", () => resolve22()));
|
|
14234
|
-
let closing;
|
|
14235
|
-
const close = () => closing ??= (async () => {
|
|
14236
|
-
const done = new Promise((resolve22) => server.close(() => resolve22()));
|
|
14237
|
-
server.closeIdleConnections();
|
|
14238
|
-
const idle = setInterval(() => server.closeIdleConnections(), 50);
|
|
14239
|
-
const force = setTimeout(() => server.closeAllConnections(), options.shutdownTimeout);
|
|
14240
|
-
await done;
|
|
14241
|
-
clearInterval(idle);
|
|
14242
|
-
clearTimeout(force);
|
|
14243
|
-
})();
|
|
14244
|
-
if (options.signals) exitOnSignals(close, closed);
|
|
14245
|
-
return {
|
|
14246
|
-
runtime: "node",
|
|
14247
|
-
hostname: options.hostname,
|
|
14248
|
-
port: address.port,
|
|
14249
|
-
url: `http://${displayHost(options.hostname)}:${address.port}`,
|
|
14250
|
-
close,
|
|
14251
|
-
closed
|
|
14252
|
-
};
|
|
14253
|
-
}
|
|
14254
|
-
function detectRuntime() {
|
|
14255
|
-
return bunRuntime() !== void 0 ? "bun" : "node";
|
|
14256
|
-
}
|
|
14257
|
-
async function serve(app2, options = {}) {
|
|
14258
|
-
const resolved = {
|
|
14259
|
-
port: options.port ?? Number(process.env.PORT ?? process.env.SERVER_PORT ?? 8e3),
|
|
14260
|
-
hostname: options.hostname ?? "127.0.0.1",
|
|
14261
|
-
signals: options.signals ?? true,
|
|
14262
|
-
shutdownTimeout: options.shutdownTimeout ?? 1e4,
|
|
14263
|
-
...options.publicPath !== false && { publicPath: options.publicPath ?? app2.publicPath() }
|
|
14264
|
-
};
|
|
14265
|
-
await app2.boot();
|
|
14266
|
-
const runtime = options.runtime ?? detectRuntime();
|
|
14267
|
-
const server = runtime === "bun" ? await serveBun(app2, resolved) : await serveNode(app2, resolved);
|
|
14268
|
-
const onListen = options.onListen ?? ((running) => console.log(`Server running on [${running.url}].`));
|
|
14269
|
-
onListen(server);
|
|
14270
|
-
return server;
|
|
14271
|
-
}
|
|
14272
|
-
function io(command) {
|
|
14273
|
-
return {
|
|
14274
|
-
option: (name) => {
|
|
14275
|
-
const value2 = command.option(name);
|
|
14276
|
-
return value2 === void 0 || value2 === null || value2 === false || value2 === "" ? void 0 : String(value2);
|
|
14277
|
-
},
|
|
14278
|
-
flag: (name) => {
|
|
14279
|
-
const value2 = command.option(name);
|
|
14280
|
-
return value2 === true || value2 === "true" || value2 === "1";
|
|
14281
|
-
},
|
|
14282
|
-
info: (message) => command.info(message),
|
|
14283
|
-
line: (message) => command.line(message),
|
|
14284
|
-
warn: (message) => command.warn(message),
|
|
14285
|
-
error: (message) => command.error(message)
|
|
14286
|
-
};
|
|
14287
|
-
}
|
|
14288
|
-
var middlewareName = (reference) => typeof reference === "string" ? reference : reference.name;
|
|
14289
|
-
function routeListRows(routes) {
|
|
14290
|
-
const rows = routes.map((route2) => {
|
|
14291
|
-
const listable = route2;
|
|
14292
|
-
return {
|
|
14293
|
-
method: route2.methods.join("|"),
|
|
14294
|
-
uri: route2.uri,
|
|
14295
|
-
name: route2.getName() ?? null,
|
|
14296
|
-
action: typeof listable.getActionName === "function" ? listable.getActionName() : "Closure",
|
|
14297
|
-
middleware: typeof listable.gatherMiddleware === "function" ? listable.gatherMiddleware().map(middlewareName) : []
|
|
14298
|
-
};
|
|
14299
|
-
});
|
|
14300
|
-
return rows.sort((a, b) => a.uri < b.uri ? -1 : a.uri > b.uri ? 1 : 0);
|
|
14301
|
-
}
|
|
14302
|
-
function filterRouteList(rows, filters) {
|
|
14303
|
-
const excluded2 = (filters.exceptPath ?? "").split(",").filter((path) => path !== "");
|
|
14304
|
-
return rows.filter((row) => {
|
|
14305
|
-
if (filters.name !== void 0 && !(row.name ?? "").includes(filters.name)) return false;
|
|
14306
|
-
if (filters.path !== void 0 && !row.uri.includes(filters.path)) return false;
|
|
14307
|
-
if (filters.method !== void 0 && !row.method.includes(filters.method.toUpperCase())) return false;
|
|
14308
|
-
return !excluded2.some((path) => row.uri.includes(path));
|
|
14309
|
-
});
|
|
14310
|
-
}
|
|
14311
|
-
function formatRouteList(rows, width) {
|
|
14312
|
-
const methodWidth = Math.max(...rows.map((row) => row.method.length));
|
|
14313
|
-
const lines = rows.map((row) => {
|
|
14314
|
-
const spaces = " ".repeat(Math.max(methodWidth + 6 - row.method.length, 0));
|
|
14315
|
-
const action = row.action === "Closure" ? row.name ?? "" : row.name === null ? row.action : `${row.name} \u203A ${row.action}`;
|
|
14316
|
-
const used = row.method.length + spaces.length + row.uri.length + action.length + 6 + (action === "" ? 0 : 1);
|
|
14317
|
-
const dots = ".".repeat(Math.max(width - used, 0));
|
|
14318
|
-
return ` ${row.method} ${spaces}${row.uri}${dots === "" ? "" : ` ${dots}`}${action === "" ? "" : ` ${action}`}`;
|
|
14319
|
-
});
|
|
14320
|
-
const count = `Showing [${rows.length}] ${rows.length === 1 ? "route" : "routes"}`;
|
|
14321
|
-
return [...lines, "", `${" ".repeat(Math.max(width - count.length - 2, 0))}${count}`];
|
|
14322
|
-
}
|
|
14323
|
-
var API_ROUTES_STUB = `import { request, Route } from '@orieljs/framework'
|
|
14324
|
-
|
|
14325
|
-
Route.get('/user', () => request().user()).middleware('auth:token')
|
|
14326
|
-
`;
|
|
14327
|
-
function addApiRouting(source) {
|
|
14328
|
-
const code = source.replace(/^[ \t]*\/\/.*$/gm, "");
|
|
14329
|
-
if (/withRouting\(\s*\{[^}]*\bapi\s*:/.test(code)) return source;
|
|
14330
|
-
const commented = /^([ \t]*)\/\/\s*(api:\s*['"`][^'"`\n]*['"`],?)[ \t]*$/m.exec(source);
|
|
14331
|
-
if (commented !== null) return source.replace(commented[0], () => `${commented[1]}${commented[2]}`);
|
|
14332
|
-
const web = /^([ \t]*)web:\s*(['"`])[^'"`\n]*\2[ \t]*,?[ \t]*$/m.exec(source);
|
|
14333
|
-
if (web !== null) {
|
|
14334
|
-
const line = web[0].trimEnd();
|
|
14335
|
-
return source.replace(web[0], () => `${line.endsWith(",") ? line : `${line},`}
|
|
14336
|
-
${web[1]}api: 'routes/api.ts',`);
|
|
14337
|
-
}
|
|
14338
|
-
const inline = /withRouting\(\s*\{/.exec(source);
|
|
14339
|
-
if (inline !== null) return source.replace(inline[0], () => `${inline[0]} api: 'routes/api.ts',`);
|
|
14340
|
-
const create = /^([ \t]*)\.create\(\)/m.exec(source);
|
|
14341
|
-
if (create !== null) return source.replace(create[0], () => `${create[1]}.withRouting({ api: 'routes/api.ts' })
|
|
14342
|
-
${create[0]}`);
|
|
14343
|
-
return void 0;
|
|
14344
|
-
}
|
|
14345
|
-
function registerHttpCommands(kernel, app2, options = {}) {
|
|
14346
|
-
const serveApp = options.serve ?? serve;
|
|
14347
|
-
const terminalWidth = options.terminalWidth ?? (() => process.stdout.columns ?? 120);
|
|
14348
|
-
kernel.command(
|
|
14349
|
-
"serve {--host=127.0.0.1 : The host address to serve the application on} {--port= : The port to serve the application on}",
|
|
14350
|
-
async function() {
|
|
14351
|
-
const out = io(this);
|
|
14352
|
-
const port = out.option("port");
|
|
14353
|
-
if (port !== void 0 && !/^\d+$/.test(port)) {
|
|
14354
|
-
out.error("The --port option must be a number.");
|
|
14355
|
-
return 1;
|
|
14356
|
-
}
|
|
14357
|
-
const server = await serveApp(app2, {
|
|
14358
|
-
hostname: out.option("host") ?? "127.0.0.1",
|
|
14359
|
-
...port !== void 0 && { port: Number(port) },
|
|
14360
|
-
onListen: (running) => {
|
|
14361
|
-
out.info(`Server running on [${running.url}].`);
|
|
14362
|
-
out.line("Press Ctrl+C to stop the server");
|
|
14363
|
-
}
|
|
14364
|
-
});
|
|
14365
|
-
await server.closed;
|
|
14366
|
-
return 0;
|
|
14367
|
-
}
|
|
14368
|
-
).purpose("Serve the application on the Oriel development server");
|
|
14369
|
-
kernel.command(
|
|
14370
|
-
"route:list {--method= : Filter the routes by method} {--name= : Filter the routes by name} {--path= : Only show routes matching the given path pattern} {--except-path= : Do not display the routes matching the given path pattern} {--reverse : Reverse the ordering of the routes} {--json : Output the route list as JSON}",
|
|
14371
|
-
function() {
|
|
14372
|
-
const out = io(this);
|
|
14373
|
-
if (!app2.bound(Router)) {
|
|
14374
|
-
out.error("The router is not available. Is the Routing service provider registered?");
|
|
14375
|
-
return 1;
|
|
14376
|
-
}
|
|
14377
|
-
const all = routeListRows(app2.make(Router).getRoutes());
|
|
14378
|
-
if (all.length === 0) {
|
|
14379
|
-
out.error("Your application doesn't have any routes.");
|
|
14380
|
-
return 0;
|
|
14381
|
-
}
|
|
14382
|
-
const rows = filterRouteList(all, {
|
|
14383
|
-
...out.option("method") !== void 0 && { method: out.option("method") },
|
|
14384
|
-
...out.option("name") !== void 0 && { name: out.option("name") },
|
|
14385
|
-
...out.option("path") !== void 0 && { path: out.option("path") },
|
|
14386
|
-
...out.option("except-path") !== void 0 && { exceptPath: out.option("except-path") }
|
|
14387
|
-
});
|
|
14388
|
-
if (rows.length === 0) {
|
|
14389
|
-
out.error("Your application doesn't have any routes matching the given criteria.");
|
|
14390
|
-
return 0;
|
|
14391
|
-
}
|
|
14392
|
-
if (out.flag("reverse")) rows.reverse();
|
|
14393
|
-
if (out.flag("json")) {
|
|
14394
|
-
out.line(JSON.stringify(rows));
|
|
14395
|
-
return 0;
|
|
14396
|
-
}
|
|
14397
|
-
for (const line of formatRouteList(rows, terminalWidth())) out.line(line);
|
|
14398
|
-
return 0;
|
|
14399
|
-
}
|
|
14400
|
-
).purpose("List all registered routes");
|
|
14401
|
-
kernel.command("install:api {--force : Overwrite any existing API routes file}", async function() {
|
|
14402
|
-
const out = io(this);
|
|
14403
|
-
const routesFile = app2.basePath("routes/api.ts");
|
|
14404
|
-
if (existsSync7(routesFile) && !out.flag("force")) {
|
|
14405
|
-
out.error("API routes file already exists.");
|
|
14406
|
-
} else {
|
|
14407
|
-
await mkdir5(dirname5(routesFile), { recursive: true });
|
|
14408
|
-
await writeFile6(routesFile, API_ROUTES_STUB);
|
|
14409
|
-
out.info("Published API routes file.");
|
|
14410
|
-
}
|
|
14411
|
-
const bootstrapFile = app2.bootstrapPath("app.ts");
|
|
14412
|
-
const source = existsSync7(bootstrapFile) ? await readFile22(bootstrapFile, "utf8") : void 0;
|
|
14413
|
-
const updated = source === void 0 ? void 0 : addApiRouting(source);
|
|
14414
|
-
if (updated === void 0) {
|
|
14415
|
-
out.warn(
|
|
14416
|
-
"Unable to automatically add API route definition to bootstrap file. Add api: 'routes/api.ts' to withRouting() in bootstrap/app.ts."
|
|
14417
|
-
);
|
|
14418
|
-
} else if (updated !== source) {
|
|
14419
|
-
await writeFile6(bootstrapFile, updated);
|
|
14420
|
-
}
|
|
14421
|
-
out.info("API scaffolding installed. Run [oriel migrate] to create the personal access tokens table.");
|
|
14422
|
-
return 0;
|
|
14423
|
-
}).purpose("Create an API routes file and prepare the application for API authentication");
|
|
14424
|
-
}
|
|
14425
|
-
var HttpServiceProvider = class extends ServiceProvider {
|
|
14426
|
-
register() {
|
|
14427
|
-
this.mergeConfigFrom(
|
|
14428
|
-
{
|
|
14429
|
-
trusted_proxies: [],
|
|
14430
|
-
max_body_size: 8 * 1024 * 1024,
|
|
14431
|
-
csrf_except: [],
|
|
14432
|
-
redirect_guests_to: void 0,
|
|
14433
|
-
redirect_users_to: void 0
|
|
14434
|
-
},
|
|
14435
|
-
"http"
|
|
14436
|
-
);
|
|
14437
|
-
this.app.singleton(HttpKernel, () => new Kernel2(this.app));
|
|
14438
|
-
this.app.singleton(ExceptionHandler, () => {
|
|
14439
|
-
const handler3 = new ErrorHandler(this.app);
|
|
14440
|
-
applyExceptionCallbacks(this.app, handler3);
|
|
14441
|
-
return handler3;
|
|
14442
|
-
});
|
|
14443
|
-
this.app.singleton(ResponseFactory, () => new HttpResponseFactory());
|
|
14444
|
-
this.app.singleton(Redirector, () => new HttpRedirector());
|
|
14445
|
-
}
|
|
14446
|
-
boot() {
|
|
14447
|
-
this.app.booted(() => {
|
|
14448
|
-
const kernel = this.app.make(HttpKernel);
|
|
14449
|
-
if (kernel instanceof Kernel2 && this.app.bound(Router)) applyMiddlewareCallbacks(this.app, kernel);
|
|
14450
|
-
});
|
|
14451
|
-
if (this.app.bound(ConsoleKernel)) registerHttpCommands(this.app.make(ConsoleKernel), this.app);
|
|
14452
|
-
}
|
|
14453
|
-
};
|
|
14454
|
-
|
|
14455
|
-
// ../Inertia/dist/index.js
|
|
14456
|
-
import { existsSync as existsSync8 } from "fs";
|
|
14457
|
-
import { join as join10 } from "path";
|
|
14458
|
-
import { createHash as createHash5 } from "crypto";
|
|
14459
|
-
import { existsSync as existsSync23, readFileSync } from "fs";
|
|
14460
|
-
import { spawn as spawn2 } from "child_process";
|
|
14461
|
-
import { existsSync as existsSync33 } from "fs";
|
|
14462
|
-
import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
|
|
14463
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join24, relative as relative6 } from "path";
|
|
14464
|
-
import { existsSync as existsSync42, readFileSync as readFileSync2 } from "fs";
|
|
14465
|
-
var Header = {
|
|
14466
|
-
INERTIA: "X-Inertia",
|
|
14467
|
-
ERROR_BAG: "X-Inertia-Error-Bag",
|
|
14468
|
-
LOCATION: "X-Inertia-Location",
|
|
14469
|
-
REDIRECT: "X-Inertia-Redirect",
|
|
14470
|
-
VERSION: "X-Inertia-Version",
|
|
14471
|
-
PARTIAL_COMPONENT: "X-Inertia-Partial-Component",
|
|
14472
|
-
PARTIAL_ONLY: "X-Inertia-Partial-Data",
|
|
14473
|
-
PARTIAL_EXCEPT: "X-Inertia-Partial-Except",
|
|
14474
|
-
RESET: "X-Inertia-Reset",
|
|
14475
|
-
INFINITE_SCROLL_MERGE_INTENT: "X-Inertia-Infinite-Scroll-Merge-Intent",
|
|
14476
|
-
EXCEPT_ONCE_PROPS: "X-Inertia-Except-Once-Props"
|
|
14477
|
-
};
|
|
14478
|
-
function parseList(value2) {
|
|
14479
|
-
const items = (value2 ?? "").split(",").filter((item) => item !== "");
|
|
14480
|
-
return items.length === 0 ? void 0 : items;
|
|
14481
|
-
}
|
|
14482
|
-
var Prop = class {
|
|
14483
|
-
constructor(value2) {
|
|
14484
|
-
this.value = value2;
|
|
14485
|
-
}
|
|
14486
|
-
value;
|
|
14487
|
-
mergeState = { merge: false, deep: false, append: true, appendPaths: [], prependPaths: [], matchOn: [] };
|
|
14488
|
-
onceState = { once: false, fresh: false, key: void 0, ttlSeconds: void 0 };
|
|
14489
|
-
deferred = false;
|
|
14490
|
-
deferGroup;
|
|
14491
|
-
/** Calls the callback, if the value is one. */
|
|
14492
|
-
async resolve() {
|
|
14493
|
-
return typeof this.value === "function" ? await this.value() : this.value;
|
|
14494
|
-
}
|
|
14495
|
-
/** Never sent on the first load (OptionalProp, DeferProp). */
|
|
14496
|
-
ignoresFirstLoad() {
|
|
14497
|
-
return false;
|
|
14498
|
-
}
|
|
14499
|
-
/** Sent even when a partial reload didn't ask for it (AlwaysProp). */
|
|
14500
|
-
isAlways() {
|
|
14501
|
-
return false;
|
|
14502
|
-
}
|
|
14503
|
-
/** Errors are reported and the prop is left out, instead of failing the page (defer(..., { rescue: true })). */
|
|
14504
|
-
shouldRescue() {
|
|
14505
|
-
return false;
|
|
14506
|
-
}
|
|
14507
|
-
// Once (honoured by OptionalProp, DeferProp, MergeProp and OnceProp) ------------------------------------
|
|
14508
|
-
/** once(), once(false), once(true, { as: 'key', until: 3600 }). */
|
|
14509
|
-
once(value2 = true, options = {}) {
|
|
14510
|
-
this.onceState.once = value2;
|
|
14511
|
-
if (options.as !== void 0) this.onceState.key = options.as;
|
|
14512
|
-
if (options.until !== void 0) this.onceState.ttlSeconds = secondsUntil(options.until);
|
|
14513
|
-
return this;
|
|
14514
|
-
}
|
|
14515
|
-
/** A custom once key, so pages can share the prop under different names. */
|
|
14516
|
-
as(key) {
|
|
14517
|
-
this.onceState.key = key;
|
|
14518
|
-
return this;
|
|
14519
|
-
}
|
|
14520
|
-
/** Send the prop again even though the client already has it. */
|
|
14521
|
-
fresh(value2 = true) {
|
|
14522
|
-
this.onceState.fresh = value2;
|
|
14523
|
-
return this;
|
|
14524
|
-
}
|
|
14525
|
-
/** Expire after a number of seconds, or at a Date. */
|
|
14526
|
-
until(delay) {
|
|
14527
|
-
this.onceState.ttlSeconds = secondsUntil(delay);
|
|
14528
|
-
return this;
|
|
14529
|
-
}
|
|
14530
|
-
// Merging -------------------------------------------------------------------------------------------------
|
|
14531
|
-
isMergeable() {
|
|
14532
|
-
return false;
|
|
14533
|
-
}
|
|
14534
|
-
shouldMerge() {
|
|
14535
|
-
return this.isMergeable() && this.mergeState.merge;
|
|
14536
|
-
}
|
|
14537
|
-
shouldDeepMerge() {
|
|
14538
|
-
return this.mergeState.deep;
|
|
14539
|
-
}
|
|
14540
|
-
matchesOn() {
|
|
14541
|
-
return [...this.mergeState.matchOn];
|
|
12977
|
+
matchesOn() {
|
|
12978
|
+
return [...this.mergeState.matchOn];
|
|
14542
12979
|
}
|
|
14543
12980
|
appendsAtRoot() {
|
|
14544
12981
|
return this.mergeState.append && this.mergesAtRoot();
|
|
@@ -15116,9 +13553,9 @@ var Response2 = class {
|
|
|
15116
13553
|
}
|
|
15117
13554
|
};
|
|
15118
13555
|
function pageExists(component, paths, extensions) {
|
|
15119
|
-
return paths.some((path) => extensions.some((extension) =>
|
|
13556
|
+
return paths.some((path) => extensions.some((extension) => existsSync7(join10(path, `${component}.${extension}`))));
|
|
15120
13557
|
}
|
|
15121
|
-
var
|
|
13558
|
+
var ResponseFactory = class _ResponseFactory {
|
|
15122
13559
|
constructor(app2, parent) {
|
|
15123
13560
|
this.app = app2;
|
|
15124
13561
|
this.parent = parent;
|
|
@@ -15243,7 +13680,7 @@ function inertiaFactory() {
|
|
|
15243
13680
|
const container = currentContainer();
|
|
15244
13681
|
if (container === void 0) throw new ContainerNotAvailableError("Inertia");
|
|
15245
13682
|
if (container.bound(HttpRequest)) return container.make(InertiaFactory);
|
|
15246
|
-
return container.make(Application).make(
|
|
13683
|
+
return container.make(Application).make(ResponseFactory);
|
|
15247
13684
|
}
|
|
15248
13685
|
function inertia(component, props = {}) {
|
|
15249
13686
|
const factory = inertiaFactory();
|
|
@@ -15419,7 +13856,7 @@ function isEmpty(response2) {
|
|
|
15419
13856
|
return response2.status === 200 && (response2.body === null || response2.headers.get("content-length") === "0");
|
|
15420
13857
|
}
|
|
15421
13858
|
function md5(value2) {
|
|
15422
|
-
return
|
|
13859
|
+
return createHash7("md5").update(value2).digest("hex");
|
|
15423
13860
|
}
|
|
15424
13861
|
var EncryptHistory = class {
|
|
15425
13862
|
#container = inject(Container);
|
|
@@ -15498,6 +13935,7 @@ export class {{ class }} extends InertiaMiddleware {
|
|
|
15498
13935
|
}
|
|
15499
13936
|
}
|
|
15500
13937
|
`;
|
|
13938
|
+
var DEFAULT_EXCEPT_ROUTES = ["live.*"];
|
|
15501
13939
|
async function loadPageTypes() {
|
|
15502
13940
|
const specifier = "@orieljs/vite/types";
|
|
15503
13941
|
try {
|
|
@@ -15521,12 +13959,12 @@ function registerInertiaCommands(kernel, app2, gateway, options = {}) {
|
|
|
15521
13959
|
}
|
|
15522
13960
|
const output = absolute(optionText(this.option("output")) ?? config2("inertia.types.routes", "resources/js/oriel/routes.ts"));
|
|
15523
13961
|
const server = absolute(optionText(this.option("server")) ?? config2("inertia.types.server_routes", "types/routes.d.ts"));
|
|
15524
|
-
const table = routeTable(app2.make(Router).getRoutes(), config2("inertia.types.except_routes",
|
|
15525
|
-
await
|
|
15526
|
-
await
|
|
15527
|
-
await
|
|
15528
|
-
await
|
|
15529
|
-
this.info(`Route types for ${Object.keys(table).length} named routes written to ${
|
|
13962
|
+
const table = routeTable(app2.make(Router).getRoutes(), config2("inertia.types.except_routes", DEFAULT_EXCEPT_ROUTES));
|
|
13963
|
+
await mkdir5(dirname5(output), { recursive: true });
|
|
13964
|
+
await writeFile6(output, renderRoutesModule(table));
|
|
13965
|
+
await mkdir5(dirname5(server), { recursive: true });
|
|
13966
|
+
await writeFile6(server, renderServerRouteTypes(routeTable(app2.make(Router).getRoutes())));
|
|
13967
|
+
this.info(`Route types for ${Object.keys(table).length} named routes written to ${relative5(app2.basePath(), output)}.`);
|
|
15530
13968
|
return 0;
|
|
15531
13969
|
}
|
|
15532
13970
|
).purpose("Generate the route table and route name types for the frontend");
|
|
@@ -15539,7 +13977,7 @@ function registerInertiaCommands(kernel, app2, gateway, options = {}) {
|
|
|
15539
13977
|
const output = absolute(optionText(this.option("output")) ?? config2("inertia.types.pages", "resources/js/oriel/pages.d.ts"));
|
|
15540
13978
|
const result = await module.generatePageTypes({ root: app2.basePath(), output });
|
|
15541
13979
|
for (const warning of result.warnings) this.warn(warning);
|
|
15542
|
-
this.info(`Page types for ${result.pages} pages written to ${
|
|
13980
|
+
this.info(`Page types for ${result.pages} pages written to ${relative5(app2.basePath(), result.output)}.`);
|
|
15543
13981
|
return 0;
|
|
15544
13982
|
}).purpose("Generate TypeScript types for the Inertia page props");
|
|
15545
13983
|
kernel.command("inertia:middleware {name=HandleInertiaRequests : The middleware class name} {--force : Overwrite an existing file}", async function() {
|
|
@@ -15550,12 +13988,12 @@ function registerInertiaCommands(kernel, app2, gateway, options = {}) {
|
|
|
15550
13988
|
}
|
|
15551
13989
|
const file = app2.appPath(join24("Http", "Middleware", `${name}.ts`));
|
|
15552
13990
|
if (existsSync33(file) && this.option("force") !== true) {
|
|
15553
|
-
this.error(`Middleware [${
|
|
13991
|
+
this.error(`Middleware [${relative5(app2.basePath(), file)}] already exists.`);
|
|
15554
13992
|
return 1;
|
|
15555
13993
|
}
|
|
15556
|
-
await
|
|
15557
|
-
await
|
|
15558
|
-
this.info(`Middleware [${
|
|
13994
|
+
await mkdir5(dirname5(file), { recursive: true });
|
|
13995
|
+
await writeFile6(file, MIDDLEWARE_STUB2.replace("{{ class }}", () => name));
|
|
13996
|
+
this.info(`Middleware [${relative5(app2.basePath(), file)}] created successfully.`);
|
|
15559
13997
|
return 0;
|
|
15560
13998
|
}).purpose("Create a new Inertia middleware");
|
|
15561
13999
|
kernel.command("inertia:start-ssr {--runtime= : The runtime that runs the SSR bundle (node or bun)}", async function() {
|
|
@@ -15568,13 +14006,18 @@ function registerInertiaCommands(kernel, app2, gateway, options = {}) {
|
|
|
15568
14006
|
this.error("Inertia SSR bundle not found. Build it with `vite build --ssr`, or set `inertia.ssr.bundle`.");
|
|
15569
14007
|
return 1;
|
|
15570
14008
|
}
|
|
14009
|
+
const port = urlPort(gateway.productionUrl());
|
|
14010
|
+
if (port === void 0) {
|
|
14011
|
+
this.error(`inertia.ssr.url [${gateway.productionUrl()}] is not a URL.`);
|
|
14012
|
+
return 1;
|
|
14013
|
+
}
|
|
15571
14014
|
const runtime = optionText(this.option("runtime")) ?? config2("inertia.ssr.runtime", "node");
|
|
15572
|
-
const child = (options.spawn ?? spawn2)(runtime, [bundle], { stdio: "inherit" });
|
|
15573
|
-
return await new Promise((
|
|
15574
|
-
child.on("exit", (code) =>
|
|
14015
|
+
const child = (options.spawn ?? spawn2)(runtime, [bundle], { stdio: "inherit", env: { ...process.env, INERTIA_SSR_PORT: port } });
|
|
14016
|
+
return await new Promise((resolve3) => {
|
|
14017
|
+
child.on("exit", (code) => resolve3(code ?? 0));
|
|
15575
14018
|
child.on("error", (error) => {
|
|
15576
14019
|
this.error(`Could not start the SSR server: ${error.message}`);
|
|
15577
|
-
|
|
14020
|
+
resolve3(1);
|
|
15578
14021
|
});
|
|
15579
14022
|
});
|
|
15580
14023
|
}).purpose("Start the Inertia SSR server");
|
|
@@ -15595,6 +14038,15 @@ function registerInertiaCommands(kernel, app2, gateway, options = {}) {
|
|
|
15595
14038
|
return 1;
|
|
15596
14039
|
}).purpose("Check the Inertia SSR server health status");
|
|
15597
14040
|
}
|
|
14041
|
+
function urlPort(url2) {
|
|
14042
|
+
try {
|
|
14043
|
+
const parsed = new URL(url2);
|
|
14044
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return void 0;
|
|
14045
|
+
return parsed.port !== "" ? parsed.port : parsed.protocol === "https:" ? "443" : "80";
|
|
14046
|
+
} catch {
|
|
14047
|
+
return void 0;
|
|
14048
|
+
}
|
|
14049
|
+
}
|
|
15598
14050
|
function optionText(value2) {
|
|
15599
14051
|
return value2 === void 0 || value2 === null || value2 === false || value2 === "" ? void 0 : String(value2);
|
|
15600
14052
|
}
|
|
@@ -15722,12 +14174,13 @@ var InertiaServiceProvider = class extends ServiceProvider {
|
|
|
15722
14174
|
expose_shared_prop_keys: true,
|
|
15723
14175
|
store_previous_url: false,
|
|
15724
14176
|
history: { encrypt: false },
|
|
15725
|
-
|
|
14177
|
+
// live.* (Live's update endpoint) stays out of the browser's route table; the server's route names keep it.
|
|
14178
|
+
types: { pages: "resources/js/oriel/pages.d.ts", routes: "resources/js/oriel/routes.ts", server_routes: "types/routes.d.ts", except_routes: [...DEFAULT_EXCEPT_ROUTES] }
|
|
15726
14179
|
},
|
|
15727
14180
|
"inertia"
|
|
15728
14181
|
);
|
|
15729
|
-
this.app.singleton(
|
|
15730
|
-
this.app.scoped(InertiaFactory, (container) => container.make(
|
|
14182
|
+
this.app.singleton(ResponseFactory, () => new ResponseFactory(this.app));
|
|
14183
|
+
this.app.scoped(InertiaFactory, (container) => container.make(ResponseFactory).forRequest());
|
|
15731
14184
|
this.app.singleton(HttpGateway, () => new HttpGateway(this.app));
|
|
15732
14185
|
this.app.singleton(InertiaSsrGateway, (container) => container.make(HttpGateway));
|
|
15733
14186
|
}
|
|
@@ -15740,7 +14193,7 @@ var InertiaServiceProvider = class extends ServiceProvider {
|
|
|
15740
14193
|
// ../Log/dist/index.js
|
|
15741
14194
|
import pino2 from "pino";
|
|
15742
14195
|
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2, readdirSync as readdirSync5, rmSync } from "fs";
|
|
15743
|
-
import { basename as
|
|
14196
|
+
import { basename as basename2, dirname as dirname6, extname as extname3, join as join11 } from "path";
|
|
15744
14197
|
import { Writable } from "stream";
|
|
15745
14198
|
import "pino";
|
|
15746
14199
|
var rootKey = {};
|
|
@@ -15862,12 +14315,12 @@ function localDay(date) {
|
|
|
15862
14315
|
}
|
|
15863
14316
|
var DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
15864
14317
|
var DailyRotatingStream = class extends Writable {
|
|
15865
|
-
constructor(basePath, days,
|
|
14318
|
+
constructor(basePath, days, now5 = () => /* @__PURE__ */ new Date()) {
|
|
15866
14319
|
super();
|
|
15867
14320
|
this.days = days;
|
|
15868
|
-
this.now =
|
|
15869
|
-
this.dir =
|
|
15870
|
-
this.stem =
|
|
14321
|
+
this.now = now5;
|
|
14322
|
+
this.dir = dirname6(basePath);
|
|
14323
|
+
this.stem = basename2(basePath, extname3(basePath) || void 0);
|
|
15871
14324
|
mkdirSync2(this.dir, { recursive: true });
|
|
15872
14325
|
}
|
|
15873
14326
|
days;
|
|
@@ -15932,8 +14385,8 @@ var DailyRotatingStream = class extends Writable {
|
|
|
15932
14385
|
prune() {
|
|
15933
14386
|
if (this.days <= 0) return;
|
|
15934
14387
|
const prefix = `${this.stem}-`;
|
|
15935
|
-
const
|
|
15936
|
-
const cutoff = new Date(
|
|
14388
|
+
const now5 = this.now();
|
|
14389
|
+
const cutoff = new Date(now5.getFullYear(), now5.getMonth(), now5.getDate() - (this.days - 1)).getTime();
|
|
15937
14390
|
for (const file of readdirSync5(this.dir)) {
|
|
15938
14391
|
if (!file.startsWith(prefix) || !file.endsWith(".log")) continue;
|
|
15939
14392
|
const match = DATE_PATTERN.exec(file.slice(prefix.length, -".log".length));
|
|
@@ -15996,9 +14449,9 @@ function createSingleChannel(path, minimumLevel = "debug") {
|
|
|
15996
14449
|
destination.on("error", (error) => reportLogWriteFailure(path, error));
|
|
15997
14450
|
return new PinoLogger(pino2(PINO_OPTIONS, destination), minimumLevel);
|
|
15998
14451
|
}
|
|
15999
|
-
function createDailyChannel(path, days = 14, minimumLevel = "debug",
|
|
14452
|
+
function createDailyChannel(path, days = 14, minimumLevel = "debug", now5) {
|
|
16000
14453
|
assertLogLevel(minimumLevel);
|
|
16001
|
-
const stream = new DailyRotatingStream(path, days,
|
|
14454
|
+
const stream = new DailyRotatingStream(path, days, now5);
|
|
16002
14455
|
return new PinoLogger(pino2(PINO_OPTIONS, stream), minimumLevel);
|
|
16003
14456
|
}
|
|
16004
14457
|
function createStderrChannel(minimumLevel = "debug") {
|
|
@@ -16701,7 +15154,8 @@ var MailMessage = class {
|
|
|
16701
15154
|
introLines = [];
|
|
16702
15155
|
actionData;
|
|
16703
15156
|
outroLines = [];
|
|
16704
|
-
|
|
15157
|
+
/** Unset: "Regards," and config('app.name'), as Laravel's template. */
|
|
15158
|
+
salutationLine;
|
|
16705
15159
|
toAddresses = [];
|
|
16706
15160
|
ccAddresses = [];
|
|
16707
15161
|
bccAddresses = [];
|
|
@@ -16766,11 +15220,18 @@ var MailMessage = class {
|
|
|
16766
15220
|
html2.push(`<p>${escapeHtml2(line)}</p>`);
|
|
16767
15221
|
text3.push(line);
|
|
16768
15222
|
}
|
|
16769
|
-
|
|
16770
|
-
|
|
15223
|
+
const salutation = this.salutationLine ?? `Regards,
|
|
15224
|
+
${appName()}`;
|
|
15225
|
+
html2.push(`<p>${escapeHtml2(salutation).replace(/\n/g, "<br>")}</p>`);
|
|
15226
|
+
text3.push(salutation);
|
|
16771
15227
|
return { html: `<!doctype html><html><body>${html2.join("\n")}</body></html>`, text: text3.join("\n\n") };
|
|
16772
15228
|
}
|
|
16773
15229
|
};
|
|
15230
|
+
function appName() {
|
|
15231
|
+
const container = currentContainer();
|
|
15232
|
+
const name = container?.bound(ConfigRepository) ? container.make(ConfigRepository).get("app.name") : void 0;
|
|
15233
|
+
return typeof name === "string" && name !== "" ? name : "Oriel";
|
|
15234
|
+
}
|
|
16774
15235
|
function escapeHtml2(value2) {
|
|
16775
15236
|
return value2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
16776
15237
|
}
|
|
@@ -16841,9 +15302,9 @@ function wrapRow(row, db) {
|
|
|
16841
15302
|
readAt: row.read_at ? parseStoredDate2(row.read_at) : void 0,
|
|
16842
15303
|
async markAsRead() {
|
|
16843
15304
|
if (record.readAt) return;
|
|
16844
|
-
const
|
|
16845
|
-
await db.table(NOTIFICATIONS_TABLE).where("id", record.id).update({ read_at:
|
|
16846
|
-
record.readAt =
|
|
15305
|
+
const now5 = /* @__PURE__ */ new Date();
|
|
15306
|
+
await db.table(NOTIFICATIONS_TABLE).where("id", record.id).update({ read_at: now5, updated_at: now5 });
|
|
15307
|
+
record.readAt = now5;
|
|
16847
15308
|
},
|
|
16848
15309
|
async markAsUnread() {
|
|
16849
15310
|
if (!record.readAt) return;
|
|
@@ -16875,7 +15336,7 @@ var DatabaseNotificationChannel = class {
|
|
|
16875
15336
|
const model = notifiable;
|
|
16876
15337
|
if (typeof model.getKey !== "function") throw new NotDatabaseNotifiableError(notifiable.constructor.name);
|
|
16877
15338
|
const db = requireDatabase();
|
|
16878
|
-
const
|
|
15339
|
+
const now5 = /* @__PURE__ */ new Date();
|
|
16879
15340
|
await db.table(NOTIFICATIONS_TABLE).insert({
|
|
16880
15341
|
id: notification.id ?? randomUUID4(),
|
|
16881
15342
|
type: notification.constructor.name,
|
|
@@ -16883,8 +15344,8 @@ var DatabaseNotificationChannel = class {
|
|
|
16883
15344
|
notifiable_id: model.getKey(),
|
|
16884
15345
|
data: JSON.stringify(data),
|
|
16885
15346
|
read_at: null,
|
|
16886
|
-
created_at:
|
|
16887
|
-
updated_at:
|
|
15347
|
+
created_at: now5,
|
|
15348
|
+
updated_at: now5
|
|
16888
15349
|
});
|
|
16889
15350
|
}
|
|
16890
15351
|
};
|
|
@@ -17226,7 +15687,7 @@ import { randomUUID as randomUUID24 } from "crypto";
|
|
|
17226
15687
|
import { Redis as Redis2 } from "ioredis";
|
|
17227
15688
|
import { randomUUID as randomUUID32 } from "crypto";
|
|
17228
15689
|
import { setTimeout as sleep4 } from "timers/promises";
|
|
17229
|
-
import { existsSync as
|
|
15690
|
+
import { existsSync as existsSync8, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
17230
15691
|
import { join as join12 } from "path";
|
|
17231
15692
|
import { pathToFileURL as pathToFileURL6 } from "url";
|
|
17232
15693
|
var QueueError = class extends Error {
|
|
@@ -17331,7 +15792,7 @@ function resolveClass(registry2, name) {
|
|
|
17331
15792
|
if (!registry2.has(name)) throw new JobClassNotFoundError(name);
|
|
17332
15793
|
return registry2.resolve(name);
|
|
17333
15794
|
}
|
|
17334
|
-
function
|
|
15795
|
+
function isPlainObject2(value2) {
|
|
17335
15796
|
const proto = Object.getPrototypeOf(value2);
|
|
17336
15797
|
return proto === Object.prototype || proto === null;
|
|
17337
15798
|
}
|
|
@@ -17385,7 +15846,7 @@ function serializeValue(value2, registry2, path = "data", seen = /* @__PURE__ */
|
|
|
17385
15846
|
}
|
|
17386
15847
|
return { [TAG]: "model", class: name2, key: serializeValue(object.getKey(), registry2, `${path}.key`, seen) ?? null };
|
|
17387
15848
|
}
|
|
17388
|
-
if (
|
|
15849
|
+
if (isPlainObject2(object)) {
|
|
17389
15850
|
const fields = serializeFields(object, registry2, path, seen);
|
|
17390
15851
|
return Object.hasOwn(fields, TAG) ? { [TAG]: "object", value: fields } : fields;
|
|
17391
15852
|
}
|
|
@@ -17719,8 +16180,8 @@ var CallQueuedHandler = class {
|
|
|
17719
16180
|
const lock = payload.uniqueLock;
|
|
17720
16181
|
if (!lock || !this.container.bound(CacheManager)) return;
|
|
17721
16182
|
const cache2 = this.container.make(CacheManager);
|
|
17722
|
-
const
|
|
17723
|
-
await
|
|
16183
|
+
const store = lock.store !== void 0 ? cache2.store(lock.store) : cache2;
|
|
16184
|
+
await store.lock(lock.key).forceRelease();
|
|
17724
16185
|
}
|
|
17725
16186
|
};
|
|
17726
16187
|
var WithoutOverlapping = class {
|
|
@@ -17957,34 +16418,34 @@ var DatabaseQueue = class extends QueueBase {
|
|
|
17957
16418
|
});
|
|
17958
16419
|
}
|
|
17959
16420
|
async pushToDatabase(queue, payload, delaySeconds2, attempts, db = this.database()) {
|
|
17960
|
-
const
|
|
16421
|
+
const now5 = this.currentTime();
|
|
17961
16422
|
const id = await db.table(this.table).insertGetId({
|
|
17962
16423
|
queue,
|
|
17963
16424
|
payload: encodePayload({ ...payload, attempts: 0 }),
|
|
17964
16425
|
attempts,
|
|
17965
16426
|
reserved_at: null,
|
|
17966
|
-
available_at:
|
|
17967
|
-
created_at:
|
|
16427
|
+
available_at: now5 + Math.max(0, Math.round(delaySeconds2)),
|
|
16428
|
+
created_at: now5
|
|
17968
16429
|
});
|
|
17969
16430
|
return String(id);
|
|
17970
16431
|
}
|
|
17971
16432
|
/** The oldest available row, or the oldest reservation older than retry_after, whichever has the lower id. */
|
|
17972
16433
|
async getNextAvailableJob(db, queue) {
|
|
17973
|
-
const
|
|
17974
|
-
const available = await db.table(this.table).where("queue", queue).whereNull("reserved_at").where("available_at", "<=",
|
|
17975
|
-
const expired = await db.table(this.table).where("queue", queue).whereNotNull("reserved_at").where("reserved_at", "<=",
|
|
16434
|
+
const now5 = this.currentTime();
|
|
16435
|
+
const available = await db.table(this.table).where("queue", queue).whereNull("reserved_at").where("available_at", "<=", now5).orderBy("id", "asc").lockForUpdate().first();
|
|
16436
|
+
const expired = await db.table(this.table).where("queue", queue).whereNotNull("reserved_at").where("reserved_at", "<=", now5 - this.retryAfter).orderBy("id", "asc").lockForUpdate().first();
|
|
17976
16437
|
if (!available || !expired) return available ?? expired;
|
|
17977
16438
|
return Number(available.id) <= Number(expired.id) ? available : expired;
|
|
17978
16439
|
}
|
|
17979
16440
|
/** Reserves the row only if nobody else changed it since we read it. */
|
|
17980
16441
|
async markJobAsReserved(db, record) {
|
|
17981
|
-
const
|
|
16442
|
+
const now5 = this.currentTime();
|
|
17982
16443
|
const query = db.table(this.table).where("id", record.id).where("attempts", record.attempts);
|
|
17983
16444
|
if (record.reserved_at === null) query.whereNull("reserved_at");
|
|
17984
16445
|
else query.where("reserved_at", record.reserved_at);
|
|
17985
|
-
const affected = await query.update({ reserved_at:
|
|
16446
|
+
const affected = await query.update({ reserved_at: now5, attempts: Number(record.attempts) + 1 });
|
|
17986
16447
|
if (affected === 0) return false;
|
|
17987
|
-
record.reserved_at =
|
|
16448
|
+
record.reserved_at = now5;
|
|
17988
16449
|
record.attempts = Number(record.attempts) + 1;
|
|
17989
16450
|
return true;
|
|
17990
16451
|
}
|
|
@@ -18112,11 +16573,11 @@ var RedisQueue = class extends QueueBase {
|
|
|
18112
16573
|
}
|
|
18113
16574
|
async pop(queue) {
|
|
18114
16575
|
const key = this.key(queue);
|
|
18115
|
-
const
|
|
18116
|
-
await this.redis().eval(MIGRATE_EXPIRED_JOBS, 3, `${key}:delayed`, key, `${key}:notify`,
|
|
18117
|
-
await this.redis().eval(MIGRATE_EXPIRED_JOBS, 3, `${key}:reserved`, key, `${key}:notify`,
|
|
16576
|
+
const now5 = this.now();
|
|
16577
|
+
await this.redis().eval(MIGRATE_EXPIRED_JOBS, 3, `${key}:delayed`, key, `${key}:notify`, now5);
|
|
16578
|
+
await this.redis().eval(MIGRATE_EXPIRED_JOBS, 3, `${key}:reserved`, key, `${key}:notify`, now5);
|
|
18118
16579
|
for (; ; ) {
|
|
18119
|
-
const [job, reserved] = await this.redis().eval(POP, 3, key, `${key}:reserved`, `${key}:notify`,
|
|
16580
|
+
const [job, reserved] = await this.redis().eval(POP, 3, key, `${key}:reserved`, `${key}:notify`, now5 + this.retryAfter);
|
|
18120
16581
|
if (!job || !reserved) return void 0;
|
|
18121
16582
|
try {
|
|
18122
16583
|
return new RedisJob(this.jobContext(), this, job, reserved, this.getQueue(queue));
|
|
@@ -18510,8 +16971,8 @@ var DatabaseBatchRepository = class {
|
|
|
18510
16971
|
await this.database().table(this.table).where("id", id).update({ finished_at: this.now() });
|
|
18511
16972
|
}
|
|
18512
16973
|
async cancel(id) {
|
|
18513
|
-
const
|
|
18514
|
-
await this.database().table(this.table).where("id", id).update({ cancelled_at:
|
|
16974
|
+
const now5 = this.now();
|
|
16975
|
+
await this.database().table(this.table).where("id", id).update({ cancelled_at: now5, finished_at: now5 });
|
|
18515
16976
|
}
|
|
18516
16977
|
async delete(id) {
|
|
18517
16978
|
await this.database().table(this.table).where("id", id).delete();
|
|
@@ -18816,13 +17277,13 @@ var Worker = class _Worker {
|
|
|
18816
17277
|
}
|
|
18817
17278
|
}
|
|
18818
17279
|
};
|
|
18819
|
-
var
|
|
17280
|
+
var EXTENSIONS2 = [".ts", ".js", ".mts", ".mjs"];
|
|
18820
17281
|
function files2(directory) {
|
|
18821
17282
|
const found = [];
|
|
18822
17283
|
for (const entry of readdirSync6(directory).sort()) {
|
|
18823
17284
|
const path = join12(directory, entry);
|
|
18824
17285
|
if (statSync3(path).isDirectory()) found.push(...files2(path));
|
|
18825
|
-
else if (
|
|
17286
|
+
else if (EXTENSIONS2.some((extension) => entry.endsWith(extension)) && !entry.endsWith(".d.ts")) found.push(path);
|
|
18826
17287
|
}
|
|
18827
17288
|
return found;
|
|
18828
17289
|
}
|
|
@@ -18830,7 +17291,7 @@ var WORKER_DISCOVERY_DIRECTORIES = ["Events", "Listeners", "Mail", "Notification
|
|
|
18830
17291
|
var isClass2 = (value2) => typeof value2 === "function" && /^class[\s{]/.test(Function.prototype.toString.call(value2));
|
|
18831
17292
|
var isJobClass = (value2) => typeof value2.prototype.handle === "function";
|
|
18832
17293
|
async function discoverClasses(directory, registry2, filter = () => true) {
|
|
18833
|
-
if (!
|
|
17294
|
+
if (!existsSync8(directory)) return [];
|
|
18834
17295
|
const names = [];
|
|
18835
17296
|
for (const file of files2(directory)) {
|
|
18836
17297
|
const module = await import(pathToFileURL6(file).href);
|
|
@@ -19041,7 +17502,9 @@ var QueueServiceProvider = class extends ServiceProvider {
|
|
|
19041
17502
|
};
|
|
19042
17503
|
|
|
19043
17504
|
// ../Routing/dist/index.js
|
|
17505
|
+
import { createHmac as createHmac4, timingSafeEqual as timingSafeEqual4 } from "crypto";
|
|
19044
17506
|
import { pathToFileURL as pathToFileURL7 } from "url";
|
|
17507
|
+
import { createHash as createHash8 } from "crypto";
|
|
19045
17508
|
var NotFoundHttpError = class extends Error {
|
|
19046
17509
|
kind = "Http";
|
|
19047
17510
|
status = 404;
|
|
@@ -19095,6 +17558,24 @@ var RoutingError = class extends Error {
|
|
|
19095
17558
|
status = 500;
|
|
19096
17559
|
name = "RoutingError";
|
|
19097
17560
|
};
|
|
17561
|
+
var InvalidUrlSignatureError = class extends Error {
|
|
17562
|
+
kind = "Http";
|
|
17563
|
+
status = 403;
|
|
17564
|
+
name = "InvalidUrlSignatureError";
|
|
17565
|
+
constructor() {
|
|
17566
|
+
super("Invalid signature.");
|
|
17567
|
+
}
|
|
17568
|
+
};
|
|
17569
|
+
var ThrottleRequestsError = class extends Error {
|
|
17570
|
+
constructor(headers = {}) {
|
|
17571
|
+
super("Too Many Attempts.");
|
|
17572
|
+
this.headers = headers;
|
|
17573
|
+
}
|
|
17574
|
+
headers;
|
|
17575
|
+
kind = "Http";
|
|
17576
|
+
status = 429;
|
|
17577
|
+
name = "ThrottleRequestsError";
|
|
17578
|
+
};
|
|
19098
17579
|
async function toResponse(request2, value2) {
|
|
19099
17580
|
if (value2 instanceof Response) return value2;
|
|
19100
17581
|
if (value2 === null || value2 === void 0) return new Response(null, { status: 204 });
|
|
@@ -19339,6 +17820,7 @@ var RouteDefinition = class {
|
|
|
19339
17820
|
this.#name = (this.#name ?? "") + name;
|
|
19340
17821
|
return this;
|
|
19341
17822
|
}
|
|
17823
|
+
/** middleware('auth', 'verified') or middleware(['auth', 'verified']). */
|
|
19342
17824
|
middleware(...middleware) {
|
|
19343
17825
|
this.#middleware.push(...middleware.flat());
|
|
19344
17826
|
return this;
|
|
@@ -19796,7 +18278,7 @@ var BaseRouter = class {
|
|
|
19796
18278
|
}
|
|
19797
18279
|
};
|
|
19798
18280
|
var VALID_URL = /^(#|\/\/|https?:\/\/|(mailto|tel|sms):)/i;
|
|
19799
|
-
var
|
|
18281
|
+
var isPlainObject3 = (value2) => {
|
|
19800
18282
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) return false;
|
|
19801
18283
|
const prototype = Object.getPrototypeOf(value2);
|
|
19802
18284
|
return prototype === Object.prototype || prototype === null;
|
|
@@ -19805,7 +18287,7 @@ function buildQuery2(values) {
|
|
|
19805
18287
|
const pairs = [];
|
|
19806
18288
|
const add = (key, value2) => {
|
|
19807
18289
|
if (value2 === null || value2 === void 0) return;
|
|
19808
|
-
if (typeof value2 === "object" && (Array.isArray(value2) ||
|
|
18290
|
+
if (typeof value2 === "object" && (Array.isArray(value2) || isPlainObject3(value2))) {
|
|
19809
18291
|
for (const [child, nested] of Object.entries(value2)) add(`${key}[${child}]`, nested);
|
|
19810
18292
|
return;
|
|
19811
18293
|
}
|
|
@@ -19821,6 +18303,17 @@ function routeKey(value2, field) {
|
|
|
19821
18303
|
if (field !== void 0) return typeof model.getAttribute === "function" ? model.getAttribute(field) : model[field];
|
|
19822
18304
|
return typeof model.getRouteKey === "function" ? model.getRouteKey() : value2;
|
|
19823
18305
|
}
|
|
18306
|
+
function sign(url2, key) {
|
|
18307
|
+
return createHmac4("sha256", key).update(url2).digest("hex");
|
|
18308
|
+
}
|
|
18309
|
+
function safeEquals(expected, given) {
|
|
18310
|
+
const a = Buffer.from(expected);
|
|
18311
|
+
const b = Buffer.from(given);
|
|
18312
|
+
return a.length === b.length && timingSafeEqual4(a, b);
|
|
18313
|
+
}
|
|
18314
|
+
function availableAt(expiration) {
|
|
18315
|
+
return expiration instanceof Date ? Math.floor(expiration.getTime() / 1e3) : Math.floor(Date.now() / 1e3) + expiration;
|
|
18316
|
+
}
|
|
19824
18317
|
var BaseUrlGenerator = class {
|
|
19825
18318
|
constructor(router, container) {
|
|
19826
18319
|
this.router = router;
|
|
@@ -19849,8 +18342,8 @@ var BaseUrlGenerator = class {
|
|
|
19849
18342
|
route(name, parameters, absolute = true) {
|
|
19850
18343
|
const route2 = this.router.getByName(name);
|
|
19851
18344
|
if (route2 === void 0) throw new RouteNotDefinedError(name);
|
|
19852
|
-
const named =
|
|
19853
|
-
const positional = Array.isArray(parameters) ? [...parameters] : parameters === void 0 || parameters === null ||
|
|
18345
|
+
const named = isPlainObject3(parameters) ? { ...parameters } : {};
|
|
18346
|
+
const positional = Array.isArray(parameters) ? [...parameters] : parameters === void 0 || parameters === null || isPlainObject3(parameters) ? [] : [parameters];
|
|
19854
18347
|
const values = /* @__PURE__ */ new Map();
|
|
19855
18348
|
const missing = [];
|
|
19856
18349
|
for (const parameter of route2.parameters) {
|
|
@@ -19908,6 +18401,69 @@ var BaseUrlGenerator = class {
|
|
|
19908
18401
|
hasRoute(name) {
|
|
19909
18402
|
return this.router.getByName(name) !== void 0;
|
|
19910
18403
|
}
|
|
18404
|
+
/**
|
|
18405
|
+
* Laravel's URL::signedRoute(): the route URL with its parameters sorted by name, then a `signature` query (the
|
|
18406
|
+
* HMAC-SHA256 of that URL, keyed by APP_KEY). `expiration` (a Date, or seconds from now) adds `expires`.
|
|
18407
|
+
* `absolute: false` signs the path only (checked by `signed:relative`).
|
|
18408
|
+
*/
|
|
18409
|
+
signedRoute(name, parameters, expiration, absolute = true) {
|
|
18410
|
+
const named = this.#namedParameters(name, parameters);
|
|
18411
|
+
for (const reserved of ["signature", "expires"]) {
|
|
18412
|
+
if (Object.hasOwn(named, reserved)) {
|
|
18413
|
+
throw new RoutingError(`"${reserved}" is a reserved parameter when generating signed routes. Please rename your route parameter.`);
|
|
18414
|
+
}
|
|
18415
|
+
}
|
|
18416
|
+
if (expiration !== void 0) named.expires = availableAt(expiration);
|
|
18417
|
+
const sorted = Object.fromEntries(Object.keys(named).sort().map((key) => [key, named[key]]));
|
|
18418
|
+
const signature = sign(this.route(name, sorted, absolute), this.#signingKeys()[0]);
|
|
18419
|
+
return this.route(name, { ...sorted, signature }, absolute);
|
|
18420
|
+
}
|
|
18421
|
+
/** Laravel's URL::temporarySignedRoute(): a signed URL that expires at `expiration` (a Date, or seconds from now). */
|
|
18422
|
+
temporarySignedRoute(name, expiration, parameters, absolute = true) {
|
|
18423
|
+
return this.signedRoute(name, parameters, expiration, absolute);
|
|
18424
|
+
}
|
|
18425
|
+
/** The request URL carries a correct signature (current or previous APP_KEY) that hasn't expired. */
|
|
18426
|
+
hasValidSignature(request2, absolute = true) {
|
|
18427
|
+
return this.hasCorrectSignature(request2, absolute) && this.signatureHasNotExpired(request2);
|
|
18428
|
+
}
|
|
18429
|
+
/** The signature matches the URL without its `signature` query, in a constant-time comparison. */
|
|
18430
|
+
hasCorrectSignature(request2, absolute = true) {
|
|
18431
|
+
const full = new URL(request2.fullUrl());
|
|
18432
|
+
const path = request2.path();
|
|
18433
|
+
const url2 = absolute ? request2.url() : path === "/" ? "/" : `/${path}`;
|
|
18434
|
+
const query = full.search.slice(1).split("&").filter((pair) => pair !== "" && pair.split("=")[0] !== "signature").join("&");
|
|
18435
|
+
const original = query === "" ? url2 : `${url2}?${query}`;
|
|
18436
|
+
const given = full.searchParams.get("signature") ?? "";
|
|
18437
|
+
return this.#signingKeys().some((key) => safeEquals(sign(original, key), given));
|
|
18438
|
+
}
|
|
18439
|
+
/** No `expires` query, or one that is still in the future. */
|
|
18440
|
+
signatureHasNotExpired(request2) {
|
|
18441
|
+
const expires = new URL(request2.fullUrl()).searchParams.get("expires");
|
|
18442
|
+
if (expires === null || expires === "") return true;
|
|
18443
|
+
const at = Number(expires);
|
|
18444
|
+
return Number.isFinite(at) && Math.floor(Date.now() / 1e3) <= at;
|
|
18445
|
+
}
|
|
18446
|
+
/** Named parameters: an object as is, positional values (a list or one value) by the route's parameter names. */
|
|
18447
|
+
#namedParameters(name, parameters) {
|
|
18448
|
+
if (isPlainObject3(parameters)) return { ...parameters };
|
|
18449
|
+
const route2 = this.router.getByName(name);
|
|
18450
|
+
if (route2 === void 0) throw new RouteNotDefinedError(name);
|
|
18451
|
+
const values = parameters === void 0 || parameters === null ? [] : Array.isArray(parameters) ? parameters : [parameters];
|
|
18452
|
+
const named = {};
|
|
18453
|
+
route2.parameters.forEach((parameter, index) => {
|
|
18454
|
+
if (index < values.length) named[parameter.name] = values[index];
|
|
18455
|
+
});
|
|
18456
|
+
return named;
|
|
18457
|
+
}
|
|
18458
|
+
/** The Encrypter's key, then its previous keys (config app.previous_keys), so rotated keys still verify. */
|
|
18459
|
+
#signingKeys() {
|
|
18460
|
+
const scope = this.#scope();
|
|
18461
|
+
if (scope === void 0 || !scope.bound(Encrypter)) {
|
|
18462
|
+
throw new RoutingError("Signed URLs need the Encrypter: set APP_KEY (oriel key:generate).");
|
|
18463
|
+
}
|
|
18464
|
+
const encrypter = scope.make(Encrypter);
|
|
18465
|
+
return typeof encrypter.getAllKeys === "function" ? encrypter.getAllKeys() : [encrypter.getKey()];
|
|
18466
|
+
}
|
|
19911
18467
|
#join(path, absolute) {
|
|
19912
18468
|
const trimmed = path.replace(/^\/+|\/+$/g, "");
|
|
19913
18469
|
if (!absolute) return `/${trimmed}`;
|
|
@@ -19940,6 +18496,60 @@ function healthResponse() {
|
|
|
19940
18496
|
const html2 = '<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n<title>Application up</title>\n</head>\n<body><h1>Application up</h1></body>\n</html>';
|
|
19941
18497
|
return new Response(html2, { status: 200, headers: { "content-type": "text/html; charset=utf-8" } });
|
|
19942
18498
|
}
|
|
18499
|
+
var sha12 = (value2) => createHash8("sha1").update(value2).digest("hex");
|
|
18500
|
+
function withHeaders2(response2, headers) {
|
|
18501
|
+
try {
|
|
18502
|
+
for (const [name, value2] of Object.entries(headers)) response2.headers.set(name, value2);
|
|
18503
|
+
return response2;
|
|
18504
|
+
} catch {
|
|
18505
|
+
const copy = new Headers(response2.headers);
|
|
18506
|
+
for (const [name, value2] of Object.entries(headers)) copy.set(name, value2);
|
|
18507
|
+
return new Response(response2.body, { status: response2.status, statusText: response2.statusText, headers: copy });
|
|
18508
|
+
}
|
|
18509
|
+
}
|
|
18510
|
+
var ThrottleRequests = class {
|
|
18511
|
+
async handle(request2, next, maxAttempts = "60", decayMinutes = "1", prefix = "") {
|
|
18512
|
+
const max = Number(maxAttempts);
|
|
18513
|
+
const decay = Number(decayMinutes);
|
|
18514
|
+
if (maxAttempts.trim() === "" || !Number.isInteger(max) || max < 0 || decayMinutes.trim() === "" || !Number.isFinite(decay) || decay <= 0) {
|
|
18515
|
+
throw new RoutingError(
|
|
18516
|
+
`Invalid throttle parameters "${maxAttempts},${decayMinutes}": use throttle:<maxAttempts>,<decayMinutes>[,<prefix>] (named rate limiters are not supported).`
|
|
18517
|
+
);
|
|
18518
|
+
}
|
|
18519
|
+
const limiter = inject(RateLimiter);
|
|
18520
|
+
const key = prefix + this.resolveRequestSignature(request2);
|
|
18521
|
+
if (await limiter.tooManyAttempts(key, max)) {
|
|
18522
|
+
const retryAfter = await limiter.availableIn(key);
|
|
18523
|
+
throw new ThrottleRequestsError({
|
|
18524
|
+
"X-RateLimit-Limit": String(max),
|
|
18525
|
+
"X-RateLimit-Remaining": "0",
|
|
18526
|
+
"Retry-After": String(retryAfter),
|
|
18527
|
+
"X-RateLimit-Reset": String(Math.floor(Date.now() / 1e3) + retryAfter)
|
|
18528
|
+
});
|
|
18529
|
+
}
|
|
18530
|
+
await limiter.hit(key, Math.round(decay * 60));
|
|
18531
|
+
const response2 = await next(request2);
|
|
18532
|
+
return withHeaders2(response2, {
|
|
18533
|
+
"X-RateLimit-Limit": String(max),
|
|
18534
|
+
"X-RateLimit-Remaining": String(await limiter.remaining(key, max))
|
|
18535
|
+
});
|
|
18536
|
+
}
|
|
18537
|
+
/** The signed-in user's identifier, else the client IP, hashed (Laravel's resolveRequestSignature()). */
|
|
18538
|
+
resolveRequestSignature(request2) {
|
|
18539
|
+
const user = request2.user();
|
|
18540
|
+
if (user !== void 0 && user !== null && typeof user.getAuthIdentifier === "function") {
|
|
18541
|
+
return sha12(String(user.getAuthIdentifier()));
|
|
18542
|
+
}
|
|
18543
|
+
return sha12(`|${request2.ip() ?? ""}`);
|
|
18544
|
+
}
|
|
18545
|
+
};
|
|
18546
|
+
var ValidateSignature = class {
|
|
18547
|
+
async handle(request2, next, ...parameters) {
|
|
18548
|
+
const absolute = parameters[0] !== "relative";
|
|
18549
|
+
if (inject(UrlGenerator).hasValidSignature(request2, absolute)) return next(request2);
|
|
18550
|
+
throw new InvalidUrlSignatureError();
|
|
18551
|
+
}
|
|
18552
|
+
};
|
|
19943
18553
|
var RoutingServiceProvider = class extends ServiceProvider {
|
|
19944
18554
|
register() {
|
|
19945
18555
|
this.app.singleton(Router, () => new BaseRouter(this.app));
|
|
@@ -19957,23 +18567,28 @@ var RoutingServiceProvider = class extends ServiceProvider {
|
|
|
19957
18567
|
* when the route files run.
|
|
19958
18568
|
*/
|
|
19959
18569
|
boot() {
|
|
18570
|
+
this.app.make(Router).aliasMiddleware("signed", ValidateSignature).aliasMiddleware("throttle", ThrottleRequests);
|
|
19960
18571
|
this.app.booted(async () => {
|
|
19961
18572
|
if (!this.app.bound(RoutingPaths)) return;
|
|
19962
18573
|
const { web, api, health, apiPrefix } = this.app.make(RoutingPaths);
|
|
19963
18574
|
const router = this.app.make(Router);
|
|
19964
18575
|
if (health !== void 0) router.get(health, () => healthResponse());
|
|
19965
|
-
if (web !== void 0) await router.middleware("web").group(() =>
|
|
19966
|
-
if (api !== void 0) await router.prefix(apiPrefix).middleware("api").group(() =>
|
|
18576
|
+
if (web !== void 0) await router.middleware("web").group(() => this.#load(router, web));
|
|
18577
|
+
if (api !== void 0) await router.prefix(apiPrefix).middleware("api").group(() => this.#load(router, api));
|
|
19967
18578
|
});
|
|
19968
18579
|
}
|
|
18580
|
+
/** One file or several, in order: each is imported afresh for this application (a nested import is not). */
|
|
18581
|
+
async #load(router, files3) {
|
|
18582
|
+
for (const file of [files3].flat()) await loadRoutesFrom(this.app, router, file);
|
|
18583
|
+
}
|
|
19969
18584
|
};
|
|
19970
18585
|
|
|
19971
18586
|
// ../Session/dist/index.js
|
|
19972
|
-
import { mkdir as
|
|
18587
|
+
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile4, rename as rename3, rm as rm3, stat as stat3, writeFile as writeFile7 } from "fs/promises";
|
|
19973
18588
|
import { join as join13 } from "path";
|
|
19974
18589
|
import { Redis as Redis3 } from "ioredis";
|
|
19975
18590
|
import { randomInt } from "crypto";
|
|
19976
|
-
import { timingSafeEqual as
|
|
18591
|
+
import { timingSafeEqual as timingSafeEqual5 } from "crypto";
|
|
19977
18592
|
var unique = (values) => [...new Set(values)];
|
|
19978
18593
|
var Store = class {
|
|
19979
18594
|
#id = "";
|
|
@@ -20212,18 +18827,18 @@ var FileSessionHandler = class {
|
|
|
20212
18827
|
if (!VALID_ID.test(id)) return "";
|
|
20213
18828
|
const file = join13(this.path, id);
|
|
20214
18829
|
try {
|
|
20215
|
-
const { mtimeMs } = await
|
|
18830
|
+
const { mtimeMs } = await stat3(file);
|
|
20216
18831
|
if (mtimeMs < this.clock() - this.minutes * 6e4) return "";
|
|
20217
|
-
return await
|
|
18832
|
+
return await readFile4(file, "utf8");
|
|
20218
18833
|
} catch {
|
|
20219
18834
|
return "";
|
|
20220
18835
|
}
|
|
20221
18836
|
}
|
|
20222
18837
|
async write(id, data) {
|
|
20223
18838
|
if (!VALID_ID.test(id)) return;
|
|
20224
|
-
await
|
|
18839
|
+
await mkdir6(this.path, { recursive: true });
|
|
20225
18840
|
const temporary = join13(this.path, `.${id}.${Str.random(8)}.tmp`);
|
|
20226
|
-
await
|
|
18841
|
+
await writeFile7(temporary, data, "utf8");
|
|
20227
18842
|
await rename3(temporary, join13(this.path, id));
|
|
20228
18843
|
}
|
|
20229
18844
|
async destroy(id) {
|
|
@@ -20234,7 +18849,7 @@ var FileSessionHandler = class {
|
|
|
20234
18849
|
const files3 = await readdir3(this.path).catch(() => []);
|
|
20235
18850
|
for (const file of files3) {
|
|
20236
18851
|
if (!VALID_ID.test(file)) continue;
|
|
20237
|
-
const { mtimeMs } = await
|
|
18852
|
+
const { mtimeMs } = await stat3(join13(this.path, file)).catch(() => ({ mtimeMs: Number.POSITIVE_INFINITY }));
|
|
20238
18853
|
if (mtimeMs <= expiration) await rm3(join13(this.path, file), { force: true });
|
|
20239
18854
|
}
|
|
20240
18855
|
}
|
|
@@ -20542,7 +19157,7 @@ var StartSession = class {
|
|
|
20542
19157
|
function equals3(known, user) {
|
|
20543
19158
|
const a = Buffer.from(known);
|
|
20544
19159
|
const b = Buffer.from(user);
|
|
20545
|
-
return a.length === b.length &&
|
|
19160
|
+
return a.length === b.length && timingSafeEqual5(a, b);
|
|
20546
19161
|
}
|
|
20547
19162
|
var VerifyCsrfToken = class {
|
|
20548
19163
|
/** URIs (wildcards allowed) excluded from the check, in addition to config('http.csrf_except'). */
|
|
@@ -20644,15 +19259,15 @@ var SessionFacade = facade(Session, {
|
|
|
20644
19259
|
extend: (driver, factory) => inject(SessionManager).extend(driver, factory)
|
|
20645
19260
|
});
|
|
20646
19261
|
function session(key, defaultValue) {
|
|
20647
|
-
const
|
|
20648
|
-
if (key === void 0) return
|
|
20649
|
-
if (typeof key === "string") return
|
|
20650
|
-
|
|
19262
|
+
const store = inject(Session);
|
|
19263
|
+
if (key === void 0) return store;
|
|
19264
|
+
if (typeof key === "string") return store.get(key, defaultValue);
|
|
19265
|
+
store.put(key);
|
|
20651
19266
|
return void 0;
|
|
20652
19267
|
}
|
|
20653
19268
|
function old(key, defaultValue) {
|
|
20654
|
-
const
|
|
20655
|
-
return
|
|
19269
|
+
const store = scopeSession();
|
|
19270
|
+
return store === void 0 ? defaultValue : store.getOldInput(key, defaultValue);
|
|
20656
19271
|
}
|
|
20657
19272
|
function csrfToken() {
|
|
20658
19273
|
return inject(Session).token();
|
|
@@ -20705,6 +19320,23 @@ var ValidationErrorImpl = class extends Error {
|
|
|
20705
19320
|
status = 422;
|
|
20706
19321
|
name = "ValidationError";
|
|
20707
19322
|
};
|
|
19323
|
+
var ValidationException = class _ValidationException extends ValidationErrorImpl {
|
|
19324
|
+
/** Messages per field, each a string or a list. */
|
|
19325
|
+
static withMessages(messages) {
|
|
19326
|
+
const errors2 = Object.fromEntries(Object.entries(messages).map(([field, list3]) => [field, typeof list3 === "string" ? [list3] : [...list3]]));
|
|
19327
|
+
return new _ValidationException(errors2);
|
|
19328
|
+
}
|
|
19329
|
+
constructor(errors2, errorBag = "default", redirectTo2) {
|
|
19330
|
+
super(errors2, errorBag, redirectTo2);
|
|
19331
|
+
this.message = summarize(errors2);
|
|
19332
|
+
}
|
|
19333
|
+
};
|
|
19334
|
+
function summarize(errors2) {
|
|
19335
|
+
const messages = Object.values(errors2).flat();
|
|
19336
|
+
if (messages.length === 0) return "The given data was invalid.";
|
|
19337
|
+
const more = messages.length - 1;
|
|
19338
|
+
return more === 0 ? messages[0] : `${messages[0]} (and ${more} more ${more === 1 ? "error" : "errors"})`;
|
|
19339
|
+
}
|
|
20708
19340
|
var AuthorizationErrorImpl = class extends Error {
|
|
20709
19341
|
kind = "Authorization";
|
|
20710
19342
|
status = 403;
|
|
@@ -20780,6 +19412,13 @@ var DEFAULT_MESSAGES = {
|
|
|
20780
19412
|
alpha_num: "The :attribute field must only contain letters and numbers.",
|
|
20781
19413
|
alpha_dash: "The :attribute field must only contain letters, numbers, dashes and underscores.",
|
|
20782
19414
|
regex: "The :attribute field format is invalid.",
|
|
19415
|
+
lowercase: "The :attribute field must be lowercase.",
|
|
19416
|
+
uppercase: "The :attribute field must be uppercase.",
|
|
19417
|
+
current_password: "The password is incorrect.",
|
|
19418
|
+
"password.letters": "The :attribute field must contain at least one letter.",
|
|
19419
|
+
"password.mixed": "The :attribute field must contain at least one uppercase and one lowercase letter.",
|
|
19420
|
+
"password.numbers": "The :attribute field must contain at least one number.",
|
|
19421
|
+
"password.symbols": "The :attribute field must contain at least one symbol.",
|
|
20783
19422
|
confirmed: "The :attribute field confirmation does not match.",
|
|
20784
19423
|
same: "The :attribute field must match :other.",
|
|
20785
19424
|
different: "The :attribute field must be different from :other.",
|
|
@@ -20845,6 +19484,17 @@ var MessageBagImpl = class {
|
|
|
20845
19484
|
return structuredClone(this.items);
|
|
20846
19485
|
}
|
|
20847
19486
|
};
|
|
19487
|
+
var authRules = {
|
|
19488
|
+
current_password: {
|
|
19489
|
+
validate: async (ctx) => {
|
|
19490
|
+
const guard2 = inject(AuthFactory).guard(ctx.parameters[0]);
|
|
19491
|
+
if (await guard2.guest()) return false;
|
|
19492
|
+
const user = await guard2.user();
|
|
19493
|
+
return user !== void 0 && typeof ctx.value === "string" && inject(Hasher).check(ctx.value, user.getAuthPassword());
|
|
19494
|
+
},
|
|
19495
|
+
messageKey: () => "current_password"
|
|
19496
|
+
}
|
|
19497
|
+
};
|
|
20848
19498
|
function guessColumn(attribute, expandedFromWildcard = false) {
|
|
20849
19499
|
if (!expandedFromWildcard) return attribute;
|
|
20850
19500
|
return attribute.split(".").filter((segment) => !/^\d+$/.test(segment)).at(-1) ?? attribute;
|
|
@@ -21027,8 +19677,8 @@ function resolveDateParam(rule, param, data) {
|
|
|
21027
19677
|
const parsed = parseDate(fieldValue);
|
|
21028
19678
|
if (!Number.isNaN(parsed)) return parsed;
|
|
21029
19679
|
}
|
|
21030
|
-
const
|
|
21031
|
-
if (
|
|
19680
|
+
const relative6 = relativeDate(param);
|
|
19681
|
+
if (relative6 !== void 0) return relative6;
|
|
21032
19682
|
const literal = parseDate(param);
|
|
21033
19683
|
if (!Number.isNaN(literal)) return literal;
|
|
21034
19684
|
if (FIELD_REFERENCE_RE.test(param)) return Number.NaN;
|
|
@@ -21065,6 +19715,14 @@ var formatRules = {
|
|
|
21065
19715
|
validate: (ctx) => typeof ctx.value === "string" && ALPHA_DASH_RE.test(ctx.value),
|
|
21066
19716
|
messageKey: () => "alpha_dash"
|
|
21067
19717
|
},
|
|
19718
|
+
lowercase: {
|
|
19719
|
+
validate: (ctx) => (typeof ctx.value === "string" || typeof ctx.value === "number") && String(ctx.value).toLowerCase() === String(ctx.value),
|
|
19720
|
+
messageKey: () => "lowercase"
|
|
19721
|
+
},
|
|
19722
|
+
uppercase: {
|
|
19723
|
+
validate: (ctx) => (typeof ctx.value === "string" || typeof ctx.value === "number") && String(ctx.value).toUpperCase() === String(ctx.value),
|
|
19724
|
+
messageKey: () => "uppercase"
|
|
19725
|
+
},
|
|
21068
19726
|
regex: {
|
|
21069
19727
|
validate: (ctx) => typeof ctx.value === "string" && compileRegex(ctx.parameters[0] ?? "").test(ctx.value),
|
|
21070
19728
|
messageKey: () => "regex"
|
|
@@ -21186,7 +19844,7 @@ var typeRules = {
|
|
|
21186
19844
|
function hasAny(ctx, names) {
|
|
21187
19845
|
return names.some((name) => ctx.ruleNames.includes(name));
|
|
21188
19846
|
}
|
|
21189
|
-
function
|
|
19847
|
+
function isPlainObject4(value2) {
|
|
21190
19848
|
if (typeof value2 !== "object" || value2 === null) return false;
|
|
21191
19849
|
const proto = Object.getPrototypeOf(value2);
|
|
21192
19850
|
return proto === Object.prototype || proto === null;
|
|
@@ -21199,7 +19857,7 @@ function measure(ctx) {
|
|
|
21199
19857
|
if (Array.isArray(value2)) return { type: "array", size: value2.length };
|
|
21200
19858
|
if (isUploadedFileLike(value2)) return { type: "file", size: value2.size / 1024 };
|
|
21201
19859
|
if (hasAny(ctx, ["file", "image"])) return { type: "file", size: Number.NaN };
|
|
21202
|
-
if (
|
|
19860
|
+
if (isPlainObject4(value2)) return { type: "array", size: Object.keys(value2).length };
|
|
21203
19861
|
if (hasAny(ctx, ["array"])) return { type: "array", size: stringLength(value2) };
|
|
21204
19862
|
return { type: "string", size: stringLength(value2) };
|
|
21205
19863
|
}
|
|
@@ -21246,7 +19904,81 @@ var builtinRules = {
|
|
|
21246
19904
|
...formatRules,
|
|
21247
19905
|
...sizeRules,
|
|
21248
19906
|
...fileRules,
|
|
21249
|
-
...databaseRules
|
|
19907
|
+
...databaseRules,
|
|
19908
|
+
...authRules
|
|
19909
|
+
};
|
|
19910
|
+
var defaultRule;
|
|
19911
|
+
var PasswordRule = class _PasswordRule {
|
|
19912
|
+
#min;
|
|
19913
|
+
#max;
|
|
19914
|
+
#letters = false;
|
|
19915
|
+
#mixedCase = false;
|
|
19916
|
+
#numbers = false;
|
|
19917
|
+
#symbols = false;
|
|
19918
|
+
constructor(min = 8) {
|
|
19919
|
+
this.#min = Math.max(1, min);
|
|
19920
|
+
}
|
|
19921
|
+
/** A password rule of at least `size` characters: PasswordRule.min(12).mixedCase(). */
|
|
19922
|
+
static min(size) {
|
|
19923
|
+
return new _PasswordRule(size);
|
|
19924
|
+
}
|
|
19925
|
+
static defaults(rule) {
|
|
19926
|
+
if (rule !== void 0) {
|
|
19927
|
+
defaultRule = rule ?? void 0;
|
|
19928
|
+
return;
|
|
19929
|
+
}
|
|
19930
|
+
const resolved = typeof defaultRule === "function" ? defaultRule() : defaultRule;
|
|
19931
|
+
return resolved === void 0 ? new _PasswordRule(8) : resolved.#copy();
|
|
19932
|
+
}
|
|
19933
|
+
min(size) {
|
|
19934
|
+
this.#min = Math.max(1, size);
|
|
19935
|
+
return this;
|
|
19936
|
+
}
|
|
19937
|
+
max(size) {
|
|
19938
|
+
this.#max = size;
|
|
19939
|
+
return this;
|
|
19940
|
+
}
|
|
19941
|
+
/** At least one letter. */
|
|
19942
|
+
letters() {
|
|
19943
|
+
this.#letters = true;
|
|
19944
|
+
return this;
|
|
19945
|
+
}
|
|
19946
|
+
/** At least one uppercase and one lowercase letter. */
|
|
19947
|
+
mixedCase() {
|
|
19948
|
+
this.#mixedCase = true;
|
|
19949
|
+
return this;
|
|
19950
|
+
}
|
|
19951
|
+
/** At least one number. */
|
|
19952
|
+
numbers() {
|
|
19953
|
+
this.#numbers = true;
|
|
19954
|
+
return this;
|
|
19955
|
+
}
|
|
19956
|
+
/** At least one symbol (punctuation, a symbol or a space). */
|
|
19957
|
+
symbols() {
|
|
19958
|
+
this.#symbols = true;
|
|
19959
|
+
return this;
|
|
19960
|
+
}
|
|
19961
|
+
validate(attribute, value2, fail) {
|
|
19962
|
+
const name = defaultAttributeName(attribute);
|
|
19963
|
+
const say = (key, replacements = {}) => fail(applyReplacements(DEFAULT_MESSAGES[key], { attribute: name, ...replacements }));
|
|
19964
|
+
if (typeof value2 !== "string") return say("string");
|
|
19965
|
+
const length = [...value2].length;
|
|
19966
|
+
if (length < this.#min) say("min.string", { min: String(this.#min) });
|
|
19967
|
+
if (this.#max !== void 0 && length > this.#max) say("max.string", { max: String(this.#max) });
|
|
19968
|
+
if (this.#mixedCase && !/(\p{Ll}+.*\p{Lu})|(\p{Lu}+.*\p{Ll})/u.test(value2)) say("password.mixed");
|
|
19969
|
+
if (this.#letters && !/\p{L}/u.test(value2)) say("password.letters");
|
|
19970
|
+
if (this.#symbols && !/\p{Z}|\p{S}|\p{P}/u.test(value2)) say("password.symbols");
|
|
19971
|
+
if (this.#numbers && !/\p{N}/u.test(value2)) say("password.numbers");
|
|
19972
|
+
}
|
|
19973
|
+
#copy() {
|
|
19974
|
+
const copy = new _PasswordRule(this.#min);
|
|
19975
|
+
copy.#max = this.#max;
|
|
19976
|
+
copy.#letters = this.#letters;
|
|
19977
|
+
copy.#mixedCase = this.#mixedCase;
|
|
19978
|
+
copy.#numbers = this.#numbers;
|
|
19979
|
+
copy.#symbols = this.#symbols;
|
|
19980
|
+
return copy;
|
|
19981
|
+
}
|
|
21250
19982
|
};
|
|
21251
19983
|
var BuiltinRuleObject = class {
|
|
21252
19984
|
// Declares all 4 contract parameters so a subclass's inferred type (from `Rule.in(...)` etc.) still accepts a
|
|
@@ -21319,7 +20051,9 @@ var ExistsRule = class extends BuiltinRuleObject {
|
|
|
21319
20051
|
var Rule = {
|
|
21320
20052
|
in: (values) => new InRule(values),
|
|
21321
20053
|
unique: (table, column) => new UniqueRule(table, column),
|
|
21322
|
-
exists: (table, column) => new ExistsRule(table, column)
|
|
20054
|
+
exists: (table, column) => new ExistsRule(table, column),
|
|
20055
|
+
/** Laravel's Password::defaults(): the application's password rule (at least 8 characters unless PasswordRule.defaults() changed it). */
|
|
20056
|
+
password: () => PasswordRule.defaults()
|
|
21323
20057
|
};
|
|
21324
20058
|
var SKIPPED_MODIFIERS = /* @__PURE__ */ new Set(["bail", "nullable", "sometimes"]);
|
|
21325
20059
|
function buildNested(flat) {
|
|
@@ -21434,9 +20168,9 @@ var ValidatorImpl = class {
|
|
|
21434
20168
|
const implicit = rule.kind === "named" && (this.registry[rule.name]?.implicit ?? false);
|
|
21435
20169
|
if (!implicit && (!present2 || isBlank2)) continue;
|
|
21436
20170
|
if (!implicit && nullable && isNull) continue;
|
|
21437
|
-
const
|
|
21438
|
-
if (
|
|
21439
|
-
this.bag.add(field, message);
|
|
20171
|
+
const messages = await this.runRule(rule, field, pattern, value2, names);
|
|
20172
|
+
if (messages.length > 0) {
|
|
20173
|
+
for (const message of messages) this.bag.add(field, message);
|
|
21440
20174
|
if (bail || implicit) break;
|
|
21441
20175
|
}
|
|
21442
20176
|
}
|
|
@@ -21449,26 +20183,24 @@ var ValidatorImpl = class {
|
|
|
21449
20183
|
const expanded = pattern.includes("*");
|
|
21450
20184
|
if (rule.kind === "object") {
|
|
21451
20185
|
if (rule.rule instanceof BuiltinRuleObject) {
|
|
21452
|
-
if (await rule.rule.passes(field, value2, this.data, expanded)) return
|
|
20186
|
+
if (await rule.rule.passes(field, value2, this.data, expanded)) return [];
|
|
21453
20187
|
const ctx2 = { attribute: field, expandedFromWildcard: expanded, value: value2, parameters: [], data: this.data, ruleNames };
|
|
21454
|
-
return this.failureMessage(rule.rule.ruleName, this.registry[rule.rule.ruleName], ctx2, pattern);
|
|
20188
|
+
return [this.failureMessage(rule.rule.ruleName, this.registry[rule.rule.ruleName], ctx2, pattern)];
|
|
21455
20189
|
}
|
|
21456
|
-
|
|
21457
|
-
await rule.rule.validate(field, value2, (message) =>
|
|
21458
|
-
|
|
21459
|
-
}, this.data);
|
|
21460
|
-
return failure;
|
|
20190
|
+
const failures = [];
|
|
20191
|
+
await rule.rule.validate(field, value2, (message) => void failures.push(message), this.data);
|
|
20192
|
+
return failures;
|
|
21461
20193
|
}
|
|
21462
20194
|
const builtin = this.registry[rule.name];
|
|
21463
20195
|
if (!builtin) throw new UnknownValidationRuleError(rule.name);
|
|
21464
20196
|
const ctx = { attribute: field, expandedFromWildcard: expanded, value: value2, parameters: rule.parameters, data: this.data, ruleNames };
|
|
21465
|
-
if (await builtin.validate(ctx)) return
|
|
21466
|
-
return this.failureMessage(rule.name, builtin, ctx, pattern);
|
|
20197
|
+
if (await builtin.validate(ctx)) return [];
|
|
20198
|
+
return [this.failureMessage(rule.name, builtin, ctx, pattern)];
|
|
21467
20199
|
}
|
|
21468
20200
|
/** Custom message (concrete field, then wildcard pattern, then rule name) or the default, with :attribute filled. */
|
|
21469
20201
|
failureMessage(name, builtin, ctx, pattern) {
|
|
21470
20202
|
const field = ctx.attribute;
|
|
21471
|
-
const template = this.customMessages[`${field}.${name}`] ?? this.customMessages[`${pattern}.${name}`] ?? this.customMessages[name] ?? DEFAULT_MESSAGES[builtin?.messageKey(ctx) ?? name] ?? builtin?.defaultMessage ?? "The :attribute field is invalid.";
|
|
20203
|
+
const template = this.customMessages[`${field}.${name}`] ?? this.customMessages[`${pattern}.${name}`] ?? this.customMessages[name] ?? builtin?.message ?? DEFAULT_MESSAGES[builtin?.messageKey(ctx) ?? name] ?? builtin?.defaultMessage ?? "The :attribute field is invalid.";
|
|
21472
20204
|
const display = this.customAttributes[field] ?? this.customAttributes[pattern] ?? defaultAttributeName(field);
|
|
21473
20205
|
return applyReplacements(template, { attribute: display, ...builtin?.replacements?.(ctx) ?? {} });
|
|
21474
20206
|
}
|
|
@@ -21482,6 +20214,7 @@ var ValidationFactoryImpl = class {
|
|
|
21482
20214
|
this.extended[name] = {
|
|
21483
20215
|
validate: (ctx) => callback(ctx.attribute, ctx.value, ctx.parameters, ctx.data),
|
|
21484
20216
|
messageKey: () => name,
|
|
20217
|
+
...message === void 0 ? {} : { message },
|
|
21485
20218
|
defaultMessage: message ?? "The :attribute field is invalid."
|
|
21486
20219
|
};
|
|
21487
20220
|
}
|
|
@@ -21593,6 +20326,7 @@ export {
|
|
|
21593
20326
|
CHAIN,
|
|
21594
20327
|
Cache,
|
|
21595
20328
|
CacheManager2 as CacheManager,
|
|
20329
|
+
CacheRateLimiter,
|
|
21596
20330
|
Repository2 as CacheRepositoryImpl,
|
|
21597
20331
|
CacheServiceProvider,
|
|
21598
20332
|
CallQueuedHandler,
|
|
@@ -21609,7 +20343,7 @@ export {
|
|
|
21609
20343
|
ComponentNotFoundError,
|
|
21610
20344
|
Computed,
|
|
21611
20345
|
Connection,
|
|
21612
|
-
|
|
20346
|
+
Kernel2 as ConsoleKernelImpl,
|
|
21613
20347
|
ConsoleServiceProvider,
|
|
21614
20348
|
Container2 as Container,
|
|
21615
20349
|
ContainerNotAvailableError,
|
|
@@ -21646,6 +20380,7 @@ export {
|
|
|
21646
20380
|
Dispatchable,
|
|
21647
20381
|
ELEMENT,
|
|
21648
20382
|
EloquentUserProvider,
|
|
20383
|
+
EmailVerificationRequest,
|
|
21649
20384
|
EncryptCookies,
|
|
21650
20385
|
EncryptError,
|
|
21651
20386
|
EncryptHistory,
|
|
@@ -21695,7 +20430,7 @@ export {
|
|
|
21695
20430
|
HelpCommand,
|
|
21696
20431
|
HtmlString,
|
|
21697
20432
|
HttpException,
|
|
21698
|
-
|
|
20433
|
+
Kernel as HttpKernelImpl,
|
|
21699
20434
|
HttpRedirectResponse,
|
|
21700
20435
|
HttpRedirector,
|
|
21701
20436
|
HttpResponseException,
|
|
@@ -21709,7 +20444,7 @@ export {
|
|
|
21709
20444
|
InertiaHtml,
|
|
21710
20445
|
InertiaMiddleware,
|
|
21711
20446
|
Response2 as InertiaPageResponse,
|
|
21712
|
-
|
|
20447
|
+
ResponseFactory as InertiaResponseFactory,
|
|
21713
20448
|
InertiaServiceProvider,
|
|
21714
20449
|
InvalidCacheConfigError,
|
|
21715
20450
|
InvalidCastError,
|
|
@@ -21718,6 +20453,7 @@ export {
|
|
|
21718
20453
|
InvalidLogLevelError,
|
|
21719
20454
|
InvalidRuleParameterError,
|
|
21720
20455
|
InvalidSignatureError,
|
|
20456
|
+
InvalidUrlSignatureError,
|
|
21721
20457
|
InvalidViewError,
|
|
21722
20458
|
JOBS_TABLE_MIGRATION,
|
|
21723
20459
|
JobClassNotFoundError,
|
|
@@ -21736,6 +20472,7 @@ export {
|
|
|
21736
20472
|
LocalFilesystem,
|
|
21737
20473
|
LockTimeoutError,
|
|
21738
20474
|
Locked,
|
|
20475
|
+
Lockout,
|
|
21739
20476
|
Log,
|
|
21740
20477
|
LogChannelCycleError,
|
|
21741
20478
|
LogManager2 as LogManager,
|
|
@@ -21820,12 +20557,14 @@ export {
|
|
|
21820
20557
|
On,
|
|
21821
20558
|
OnceProp,
|
|
21822
20559
|
OptionalProp,
|
|
20560
|
+
PERSISTENT_MIDDLEWARE,
|
|
21823
20561
|
PERSONAL_ACCESS_TOKENS_MIGRATION,
|
|
21824
20562
|
Paginator,
|
|
21825
20563
|
Password,
|
|
21826
20564
|
PasswordBroker2 as PasswordBroker,
|
|
21827
20565
|
PasswordBrokerManager,
|
|
21828
20566
|
PasswordReset,
|
|
20567
|
+
PasswordRule,
|
|
21829
20568
|
PathTraversalError,
|
|
21830
20569
|
PendingBatch,
|
|
21831
20570
|
PendingChain,
|
|
@@ -21854,6 +20593,7 @@ export {
|
|
|
21854
20593
|
QueuedConsoleInput,
|
|
21855
20594
|
QueuedMailSender,
|
|
21856
20595
|
RESTART_CACHE_KEY,
|
|
20596
|
+
RateLimiter2 as RateLimiter,
|
|
21857
20597
|
RedirectIfAuthenticated,
|
|
21858
20598
|
RedisJob,
|
|
21859
20599
|
RedisLock,
|
|
@@ -21862,6 +20602,7 @@ export {
|
|
|
21862
20602
|
RedisSessionHandler,
|
|
21863
20603
|
RedisStore,
|
|
21864
20604
|
RedisTaggedStore,
|
|
20605
|
+
Registered,
|
|
21865
20606
|
Relation,
|
|
21866
20607
|
RelationNotFoundError,
|
|
21867
20608
|
RelationNotLoadedError,
|
|
@@ -21891,6 +20632,7 @@ export {
|
|
|
21891
20632
|
SchemaGrammar,
|
|
21892
20633
|
ScrollProp,
|
|
21893
20634
|
Seeder,
|
|
20635
|
+
SendEmailVerificationNotification,
|
|
21894
20636
|
SendQueuedMailable,
|
|
21895
20637
|
SendQueuedNotifications,
|
|
21896
20638
|
ServiceProvider,
|
|
@@ -21913,7 +20655,10 @@ export {
|
|
|
21913
20655
|
SyncQueue,
|
|
21914
20656
|
TagsNotSupportedError,
|
|
21915
20657
|
TestCommand,
|
|
20658
|
+
TestRequestScope,
|
|
21916
20659
|
Testable,
|
|
20660
|
+
ThrottleRequests,
|
|
20661
|
+
ThrottleRequestsError,
|
|
21917
20662
|
TimeoutExceededError,
|
|
21918
20663
|
TinkerCommand,
|
|
21919
20664
|
TokenGuard,
|
|
@@ -21944,13 +20689,17 @@ export {
|
|
|
21944
20689
|
UnsupportedCipherError,
|
|
21945
20690
|
UnsupportedOperationError,
|
|
21946
20691
|
UrlGenerationError,
|
|
20692
|
+
ValidateSignature,
|
|
21947
20693
|
Validated,
|
|
21948
20694
|
ValidationErrorImpl,
|
|
20695
|
+
ValidationException,
|
|
21949
20696
|
ValidationFactoryImpl,
|
|
21950
20697
|
ValidationServiceProvider,
|
|
21951
20698
|
Validator,
|
|
21952
20699
|
ValidatorImpl,
|
|
20700
|
+
Verified,
|
|
21953
20701
|
VerifyCsrfToken,
|
|
20702
|
+
VerifyEmail,
|
|
21954
20703
|
View,
|
|
21955
20704
|
Factory as ViewFactoryImpl,
|
|
21956
20705
|
ViewFactoryUnavailableError,
|
|
@@ -21963,6 +20712,7 @@ export {
|
|
|
21963
20712
|
WORKER_DISCOVERY_DIRECTORIES,
|
|
21964
20713
|
WithoutOverlapping,
|
|
21965
20714
|
Worker,
|
|
20715
|
+
__,
|
|
21966
20716
|
abort,
|
|
21967
20717
|
abortIf,
|
|
21968
20718
|
abortUnless,
|
|
@@ -22001,7 +20751,7 @@ export {
|
|
|
22001
20751
|
csrfToken,
|
|
22002
20752
|
currentContainer,
|
|
22003
20753
|
currentLogContext,
|
|
22004
|
-
|
|
20754
|
+
currentRequest,
|
|
22005
20755
|
currentVite,
|
|
22006
20756
|
databaseConfigDefaults,
|
|
22007
20757
|
debugPage,
|
|
@@ -22032,6 +20782,7 @@ export {
|
|
|
22032
20782
|
errors,
|
|
22033
20783
|
escapeHtml,
|
|
22034
20784
|
event,
|
|
20785
|
+
exceedsJsonDepth,
|
|
22035
20786
|
expandWildcardKeys,
|
|
22036
20787
|
extensionFromMime,
|
|
22037
20788
|
facade,
|
|
@@ -22108,6 +20859,7 @@ export {
|
|
|
22108
20859
|
parseRuleSpec,
|
|
22109
20860
|
parseSignature,
|
|
22110
20861
|
passwordVerify,
|
|
20862
|
+
persistentMiddleware,
|
|
22111
20863
|
prepareValue,
|
|
22112
20864
|
queueConfigDefaults,
|
|
22113
20865
|
queueOptionsOf,
|