@orieljs/framework 0.1.0-alpha.4 → 0.1.0-alpha.5
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-3DETYZMZ.js → chunk-A5XRLEWM.js} +3 -3
- package/dist/{chunk-WSGWYXAO.js → chunk-BSQKOLSK.js} +3 -1
- package/dist/chunk-BSQKOLSK.js.map +1 -0
- package/dist/{chunk-DCI2T7WJ.js → chunk-PM5YTG57.js} +117 -3
- package/dist/chunk-PM5YTG57.js.map +1 -0
- package/dist/{chunk-SBZQ6L3Z.js → chunk-WNJP46B7.js} +563 -73
- package/dist/chunk-WNJP46B7.js.map +1 -0
- package/dist/contracts.d.ts +43 -1
- package/dist/contracts.js +3 -1
- package/dist/index.d.ts +391 -52
- package/dist/index.js +610 -144
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/{testing-D3dCOkTm.d.ts → testing-BErengYY.d.ts} +89 -12
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +3 -3
- package/package.json +30 -30
- package/dist/chunk-DCI2T7WJ.js.map +0 -1
- package/dist/chunk-SBZQ6L3Z.js.map +0 -1
- package/dist/chunk-WSGWYXAO.js.map +0 -1
- /package/dist/{chunk-3DETYZMZ.js.map → chunk-A5XRLEWM.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
renderToString,
|
|
23
23
|
styleString,
|
|
24
24
|
view
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-A5XRLEWM.js";
|
|
26
26
|
import {
|
|
27
27
|
API_ROUTES_STUB,
|
|
28
28
|
Application as Application2,
|
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
NotificationFake,
|
|
61
61
|
On,
|
|
62
62
|
PERSISTENT_MIDDLEWARE,
|
|
63
|
+
Pagination,
|
|
63
64
|
PendingEvent,
|
|
64
65
|
PropertyNotUpdatableError,
|
|
65
66
|
ProviderBootError,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
Vite,
|
|
75
76
|
ViteError,
|
|
76
77
|
ViteHtml,
|
|
78
|
+
WithPagination,
|
|
77
79
|
abort,
|
|
78
80
|
abortIf,
|
|
79
81
|
abortUnless,
|
|
@@ -129,7 +131,7 @@ import {
|
|
|
129
131
|
vite,
|
|
130
132
|
viteReactRefresh,
|
|
131
133
|
writeResponse
|
|
132
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-WNJP46B7.js";
|
|
133
135
|
import {
|
|
134
136
|
Arr,
|
|
135
137
|
BindingResolutionError,
|
|
@@ -147,12 +149,13 @@ import {
|
|
|
147
149
|
config,
|
|
148
150
|
currentContainer,
|
|
149
151
|
facade,
|
|
152
|
+
fileType_exports,
|
|
150
153
|
inject,
|
|
151
154
|
now,
|
|
152
155
|
retry,
|
|
153
156
|
tap,
|
|
154
157
|
value
|
|
155
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-PM5YTG57.js";
|
|
156
159
|
import {
|
|
157
160
|
Application,
|
|
158
161
|
AuthFactory,
|
|
@@ -179,6 +182,7 @@ import {
|
|
|
179
182
|
LogManager,
|
|
180
183
|
MailManager,
|
|
181
184
|
NotificationDispatcher,
|
|
185
|
+
PaginationState,
|
|
182
186
|
PasswordBroker,
|
|
183
187
|
PipelineFactory,
|
|
184
188
|
QueueManager,
|
|
@@ -193,7 +197,7 @@ import {
|
|
|
193
197
|
ValidationFactory,
|
|
194
198
|
ViewFactory,
|
|
195
199
|
token
|
|
196
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-BSQKOLSK.js";
|
|
197
201
|
|
|
198
202
|
// ../Auth/dist/index.js
|
|
199
203
|
import { createHash } from "crypto";
|
|
@@ -1377,6 +1381,39 @@ var AccessGate = class _AccessGate {
|
|
|
1377
1381
|
return registered === void 0 ? [cls.name] : [baseName(registered), cls.name];
|
|
1378
1382
|
}
|
|
1379
1383
|
};
|
|
1384
|
+
var list = (abilities) => typeof abilities === "string" ? [abilities] : [...abilities];
|
|
1385
|
+
function Authorizable(Base) {
|
|
1386
|
+
return class AuthorizableUser extends Base {
|
|
1387
|
+
/** Whether the user has the ability (every one, for a list); the arguments go to the policy or ability callback. */
|
|
1388
|
+
async can(abilities, ...args) {
|
|
1389
|
+
const gate = inject(Gate).forUser(this);
|
|
1390
|
+
for (const ability of list(abilities)) if (!await gate.allows(ability, ...args)) return false;
|
|
1391
|
+
return true;
|
|
1392
|
+
}
|
|
1393
|
+
/** Whether the user has any of the abilities. */
|
|
1394
|
+
async canAny(abilities, ...args) {
|
|
1395
|
+
return inject(Gate).forUser(this).any(list(abilities), ...args);
|
|
1396
|
+
}
|
|
1397
|
+
/** Whether the user lacks the ability (any one, for a list). */
|
|
1398
|
+
async cant(abilities, ...args) {
|
|
1399
|
+
return !await this.can(abilities, ...args);
|
|
1400
|
+
}
|
|
1401
|
+
/** The same as cant(). */
|
|
1402
|
+
cannot(abilities, ...args) {
|
|
1403
|
+
return this.cant(abilities, ...args);
|
|
1404
|
+
}
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
var Controller = class {
|
|
1408
|
+
/** Authorizes the ability for the signed-in user (the Gate's authorize()). */
|
|
1409
|
+
async authorize(ability, ...args) {
|
|
1410
|
+
return inject(Gate).authorize(ability, ...args);
|
|
1411
|
+
}
|
|
1412
|
+
/** Authorizes the ability for the given user (Gate.forUser(user).authorize()). */
|
|
1413
|
+
async authorizeForUser(user, ability, ...args) {
|
|
1414
|
+
return inject(Gate).forUser(user).authorize(ability, ...args);
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1380
1417
|
var Authorize = class {
|
|
1381
1418
|
#gate = inject(Gate);
|
|
1382
1419
|
async handle(request2, next, ability, ...models) {
|
|
@@ -1618,7 +1655,7 @@ async function discoverPolicies(directory, gate) {
|
|
|
1618
1655
|
return found;
|
|
1619
1656
|
}
|
|
1620
1657
|
var Auth = facade(AuthFactory);
|
|
1621
|
-
var
|
|
1658
|
+
var Gate4 = facade(Gate);
|
|
1622
1659
|
var Password = facade(PasswordBroker, {
|
|
1623
1660
|
broker: (name) => inject(PasswordBrokerManager).broker(name)
|
|
1624
1661
|
});
|
|
@@ -1689,7 +1726,7 @@ var QUEUE_OPTIONS = ["connection", "queue", "delay", "tries", "backoff", "timeou
|
|
|
1689
1726
|
function isQueueable(job) {
|
|
1690
1727
|
if (typeof job !== "object" || job === null) return false;
|
|
1691
1728
|
const members = job;
|
|
1692
|
-
if (members[SHOULD_QUEUE] === true) return true;
|
|
1729
|
+
if (members.shouldQueue === true || members[SHOULD_QUEUE] === true) return true;
|
|
1693
1730
|
if (QUEUE_OPTIONS.some((option) => members[option] !== void 0)) return true;
|
|
1694
1731
|
return typeof members.uniqueId === "function" || typeof members.retryUntil === "function";
|
|
1695
1732
|
}
|
|
@@ -1900,9 +1937,9 @@ var Dispatcher = class {
|
|
|
1900
1937
|
}
|
|
1901
1938
|
#afterResponseList() {
|
|
1902
1939
|
const owner = currentContainer() ?? this.container;
|
|
1903
|
-
let
|
|
1904
|
-
if (
|
|
1905
|
-
return
|
|
1940
|
+
let list4 = this.#afterResponse.get(owner);
|
|
1941
|
+
if (list4 === void 0) this.#afterResponse.set(owner, list4 = []);
|
|
1942
|
+
return list4;
|
|
1906
1943
|
}
|
|
1907
1944
|
/** Runs the job (like dispatchSync) after the response is sent, or after the current queued job. */
|
|
1908
1945
|
dispatchAfterResponse(job) {
|
|
@@ -2051,6 +2088,10 @@ var Dispatchable = class {
|
|
|
2051
2088
|
}
|
|
2052
2089
|
};
|
|
2053
2090
|
var Queueable = class extends Dispatchable {
|
|
2091
|
+
/** ShouldQueue's marker, so subclasses may write `implements ShouldQueue` without the field. */
|
|
2092
|
+
get shouldQueue() {
|
|
2093
|
+
return true;
|
|
2094
|
+
}
|
|
2054
2095
|
};
|
|
2055
2096
|
Object.defineProperty(Queueable.prototype, SHOULD_QUEUE, { value: true });
|
|
2056
2097
|
function dispatch(job) {
|
|
@@ -2921,8 +2962,8 @@ var RedisRepository = class extends Repository2 {
|
|
|
2921
2962
|
redisStore;
|
|
2922
2963
|
redis;
|
|
2923
2964
|
tags(names) {
|
|
2924
|
-
const
|
|
2925
|
-
const taggedStore = this.redisStore.tags(
|
|
2965
|
+
const list4 = Array.isArray(names) ? names : [names];
|
|
2966
|
+
const taggedStore = this.redisStore.tags(list4);
|
|
2926
2967
|
const prefix = this.redisStore.getPrefix();
|
|
2927
2968
|
return new Repository2(taggedStore, (_store, name, seconds, owner) => new RedisLock(this.redis, prefix + name, seconds, owner));
|
|
2928
2969
|
}
|
|
@@ -3765,9 +3806,12 @@ export class {{ class }} extends Dispatchable {
|
|
|
3765
3806
|
}
|
|
3766
3807
|
`;
|
|
3767
3808
|
var MAIL_STUB = `import { Mailable } from '@orieljs/framework'
|
|
3768
|
-
import type { Content, Envelope } from '@orieljs/framework/contracts'
|
|
3809
|
+
import type { Content, Envelope, ShouldQueue } from '@orieljs/framework/contracts'
|
|
3810
|
+
|
|
3811
|
+
export class {{ class }} extends Mailable implements ShouldQueue {
|
|
3812
|
+
/** Sent by the queue worker (node oriel queue:work): remove this line and \`implements ShouldQueue\` to send it right away. */
|
|
3813
|
+
readonly shouldQueue = true
|
|
3769
3814
|
|
|
3770
|
-
export class {{ class }} extends Mailable {
|
|
3771
3815
|
override async envelope(): Promise<Envelope> {
|
|
3772
3816
|
return { subject: '{{ subject }}' }
|
|
3773
3817
|
}
|
|
@@ -3778,9 +3822,12 @@ export class {{ class }} extends Mailable {
|
|
|
3778
3822
|
}
|
|
3779
3823
|
`;
|
|
3780
3824
|
var NOTIFICATION_STUB = `import { MailMessage, Notification } from '@orieljs/framework'
|
|
3781
|
-
import type { Notifiable } from '@orieljs/framework/contracts'
|
|
3825
|
+
import type { Notifiable, ShouldQueue } from '@orieljs/framework/contracts'
|
|
3826
|
+
|
|
3827
|
+
export class {{ class }} extends Notification implements ShouldQueue {
|
|
3828
|
+
/** Sent by the queue worker (node oriel queue:work): remove this line and \`implements ShouldQueue\` to send it right away. */
|
|
3829
|
+
readonly shouldQueue = true
|
|
3782
3830
|
|
|
3783
|
-
export class {{ class }} extends Notification {
|
|
3784
3831
|
via(_notifiable: Notifiable): string[] {
|
|
3785
3832
|
return ['mail']
|
|
3786
3833
|
}
|
|
@@ -4527,7 +4574,7 @@ var SHOULD_QUEUE2 = /* @__PURE__ */ Symbol.for("oriel:bus.shouldQueue");
|
|
|
4527
4574
|
var QUEUE_OPTIONS2 = ["connection", "queue", "delay", "tries", "backoff", "timeout"];
|
|
4528
4575
|
function isQueueable2(job) {
|
|
4529
4576
|
const members = job;
|
|
4530
|
-
if (members[SHOULD_QUEUE2] === true) return true;
|
|
4577
|
+
if (members.shouldQueue === true || members[SHOULD_QUEUE2] === true) return true;
|
|
4531
4578
|
if (QUEUE_OPTIONS2.some((option) => members[option] !== void 0)) return true;
|
|
4532
4579
|
return typeof members.uniqueId === "function" || typeof members.retryUntil === "function";
|
|
4533
4580
|
}
|
|
@@ -5623,14 +5670,17 @@ var LengthAwarePaginator = class extends AbstractPaginator {
|
|
|
5623
5670
|
nextPageUrl() {
|
|
5624
5671
|
return this.hasMorePages() ? this.url(this.currentPageValue + 1) : null;
|
|
5625
5672
|
}
|
|
5626
|
-
/**
|
|
5673
|
+
/**
|
|
5674
|
+
* The page links Laravel renders: previous, the page window with '...' gaps, next. The labels are plain text
|
|
5675
|
+
* ("« Previous", "Next »"), not Laravel's `«` entities, so a page can print them as text.
|
|
5676
|
+
*/
|
|
5627
5677
|
linkCollection() {
|
|
5628
|
-
const links = [{ url: this.previousPageUrl(), label: "
|
|
5678
|
+
const links = [{ url: this.previousPageUrl(), label: "\xAB Previous", active: false }];
|
|
5629
5679
|
for (const element of this.elements()) {
|
|
5630
5680
|
if (element === "...") links.push({ url: null, label: "...", active: false });
|
|
5631
5681
|
else for (const [page, url2] of element) links.push({ url: url2, label: String(page), active: page === this.currentPageValue });
|
|
5632
5682
|
}
|
|
5633
|
-
links.push({ url: this.nextPageUrl(), label: "Next
|
|
5683
|
+
links.push({ url: this.nextPageUrl(), label: "Next \xBB", active: false });
|
|
5634
5684
|
return links;
|
|
5635
5685
|
}
|
|
5636
5686
|
/** Laravel's UrlWindow: the first pages, the slider around the current page and the last pages, with '...' between. */
|
|
@@ -5752,6 +5802,9 @@ var EMPTY = sql2.raw("");
|
|
|
5752
5802
|
var isSqlFragment = (value2) => typeof value2 === "object" && value2 !== null && typeof value2.toOperationNode === "function";
|
|
5753
5803
|
var join8 = (parts, separator = ", ") => sql2.join(parts, sql2.raw(separator));
|
|
5754
5804
|
var clauses = (parts) => join8(parts.filter((part) => part !== void 0), " ");
|
|
5805
|
+
function likeToGlob(pattern) {
|
|
5806
|
+
return pattern.replaceAll("*", "[*]").replaceAll("?", "[?]").replaceAll("%", "*").replaceAll("_", "?");
|
|
5807
|
+
}
|
|
5755
5808
|
var Grammar = class {
|
|
5756
5809
|
constructor(driver) {
|
|
5757
5810
|
this.driver = driver;
|
|
@@ -5832,6 +5885,8 @@ var Grammar = class {
|
|
|
5832
5885
|
}
|
|
5833
5886
|
case "null":
|
|
5834
5887
|
return sql2`${this.wrap(where.column)} ${sql2.raw(where.not ? "is not null" : "is null")}`;
|
|
5888
|
+
case "like":
|
|
5889
|
+
return this.compileWhereLike(where);
|
|
5835
5890
|
case "between":
|
|
5836
5891
|
return sql2`${this.wrap(where.column)} ${sql2.raw(where.not ? "not between" : "between")} ${this.parameter(where.values[0])} and ${this.parameter(where.values[1])}`;
|
|
5837
5892
|
case "column":
|
|
@@ -5844,6 +5899,18 @@ var Grammar = class {
|
|
|
5844
5899
|
return rawWithBindings(where.sql, where.bindings.map((value2) => this.prepare(value2)));
|
|
5845
5900
|
}
|
|
5846
5901
|
}
|
|
5902
|
+
/**
|
|
5903
|
+
* whereLike() per driver, as Laravel 12's grammars: Postgres compares the column as text with ilike (like when
|
|
5904
|
+
* case-sensitive); MySQL uses like (like binary); SQLite uses like, or glob with the pattern translated.
|
|
5905
|
+
*/
|
|
5906
|
+
compileWhereLike(where) {
|
|
5907
|
+
const not = where.not ? "not " : "";
|
|
5908
|
+
const column = this.wrap(where.column);
|
|
5909
|
+
if (this.driver === "pgsql") return sql2`${column}::text ${sql2.raw(`${not}${where.caseSensitive ? "like" : "ilike"}`)} ${this.parameter(where.value)}`;
|
|
5910
|
+
if (this.driver === "mysql") return sql2`${column} ${sql2.raw(`${not}${where.caseSensitive ? "like binary" : "like"}`)} ${this.parameter(where.value)}`;
|
|
5911
|
+
if (where.caseSensitive) return sql2`${column} ${sql2.raw(`${not}glob`)} ${this.parameter(likeToGlob(where.value))}`;
|
|
5912
|
+
return sql2`${column} ${sql2.raw(`${not}like`)} ${this.parameter(where.value)}`;
|
|
5913
|
+
}
|
|
5847
5914
|
compileJoin(joinClause) {
|
|
5848
5915
|
if (joinClause.joinType === "cross") return sql2`cross join ${this.wrapTable(joinClause.table)}`;
|
|
5849
5916
|
return sql2`${sql2.raw(joinClause.joinType)} join ${this.wrapTable(joinClause.table)} ${this.compileWheres(joinClause.wheres, "on") ?? EMPTY}`;
|
|
@@ -6096,6 +6163,25 @@ var Builder = class _Builder {
|
|
|
6096
6163
|
this.wheres.push({ type: "between", column, values, not: true, boolean: "and" });
|
|
6097
6164
|
return this;
|
|
6098
6165
|
}
|
|
6166
|
+
/**
|
|
6167
|
+
* Laravel's whereLike(): the value is the pattern, `%` and `_` included (`whereLike('title', `%${term}%`)`).
|
|
6168
|
+
* Case-insensitive unless caseSensitive: ilike on Postgres, like on MySQL and SQLite (their like already ignores
|
|
6169
|
+
* case: MySQL through the column's collation, SQLite for ASCII letters). Case-sensitive is like on Postgres,
|
|
6170
|
+
* like binary on MySQL and glob on SQLite.
|
|
6171
|
+
*/
|
|
6172
|
+
whereLike(column, value2, caseSensitive = false, boolean = "and", not = false) {
|
|
6173
|
+
this.wheres.push({ type: "like", column, value: value2, caseSensitive, not, boolean });
|
|
6174
|
+
return this;
|
|
6175
|
+
}
|
|
6176
|
+
orWhereLike(column, value2, caseSensitive = false) {
|
|
6177
|
+
return this.whereLike(column, value2, caseSensitive, "or");
|
|
6178
|
+
}
|
|
6179
|
+
whereNotLike(column, value2, caseSensitive = false, boolean = "and") {
|
|
6180
|
+
return this.whereLike(column, value2, caseSensitive, boolean, true);
|
|
6181
|
+
}
|
|
6182
|
+
orWhereNotLike(column, value2, caseSensitive = false) {
|
|
6183
|
+
return this.whereNotLike(column, value2, caseSensitive, "or");
|
|
6184
|
+
}
|
|
6099
6185
|
/** Compares two columns: whereColumn('updated_at', '>', 'created_at'). */
|
|
6100
6186
|
whereColumn(first, operatorOrSecond, second, boolean = "and") {
|
|
6101
6187
|
const [operator, other] = second === void 0 ? ["=", operatorOrSecond] : [operatorOrSecond, second];
|
|
@@ -6219,10 +6305,16 @@ var Builder = class _Builder {
|
|
|
6219
6305
|
this.lockMode = "share";
|
|
6220
6306
|
return this;
|
|
6221
6307
|
}
|
|
6222
|
-
/** Calls callback(this, value) when value is truthy (or the default callback otherwise). */
|
|
6223
6308
|
when(value2, callback, otherwise) {
|
|
6224
|
-
|
|
6225
|
-
|
|
6309
|
+
const resolved = typeof value2 === "function" ? value2(this) : value2;
|
|
6310
|
+
if (resolved) callback(this, resolved);
|
|
6311
|
+
else otherwise?.(this, resolved);
|
|
6312
|
+
return this;
|
|
6313
|
+
}
|
|
6314
|
+
unless(value2, callback, otherwise) {
|
|
6315
|
+
const resolved = typeof value2 === "function" ? value2(this) : value2;
|
|
6316
|
+
if (!resolved) callback(this, resolved);
|
|
6317
|
+
else otherwise?.(this, resolved);
|
|
6226
6318
|
return this;
|
|
6227
6319
|
}
|
|
6228
6320
|
tap(callback) {
|
|
@@ -7909,6 +8001,18 @@ var Builder2 = class extends Builder {
|
|
|
7909
8001
|
whereBetween(column, values) {
|
|
7910
8002
|
return super.whereBetween(column, values);
|
|
7911
8003
|
}
|
|
8004
|
+
whereLike(column, value2, caseSensitive = false, boolean = "and", not = false) {
|
|
8005
|
+
return super.whereLike(column, value2, caseSensitive, boolean, not);
|
|
8006
|
+
}
|
|
8007
|
+
orWhereLike(column, value2, caseSensitive = false) {
|
|
8008
|
+
return super.orWhereLike(column, value2, caseSensitive);
|
|
8009
|
+
}
|
|
8010
|
+
whereNotLike(column, value2, caseSensitive = false, boolean = "and") {
|
|
8011
|
+
return super.whereNotLike(column, value2, caseSensitive, boolean);
|
|
8012
|
+
}
|
|
8013
|
+
orWhereNotLike(column, value2, caseSensitive = false) {
|
|
8014
|
+
return super.orWhereNotLike(column, value2, caseSensitive);
|
|
8015
|
+
}
|
|
7912
8016
|
orderBy(column, direction = "asc") {
|
|
7913
8017
|
return super.orderBy(column, direction);
|
|
7914
8018
|
}
|
|
@@ -9472,6 +9576,14 @@ var Model = class _Model {
|
|
|
9472
9576
|
const query = this.query();
|
|
9473
9577
|
return Reflect.apply(query.where, query, args);
|
|
9474
9578
|
}
|
|
9579
|
+
static when(...args) {
|
|
9580
|
+
const query = this.query();
|
|
9581
|
+
return Reflect.apply(query.when, query, args);
|
|
9582
|
+
}
|
|
9583
|
+
static unless(...args) {
|
|
9584
|
+
const query = this.query();
|
|
9585
|
+
return Reflect.apply(query.unless, query, args);
|
|
9586
|
+
}
|
|
9475
9587
|
static whereKey(id) {
|
|
9476
9588
|
return this.query().whereKey(id);
|
|
9477
9589
|
}
|
|
@@ -9490,6 +9602,13 @@ var Model = class _Model {
|
|
|
9490
9602
|
static whereBetween(column, values) {
|
|
9491
9603
|
return this.query().whereBetween(column, values);
|
|
9492
9604
|
}
|
|
9605
|
+
/** Post.whereLike('title', `%${term}%`): case-insensitive unless caseSensitive (see the query builder's whereLike()). */
|
|
9606
|
+
static whereLike(column, value2, caseSensitive = false) {
|
|
9607
|
+
return this.query().whereLike(column, value2, caseSensitive);
|
|
9608
|
+
}
|
|
9609
|
+
static whereNotLike(column, value2, caseSensitive = false) {
|
|
9610
|
+
return this.query().whereNotLike(column, value2, caseSensitive);
|
|
9611
|
+
}
|
|
9493
9612
|
static whereColumn(first, operatorOrSecond, second) {
|
|
9494
9613
|
return this.query().whereColumn(first, operatorOrSecond, second);
|
|
9495
9614
|
}
|
|
@@ -9675,8 +9794,8 @@ var Model = class _Model {
|
|
|
9675
9794
|
/** Guarded names match case-insensitively: SQLite and MySQL column names are case-insensitive. */
|
|
9676
9795
|
isGuarded(key) {
|
|
9677
9796
|
if (this.guarded.length === 0) return false;
|
|
9678
|
-
const
|
|
9679
|
-
return this.guarded.some((guarded) => guarded === "*" || guarded.toLowerCase() ===
|
|
9797
|
+
const lower2 = key.toLowerCase();
|
|
9798
|
+
return this.guarded.some((guarded) => guarded === "*" || guarded.toLowerCase() === lower2);
|
|
9680
9799
|
}
|
|
9681
9800
|
totallyGuarded() {
|
|
9682
9801
|
return !_Model.isUnguarded() && this.fillable.length === 0 && this.guarded.length === 1 && this.guarded[0] === "*";
|
|
@@ -10448,6 +10567,90 @@ var Pivot = class extends Model {
|
|
|
10448
10567
|
incrementing = false;
|
|
10449
10568
|
timestamps = false;
|
|
10450
10569
|
};
|
|
10570
|
+
var DatabaseNotification = class extends Model {
|
|
10571
|
+
table = "notifications";
|
|
10572
|
+
keyType = "string";
|
|
10573
|
+
incrementing = false;
|
|
10574
|
+
guarded = [];
|
|
10575
|
+
casts = { data: "array", read_at: "datetime" };
|
|
10576
|
+
/** The model the notification was sent to. */
|
|
10577
|
+
notifiable() {
|
|
10578
|
+
return this.morphTo("notifiable");
|
|
10579
|
+
}
|
|
10580
|
+
/** Sets read_at to now and saves, unless it is already read. */
|
|
10581
|
+
async markAsRead() {
|
|
10582
|
+
if (this.unread()) await this.forceFill({ read_at: this.freshTimestamp() }).save();
|
|
10583
|
+
}
|
|
10584
|
+
/** Clears read_at and saves, unless it is already unread. */
|
|
10585
|
+
async markAsUnread() {
|
|
10586
|
+
if (this.read()) await this.forceFill({ read_at: null }).save();
|
|
10587
|
+
}
|
|
10588
|
+
read() {
|
|
10589
|
+
return this.read_at !== null && this.read_at !== void 0;
|
|
10590
|
+
}
|
|
10591
|
+
unread() {
|
|
10592
|
+
return !this.read();
|
|
10593
|
+
}
|
|
10594
|
+
/** `query.read()`: only read notifications. */
|
|
10595
|
+
static scopeRead(query) {
|
|
10596
|
+
return query.whereNotNull("read_at");
|
|
10597
|
+
}
|
|
10598
|
+
/** `query.unread()`: only unread notifications. */
|
|
10599
|
+
static scopeUnread(query) {
|
|
10600
|
+
return query.whereNull("read_at");
|
|
10601
|
+
}
|
|
10602
|
+
};
|
|
10603
|
+
var DatabaseNotificationCollection = class extends Collection {
|
|
10604
|
+
/** Marks every notification as read (one save each, as in Laravel). */
|
|
10605
|
+
async markAsRead() {
|
|
10606
|
+
for (const notification of this.all()) await notification.markAsRead();
|
|
10607
|
+
}
|
|
10608
|
+
/** Marks every notification as unread. */
|
|
10609
|
+
async markAsUnread() {
|
|
10610
|
+
for (const notification of this.all()) await notification.markAsUnread();
|
|
10611
|
+
}
|
|
10612
|
+
};
|
|
10613
|
+
var DatabaseNotificationsRelation = class extends MorphMany {
|
|
10614
|
+
async get() {
|
|
10615
|
+
return new DatabaseNotificationCollection(await this.runSelect());
|
|
10616
|
+
}
|
|
10617
|
+
async getResults() {
|
|
10618
|
+
const key = this.getParentKey();
|
|
10619
|
+
return key === null || key === void 0 ? new DatabaseNotificationCollection() : this.get();
|
|
10620
|
+
}
|
|
10621
|
+
initRelation(models, relation) {
|
|
10622
|
+
for (const model of models) model.setRelation(relation, new DatabaseNotificationCollection());
|
|
10623
|
+
return models;
|
|
10624
|
+
}
|
|
10625
|
+
match(models, results, relation) {
|
|
10626
|
+
const dictionary = this.buildDictionary(results);
|
|
10627
|
+
for (const model of models) {
|
|
10628
|
+
model.setRelation(relation, new DatabaseNotificationCollection(dictionary.get(String(model.getAttribute(this.localKey))) ?? []));
|
|
10629
|
+
}
|
|
10630
|
+
return models;
|
|
10631
|
+
}
|
|
10632
|
+
};
|
|
10633
|
+
function HasDatabaseNotifications(Base) {
|
|
10634
|
+
class WithDatabaseNotifications extends Base {
|
|
10635
|
+
notifications() {
|
|
10636
|
+
const related = this.newRelatedInstance(DatabaseNotification);
|
|
10637
|
+
return new DatabaseNotificationsRelation(
|
|
10638
|
+
related,
|
|
10639
|
+
this,
|
|
10640
|
+
related.qualifyColumn("notifiable_type"),
|
|
10641
|
+
related.qualifyColumn("notifiable_id"),
|
|
10642
|
+
this.getKeyName()
|
|
10643
|
+
).latest();
|
|
10644
|
+
}
|
|
10645
|
+
readNotifications() {
|
|
10646
|
+
return this.notifications().whereNotNull("read_at");
|
|
10647
|
+
}
|
|
10648
|
+
unreadNotifications() {
|
|
10649
|
+
return this.notifications().whereNull("read_at");
|
|
10650
|
+
}
|
|
10651
|
+
}
|
|
10652
|
+
return WithDatabaseNotifications;
|
|
10653
|
+
}
|
|
10451
10654
|
var Migration = class {
|
|
10452
10655
|
/** The connection to run on (default: the default connection). */
|
|
10453
10656
|
connection = void 0;
|
|
@@ -10858,7 +11061,7 @@ var TypeGenerator = class {
|
|
|
10858
11061
|
}
|
|
10859
11062
|
};
|
|
10860
11063
|
var text = (value2) => typeof value2 === "string" && value2 !== "" ? value2 : void 0;
|
|
10861
|
-
var
|
|
11064
|
+
var list2 = (value2) => Array.isArray(value2) ? value2.map(String) : text(value2) ? [String(value2)] : [];
|
|
10862
11065
|
var integer = (value2) => {
|
|
10863
11066
|
const number3 = Number(value2 ?? 0);
|
|
10864
11067
|
return Number.isInteger(number3) && number3 > 0 ? number3 : 0;
|
|
@@ -10874,7 +11077,7 @@ function confirmToProceed(context, command) {
|
|
|
10874
11077
|
return false;
|
|
10875
11078
|
}
|
|
10876
11079
|
function migrationPaths(context, command) {
|
|
10877
|
-
const paths =
|
|
11080
|
+
const paths = list2(command.option("path"));
|
|
10878
11081
|
if (!paths.length) return [context.app.databasePath("migrations")];
|
|
10879
11082
|
return paths.map((path) => isAbsolute(path) ? path : context.app.basePath(path));
|
|
10880
11083
|
}
|
|
@@ -11462,9 +11665,21 @@ function currentRequest2() {
|
|
|
11462
11665
|
return void 0;
|
|
11463
11666
|
}
|
|
11464
11667
|
}
|
|
11668
|
+
function paginationState() {
|
|
11669
|
+
const container = currentContainer();
|
|
11670
|
+
if (!container?.bound(PaginationState)) return void 0;
|
|
11671
|
+
try {
|
|
11672
|
+
return container.make(PaginationState);
|
|
11673
|
+
} catch (error) {
|
|
11674
|
+
if (error instanceof BindingResolutionError) return void 0;
|
|
11675
|
+
throw error;
|
|
11676
|
+
}
|
|
11677
|
+
}
|
|
11465
11678
|
function usePaginationResolvers() {
|
|
11466
|
-
AbstractPaginator.currentPathResolver = () => currentRequest2()?.url() ?? "/";
|
|
11679
|
+
AbstractPaginator.currentPathResolver = () => paginationState()?.currentPath() ?? currentRequest2()?.url() ?? "/";
|
|
11467
11680
|
AbstractPaginator.currentPageResolver = (pageName) => {
|
|
11681
|
+
const state = paginationState()?.currentPage(pageName);
|
|
11682
|
+
if (state !== void 0) return state;
|
|
11468
11683
|
const page = Number(currentRequest2()?.input(pageName));
|
|
11469
11684
|
return Number.isInteger(page) && page >= 1 ? page : 1;
|
|
11470
11685
|
};
|
|
@@ -11713,8 +11928,8 @@ function decrypt(payload, unserialize = true) {
|
|
|
11713
11928
|
return inject(Encrypter).decrypt(payload, unserialize);
|
|
11714
11929
|
}
|
|
11715
11930
|
function previousKeys(value2) {
|
|
11716
|
-
const
|
|
11717
|
-
return
|
|
11931
|
+
const list4 = Array.isArray(value2) ? value2 : typeof value2 === "string" ? value2.split(",") : [];
|
|
11932
|
+
return list4.map((key) => String(key).trim()).filter((key) => key !== "");
|
|
11718
11933
|
}
|
|
11719
11934
|
var EncryptionServiceProvider = class extends ServiceProvider {
|
|
11720
11935
|
register() {
|
|
@@ -11846,8 +12061,8 @@ var SHOULD_QUEUE22 = /* @__PURE__ */ Symbol.for("oriel:bus.shouldQueue");
|
|
|
11846
12061
|
var QUEUE_OPTION_KEYS = ["connection", "queue", "delay", "tries", "backoff", "timeout"];
|
|
11847
12062
|
function isQueueableListener(cls, instance) {
|
|
11848
12063
|
const members = instance;
|
|
11849
|
-
if (members[SHOULD_QUEUE22] === true) return true;
|
|
11850
12064
|
const statics = cls;
|
|
12065
|
+
if (members.shouldQueue === true || statics.shouldQueue === true || members[SHOULD_QUEUE22] === true) return true;
|
|
11851
12066
|
if (QUEUE_OPTION_KEYS.some((key) => members[key] !== void 0 || statics[key] !== void 0)) return true;
|
|
11852
12067
|
return typeof members.uniqueId === "function" || typeof members.retryUntil === "function" || typeof statics.uniqueId === "function" || typeof statics.retryUntil === "function";
|
|
11853
12068
|
}
|
|
@@ -11892,9 +12107,9 @@ var Dispatcher2 = class {
|
|
|
11892
12107
|
throw new InvalidListenerError(label);
|
|
11893
12108
|
}
|
|
11894
12109
|
for (const event2 of Array.isArray(events) ? events : [events]) {
|
|
11895
|
-
const
|
|
11896
|
-
|
|
11897
|
-
this.listeners.set(event2,
|
|
12110
|
+
const list4 = this.listeners.get(event2) ?? [];
|
|
12111
|
+
list4.push(listener);
|
|
12112
|
+
this.listeners.set(event2, list4);
|
|
11898
12113
|
}
|
|
11899
12114
|
}
|
|
11900
12115
|
hasListeners(event2) {
|
|
@@ -11907,7 +12122,7 @@ var Dispatcher2 = class {
|
|
|
11907
12122
|
/** Introspection for the event:list command. Not part of the EventDispatcher contract. */
|
|
11908
12123
|
registeredEvents() {
|
|
11909
12124
|
const rows = [];
|
|
11910
|
-
for (const [key,
|
|
12125
|
+
for (const [key, list4] of this.listeners) rows.push({ event: nameOf(key), listeners: list4.length });
|
|
11911
12126
|
return rows.sort((a, b) => a.event.localeCompare(b.event));
|
|
11912
12127
|
}
|
|
11913
12128
|
subscribe(subscriber) {
|
|
@@ -11951,8 +12166,8 @@ var Dispatcher2 = class {
|
|
|
11951
12166
|
const exact = [...this.listeners.get(key) ?? []];
|
|
11952
12167
|
const wildcardLists = typeof key === "string" ? this.wildcardPatternsFor(key).map((pattern) => [...this.listeners.get(pattern) ?? []]) : [];
|
|
11953
12168
|
for (const listener of exact) yield { listener, wildcard: false };
|
|
11954
|
-
for (const
|
|
11955
|
-
for (const listener of
|
|
12169
|
+
for (const list4 of wildcardLists) {
|
|
12170
|
+
for (const listener of list4) yield { listener, wildcard: true };
|
|
11956
12171
|
}
|
|
11957
12172
|
}
|
|
11958
12173
|
wildcardPatternsFor(event2) {
|
|
@@ -12039,6 +12254,7 @@ import { dirname as dirname4, extname as extname2, resolve as resolve2 } from "p
|
|
|
12039
12254
|
import { Readable } from "stream";
|
|
12040
12255
|
import { pipeline } from "stream/promises";
|
|
12041
12256
|
import { resolve, sep as sep3 } from "path";
|
|
12257
|
+
import { posix } from "path";
|
|
12042
12258
|
import {
|
|
12043
12259
|
CopyObjectCommand,
|
|
12044
12260
|
DeleteObjectCommand,
|
|
@@ -12109,24 +12325,54 @@ var MIME_TYPES = {
|
|
|
12109
12325
|
zip: "application/zip",
|
|
12110
12326
|
gz: "application/gzip",
|
|
12111
12327
|
tar: "application/x-tar",
|
|
12328
|
+
"7z": "application/x-7z-compressed",
|
|
12329
|
+
rar: "application/vnd.rar",
|
|
12330
|
+
epub: "application/epub+zip",
|
|
12331
|
+
rtf: "application/rtf",
|
|
12332
|
+
doc: "application/msword",
|
|
12333
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
12334
|
+
xls: "application/vnd.ms-excel",
|
|
12335
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
12336
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
12337
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
12338
|
+
odt: "application/vnd.oasis.opendocument.text",
|
|
12339
|
+
ods: "application/vnd.oasis.opendocument.spreadsheet",
|
|
12340
|
+
odp: "application/vnd.oasis.opendocument.presentation",
|
|
12112
12341
|
png: "image/png",
|
|
12113
12342
|
jpg: "image/jpeg",
|
|
12114
12343
|
jpeg: "image/jpeg",
|
|
12115
12344
|
gif: "image/gif",
|
|
12116
12345
|
webp: "image/webp",
|
|
12346
|
+
avif: "image/avif",
|
|
12117
12347
|
svg: "image/svg+xml",
|
|
12118
12348
|
ico: "image/x-icon",
|
|
12119
12349
|
bmp: "image/bmp",
|
|
12350
|
+
tif: "image/tiff",
|
|
12351
|
+
tiff: "image/tiff",
|
|
12352
|
+
heic: "image/heic",
|
|
12353
|
+
heif: "image/heif",
|
|
12120
12354
|
mp3: "audio/mpeg",
|
|
12355
|
+
m4a: "audio/mp4",
|
|
12121
12356
|
wav: "audio/wav",
|
|
12357
|
+
ogg: "audio/ogg",
|
|
12358
|
+
oga: "audio/ogg",
|
|
12359
|
+
opus: "audio/ogg",
|
|
12360
|
+
flac: "audio/flac",
|
|
12361
|
+
aac: "audio/aac",
|
|
12122
12362
|
mp4: "video/mp4",
|
|
12363
|
+
mov: "video/quicktime",
|
|
12123
12364
|
webm: "video/webm",
|
|
12365
|
+
ogv: "video/ogg",
|
|
12366
|
+
avi: "video/x-msvideo",
|
|
12124
12367
|
woff: "font/woff",
|
|
12125
12368
|
woff2: "font/woff2",
|
|
12126
|
-
ttf: "font/ttf"
|
|
12369
|
+
ttf: "font/ttf",
|
|
12370
|
+
otf: "font/otf",
|
|
12371
|
+
wasm: "application/wasm"
|
|
12127
12372
|
};
|
|
12128
12373
|
function mimeFromExtension(extension) {
|
|
12129
|
-
|
|
12374
|
+
const key = extension.replace(/^\./, "").toLowerCase();
|
|
12375
|
+
return Object.hasOwn(MIME_TYPES, key) ? MIME_TYPES[key] : void 0;
|
|
12130
12376
|
}
|
|
12131
12377
|
function resolveDiskPath(root, path) {
|
|
12132
12378
|
const resolvedRoot = resolve(root);
|
|
@@ -12206,7 +12452,7 @@ var LocalFilesystem = class {
|
|
|
12206
12452
|
async putFileAs(directory, file, name, options) {
|
|
12207
12453
|
const path = joinDiskPath(directory, name);
|
|
12208
12454
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
12209
|
-
await this.put(path, bytes,
|
|
12455
|
+
await this.put(path, bytes, options);
|
|
12210
12456
|
return path;
|
|
12211
12457
|
}
|
|
12212
12458
|
async delete(paths) {
|
|
@@ -12371,27 +12617,37 @@ var S3Filesystem = class {
|
|
|
12371
12617
|
const response2 = await this.getObject(path);
|
|
12372
12618
|
return response2.Body.transformToWebStream();
|
|
12373
12619
|
}
|
|
12620
|
+
/** Sends the type of the path when the options name none (Laravel's S3 adapter detects one too). */
|
|
12374
12621
|
async put(path, contents, options) {
|
|
12375
12622
|
const body = contents instanceof ReadableStream ? await collectStream(contents) : contents;
|
|
12376
|
-
await this.
|
|
12377
|
-
new PutObjectCommand({
|
|
12378
|
-
Bucket: this.config.bucket,
|
|
12379
|
-
Key: path,
|
|
12380
|
-
Body: body,
|
|
12381
|
-
ContentType: options?.mimeType,
|
|
12382
|
-
ACL: options?.visibility === "public" ? "public-read" : void 0
|
|
12383
|
-
})
|
|
12384
|
-
);
|
|
12623
|
+
await this.putObject(path, body, options?.mimeType ?? mimeFromExtension(posix.extname(path)), options);
|
|
12385
12624
|
return true;
|
|
12386
12625
|
}
|
|
12387
12626
|
async putFile(directory, file, options) {
|
|
12388
12627
|
return this.putFileAs(directory, file, uniqueFileName(file.extension()), options);
|
|
12389
12628
|
}
|
|
12629
|
+
/**
|
|
12630
|
+
* Sends the upload's own type: its extension(), which follows what a request upload's bytes show (the client's claim
|
|
12631
|
+
* counts only where extension() keeps it). Never the MIME type the client sent as such, nor the name it is stored
|
|
12632
|
+
* under (an app may name it after the client's file name): S3, or a CDN in front of it, serves the object with this
|
|
12633
|
+
* type. An upload of no known type is sent with none (served as binary).
|
|
12634
|
+
*/
|
|
12390
12635
|
async putFileAs(directory, file, name, options) {
|
|
12391
12636
|
const path = joinDiskPath(directory, name);
|
|
12392
|
-
await this.
|
|
12637
|
+
await this.putObject(path, new Uint8Array(await file.arrayBuffer()), options?.mimeType ?? mimeFromExtension(file.extension()), options);
|
|
12393
12638
|
return path;
|
|
12394
12639
|
}
|
|
12640
|
+
async putObject(path, body, contentType, options) {
|
|
12641
|
+
await this.client.send(
|
|
12642
|
+
new PutObjectCommand({
|
|
12643
|
+
Bucket: this.config.bucket,
|
|
12644
|
+
Key: path,
|
|
12645
|
+
Body: body,
|
|
12646
|
+
ContentType: contentType,
|
|
12647
|
+
ACL: options?.visibility === "public" ? "public-read" : void 0
|
|
12648
|
+
})
|
|
12649
|
+
);
|
|
12650
|
+
}
|
|
12395
12651
|
async delete(paths) {
|
|
12396
12652
|
for (const path of Array.isArray(paths) ? paths : [paths]) {
|
|
12397
12653
|
await this.client.send(new DeleteObjectCommand({ Bucket: this.config.bucket, Key: path }));
|
|
@@ -13814,8 +14070,8 @@ var InertiaMiddleware = class {
|
|
|
13814
14070
|
bag,
|
|
13815
14071
|
Object.fromEntries(
|
|
13816
14072
|
Object.entries(fields ?? {}).map(([field, messages]) => {
|
|
13817
|
-
const
|
|
13818
|
-
return [field, this.withAllErrors ?
|
|
14073
|
+
const list4 = Array.isArray(messages) ? messages.map(String) : [String(messages)];
|
|
14074
|
+
return [field, this.withAllErrors ? list4 : list4[0] ?? ""];
|
|
13819
14075
|
})
|
|
13820
14076
|
)
|
|
13821
14077
|
])
|
|
@@ -14667,8 +14923,8 @@ function normalizeAddress(recipient) {
|
|
|
14667
14923
|
}
|
|
14668
14924
|
function normalizeAddresses(recipients) {
|
|
14669
14925
|
if (recipients === void 0) return [];
|
|
14670
|
-
const
|
|
14671
|
-
return
|
|
14926
|
+
const list4 = Array.isArray(recipients) ? recipients : [recipients];
|
|
14927
|
+
return list4.map(normalizeAddress);
|
|
14672
14928
|
}
|
|
14673
14929
|
function formatAddress(address) {
|
|
14674
14930
|
return address.name ? `${address.name} <${address.address}>` : address.address;
|
|
@@ -14837,7 +15093,7 @@ var Mailable = class {
|
|
|
14837
15093
|
var SHOULD_QUEUE4 = /* @__PURE__ */ Symbol.for("oriel:bus.shouldQueue");
|
|
14838
15094
|
function isQueueableMailable(mailable) {
|
|
14839
15095
|
const record = mailable;
|
|
14840
|
-
if (record[SHOULD_QUEUE4] === true) return true;
|
|
15096
|
+
if (record.shouldQueue === true || record[SHOULD_QUEUE4] === true) return true;
|
|
14841
15097
|
return record.connection !== void 0 || record.queue !== void 0 || record.delay !== void 0 || record.tries !== void 0 || record.backoff !== void 0 || record.timeout !== void 0 || typeof record.uniqueId === "function" || typeof record.retryUntil === "function";
|
|
14842
15098
|
}
|
|
14843
15099
|
var MailerImpl = class {
|
|
@@ -15285,47 +15541,10 @@ var MailNotificationChannel = class {
|
|
|
15285
15541
|
}
|
|
15286
15542
|
};
|
|
15287
15543
|
var NOTIFICATIONS_TABLE = "notifications";
|
|
15288
|
-
|
|
15289
|
-
function parseStoredDate2(value2) {
|
|
15290
|
-
if (value2 instanceof Date) return value2;
|
|
15291
|
-
if (typeof value2 === "number") return new Date(value2);
|
|
15292
|
-
const text3 = String(value2);
|
|
15293
|
-
return ZONELESS_TIMESTAMP.test(text3) ? /* @__PURE__ */ new Date(`${text3.replace(" ", "T")}Z`) : new Date(text3);
|
|
15294
|
-
}
|
|
15295
|
-
function wrapRow(row, db) {
|
|
15296
|
-
const record = {
|
|
15297
|
-
id: String(row.id),
|
|
15298
|
-
type: String(row.type),
|
|
15299
|
-
data: JSON.parse(String(row.data)),
|
|
15300
|
-
createdAt: parseStoredDate2(row.created_at),
|
|
15301
|
-
updatedAt: parseStoredDate2(row.updated_at),
|
|
15302
|
-
readAt: row.read_at ? parseStoredDate2(row.read_at) : void 0,
|
|
15303
|
-
async markAsRead() {
|
|
15304
|
-
if (record.readAt) return;
|
|
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;
|
|
15308
|
-
},
|
|
15309
|
-
async markAsUnread() {
|
|
15310
|
-
if (!record.readAt) return;
|
|
15311
|
-
await db.table(NOTIFICATIONS_TABLE).where("id", record.id).update({ read_at: null, updated_at: /* @__PURE__ */ new Date() });
|
|
15312
|
-
record.readAt = void 0;
|
|
15313
|
-
}
|
|
15314
|
-
};
|
|
15315
|
-
return record;
|
|
15316
|
-
}
|
|
15317
|
-
function requireDatabase() {
|
|
15544
|
+
function requireDatabase(connection) {
|
|
15318
15545
|
const container = currentContainer();
|
|
15319
15546
|
if (!container?.bound(DatabaseManager)) throw new DatabaseUnavailableError();
|
|
15320
|
-
return container.make(DatabaseManager).connection();
|
|
15321
|
-
}
|
|
15322
|
-
async function fetchNotifications(notifiableType, notifiableId, filter = "all") {
|
|
15323
|
-
const db = requireDatabase();
|
|
15324
|
-
let query = db.table(NOTIFICATIONS_TABLE).where("notifiable_type", notifiableType).where("notifiable_id", notifiableId).orderBy("created_at", "desc");
|
|
15325
|
-
if (filter === "unread") query = query.whereNull("read_at");
|
|
15326
|
-
if (filter === "read") query = query.whereNotNull("read_at");
|
|
15327
|
-
const rows = await query.get();
|
|
15328
|
-
return rows.all().map((row) => wrapRow(row, db));
|
|
15547
|
+
return container.make(DatabaseManager).connection(connection);
|
|
15329
15548
|
}
|
|
15330
15549
|
var DatabaseNotificationChannel = class {
|
|
15331
15550
|
async send(notifiable, notification) {
|
|
@@ -15335,12 +15554,12 @@ var DatabaseNotificationChannel = class {
|
|
|
15335
15554
|
const data = notification.toDatabase ? notification.toDatabase(notifiable) : notification.toArray(notifiable);
|
|
15336
15555
|
const model = notifiable;
|
|
15337
15556
|
if (typeof model.getKey !== "function") throw new NotDatabaseNotifiableError(notifiable.constructor.name);
|
|
15338
|
-
const db = requireDatabase();
|
|
15557
|
+
const db = requireDatabase(typeof model.getConnectionName === "function" ? model.getConnectionName() : void 0);
|
|
15339
15558
|
const now5 = /* @__PURE__ */ new Date();
|
|
15340
15559
|
await db.table(NOTIFICATIONS_TABLE).insert({
|
|
15341
15560
|
id: notification.id ?? randomUUID4(),
|
|
15342
15561
|
type: notification.constructor.name,
|
|
15343
|
-
notifiable_type: notifiable.constructor.name,
|
|
15562
|
+
notifiable_type: typeof model.getMorphClass === "function" ? model.getMorphClass() : notifiable.constructor.name,
|
|
15344
15563
|
notifiable_id: model.getKey(),
|
|
15345
15564
|
data: JSON.stringify(data),
|
|
15346
15565
|
read_at: null,
|
|
@@ -15374,13 +15593,8 @@ function resolveDispatcher() {
|
|
|
15374
15593
|
if (!container?.bound(NotificationDispatcher)) throw new NotificationDispatcherUnavailableError();
|
|
15375
15594
|
return container.make(NotificationDispatcher);
|
|
15376
15595
|
}
|
|
15377
|
-
function
|
|
15378
|
-
|
|
15379
|
-
if (typeof model.getKey !== "function") throw new NotDatabaseNotifiableError(instance.constructor.name);
|
|
15380
|
-
return model.getKey();
|
|
15381
|
-
}
|
|
15382
|
-
function Notifiable(Base) {
|
|
15383
|
-
return class NotifiableMixin extends Base {
|
|
15596
|
+
function RoutesNotifications(Base) {
|
|
15597
|
+
return class RoutesNotificationsMixin extends Base {
|
|
15384
15598
|
routeNotificationFor(channel, notification) {
|
|
15385
15599
|
const custom = this[`routeNotificationFor${Str.studly(channel)}`];
|
|
15386
15600
|
if (typeof custom === "function") return custom.call(this, notification);
|
|
@@ -15397,15 +15611,6 @@ function Notifiable(Base) {
|
|
|
15397
15611
|
async notifyNow(notification, channels) {
|
|
15398
15612
|
await resolveDispatcher().sendNow(this, notification, channels);
|
|
15399
15613
|
}
|
|
15400
|
-
notifications() {
|
|
15401
|
-
return fetchNotifications(this.constructor.name, requireKey(this));
|
|
15402
|
-
}
|
|
15403
|
-
unreadNotifications() {
|
|
15404
|
-
return fetchNotifications(this.constructor.name, requireKey(this), "unread");
|
|
15405
|
-
}
|
|
15406
|
-
readNotifications() {
|
|
15407
|
-
return fetchNotifications(this.constructor.name, requireKey(this), "read");
|
|
15408
|
-
}
|
|
15409
15614
|
};
|
|
15410
15615
|
}
|
|
15411
15616
|
var AnonymousNotifiable = class {
|
|
@@ -15475,7 +15680,7 @@ var SendQueuedNotifications = class {
|
|
|
15475
15680
|
SendQueuedNotifications.prototype[SHOULD_QUEUE5] = true;
|
|
15476
15681
|
function isQueueableNotification(notification) {
|
|
15477
15682
|
const record = notification;
|
|
15478
|
-
if (record[SHOULD_QUEUE5] === true) return true;
|
|
15683
|
+
if (record.shouldQueue === true || record[SHOULD_QUEUE5] === true) return true;
|
|
15479
15684
|
return record.connection !== void 0 || record.queue !== void 0 || record.delay !== void 0 || record.tries !== void 0 || record.backoff !== void 0 || record.timeout !== void 0 || typeof record.uniqueId === "function" || typeof record.retryUntil === "function";
|
|
15480
15685
|
}
|
|
15481
15686
|
function forNotifiable(notification) {
|
|
@@ -15513,12 +15718,12 @@ var Dispatcher3 = class {
|
|
|
15513
15718
|
return channel;
|
|
15514
15719
|
}
|
|
15515
15720
|
async send(notifiables, notification) {
|
|
15516
|
-
const
|
|
15517
|
-
if (
|
|
15721
|
+
const list4 = toNotifiableList(notifiables);
|
|
15722
|
+
if (list4.length === 0) return;
|
|
15518
15723
|
if (isQueueableNotification(notification)) {
|
|
15519
15724
|
if (!this.container.bound(BusDispatcher)) throw new NotificationQueueUnavailableError();
|
|
15520
15725
|
const bus = this.container.make(BusDispatcher);
|
|
15521
|
-
for (const notifiable of
|
|
15726
|
+
for (const notifiable of list4) {
|
|
15522
15727
|
const own = forNotifiable(notification);
|
|
15523
15728
|
for (const channel of notification.via(notifiable)) {
|
|
15524
15729
|
await bus.dispatch(new SendQueuedNotifications([notifiable], own, [channel]));
|
|
@@ -15526,11 +15731,11 @@ var Dispatcher3 = class {
|
|
|
15526
15731
|
}
|
|
15527
15732
|
return;
|
|
15528
15733
|
}
|
|
15529
|
-
await this.sendNow(
|
|
15734
|
+
await this.sendNow(list4, notification);
|
|
15530
15735
|
}
|
|
15531
15736
|
async sendNow(notifiables, notification, channels) {
|
|
15532
|
-
const
|
|
15533
|
-
for (const notifiable of
|
|
15737
|
+
const list4 = toNotifiableList(notifiables);
|
|
15738
|
+
for (const notifiable of list4) {
|
|
15534
15739
|
const own = forNotifiable(notification);
|
|
15535
15740
|
const names = channels ?? notification.via(notifiable);
|
|
15536
15741
|
for (const name of names) {
|
|
@@ -17305,7 +17510,7 @@ function discoverJobs(directory, registry2) {
|
|
|
17305
17510
|
return discoverClasses(directory, registry2, isJobClass);
|
|
17306
17511
|
}
|
|
17307
17512
|
var text2 = (value2) => optionalString2(value2) || void 0;
|
|
17308
|
-
var
|
|
17513
|
+
var list3 = (value2) => Array.isArray(value2) ? value2.map(String) : text2(value2) ? [String(value2)] : [];
|
|
17309
17514
|
var number2 = (value2, fallback) => {
|
|
17310
17515
|
const parsed = Number(value2);
|
|
17311
17516
|
return value2 === void 0 || value2 === null || value2 === "" || Number.isNaN(parsed) ? fallback : parsed;
|
|
@@ -17393,7 +17598,7 @@ function registerQueueCommands(kernel, context) {
|
|
|
17393
17598
|
'queue:retry {id?* : The ID of the failed job or "all" to retry all jobs} {--queue= : Retry all of the failed jobs for the specified queue}',
|
|
17394
17599
|
"Retry a failed queue job",
|
|
17395
17600
|
async (out) => {
|
|
17396
|
-
const ids = await retryableIds(
|
|
17601
|
+
const ids = await retryableIds(list3(out.argument("id")), text2(out.option("queue")));
|
|
17397
17602
|
if (ids.length === 0) {
|
|
17398
17603
|
out.info("No retryable jobs found.");
|
|
17399
17604
|
return 0;
|
|
@@ -18215,6 +18420,14 @@ var BaseRouter = class {
|
|
|
18215
18420
|
getModel(parameter) {
|
|
18216
18421
|
return this.#models.get(parameter);
|
|
18217
18422
|
}
|
|
18423
|
+
/**
|
|
18424
|
+
* Binds a matched route's raw parameter values as a request to it would: Route.bind() callbacks, Route.model(),
|
|
18425
|
+
* then implicit binding through the RouteModelResolver of `container`. A missing model throws
|
|
18426
|
+
* RouteModelNotFoundError (404). Live uses it to check a page route's `can:` middleware again on each update.
|
|
18427
|
+
*/
|
|
18428
|
+
substituteBindings(route2, values, container) {
|
|
18429
|
+
return substituteBindings(this, route2, values, container);
|
|
18430
|
+
}
|
|
18218
18431
|
aliasMiddleware(name, middleware) {
|
|
18219
18432
|
this.#aliases[name] = middleware;
|
|
18220
18433
|
return this;
|
|
@@ -18228,20 +18441,20 @@ var BaseRouter = class {
|
|
|
18228
18441
|
return this;
|
|
18229
18442
|
}
|
|
18230
18443
|
pushMiddlewareToGroup(group, middleware) {
|
|
18231
|
-
const
|
|
18232
|
-
if (!
|
|
18444
|
+
const list4 = this.#groups[group] ??= [];
|
|
18445
|
+
if (!list4.includes(middleware)) list4.push(middleware);
|
|
18233
18446
|
return this;
|
|
18234
18447
|
}
|
|
18235
18448
|
prependMiddlewareToGroup(group, middleware) {
|
|
18236
|
-
const
|
|
18237
|
-
if (!
|
|
18449
|
+
const list4 = this.#groups[group] ??= [];
|
|
18450
|
+
if (!list4.includes(middleware)) list4.unshift(middleware);
|
|
18238
18451
|
return this;
|
|
18239
18452
|
}
|
|
18240
18453
|
hasMiddlewareGroup(name) {
|
|
18241
18454
|
return Object.hasOwn(this.#groups, name);
|
|
18242
18455
|
}
|
|
18243
18456
|
getMiddlewareGroups() {
|
|
18244
|
-
return Object.fromEntries(Object.entries(this.#groups).map(([name,
|
|
18457
|
+
return Object.fromEntries(Object.entries(this.#groups).map(([name, list4]) => [name, [...list4]]));
|
|
18245
18458
|
}
|
|
18246
18459
|
/** Every route, in registration order. */
|
|
18247
18460
|
getRoutes() {
|
|
@@ -18483,6 +18696,48 @@ var BaseUrlGenerator = class {
|
|
|
18483
18696
|
}
|
|
18484
18697
|
};
|
|
18485
18698
|
var Route = facade(Router);
|
|
18699
|
+
var DiagnosingHealth = class {
|
|
18700
|
+
};
|
|
18701
|
+
var escapeHtml3 = (value2) => value2.replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
|
|
18702
|
+
var STYLE = ':root{color-scheme:dark}*{box-sizing:border-box;margin:0}html{background:#05050b}body{min-height:100vh;display:grid;place-items:center;padding:20px;background:#1a1a1a;color:#fff;font:400 16px/1.7 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif}main{display:flex;align-items:center;gap:20px;width:100%;max-width:640px;padding:20px 32px;border-radius:18px;background:#212121}.dot{flex:none;width:12px;height:12px;border-radius:50%;background:#74ec5a}.dot.down{background:#ff3543}h1{font-size:21px;line-height:1.4;font-weight:600}p{color:#a3a3a3}.time{color:#ba94ff}';
|
|
18703
|
+
function healthResponse(page = {}) {
|
|
18704
|
+
const healthy = page.healthy ?? true;
|
|
18705
|
+
const time = page.milliseconds === void 0 ? "" : ` Response rendered in <span class="time">${Math.round(page.milliseconds)} ms</span>.`;
|
|
18706
|
+
const html2 = `<!DOCTYPE html>
|
|
18707
|
+
<html lang="en">
|
|
18708
|
+
<head>
|
|
18709
|
+
<meta charset="utf-8">
|
|
18710
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
18711
|
+
<title>${escapeHtml3(page.appName ?? "Oriel")}</title>
|
|
18712
|
+
<style>${STYLE}</style>
|
|
18713
|
+
</head>
|
|
18714
|
+
<body>
|
|
18715
|
+
<main>
|
|
18716
|
+
<span class="${healthy ? "dot" : "dot down"}" aria-hidden="true"></span>
|
|
18717
|
+
<div>
|
|
18718
|
+
<h1>Application ${healthy ? "up" : "experiencing problems"}</h1>
|
|
18719
|
+
<p>HTTP request received.${time}</p>
|
|
18720
|
+
</div>
|
|
18721
|
+
</main>
|
|
18722
|
+
</body>
|
|
18723
|
+
</html>
|
|
18724
|
+
`;
|
|
18725
|
+
return new Response(html2, { status: healthy ? 200 : 500, headers: { "content-type": "text/html; charset=utf-8" } });
|
|
18726
|
+
}
|
|
18727
|
+
async function diagnoseHealth(app2) {
|
|
18728
|
+
const started = performance.now();
|
|
18729
|
+
const config2 = app2.bound(ConfigRepository) ? app2.make(ConfigRepository) : void 0;
|
|
18730
|
+
let healthy = true;
|
|
18731
|
+
try {
|
|
18732
|
+
if (app2.bound(EventDispatcher)) await app2.make(EventDispatcher).dispatch(new DiagnosingHealth());
|
|
18733
|
+
} catch (error) {
|
|
18734
|
+
if (config2?.get("app.debug", false) === true) throw error;
|
|
18735
|
+
if (app2.bound(ExceptionHandler)) await app2.make(ExceptionHandler).report(error);
|
|
18736
|
+
healthy = false;
|
|
18737
|
+
}
|
|
18738
|
+
const appName2 = String(config2?.get("app.name", "Oriel") ?? "Oriel");
|
|
18739
|
+
return healthResponse({ healthy, appName: appName2, milliseconds: performance.now() - started });
|
|
18740
|
+
}
|
|
18486
18741
|
var generation2 = 0;
|
|
18487
18742
|
async function loadRoutesFrom(app2, router, file) {
|
|
18488
18743
|
const url2 = `${pathToFileURL7(file).href}?oriel-routes=${++generation2}`;
|
|
@@ -18492,10 +18747,6 @@ async function loadRoutesFrom(app2, router, file) {
|
|
|
18492
18747
|
));
|
|
18493
18748
|
if (typeof module.default === "function") await app2.run(() => module.default(router));
|
|
18494
18749
|
}
|
|
18495
|
-
function healthResponse() {
|
|
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>';
|
|
18497
|
-
return new Response(html2, { status: 200, headers: { "content-type": "text/html; charset=utf-8" } });
|
|
18498
|
-
}
|
|
18499
18750
|
var sha12 = (value2) => createHash8("sha1").update(value2).digest("hex");
|
|
18500
18751
|
function withHeaders2(response2, headers) {
|
|
18501
18752
|
try {
|
|
@@ -18572,7 +18823,7 @@ var RoutingServiceProvider = class extends ServiceProvider {
|
|
|
18572
18823
|
if (!this.app.bound(RoutingPaths)) return;
|
|
18573
18824
|
const { web, api, health, apiPrefix } = this.app.make(RoutingPaths);
|
|
18574
18825
|
const router = this.app.make(Router);
|
|
18575
|
-
if (health !== void 0) router.get(health, () =>
|
|
18826
|
+
if (health !== void 0) router.get(health, () => diagnoseHealth(this.app));
|
|
18576
18827
|
if (web !== void 0) await router.middleware("web").group(() => this.#load(router, web));
|
|
18577
18828
|
if (api !== void 0) await router.prefix(apiPrefix).middleware("api").group(() => this.#load(router, api));
|
|
18578
18829
|
});
|
|
@@ -18656,8 +18907,8 @@ var Store = class {
|
|
|
18656
18907
|
for (const [name, item] of Object.entries(values)) Arr.set(this.#attributes, name, item);
|
|
18657
18908
|
}
|
|
18658
18909
|
push(key, value2) {
|
|
18659
|
-
const
|
|
18660
|
-
this.put(key, [...Array.isArray(
|
|
18910
|
+
const list4 = this.get(key, []);
|
|
18911
|
+
this.put(key, [...Array.isArray(list4) ? list4 : [list4], value2]);
|
|
18661
18912
|
}
|
|
18662
18913
|
increment(key, amount = 1) {
|
|
18663
18914
|
const value2 = Number(this.get(key, 0)) + amount;
|
|
@@ -19323,7 +19574,7 @@ var ValidationErrorImpl = class extends Error {
|
|
|
19323
19574
|
var ValidationException = class _ValidationException extends ValidationErrorImpl {
|
|
19324
19575
|
/** Messages per field, each a string or a list. */
|
|
19325
19576
|
static withMessages(messages) {
|
|
19326
|
-
const errors2 = Object.fromEntries(Object.entries(messages).map(([field,
|
|
19577
|
+
const errors2 = Object.fromEntries(Object.entries(messages).map(([field, list4]) => [field, typeof list4 === "string" ? [list4] : [...list4]]));
|
|
19327
19578
|
return new _ValidationException(errors2);
|
|
19328
19579
|
}
|
|
19329
19580
|
constructor(errors2, errorBag = "default", redirectTo2) {
|
|
@@ -19434,6 +19685,9 @@ var DEFAULT_MESSAGES = {
|
|
|
19434
19685
|
file: "The :attribute field must be a file.",
|
|
19435
19686
|
image: "The :attribute field must be an image.",
|
|
19436
19687
|
mimes: "The :attribute field must be a file of type: :values.",
|
|
19688
|
+
mimetypes: "The :attribute field must be a file of type: :values.",
|
|
19689
|
+
extensions: "The :attribute field must have one of the following extensions: :values.",
|
|
19690
|
+
dimensions: "The :attribute field has invalid image dimensions.",
|
|
19437
19691
|
"max.string": "The :attribute field must not be greater than :max characters.",
|
|
19438
19692
|
"max.numeric": "The :attribute field must not be greater than :max.",
|
|
19439
19693
|
"max.array": "The :attribute field must not have more than :max items.",
|
|
@@ -19524,6 +19778,90 @@ var databaseRules = {
|
|
|
19524
19778
|
messageKey: () => "exists"
|
|
19525
19779
|
}
|
|
19526
19780
|
};
|
|
19781
|
+
var FRAME_MARKERS = /* @__PURE__ */ new Set([192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207]);
|
|
19782
|
+
var MAX_JPEG_STEPS = 1024;
|
|
19783
|
+
var MAX_BOXES = 1024;
|
|
19784
|
+
var fourcc = (view2, offset) => String.fromCharCode(view2.getUint8(offset), view2.getUint8(offset + 1), view2.getUint8(offset + 2), view2.getUint8(offset + 3));
|
|
19785
|
+
var u24le = (view2, offset) => view2.getUint8(offset) | view2.getUint8(offset + 1) << 8 | view2.getUint8(offset + 2) << 16;
|
|
19786
|
+
var READERS = {
|
|
19787
|
+
"image/png": (view2) => fourcc(view2, 12) === "IHDR" ? { width: view2.getUint32(16), height: view2.getUint32(20) } : void 0,
|
|
19788
|
+
"image/gif": (view2) => ({ width: view2.getUint16(6, true), height: view2.getUint16(8, true) }),
|
|
19789
|
+
"image/bmp": (view2) => view2.getUint32(14, true) === 12 ? { width: view2.getUint16(18, true), height: view2.getUint16(20, true) } : { width: Math.abs(view2.getInt32(18, true)), height: Math.abs(view2.getInt32(22, true)) },
|
|
19790
|
+
"image/jpeg": jpeg,
|
|
19791
|
+
"image/webp": webp,
|
|
19792
|
+
"image/avif": avif
|
|
19793
|
+
};
|
|
19794
|
+
function imageDimensions(bytes, mime) {
|
|
19795
|
+
const reader = READERS[mime];
|
|
19796
|
+
if (!reader) return void 0;
|
|
19797
|
+
try {
|
|
19798
|
+
const size = reader(new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength));
|
|
19799
|
+
return size && size.width > 0 && size.height > 0 ? size : void 0;
|
|
19800
|
+
} catch (error) {
|
|
19801
|
+
if (error instanceof RangeError) return void 0;
|
|
19802
|
+
throw error;
|
|
19803
|
+
}
|
|
19804
|
+
}
|
|
19805
|
+
function jpeg(view2) {
|
|
19806
|
+
let offset = 2;
|
|
19807
|
+
for (let step = 0; step < MAX_JPEG_STEPS && offset + 4 <= view2.byteLength; step++) {
|
|
19808
|
+
if (view2.getUint8(offset) !== 255) return void 0;
|
|
19809
|
+
const marker = view2.getUint8(offset + 1);
|
|
19810
|
+
if (marker === 255) offset += 1;
|
|
19811
|
+
else if (marker === 216 || marker === 1 || marker >= 208 && marker <= 215) offset += 2;
|
|
19812
|
+
else if (marker === 217 || marker === 218) return void 0;
|
|
19813
|
+
else if (FRAME_MARKERS.has(marker)) return { height: view2.getUint16(offset + 5), width: view2.getUint16(offset + 7) };
|
|
19814
|
+
else offset += 2 + view2.getUint16(offset + 2);
|
|
19815
|
+
}
|
|
19816
|
+
return void 0;
|
|
19817
|
+
}
|
|
19818
|
+
function webp(view2) {
|
|
19819
|
+
const chunk = fourcc(view2, 12);
|
|
19820
|
+
if (chunk === "VP8 ") {
|
|
19821
|
+
if (view2.getUint8(23) !== 157 || view2.getUint8(24) !== 1 || view2.getUint8(25) !== 42) return void 0;
|
|
19822
|
+
return { width: view2.getUint16(26, true) & 16383, height: view2.getUint16(28, true) & 16383 };
|
|
19823
|
+
}
|
|
19824
|
+
if (chunk === "VP8L") {
|
|
19825
|
+
if (view2.getUint8(20) !== 47) return void 0;
|
|
19826
|
+
const bits = view2.getUint32(21, true);
|
|
19827
|
+
return { width: (bits & 16383) + 1, height: (bits >>> 14 & 16383) + 1 };
|
|
19828
|
+
}
|
|
19829
|
+
if (chunk === "VP8X") return { width: u24le(view2, 24) + 1, height: u24le(view2, 27) + 1 };
|
|
19830
|
+
return void 0;
|
|
19831
|
+
}
|
|
19832
|
+
function* boxes(view2, start2, end) {
|
|
19833
|
+
let offset = start2;
|
|
19834
|
+
for (let count = 0; count < MAX_BOXES && offset + 8 <= end; count++) {
|
|
19835
|
+
let size = view2.getUint32(offset);
|
|
19836
|
+
let header = 8;
|
|
19837
|
+
if (size === 1) {
|
|
19838
|
+
size = Number(view2.getBigUint64(offset + 8));
|
|
19839
|
+
header = 16;
|
|
19840
|
+
} else if (size === 0) {
|
|
19841
|
+
size = end - offset;
|
|
19842
|
+
}
|
|
19843
|
+
if (size < header || offset + size > end) return;
|
|
19844
|
+
yield { type: fourcc(view2, offset + 4), start: offset + header, end: offset + size };
|
|
19845
|
+
offset += size;
|
|
19846
|
+
}
|
|
19847
|
+
}
|
|
19848
|
+
var findBox = (view2, start2, end, type) => {
|
|
19849
|
+
for (const box of boxes(view2, start2, end)) if (box.type === type) return box;
|
|
19850
|
+
return void 0;
|
|
19851
|
+
};
|
|
19852
|
+
function avif(view2) {
|
|
19853
|
+
const meta = findBox(view2, 0, view2.byteLength, "meta");
|
|
19854
|
+
const iprp = meta && findBox(view2, meta.start + 4, meta.end, "iprp");
|
|
19855
|
+
const ipco = iprp && findBox(view2, iprp.start, iprp.end, "ipco");
|
|
19856
|
+
if (!ipco) return void 0;
|
|
19857
|
+
let largest;
|
|
19858
|
+
for (const box of boxes(view2, ipco.start, ipco.end)) {
|
|
19859
|
+
if (box.type !== "ispe") continue;
|
|
19860
|
+
const size = { width: view2.getUint32(box.start + 4), height: view2.getUint32(box.start + 8) };
|
|
19861
|
+
if (!largest || size.width * size.height > largest.width * largest.height) largest = size;
|
|
19862
|
+
}
|
|
19863
|
+
return largest;
|
|
19864
|
+
}
|
|
19527
19865
|
function splitParameters(name, raw3) {
|
|
19528
19866
|
return name === "regex" || name === "not_regex" ? [raw3] : raw3.split(",");
|
|
19529
19867
|
}
|
|
@@ -19571,25 +19909,139 @@ function expandWildcardKeys(pattern, data) {
|
|
|
19571
19909
|
}
|
|
19572
19910
|
return paths;
|
|
19573
19911
|
}
|
|
19574
|
-
var
|
|
19912
|
+
var { BINARY_AND_MARKUP_TYPES, detectFileType, EMPTY: EMPTY2, RASTER_IMAGES, SVG, TEXT } = fileType_exports;
|
|
19913
|
+
var inspections = /* @__PURE__ */ new WeakMap();
|
|
19914
|
+
function inspect(file) {
|
|
19915
|
+
let inspection = inspections.get(file);
|
|
19916
|
+
if (!inspection) {
|
|
19917
|
+
inspection = file.arrayBuffer().then((buffer) => {
|
|
19918
|
+
const bytes = new Uint8Array(buffer);
|
|
19919
|
+
const type = detectFileType(bytes);
|
|
19920
|
+
return { type, dimensions: RASTER_IMAGES.has(type.mime) ? imageDimensions(bytes, type.mime) : void 0 };
|
|
19921
|
+
});
|
|
19922
|
+
inspections.set(file, inspection);
|
|
19923
|
+
}
|
|
19924
|
+
return inspection;
|
|
19925
|
+
}
|
|
19926
|
+
function clientExtension(file) {
|
|
19927
|
+
const name = file.clientName.slice(Math.max(file.clientName.lastIndexOf("/"), file.clientName.lastIndexOf("\\")) + 1);
|
|
19928
|
+
const dot = name.lastIndexOf(".");
|
|
19929
|
+
return dot === -1 ? "" : name.slice(dot + 1).trim().toLowerCase();
|
|
19930
|
+
}
|
|
19931
|
+
var PHP_EXTENSIONS = /* @__PURE__ */ new Set(["php", "php3", "php4", "php5", "php7", "php8", "phtml", "phar"]);
|
|
19932
|
+
var blocksPhp = (file, allowed) => !allowed.includes("php") && PHP_EXTENSIONS.has(clientExtension(file));
|
|
19933
|
+
var TEXT_FORMATS = /* @__PURE__ */ new Set(["txt", "text", "csv", "tsv", "json", "md"]);
|
|
19934
|
+
var RECOGNISED_EXTENSIONS = new Set(BINARY_AND_MARKUP_TYPES.flatMap(({ extensions }) => extensions));
|
|
19935
|
+
var lower = (values) => values.map((value2) => value2.trim().toLowerCase());
|
|
19936
|
+
function meetsMimes(type, extension, allowed) {
|
|
19937
|
+
if (type === EMPTY2) return false;
|
|
19938
|
+
if (type === TEXT && allowed.has("txt")) return true;
|
|
19939
|
+
if (type !== TEXT && type.extensions.length > 0) return type.extensions.some((name) => allowed.has(name));
|
|
19940
|
+
if (!allowed.has(extension) || RECOGNISED_EXTENSIONS.has(extension)) return false;
|
|
19941
|
+
return type === TEXT || !TEXT_FORMATS.has(extension);
|
|
19942
|
+
}
|
|
19943
|
+
function allowedExtensions(ctx) {
|
|
19944
|
+
const allowed = new Set(lower(ctx.parameters));
|
|
19945
|
+
if (allowed.has("jpg") || allowed.has("jpeg")) allowed.add("jpg").add("jpeg");
|
|
19946
|
+
return allowed;
|
|
19947
|
+
}
|
|
19948
|
+
var listed = (ctx) => ({ values: ctx.parameters.join(", ") });
|
|
19949
|
+
var DIMENSION_KEYS = ["width", "height", "min_width", "min_height", "max_width", "max_height", "ratio"];
|
|
19950
|
+
function namedParameter(parameter) {
|
|
19951
|
+
const at = parameter.indexOf("=");
|
|
19952
|
+
return at === -1 ? [parameter, ""] : [parameter.slice(0, at), parameter.slice(at + 1)];
|
|
19953
|
+
}
|
|
19954
|
+
function parseRatio(value2) {
|
|
19955
|
+
const match = /^(\d+(?:\.\d+)?|\.\d+)(?:\/(\d+))?$/.exec(value2.trim());
|
|
19956
|
+
if (!match) return void 0;
|
|
19957
|
+
const ratio = Number(match[1]) / Number(match[2] ?? 1);
|
|
19958
|
+
return Number.isFinite(ratio) && ratio > 0 ? ratio : void 0;
|
|
19959
|
+
}
|
|
19960
|
+
function dimensionConstraints(parameters) {
|
|
19961
|
+
if (parameters.length === 0) throw new InvalidRuleParameterError("dimensions", "", `expected one or more of ${DIMENSION_KEYS.join(", ")}`);
|
|
19962
|
+
const constraints = {};
|
|
19963
|
+
for (const parameter of parameters) {
|
|
19964
|
+
const [key, value2] = namedParameter(parameter);
|
|
19965
|
+
if (!DIMENSION_KEYS.includes(key)) {
|
|
19966
|
+
throw new InvalidRuleParameterError("dimensions", parameter, `expected one of ${DIMENSION_KEYS.join(", ")}`);
|
|
19967
|
+
}
|
|
19968
|
+
const number3 = key === "ratio" ? parseRatio(value2) : /^\d+$/.test(value2) ? Number(value2) : void 0;
|
|
19969
|
+
if (number3 === void 0) {
|
|
19970
|
+
throw new InvalidRuleParameterError("dimensions", parameter, key === "ratio" ? "expected a ratio such as 3/2 or 1.5" : "expected a whole number of pixels");
|
|
19971
|
+
}
|
|
19972
|
+
constraints[key] = number3;
|
|
19973
|
+
}
|
|
19974
|
+
return constraints;
|
|
19975
|
+
}
|
|
19976
|
+
function meetsDimensions(constraints, { width, height }) {
|
|
19977
|
+
const { width: exactWidth, height: exactHeight, min_width, max_width, min_height, max_height, ratio } = constraints;
|
|
19978
|
+
if (exactWidth !== void 0 && width !== exactWidth) return false;
|
|
19979
|
+
if (exactHeight !== void 0 && height !== exactHeight) return false;
|
|
19980
|
+
if (min_width !== void 0 && width < min_width) return false;
|
|
19981
|
+
if (max_width !== void 0 && width > max_width) return false;
|
|
19982
|
+
if (min_height !== void 0 && height < min_height) return false;
|
|
19983
|
+
if (max_height !== void 0 && height > max_height) return false;
|
|
19984
|
+
return ratio === void 0 || Math.abs(ratio - width / height) <= 1 / (Math.max((width + height) / 2, height) + 1);
|
|
19985
|
+
}
|
|
19575
19986
|
var fileRules = {
|
|
19576
19987
|
file: { validate: (ctx) => isUploadedFileLike(ctx.value), messageKey: () => "file" },
|
|
19988
|
+
/** A JPEG, PNG, GIF, WebP, AVIF or BMP by its bytes; SVG only as `image:allow_svg` (Laravel 12). */
|
|
19577
19989
|
image: {
|
|
19578
|
-
validate: (ctx) => {
|
|
19579
|
-
if (!isUploadedFileLike(ctx.value)) return false;
|
|
19580
|
-
|
|
19581
|
-
return
|
|
19990
|
+
validate: async (ctx) => {
|
|
19991
|
+
if (!isUploadedFileLike(ctx.value) || blocksPhp(ctx.value, [])) return false;
|
|
19992
|
+
const { type } = await inspect(ctx.value);
|
|
19993
|
+
return RASTER_IMAGES.has(type.mime) || type === SVG && ctx.parameters.includes("allow_svg");
|
|
19582
19994
|
},
|
|
19583
19995
|
messageKey: () => "image"
|
|
19584
19996
|
},
|
|
19585
19997
|
mimes: {
|
|
19586
|
-
validate: (ctx) => {
|
|
19998
|
+
validate: async (ctx) => {
|
|
19587
19999
|
if (!isUploadedFileLike(ctx.value)) return false;
|
|
19588
|
-
const allowed = ctx
|
|
19589
|
-
|
|
20000
|
+
const allowed = allowedExtensions(ctx);
|
|
20001
|
+
if (blocksPhp(ctx.value, [...allowed])) return false;
|
|
20002
|
+
return meetsMimes((await inspect(ctx.value)).type, clientExtension(ctx.value), allowed);
|
|
19590
20003
|
},
|
|
19591
20004
|
messageKey: () => "mimes",
|
|
19592
|
-
replacements:
|
|
20005
|
+
replacements: listed
|
|
20006
|
+
},
|
|
20007
|
+
/**
|
|
20008
|
+
* The detected MIME type is listed, or its `type/*` wildcard is. `image/*` includes SVG (`image/svg+xml`), as in
|
|
20009
|
+
* Laravel: the rule for photos is `image`.
|
|
20010
|
+
*/
|
|
20011
|
+
mimetypes: {
|
|
20012
|
+
validate: async (ctx) => {
|
|
20013
|
+
if (!isUploadedFileLike(ctx.value)) return false;
|
|
20014
|
+
const allowed = lower(ctx.parameters);
|
|
20015
|
+
if (blocksPhp(ctx.value, allowed)) return false;
|
|
20016
|
+
const { mime } = (await inspect(ctx.value)).type;
|
|
20017
|
+
return allowed.includes(mime) || allowed.includes(`${mime.split("/")[0]}/*`);
|
|
20018
|
+
},
|
|
20019
|
+
messageKey: () => "mimetypes",
|
|
20020
|
+
replacements: listed
|
|
20021
|
+
},
|
|
20022
|
+
/**
|
|
20023
|
+
* The pixel size read from the image's header meets every constraint: width, height, min_width, max_width,
|
|
20024
|
+
* min_height, max_height, ratio. SVG and images whose header can't be read fail.
|
|
20025
|
+
*/
|
|
20026
|
+
dimensions: {
|
|
20027
|
+
validate: async (ctx) => {
|
|
20028
|
+
const constraints = dimensionConstraints(ctx.parameters);
|
|
20029
|
+
if (!isUploadedFileLike(ctx.value)) return false;
|
|
20030
|
+
const { dimensions } = await inspect(ctx.value);
|
|
20031
|
+
return dimensions !== void 0 && meetsDimensions(constraints, dimensions);
|
|
20032
|
+
},
|
|
20033
|
+
messageKey: () => "dimensions",
|
|
20034
|
+
replacements: (ctx) => Object.fromEntries(ctx.parameters.map(namedParameter))
|
|
20035
|
+
},
|
|
20036
|
+
/** The client file name's extension is listed (Laravel 11). It checks the name only: pair it with mimes or image. */
|
|
20037
|
+
extensions: {
|
|
20038
|
+
validate: (ctx) => {
|
|
20039
|
+
if (!isUploadedFileLike(ctx.value)) return false;
|
|
20040
|
+
const allowed = lower(ctx.parameters);
|
|
20041
|
+
return !blocksPhp(ctx.value, allowed) && allowed.includes(clientExtension(ctx.value));
|
|
20042
|
+
},
|
|
20043
|
+
messageKey: () => "extensions",
|
|
20044
|
+
replacements: listed
|
|
19593
20045
|
}
|
|
19594
20046
|
};
|
|
19595
20047
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -20276,6 +20728,11 @@ var Notification2 = class extends Notification {
|
|
|
20276
20728
|
return NotificationFake.fake(...args);
|
|
20277
20729
|
}
|
|
20278
20730
|
};
|
|
20731
|
+
|
|
20732
|
+
// notifiable.ts
|
|
20733
|
+
function Notifiable(Base) {
|
|
20734
|
+
return RoutesNotifications(HasDatabaseNotifications(Base));
|
|
20735
|
+
}
|
|
20279
20736
|
export {
|
|
20280
20737
|
API_ROUTES_STUB,
|
|
20281
20738
|
AboutCommand,
|
|
@@ -20299,6 +20756,7 @@ export {
|
|
|
20299
20756
|
AuthenticatableModel,
|
|
20300
20757
|
Authenticate,
|
|
20301
20758
|
AuthenticationError,
|
|
20759
|
+
Authorizable,
|
|
20302
20760
|
AuthorizationError,
|
|
20303
20761
|
AuthorizationErrorImpl,
|
|
20304
20762
|
Authorize,
|
|
@@ -20347,6 +20805,7 @@ export {
|
|
|
20347
20805
|
ConsoleServiceProvider,
|
|
20348
20806
|
Container2 as Container,
|
|
20349
20807
|
ContainerNotAvailableError,
|
|
20808
|
+
Controller,
|
|
20350
20809
|
ControllerMethodNotFoundError,
|
|
20351
20810
|
ConvertEmptyStringsToNull,
|
|
20352
20811
|
Cookie,
|
|
@@ -20368,7 +20827,10 @@ export {
|
|
|
20368
20827
|
DatabaseJob,
|
|
20369
20828
|
DatabaseLock,
|
|
20370
20829
|
DatabaseManagerImpl,
|
|
20830
|
+
DatabaseNotification,
|
|
20371
20831
|
DatabaseNotificationChannel,
|
|
20832
|
+
DatabaseNotificationCollection,
|
|
20833
|
+
DatabaseNotificationsRelation,
|
|
20372
20834
|
DatabaseQueue,
|
|
20373
20835
|
DatabaseServiceProvider,
|
|
20374
20836
|
DatabaseSessionHandler,
|
|
@@ -20377,6 +20839,7 @@ export {
|
|
|
20377
20839
|
DatabaseUnavailableError,
|
|
20378
20840
|
DecryptError,
|
|
20379
20841
|
DeferProp,
|
|
20842
|
+
DiagnosingHealth,
|
|
20380
20843
|
Dispatchable,
|
|
20381
20844
|
ELEMENT,
|
|
20382
20845
|
EloquentUserProvider,
|
|
@@ -20412,13 +20875,14 @@ export {
|
|
|
20412
20875
|
FormRequest,
|
|
20413
20876
|
FormUploadedFile,
|
|
20414
20877
|
Fragment,
|
|
20415
|
-
|
|
20878
|
+
Gate4 as Gate,
|
|
20416
20879
|
GateResponse,
|
|
20417
20880
|
GeneratorCommand,
|
|
20418
20881
|
GenericLock,
|
|
20419
20882
|
Grammar,
|
|
20420
20883
|
GroupRegistrar,
|
|
20421
20884
|
HasApiTokens,
|
|
20885
|
+
HasDatabaseNotifications,
|
|
20422
20886
|
HasMany,
|
|
20423
20887
|
HasManyThrough,
|
|
20424
20888
|
HasOne,
|
|
@@ -20559,6 +21023,7 @@ export {
|
|
|
20559
21023
|
OptionalProp,
|
|
20560
21024
|
PERSISTENT_MIDDLEWARE,
|
|
20561
21025
|
PERSONAL_ACCESS_TOKENS_MIGRATION,
|
|
21026
|
+
Pagination,
|
|
20562
21027
|
Paginator,
|
|
20563
21028
|
Password,
|
|
20564
21029
|
PasswordBroker2 as PasswordBroker,
|
|
@@ -20613,6 +21078,7 @@ export {
|
|
|
20613
21078
|
RouteModelNotFoundError,
|
|
20614
21079
|
RouteModelResolverImpl,
|
|
20615
21080
|
RouteNotDefinedError,
|
|
21081
|
+
RoutesNotifications,
|
|
20616
21082
|
RoutingError,
|
|
20617
21083
|
RoutingServiceProvider,
|
|
20618
21084
|
Rule,
|
|
@@ -20710,6 +21176,7 @@ export {
|
|
|
20710
21176
|
ViteError,
|
|
20711
21177
|
ViteHtml,
|
|
20712
21178
|
WORKER_DISCOVERY_DIRECTORIES,
|
|
21179
|
+
WithPagination,
|
|
20713
21180
|
WithoutOverlapping,
|
|
20714
21181
|
Worker,
|
|
20715
21182
|
__,
|
|
@@ -20787,7 +21254,6 @@ export {
|
|
|
20787
21254
|
extensionFromMime,
|
|
20788
21255
|
facade,
|
|
20789
21256
|
fake,
|
|
20790
|
-
fetchNotifications,
|
|
20791
21257
|
filterRouteList,
|
|
20792
21258
|
formatAddress,
|
|
20793
21259
|
formatDate,
|