@orieljs/framework 0.1.0-alpha.5 → 0.1.0-alpha.6
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/NOTICE +3 -0
- package/dist/{chunk-BSQKOLSK.js → chunk-I63ZFMX6.js} +1 -1
- package/dist/{chunk-BSQKOLSK.js.map → chunk-I63ZFMX6.js.map} +1 -1
- package/dist/{chunk-A5XRLEWM.js → chunk-MFTZQMZM.js} +3 -3
- package/dist/chunk-POEP4B2M.js +2613 -0
- package/dist/chunk-POEP4B2M.js.map +1 -0
- package/dist/{chunk-WNJP46B7.js → chunk-ZOEPKBVF.js} +453 -213
- package/dist/chunk-ZOEPKBVF.js.map +1 -0
- package/dist/contracts.d.ts +20 -0
- package/dist/contracts.js +1 -1
- package/dist/index.d-BJyJx6U1.d.ts +319 -0
- package/dist/index.d.ts +1036 -5598
- package/dist/index.js +598 -55
- package/dist/index.js.map +1 -1
- package/dist/{jsx-runtime-WKTl3EEw.d.ts → jsx-runtime-CBZQYYDS.d.ts} +2 -47
- package/dist/jsx-runtime.d.ts +2 -2
- package/dist/jsx-runtime.js +3 -3
- package/dist/{testing-BErengYY.d.ts → testing-BM481Hdz.d.ts} +136 -982
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +19 -5
- package/package.json +30 -30
- package/dist/chunk-PM5YTG57.js +0 -880
- package/dist/chunk-PM5YTG57.js.map +0 -1
- package/dist/chunk-WNJP46B7.js.map +0 -1
- package/dist/index.d-DOlTeG-8.d.ts +0 -99
- /package/dist/{chunk-A5XRLEWM.js.map → chunk-MFTZQMZM.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-MFTZQMZM.js";
|
|
26
26
|
import {
|
|
27
27
|
API_ROUTES_STUB,
|
|
28
28
|
Application as Application2,
|
|
@@ -131,7 +131,7 @@ import {
|
|
|
131
131
|
vite,
|
|
132
132
|
viteReactRefresh,
|
|
133
133
|
writeResponse
|
|
134
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-ZOEPKBVF.js";
|
|
135
135
|
import {
|
|
136
136
|
Arr,
|
|
137
137
|
BindingResolutionError,
|
|
@@ -143,6 +143,7 @@ import {
|
|
|
143
143
|
LazyCollection,
|
|
144
144
|
ServiceProvider,
|
|
145
145
|
Str,
|
|
146
|
+
Stringable,
|
|
146
147
|
__,
|
|
147
148
|
app,
|
|
148
149
|
collect,
|
|
@@ -155,7 +156,7 @@ import {
|
|
|
155
156
|
retry,
|
|
156
157
|
tap,
|
|
157
158
|
value
|
|
158
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-POEP4B2M.js";
|
|
159
160
|
import {
|
|
160
161
|
Application,
|
|
161
162
|
AuthFactory,
|
|
@@ -197,7 +198,7 @@ import {
|
|
|
197
198
|
ValidationFactory,
|
|
198
199
|
ViewFactory,
|
|
199
200
|
token
|
|
200
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-I63ZFMX6.js";
|
|
201
202
|
|
|
202
203
|
// ../Auth/dist/index.js
|
|
203
204
|
import { createHash } from "crypto";
|
|
@@ -3789,6 +3790,34 @@ var LISTENER_STUB_PLAIN = `export class {{ class }} {
|
|
|
3789
3790
|
}
|
|
3790
3791
|
}
|
|
3791
3792
|
`;
|
|
3793
|
+
var LISTENER_STUB_QUEUED = `import { {{ event }} } from '{{ eventImport }}'
|
|
3794
|
+
import type { ShouldQueue } from '@orieljs/framework/contracts'
|
|
3795
|
+
|
|
3796
|
+
export class {{ class }} implements ShouldQueue {
|
|
3797
|
+
static listensTo = {{ event }}
|
|
3798
|
+
|
|
3799
|
+
/** Run by the queue worker (node oriel queue:work): remove this line and \`implements ShouldQueue\` to run it right away. */
|
|
3800
|
+
readonly shouldQueue = true
|
|
3801
|
+
|
|
3802
|
+
async handle(_event: {{ event }}): Promise<void> {
|
|
3803
|
+
//
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
`;
|
|
3807
|
+
var LISTENER_STUB_QUEUED_PLAIN = `import type { ShouldQueue } from '@orieljs/framework/contracts'
|
|
3808
|
+
|
|
3809
|
+
export class {{ class }} implements ShouldQueue {
|
|
3810
|
+
// Name the event class (or event name) this listener handles, so app/Listeners discovery registers it:
|
|
3811
|
+
// static listensTo = OrderShipped
|
|
3812
|
+
|
|
3813
|
+
/** Run by the queue worker (node oriel queue:work): remove this line and \`implements ShouldQueue\` to run it right away. */
|
|
3814
|
+
readonly shouldQueue = true
|
|
3815
|
+
|
|
3816
|
+
async handle(_event: unknown): Promise<void> {
|
|
3817
|
+
//
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
`;
|
|
3792
3821
|
var JOB_STUB = `import { Queueable } from '@orieljs/framework'
|
|
3793
3822
|
|
|
3794
3823
|
export class {{ class }} extends Queueable {
|
|
@@ -3964,15 +3993,12 @@ var MakeCastCommand = class extends GeneratorCommand {
|
|
|
3964
3993
|
}
|
|
3965
3994
|
};
|
|
3966
3995
|
var MakeCommandCommand = class extends GeneratorCommand {
|
|
3967
|
-
/** --command sets the generated signature; without it, Laravel's `app:` plus the kebab-cased name is used. */
|
|
3996
|
+
/** --command sets the generated signature; without it, Laravel's `app:` plus the kebab-cased class name is used. */
|
|
3968
3997
|
signature = "make:command {name} {--command=} {--force}";
|
|
3969
3998
|
description = "Create a new Artisan command";
|
|
3970
3999
|
type() {
|
|
3971
4000
|
return "Console/Commands";
|
|
3972
4001
|
}
|
|
3973
|
-
suffix() {
|
|
3974
|
-
return "Command";
|
|
3975
|
-
}
|
|
3976
4002
|
stub() {
|
|
3977
4003
|
return COMMAND_STUB;
|
|
3978
4004
|
}
|
|
@@ -3980,7 +4006,7 @@ var MakeCommandCommand = class extends GeneratorCommand {
|
|
|
3980
4006
|
const option = this.option("command");
|
|
3981
4007
|
const className = this.qualifyClass(rawName).className;
|
|
3982
4008
|
return {
|
|
3983
|
-
signature: typeof option === "string" ? option : `app:${Str.kebab(className
|
|
4009
|
+
signature: typeof option === "string" ? option : `app:${Str.kebab(className)}`
|
|
3984
4010
|
};
|
|
3985
4011
|
}
|
|
3986
4012
|
};
|
|
@@ -4053,13 +4079,15 @@ var MakeJobCommand = class extends GeneratorCommand {
|
|
|
4053
4079
|
}
|
|
4054
4080
|
};
|
|
4055
4081
|
var MakeListenerCommand = class extends GeneratorCommand {
|
|
4056
|
-
signature = "make:listener {name} {--e|event= : The event class being listened for} {--force}";
|
|
4082
|
+
signature = "make:listener {name} {--e|event= : The event class being listened for} {--queued : Indicates the event listener should be queued} {--force}";
|
|
4057
4083
|
description = "Create a new event listener class";
|
|
4058
4084
|
type() {
|
|
4059
4085
|
return "Listeners";
|
|
4060
4086
|
}
|
|
4061
4087
|
stub() {
|
|
4062
|
-
|
|
4088
|
+
const typed = typeof this.option("event") === "string";
|
|
4089
|
+
if (this.option("queued") === true) return typed ? LISTENER_STUB_QUEUED : LISTENER_STUB_QUEUED_PLAIN;
|
|
4090
|
+
return typed ? LISTENER_STUB : LISTENER_STUB_PLAIN;
|
|
4063
4091
|
}
|
|
4064
4092
|
extraPlaceholders(rawName) {
|
|
4065
4093
|
const event2 = this.option("event");
|
|
@@ -4247,6 +4275,29 @@ var MakeTestCommand = class extends GeneratorCommand {
|
|
|
4247
4275
|
return `${className.replace(/(?<=.)Test$/, "")}.test.ts`;
|
|
4248
4276
|
}
|
|
4249
4277
|
};
|
|
4278
|
+
var ScheduleClearCacheCommand = class extends Command {
|
|
4279
|
+
signature = "schedule:clear-cache";
|
|
4280
|
+
description = "Delete the cached mutex files created by scheduler";
|
|
4281
|
+
async handle() {
|
|
4282
|
+
let cleared = false;
|
|
4283
|
+
if (currentContainer()?.bound(CacheManager)) {
|
|
4284
|
+
const cache2 = inject(CacheManager);
|
|
4285
|
+
for (const event2 of inject(Schedule).events()) {
|
|
4286
|
+
if (!event2.preventsOverlapping) continue;
|
|
4287
|
+
const lock = cache2.lock(event2.mutexName(), event2.expiresAt * 60);
|
|
4288
|
+
if (await lock.get()) {
|
|
4289
|
+
await lock.release();
|
|
4290
|
+
continue;
|
|
4291
|
+
}
|
|
4292
|
+
this.info(`Deleting mutex for [${event2.command ?? event2.getSummaryForDisplay()}]`);
|
|
4293
|
+
await lock.forceRelease();
|
|
4294
|
+
cleared = true;
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
if (!cleared) this.info("No mutex files were found.");
|
|
4298
|
+
return 0;
|
|
4299
|
+
}
|
|
4300
|
+
};
|
|
4250
4301
|
var ScheduleListCommand = class extends Command {
|
|
4251
4302
|
signature = "schedule:list";
|
|
4252
4303
|
description = "List the scheduled commands";
|
|
@@ -4258,18 +4309,15 @@ var ScheduleListCommand = class extends Command {
|
|
|
4258
4309
|
}
|
|
4259
4310
|
this.table(
|
|
4260
4311
|
["Command", "Expression"],
|
|
4261
|
-
events.map((event2) => [event2.
|
|
4312
|
+
events.map((event2) => [event2.getSummaryForDisplay(), event2.expression])
|
|
4262
4313
|
);
|
|
4263
4314
|
return 0;
|
|
4264
4315
|
}
|
|
4265
4316
|
};
|
|
4266
|
-
function summaryOf(event2) {
|
|
4267
|
-
return event2.getSummary();
|
|
4268
|
-
}
|
|
4269
4317
|
async function runDueEvents(events, io, now5) {
|
|
4270
4318
|
const backgroundRuns = [];
|
|
4271
4319
|
for (const event2 of events) {
|
|
4272
|
-
io.info(`Running scheduled task: ${
|
|
4320
|
+
io.info(`Running scheduled task: ${event2.getSummaryForDisplay()}`);
|
|
4273
4321
|
const attempt = async () => {
|
|
4274
4322
|
try {
|
|
4275
4323
|
await event2.run(now5);
|
|
@@ -4617,6 +4665,15 @@ var ScheduledEventImpl = class {
|
|
|
4617
4665
|
get expression() {
|
|
4618
4666
|
return this.cronExpression;
|
|
4619
4667
|
}
|
|
4668
|
+
get command() {
|
|
4669
|
+
return this.commandString;
|
|
4670
|
+
}
|
|
4671
|
+
get preventsOverlapping() {
|
|
4672
|
+
return this.overlapExpiryMinutes !== void 0;
|
|
4673
|
+
}
|
|
4674
|
+
get expiresAt() {
|
|
4675
|
+
return this.overlapExpiryMinutes ?? 1440;
|
|
4676
|
+
}
|
|
4620
4677
|
cron(expression) {
|
|
4621
4678
|
this.cronExpression = expression;
|
|
4622
4679
|
return this;
|
|
@@ -4710,15 +4767,19 @@ var ScheduledEventImpl = class {
|
|
|
4710
4767
|
this.eventDescription = description;
|
|
4711
4768
|
return this;
|
|
4712
4769
|
}
|
|
4713
|
-
|
|
4770
|
+
getSummaryForDisplay() {
|
|
4771
|
+
return this.eventName ?? this.eventDescription ?? this.commandString ?? "Closure";
|
|
4772
|
+
}
|
|
4773
|
+
/** Accessors beyond the contract, read back by the schedule:run/schedule:work loop. */
|
|
4714
4774
|
getName() {
|
|
4715
4775
|
return this.eventName;
|
|
4716
4776
|
}
|
|
4717
4777
|
getDescription() {
|
|
4718
4778
|
return this.eventDescription;
|
|
4719
4779
|
}
|
|
4780
|
+
/** The same as getSummaryForDisplay(). */
|
|
4720
4781
|
getSummary() {
|
|
4721
|
-
return this.
|
|
4782
|
+
return this.getSummaryForDisplay();
|
|
4722
4783
|
}
|
|
4723
4784
|
isBackground() {
|
|
4724
4785
|
return this.background;
|
|
@@ -4774,11 +4835,11 @@ var ScheduledEventImpl = class {
|
|
|
4774
4835
|
* Follows Laravel: a command event's mutex is `sha1(expression + full command
|
|
4775
4836
|
* string incl. parameters)` (Laravel's `Event::mutexName()`) — no `name()` required. A closure event (`call()`/
|
|
4776
4837
|
* `job()`) has no command string, so its mutex is `sha1(name())` (Laravel's `CallbackEvent::mutexName()`, which
|
|
4777
|
-
* reads the description `name()` also writes)
|
|
4778
|
-
*
|
|
4838
|
+
* reads the description `name()` also writes), and `sha1('')` while it has no name, as Laravel's
|
|
4839
|
+
* (`requireLockableName()` keeps an unnamed closure from ever taking the lock).
|
|
4779
4840
|
*/
|
|
4780
4841
|
mutexName() {
|
|
4781
|
-
const key = this.commandString !== void 0 ? this.cronExpression + this.commandString : this.eventName;
|
|
4842
|
+
const key = this.commandString !== void 0 ? this.cronExpression + this.commandString : this.eventName ?? "";
|
|
4782
4843
|
return `framework/schedule-${sha1(key)}`;
|
|
4783
4844
|
}
|
|
4784
4845
|
/**
|
|
@@ -4855,6 +4916,7 @@ var ConsoleServiceProvider = class extends ServiceProvider {
|
|
|
4855
4916
|
ScheduleRunCommand,
|
|
4856
4917
|
ScheduleWorkCommand,
|
|
4857
4918
|
ScheduleListCommand,
|
|
4919
|
+
ScheduleClearCacheCommand,
|
|
4858
4920
|
MakeControllerCommand,
|
|
4859
4921
|
MakeModelCommand,
|
|
4860
4922
|
MakeMiddlewareCommand,
|
|
@@ -4884,7 +4946,7 @@ var ConsoleServiceProvider = class extends ServiceProvider {
|
|
|
4884
4946
|
}
|
|
4885
4947
|
};
|
|
4886
4948
|
var Artisan = facade(ConsoleKernel);
|
|
4887
|
-
var
|
|
4949
|
+
var Schedule5 = facade(Schedule);
|
|
4888
4950
|
async function runConsole(app2, argv = process.argv.slice(2)) {
|
|
4889
4951
|
app2.setRunningInConsole(true);
|
|
4890
4952
|
try {
|
|
@@ -4895,7 +4957,17 @@ async function runConsole(app2, argv = process.argv.slice(2)) {
|
|
|
4895
4957
|
}
|
|
4896
4958
|
}
|
|
4897
4959
|
async function runConsoleAndExit(app2, argv = process.argv.slice(2), exit = (code) => process.exit(code)) {
|
|
4898
|
-
|
|
4960
|
+
let code;
|
|
4961
|
+
try {
|
|
4962
|
+
code = await runConsole(app2, argv);
|
|
4963
|
+
} finally {
|
|
4964
|
+
await flushLogs(app2);
|
|
4965
|
+
}
|
|
4966
|
+
exit(code);
|
|
4967
|
+
}
|
|
4968
|
+
async function flushLogs(app2) {
|
|
4969
|
+
if (!app2.bound(LogManager)) return;
|
|
4970
|
+
await app2.make(LogManager).flush?.();
|
|
4899
4971
|
}
|
|
4900
4972
|
|
|
4901
4973
|
// ../Cookie/dist/index.js
|
|
@@ -5499,7 +5571,10 @@ var AbstractPaginator = class _AbstractPaginator {
|
|
|
5499
5571
|
this.collection = items;
|
|
5500
5572
|
return this;
|
|
5501
5573
|
}
|
|
5502
|
-
/**
|
|
5574
|
+
/**
|
|
5575
|
+
* Transforms each item in place, typically for serialization, and returns this paginator typed with the new items:
|
|
5576
|
+
* `posts.through((post) => ({ id: post.id }))`. Each paginator narrows the return type to its own class.
|
|
5577
|
+
*/
|
|
5503
5578
|
through(callback) {
|
|
5504
5579
|
this.collection = this.collection.map(callback);
|
|
5505
5580
|
return this;
|
|
@@ -5599,6 +5674,9 @@ var CursorPaginator = class extends AbstractPaginator {
|
|
|
5599
5674
|
getCursorName() {
|
|
5600
5675
|
return this.cursorName;
|
|
5601
5676
|
}
|
|
5677
|
+
through(callback) {
|
|
5678
|
+
return super.through(callback);
|
|
5679
|
+
}
|
|
5602
5680
|
hasMorePages() {
|
|
5603
5681
|
return this.cursorValue === void 0 && this.hasMore || this.cursorValue !== void 0 && this.cursorValue.pointsToNextItems() && this.hasMore || this.cursorValue !== void 0 && this.cursorValue.pointsToPreviousItems();
|
|
5604
5682
|
}
|
|
@@ -5655,6 +5733,9 @@ var LengthAwarePaginator = class extends AbstractPaginator {
|
|
|
5655
5733
|
total() {
|
|
5656
5734
|
return this.totalValue;
|
|
5657
5735
|
}
|
|
5736
|
+
through(callback) {
|
|
5737
|
+
return super.through(callback);
|
|
5738
|
+
}
|
|
5658
5739
|
lastPage() {
|
|
5659
5740
|
return this.lastPageValue;
|
|
5660
5741
|
}
|
|
@@ -5743,6 +5824,9 @@ var Paginator = class extends AbstractPaginator {
|
|
|
5743
5824
|
hasMorePages() {
|
|
5744
5825
|
return this.hasMore;
|
|
5745
5826
|
}
|
|
5827
|
+
through(callback) {
|
|
5828
|
+
return super.through(callback);
|
|
5829
|
+
}
|
|
5746
5830
|
hasPages() {
|
|
5747
5831
|
return this.currentPageValue !== 1 || this.hasMore;
|
|
5748
5832
|
}
|
|
@@ -8202,12 +8286,19 @@ var Builder2 = class extends Builder {
|
|
|
8202
8286
|
const key = column.includes(".") ? column.slice(column.lastIndexOf(".") + 1) : column;
|
|
8203
8287
|
return new Collection(rows.map((row) => this.model.newInstance().setRawAttributes({ [key]: row[key] }).getAttribute(key)));
|
|
8204
8288
|
}
|
|
8289
|
+
/** Whether `id` can't be one of the model's unique ids (not a UUID for HasUuids): it matches no row. */
|
|
8290
|
+
isMalformedKey(id) {
|
|
8291
|
+
return this.model.uniqueIds().includes(this.model.getKeyName()) && !this.model.isValidUniqueId(id);
|
|
8292
|
+
}
|
|
8293
|
+
/** A malformed unique id (HasUuids, HasUlids) finds nothing without a query, as route model binding does. */
|
|
8205
8294
|
async find(id) {
|
|
8295
|
+
if (this.isMalformedKey(id)) return void 0;
|
|
8206
8296
|
return this.clone().whereKey(id).first();
|
|
8207
8297
|
}
|
|
8208
8298
|
async findMany(ids) {
|
|
8209
|
-
|
|
8210
|
-
|
|
8299
|
+
const keys = ids.filter((id) => !this.isMalformedKey(id));
|
|
8300
|
+
if (!keys.length) return new Collection();
|
|
8301
|
+
return this.clone().whereKey(keys).get();
|
|
8211
8302
|
}
|
|
8212
8303
|
async findOrFail(id) {
|
|
8213
8304
|
if (Array.isArray(id)) {
|
|
@@ -8844,6 +8935,8 @@ var HasOneOrMany = class extends Relation {
|
|
|
8844
8935
|
foreignKey;
|
|
8845
8936
|
localKey;
|
|
8846
8937
|
morph;
|
|
8938
|
+
/** The relation on each related model that chaperone() points back at the parent. */
|
|
8939
|
+
inverseRelationship;
|
|
8847
8940
|
/** 'post_id' */
|
|
8848
8941
|
getForeignKeyName() {
|
|
8849
8942
|
return this.foreignKey.slice(this.foreignKey.lastIndexOf(".") + 1);
|
|
@@ -8865,6 +8958,61 @@ var HasOneOrMany = class extends Relation {
|
|
|
8865
8958
|
getMorphClass() {
|
|
8866
8959
|
return this.morph?.value;
|
|
8867
8960
|
}
|
|
8961
|
+
/**
|
|
8962
|
+
* Laravel's chaperone(): every related model this relation loads, eagerly or lazily, or makes, gets the parent as
|
|
8963
|
+
* its `relation` (guessed when not given: post_id → post, the parent's class, owner), so reading it needs no query:
|
|
8964
|
+
* `comments() { return this.hasMany(Comment).chaperone() }`.
|
|
8965
|
+
*/
|
|
8966
|
+
chaperone(relation) {
|
|
8967
|
+
const name = relation ?? this.guessInverseRelation();
|
|
8968
|
+
if (name === void 0 || !this.model.isRelation(name)) throw new RelationNotFoundError(this.model.constructor.name, name ?? "null");
|
|
8969
|
+
this.inverseRelationship = name;
|
|
8970
|
+
return this;
|
|
8971
|
+
}
|
|
8972
|
+
/** Laravel's inverse(): chaperone() under its other name. */
|
|
8973
|
+
inverse(relation) {
|
|
8974
|
+
return this.chaperone(relation);
|
|
8975
|
+
}
|
|
8976
|
+
withoutChaperone() {
|
|
8977
|
+
this.inverseRelationship = void 0;
|
|
8978
|
+
return this;
|
|
8979
|
+
}
|
|
8980
|
+
withoutInverse() {
|
|
8981
|
+
return this.withoutChaperone();
|
|
8982
|
+
}
|
|
8983
|
+
getInverseRelationship() {
|
|
8984
|
+
return this.inverseRelationship;
|
|
8985
|
+
}
|
|
8986
|
+
/** The first of the possible names that is a relation of the related model. */
|
|
8987
|
+
guessInverseRelation() {
|
|
8988
|
+
return this.getPossibleInverseRelations().find((name) => this.model.isRelation(name));
|
|
8989
|
+
}
|
|
8990
|
+
/** Laravel's candidates: the morph name, the foreign key without the parent's key, the parent's class, owner, parent. */
|
|
8991
|
+
getPossibleInverseRelations() {
|
|
8992
|
+
const key = this.parent.getKeyName();
|
|
8993
|
+
const names = [
|
|
8994
|
+
this.morph ? Str.beforeLast(this.getMorphType(), "_type") : "",
|
|
8995
|
+
Str.camel(Str.beforeLast(this.getForeignKeyName(), key)),
|
|
8996
|
+
Str.camel(Str.beforeLast(this.parent.getForeignKey(), key)),
|
|
8997
|
+
Str.camel(this.parent.constructor.name),
|
|
8998
|
+
"owner",
|
|
8999
|
+
this.parent.constructor === this.model.constructor ? "parent" : ""
|
|
9000
|
+
];
|
|
9001
|
+
return [...new Set(names.filter((name) => name !== ""))];
|
|
9002
|
+
}
|
|
9003
|
+
/** Sets the parent on a related model, when chaperone() named the relation. */
|
|
9004
|
+
applyInverseRelationToModel(model, parent = this.parent) {
|
|
9005
|
+
if (model && this.inverseRelationship !== void 0) model.setRelation(this.inverseRelationship, parent);
|
|
9006
|
+
return model;
|
|
9007
|
+
}
|
|
9008
|
+
applyInverseRelationToMany(models, parent = this.parent) {
|
|
9009
|
+
for (const model of models) this.applyInverseRelationToModel(model, parent);
|
|
9010
|
+
return models;
|
|
9011
|
+
}
|
|
9012
|
+
/** The relation query's rows (get(), first(), paginate(), …), pointing back at the parent with chaperone(). */
|
|
9013
|
+
async runSelect() {
|
|
9014
|
+
return this.applyInverseRelationToMany(await super.runSelect());
|
|
9015
|
+
}
|
|
8868
9016
|
addConstraints() {
|
|
8869
9017
|
this.where(this.foreignKey, "=", this.getParentKey());
|
|
8870
9018
|
this.whereNotNull(this.foreignKey);
|
|
@@ -8898,7 +9046,7 @@ var HasOneOrMany = class extends Relation {
|
|
|
8898
9046
|
setForeignAttributes(model) {
|
|
8899
9047
|
model.setAttribute(this.getForeignKeyName(), this.getParentKey());
|
|
8900
9048
|
if (this.morph) model.setAttribute(this.getMorphType(), this.morph.value);
|
|
8901
|
-
return model;
|
|
9049
|
+
return this.applyInverseRelationToModel(model);
|
|
8902
9050
|
}
|
|
8903
9051
|
async saveMany(models) {
|
|
8904
9052
|
const saved = [];
|
|
@@ -9217,7 +9365,8 @@ var HasMany = class extends HasOneOrMany {
|
|
|
9217
9365
|
match(models, results, relation) {
|
|
9218
9366
|
const dictionary = this.buildDictionary(results);
|
|
9219
9367
|
for (const model of models) {
|
|
9220
|
-
|
|
9368
|
+
const children = this.applyInverseRelationToMany(dictionary.get(String(model.getAttribute(this.localKey))) ?? [], model);
|
|
9369
|
+
model.setRelation(relation, new Collection(children));
|
|
9221
9370
|
}
|
|
9222
9371
|
return models;
|
|
9223
9372
|
}
|
|
@@ -9326,7 +9475,7 @@ var HasOne = class extends HasOneOrMany {
|
|
|
9326
9475
|
match(models, results, relation) {
|
|
9327
9476
|
const dictionary = this.buildDictionary(results);
|
|
9328
9477
|
for (const model of models) {
|
|
9329
|
-
model.setRelation(relation, dictionary.get(String(model.getAttribute(this.localKey)))?.[0] ?? null);
|
|
9478
|
+
model.setRelation(relation, this.applyInverseRelationToModel(dictionary.get(String(model.getAttribute(this.localKey)))?.[0] ?? null, model));
|
|
9330
9479
|
}
|
|
9331
9480
|
return models;
|
|
9332
9481
|
}
|
|
@@ -9386,6 +9535,7 @@ function methodOf(model, name) {
|
|
|
9386
9535
|
const value2 = Reflect.get(Object.getPrototypeOf(model), name);
|
|
9387
9536
|
return typeof value2 === "function" ? value2 : void 0;
|
|
9388
9537
|
}
|
|
9538
|
+
var serializing = /* @__PURE__ */ new WeakSet();
|
|
9389
9539
|
function serializeDate(date) {
|
|
9390
9540
|
return date.toISOString().replace(/\.(\d{3})Z$/, ".$1000Z");
|
|
9391
9541
|
}
|
|
@@ -9841,7 +9991,7 @@ var Model = class _Model {
|
|
|
9841
9991
|
/** Every cast, including the implied ones: the incrementing key (int) and the timestamp columns (datetime). */
|
|
9842
9992
|
getCasts() {
|
|
9843
9993
|
const implied = {};
|
|
9844
|
-
if (this.
|
|
9994
|
+
if (this.getIncrementing()) implied[this.getKeyName()] = this.getKeyType() === "int" ? "int" : "string";
|
|
9845
9995
|
if (this.usesTimestamps()) {
|
|
9846
9996
|
const created = this.getCreatedAtColumn();
|
|
9847
9997
|
const updated = this.getUpdatedAtColumn();
|
|
@@ -9964,6 +10114,29 @@ var Model = class _Model {
|
|
|
9964
10114
|
getIncrementing() {
|
|
9965
10115
|
return this.incrementing;
|
|
9966
10116
|
}
|
|
10117
|
+
/** Whether new rows get unique string ids before `creating` (HasUuids, HasUlids). */
|
|
10118
|
+
usesUniqueIds() {
|
|
10119
|
+
return false;
|
|
10120
|
+
}
|
|
10121
|
+
/** The columns that get a unique id (HasUuids and HasUlids: the primary key). */
|
|
10122
|
+
uniqueIds() {
|
|
10123
|
+
return [];
|
|
10124
|
+
}
|
|
10125
|
+
/** A new unique id (HasUuids: a version 7 UUID; HasUlids: a lower-case ULID). */
|
|
10126
|
+
newUniqueId() {
|
|
10127
|
+
return void 0;
|
|
10128
|
+
}
|
|
10129
|
+
/** Whether a value has the shape of this model's unique ids (HasUuids: a UUID). Any value passes by default. */
|
|
10130
|
+
isValidUniqueId(_value) {
|
|
10131
|
+
return true;
|
|
10132
|
+
}
|
|
10133
|
+
/** Fills each empty unique id column with newUniqueId() (Laravel's setUniqueIds()). */
|
|
10134
|
+
setUniqueIds() {
|
|
10135
|
+
for (const column of this.uniqueIds()) {
|
|
10136
|
+
const value2 = this.getAttribute(column);
|
|
10137
|
+
if (value2 === void 0 || value2 === null || value2 === "") this.setAttribute(column, this.newUniqueId());
|
|
10138
|
+
}
|
|
10139
|
+
}
|
|
9967
10140
|
getKey() {
|
|
9968
10141
|
return this.getAttribute(this.getKeyName());
|
|
9969
10142
|
}
|
|
@@ -9995,11 +10168,13 @@ var Model = class _Model {
|
|
|
9995
10168
|
}
|
|
9996
10169
|
/**
|
|
9997
10170
|
* The model a route parameter value points at: where <field or route key> = value (global scopes apply, so a
|
|
9998
|
-
* soft-deleted row isn't found). A non-numeric value for an integer primary key
|
|
10171
|
+
* soft-deleted row isn't found). A non-numeric value for an integer primary key, or a value that isn't a UUID
|
|
10172
|
+
* (ULID) for a unique id column, finds nothing without a query.
|
|
9999
10173
|
*/
|
|
10000
10174
|
async resolveRouteBinding(value2, field) {
|
|
10001
10175
|
const column = field ?? this.getRouteKeyName();
|
|
10002
|
-
if (column === this.getKeyName() && this.
|
|
10176
|
+
if (column === this.getKeyName() && this.getKeyType() === "int" && !/^-?\d+$/.test(value2)) return void 0;
|
|
10177
|
+
if (this.uniqueIds().includes(column) && !this.isValidUniqueId(value2)) return void 0;
|
|
10003
10178
|
return this.resolveRouteBindingQuery(this.newQuery(), value2, column).first();
|
|
10004
10179
|
}
|
|
10005
10180
|
/** Override to customize the binding query (Laravel's resolveRouteBindingQuery()). */
|
|
@@ -10217,6 +10392,7 @@ var Model = class _Model {
|
|
|
10217
10392
|
if (!this.exists && created && !this.isDirty(created)) this.setAttribute(created, time);
|
|
10218
10393
|
}
|
|
10219
10394
|
async performInsert(query) {
|
|
10395
|
+
if (this.usesUniqueIds()) this.setUniqueIds();
|
|
10220
10396
|
if (await this.fireModelEvent("creating") === false) return false;
|
|
10221
10397
|
if (this.usesTimestamps()) this.updateTimestamps();
|
|
10222
10398
|
const attributes = this.getAttributes();
|
|
@@ -10400,6 +10576,10 @@ var Model = class _Model {
|
|
|
10400
10576
|
if (!instance.getConnectionName()) instance.setConnection(this.getConnectionName());
|
|
10401
10577
|
return instance;
|
|
10402
10578
|
}
|
|
10579
|
+
/** Whether the model has a relation method called `name` (Laravel's isRelation()). */
|
|
10580
|
+
isRelation(name) {
|
|
10581
|
+
return !(name in _Model.prototype) && methodOf(this, name) !== void 0;
|
|
10582
|
+
}
|
|
10403
10583
|
/** Calls the relation method `name` (post.comments()) and checks that it returns a relation. */
|
|
10404
10584
|
getRelationInstance(name) {
|
|
10405
10585
|
if (name in _Model.prototype) throw new RelationNotFoundError(this.constructor.name, name);
|
|
@@ -10494,9 +10674,18 @@ var Model = class _Model {
|
|
|
10494
10674
|
this.appends = [.../* @__PURE__ */ new Set([...this.appends, ...attributes.flat()])];
|
|
10495
10675
|
return this;
|
|
10496
10676
|
}
|
|
10497
|
-
/**
|
|
10677
|
+
/**
|
|
10678
|
+
* Attributes (through accessors and casts, dates as ISO strings), appends and loaded relations, minus hidden ones.
|
|
10679
|
+
* A model met again while its own toArray() runs (a child chaperone() pointed back at it) gives its attributes only.
|
|
10680
|
+
*/
|
|
10498
10681
|
toArray() {
|
|
10499
|
-
|
|
10682
|
+
if (serializing.has(this)) return this.attributesToArray();
|
|
10683
|
+
serializing.add(this);
|
|
10684
|
+
try {
|
|
10685
|
+
return { ...this.attributesToArray(), ...this.relationsToArray() };
|
|
10686
|
+
} finally {
|
|
10687
|
+
serializing.delete(this);
|
|
10688
|
+
}
|
|
10500
10689
|
}
|
|
10501
10690
|
toJSON() {
|
|
10502
10691
|
return this.toArray();
|
|
@@ -10567,7 +10756,35 @@ var Pivot = class extends Model {
|
|
|
10567
10756
|
incrementing = false;
|
|
10568
10757
|
timestamps = false;
|
|
10569
10758
|
};
|
|
10570
|
-
|
|
10759
|
+
function uniqueStringIds(Base, generate, valid) {
|
|
10760
|
+
return class WithUniqueStringIds extends Base {
|
|
10761
|
+
usesUniqueIds() {
|
|
10762
|
+
return true;
|
|
10763
|
+
}
|
|
10764
|
+
uniqueIds() {
|
|
10765
|
+
return [this.getKeyName()];
|
|
10766
|
+
}
|
|
10767
|
+
newUniqueId() {
|
|
10768
|
+
return generate();
|
|
10769
|
+
}
|
|
10770
|
+
isValidUniqueId(value2) {
|
|
10771
|
+
return valid(value2);
|
|
10772
|
+
}
|
|
10773
|
+
getKeyType() {
|
|
10774
|
+
return this.uniqueIds().includes(this.getKeyName()) ? "string" : super.getKeyType();
|
|
10775
|
+
}
|
|
10776
|
+
getIncrementing() {
|
|
10777
|
+
return this.uniqueIds().includes(this.getKeyName()) ? false : super.getIncrementing();
|
|
10778
|
+
}
|
|
10779
|
+
};
|
|
10780
|
+
}
|
|
10781
|
+
function HasUuids(Base) {
|
|
10782
|
+
return uniqueStringIds(Base, () => Str.uuid7(), Str.isUuid);
|
|
10783
|
+
}
|
|
10784
|
+
function HasUlids(Base) {
|
|
10785
|
+
return uniqueStringIds(Base, () => Str.ulid().toLowerCase(), Str.isUlid);
|
|
10786
|
+
}
|
|
10787
|
+
var DatabaseNotification = class extends HasUuids(Model) {
|
|
10571
10788
|
table = "notifications";
|
|
10572
10789
|
keyType = "string";
|
|
10573
10790
|
incrementing = false;
|
|
@@ -11100,6 +11317,11 @@ async function generateModelTypes(context) {
|
|
|
11100
11317
|
await new TypeGenerator({ outputFile, importSource: context.typesImportSource }).write((await context.models()).all());
|
|
11101
11318
|
return relative2(context.app.basePath(), outputFile);
|
|
11102
11319
|
}
|
|
11320
|
+
async function writeModelTypes(context, command) {
|
|
11321
|
+
if (context.app.isProduction() || !existsSync4(context.app.basePath("types"))) return;
|
|
11322
|
+
const written = await generateModelTypes(context);
|
|
11323
|
+
if (written) command.line(`Model types written to ${written}.`);
|
|
11324
|
+
}
|
|
11103
11325
|
async function seedIfRequested(context, command) {
|
|
11104
11326
|
const seeder = text(command.option("seeder"));
|
|
11105
11327
|
if (command.option("seed") !== true && seeder === void 0) return;
|
|
@@ -11111,10 +11333,7 @@ function registerMigrationCommands(kernel, context) {
|
|
|
11111
11333
|
if (!confirmToProceed(context, command)) return 1;
|
|
11112
11334
|
await migrator(context, command).run(migrationPaths(context, command), { step: command.option("step") === true });
|
|
11113
11335
|
await seedIfRequested(context, command);
|
|
11114
|
-
|
|
11115
|
-
const written = await generateModelTypes(context);
|
|
11116
|
-
if (written) command.line(`Model types written to ${written}.`);
|
|
11117
|
-
}
|
|
11336
|
+
await writeModelTypes(context, command);
|
|
11118
11337
|
return 0;
|
|
11119
11338
|
});
|
|
11120
11339
|
define(kernel, "migrate:install {--database=}", "Create the migration repository", async (command) => {
|
|
@@ -11145,12 +11364,14 @@ function registerMigrationCommands(kernel, context) {
|
|
|
11145
11364
|
else await instance.reset(paths);
|
|
11146
11365
|
await instance.run(paths);
|
|
11147
11366
|
await seedIfRequested(context, command);
|
|
11367
|
+
await writeModelTypes(context, command);
|
|
11148
11368
|
return 0;
|
|
11149
11369
|
});
|
|
11150
11370
|
define(kernel, "migrate:fresh {--database=} {--force} {--path=*} {--seed} {--seeder=}", "Drop all tables and re-run all migrations", async (command) => {
|
|
11151
11371
|
if (!confirmToProceed(context, command)) return 1;
|
|
11152
11372
|
await migrator(context, command).fresh(migrationPaths(context, command));
|
|
11153
11373
|
await seedIfRequested(context, command);
|
|
11374
|
+
await writeModelTypes(context, command);
|
|
11154
11375
|
return 0;
|
|
11155
11376
|
});
|
|
11156
11377
|
define(kernel, "migrate:status {--database=} {--path=*}", "Show the status of each migration", async (command) => {
|
|
@@ -12119,6 +12340,10 @@ var Dispatcher2 = class {
|
|
|
12119
12340
|
forget(event2) {
|
|
12120
12341
|
this.listeners.delete(event2);
|
|
12121
12342
|
}
|
|
12343
|
+
/** Laravel's getRawListeners(): each event's listeners as registered (closures, classes, [class, method]). A copy. */
|
|
12344
|
+
getRawListeners() {
|
|
12345
|
+
return new Map([...this.listeners].map(([event2, list4]) => [event2, [...list4]]));
|
|
12346
|
+
}
|
|
12122
12347
|
/** Introspection for the event:list command. Not part of the EventDispatcher contract. */
|
|
12123
12348
|
registeredEvents() {
|
|
12124
12349
|
const rows = [];
|
|
@@ -14678,6 +14903,42 @@ var DailyRotatingStream = class extends Writable {
|
|
|
14678
14903
|
stream.end();
|
|
14679
14904
|
}
|
|
14680
14905
|
};
|
|
14906
|
+
function destinationCloser(destination) {
|
|
14907
|
+
const opened = new Promise((resolve3) => {
|
|
14908
|
+
const onReady = () => {
|
|
14909
|
+
destination.off("error", onError);
|
|
14910
|
+
resolve3(true);
|
|
14911
|
+
};
|
|
14912
|
+
const onError = () => {
|
|
14913
|
+
destination.off("ready", onReady);
|
|
14914
|
+
destination.flushSync = () => {
|
|
14915
|
+
};
|
|
14916
|
+
resolve3(false);
|
|
14917
|
+
};
|
|
14918
|
+
destination.once("ready", onReady);
|
|
14919
|
+
destination.once("error", onError);
|
|
14920
|
+
});
|
|
14921
|
+
let closing;
|
|
14922
|
+
const close = async () => {
|
|
14923
|
+
if (!await opened) return;
|
|
14924
|
+
await new Promise((resolve3) => {
|
|
14925
|
+
destination.once("close", () => resolve3());
|
|
14926
|
+
destination.once("error", () => resolve3());
|
|
14927
|
+
destination.end();
|
|
14928
|
+
});
|
|
14929
|
+
};
|
|
14930
|
+
return () => closing ??= close();
|
|
14931
|
+
}
|
|
14932
|
+
function writableCloser(stream) {
|
|
14933
|
+
let closing;
|
|
14934
|
+
const close = () => new Promise((resolve3) => {
|
|
14935
|
+
if (stream.writableFinished || stream.destroyed) return resolve3();
|
|
14936
|
+
stream.once("finish", () => resolve3());
|
|
14937
|
+
stream.once("error", () => resolve3());
|
|
14938
|
+
stream.end();
|
|
14939
|
+
});
|
|
14940
|
+
return () => closing ??= close();
|
|
14941
|
+
}
|
|
14681
14942
|
var PINO_METHOD = {
|
|
14682
14943
|
emergency: "fatal",
|
|
14683
14944
|
alert: "fatal",
|
|
@@ -14689,12 +14950,25 @@ var PINO_METHOD = {
|
|
|
14689
14950
|
debug: "debug"
|
|
14690
14951
|
};
|
|
14691
14952
|
var PinoLogger = class extends BaseLogger {
|
|
14692
|
-
constructor(pinoInstance, minimumLevel = "debug") {
|
|
14953
|
+
constructor(pinoInstance, minimumLevel = "debug", closeDestination = async () => {
|
|
14954
|
+
}) {
|
|
14693
14955
|
super(minimumLevel);
|
|
14694
14956
|
this.pinoInstance = pinoInstance;
|
|
14957
|
+
this.closeDestination = closeDestination;
|
|
14695
14958
|
}
|
|
14696
14959
|
pinoInstance;
|
|
14960
|
+
closeDestination;
|
|
14961
|
+
flushing;
|
|
14962
|
+
/**
|
|
14963
|
+
* Writes out every entry still buffered and closes the destination. pino writes asynchronously, so a process
|
|
14964
|
+
* awaits this before it exits (runConsoleAndExit does). The channel takes no entries afterwards: they're dropped.
|
|
14965
|
+
* Not in Laravel, whose handlers write synchronously.
|
|
14966
|
+
*/
|
|
14967
|
+
flush() {
|
|
14968
|
+
return this.flushing ??= this.closeDestination();
|
|
14969
|
+
}
|
|
14697
14970
|
write(level2, message, context) {
|
|
14971
|
+
if (this.flushing) return;
|
|
14698
14972
|
this.pinoInstance[PINO_METHOD[level2]]({ ...context, rfc5424Level: level2 }, message);
|
|
14699
14973
|
}
|
|
14700
14974
|
};
|
|
@@ -14703,19 +14977,19 @@ function createSingleChannel(path, minimumLevel = "debug") {
|
|
|
14703
14977
|
assertLogLevel(minimumLevel);
|
|
14704
14978
|
const destination = pino2.destination({ dest: path, mkdir: true, sync: false });
|
|
14705
14979
|
destination.on("error", (error) => reportLogWriteFailure(path, error));
|
|
14706
|
-
return new PinoLogger(pino2(PINO_OPTIONS, destination), minimumLevel);
|
|
14980
|
+
return new PinoLogger(pino2(PINO_OPTIONS, destination), minimumLevel, destinationCloser(destination));
|
|
14707
14981
|
}
|
|
14708
14982
|
function createDailyChannel(path, days = 14, minimumLevel = "debug", now5) {
|
|
14709
14983
|
assertLogLevel(minimumLevel);
|
|
14710
14984
|
const stream = new DailyRotatingStream(path, days, now5);
|
|
14711
|
-
return new PinoLogger(pino2(PINO_OPTIONS, stream), minimumLevel);
|
|
14985
|
+
return new PinoLogger(pino2(PINO_OPTIONS, stream), minimumLevel, writableCloser(stream));
|
|
14712
14986
|
}
|
|
14713
14987
|
function createStderrChannel(minimumLevel = "debug") {
|
|
14714
14988
|
assertLogLevel(minimumLevel);
|
|
14715
14989
|
const destination = pino2.destination({ dest: 2, sync: false });
|
|
14716
14990
|
destination.on("error", () => {
|
|
14717
14991
|
});
|
|
14718
|
-
return new PinoLogger(pino2(PINO_OPTIONS, destination), minimumLevel);
|
|
14992
|
+
return new PinoLogger(pino2(PINO_OPTIONS, destination), minimumLevel, destinationCloser(destination));
|
|
14719
14993
|
}
|
|
14720
14994
|
var Log = facade(LogManager);
|
|
14721
14995
|
function logger(message, context) {
|
|
@@ -14765,6 +15039,7 @@ var StackLogger = class {
|
|
|
14765
15039
|
return this;
|
|
14766
15040
|
}
|
|
14767
15041
|
};
|
|
15042
|
+
var isFlushable = (channel) => typeof channel.flush === "function";
|
|
14768
15043
|
var level = (config2) => config2.level ?? "debug";
|
|
14769
15044
|
var LogManager2 = class {
|
|
14770
15045
|
constructor(container) {
|
|
@@ -14806,6 +15081,16 @@ var LogManager2 = class {
|
|
|
14806
15081
|
stack(channels) {
|
|
14807
15082
|
return new StackLogger(channels.map((name) => this.channel(name)));
|
|
14808
15083
|
}
|
|
15084
|
+
/**
|
|
15085
|
+
* Writes out and closes every channel resolved so far, then forgets them, so the next entry opens its file again.
|
|
15086
|
+
* pino writes asynchronously, so a console process awaits this before it exits (runConsoleAndExit does). Not in
|
|
15087
|
+
* Laravel, whose handlers write synchronously.
|
|
15088
|
+
*/
|
|
15089
|
+
async flush() {
|
|
15090
|
+
const channels = [...this.channels.values()];
|
|
15091
|
+
this.channels.clear();
|
|
15092
|
+
await Promise.all(channels.filter(isFlushable).map((channel) => channel.flush()));
|
|
15093
|
+
}
|
|
14809
15094
|
log(logLevel, message, context) {
|
|
14810
15095
|
this.channel().log(logLevel, message, context);
|
|
14811
15096
|
}
|
|
@@ -15182,6 +15467,9 @@ var PendingMail = class {
|
|
|
15182
15467
|
async send(mailable) {
|
|
15183
15468
|
return this.mailer.send(mailable, this.overrides());
|
|
15184
15469
|
}
|
|
15470
|
+
async sendNow(mailable) {
|
|
15471
|
+
return this.mailer.sendNow(mailable, this.overrides());
|
|
15472
|
+
}
|
|
15185
15473
|
async queue(mailable) {
|
|
15186
15474
|
await this.mailer.queue(mailable, this.overrides());
|
|
15187
15475
|
}
|
|
@@ -15305,9 +15593,9 @@ var MailManager2 = class {
|
|
|
15305
15593
|
async queue(mailable) {
|
|
15306
15594
|
await this.mailer().queue(mailable);
|
|
15307
15595
|
}
|
|
15308
|
-
/**
|
|
15309
|
-
async sendNow(
|
|
15310
|
-
return this.mailer(
|
|
15596
|
+
/** Sends through the default mailer at once, even when the mailable is queueable (Laravel's Mail::sendNow()). */
|
|
15597
|
+
async sendNow(mailable) {
|
|
15598
|
+
return this.mailer().sendNow(mailable);
|
|
15311
15599
|
}
|
|
15312
15600
|
extend(transport, factory) {
|
|
15313
15601
|
this.drivers.set(transport, factory);
|
|
@@ -15330,7 +15618,10 @@ var MailServiceProvider = class extends ServiceProvider {
|
|
|
15330
15618
|
"mail"
|
|
15331
15619
|
);
|
|
15332
15620
|
this.app.singleton(MailManager, (container) => new MailManager2(container));
|
|
15333
|
-
this.app.singleton(QueuedMailSender, (container) =>
|
|
15621
|
+
this.app.singleton(QueuedMailSender, (container) => {
|
|
15622
|
+
const manager2 = container.make(MailManager);
|
|
15623
|
+
return { sendNow: (mailerName, mailable, overrides) => manager2.mailer(mailerName).sendNow(mailable, overrides) };
|
|
15624
|
+
});
|
|
15334
15625
|
this.app.make(ClassRegistry).register(SendQueuedMailable, "Mail.SendQueuedMailable");
|
|
15335
15626
|
}
|
|
15336
15627
|
};
|
|
@@ -15537,7 +15828,7 @@ var MailNotificationChannel = class {
|
|
|
15537
15828
|
const mailable = isMailable(result) ? result : mailableFromMessage(toMailMessage(result, notification.constructor.name), to);
|
|
15538
15829
|
const container = currentContainer();
|
|
15539
15830
|
if (!container?.bound(MailManager)) throw new MailUnavailableError();
|
|
15540
|
-
await container.make(MailManager).
|
|
15831
|
+
await container.make(MailManager).sendNow(mailable);
|
|
15541
15832
|
}
|
|
15542
15833
|
};
|
|
15543
15834
|
var NOTIFICATIONS_TABLE = "notifications";
|
|
@@ -15892,6 +16183,8 @@ import { randomUUID as randomUUID24 } from "crypto";
|
|
|
15892
16183
|
import { Redis as Redis2 } from "ioredis";
|
|
15893
16184
|
import { randomUUID as randomUUID32 } from "crypto";
|
|
15894
16185
|
import { setTimeout as sleep4 } from "timers/promises";
|
|
16186
|
+
import { spawn as spawnProcess } from "child_process";
|
|
16187
|
+
import { setTimeout as sleep22 } from "timers/promises";
|
|
15895
16188
|
import { existsSync as existsSync8, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
15896
16189
|
import { join as join12 } from "path";
|
|
15897
16190
|
import { pathToFileURL as pathToFileURL6 } from "url";
|
|
@@ -15980,6 +16273,40 @@ function isModel(value2) {
|
|
|
15980
16273
|
const candidate = value2;
|
|
15981
16274
|
return typeof candidate.getKey === "function" && typeof candidate.getKeyName === "function" && typeof candidate.getTable === "function" && typeof candidate.exists === "boolean";
|
|
15982
16275
|
}
|
|
16276
|
+
var isModelList = (value2) => typeof value2 === "object" && value2 !== null && !isModel(value2) && typeof value2[Symbol.iterator] === "function";
|
|
16277
|
+
function queueableRelations(model, visiting = /* @__PURE__ */ new Set()) {
|
|
16278
|
+
if (visiting.has(model)) return [];
|
|
16279
|
+
visiting.add(model);
|
|
16280
|
+
try {
|
|
16281
|
+
const relations = [];
|
|
16282
|
+
for (const [name, value2] of Object.entries(model.getRelations?.() ?? {})) {
|
|
16283
|
+
if (typeof model[name] !== "function") continue;
|
|
16284
|
+
relations.push(name);
|
|
16285
|
+
for (const nested of nestedRelations(value2, visiting)) relations.push(`${name}.${nested}`);
|
|
16286
|
+
}
|
|
16287
|
+
return [...new Set(relations)];
|
|
16288
|
+
} finally {
|
|
16289
|
+
visiting.delete(model);
|
|
16290
|
+
}
|
|
16291
|
+
}
|
|
16292
|
+
function nestedRelations(value2, visiting) {
|
|
16293
|
+
if (isModel(value2)) return queueableRelations(value2, visiting);
|
|
16294
|
+
if (!isModelList(value2)) return [];
|
|
16295
|
+
const members = [...value2].filter(isModel).map((member) => queueableRelations(member, visiting));
|
|
16296
|
+
if (members.length === 0) return [];
|
|
16297
|
+
return members.reduce((shared2, next) => shared2.filter((path) => next.includes(path)));
|
|
16298
|
+
}
|
|
16299
|
+
async function findForRestoration(model, key, connection) {
|
|
16300
|
+
if (connection !== void 0) {
|
|
16301
|
+
const instance = new model();
|
|
16302
|
+
if (typeof instance.setConnection === "function" && typeof instance.newQueryWithoutScopes === "function") {
|
|
16303
|
+
instance.setConnection(connection);
|
|
16304
|
+
return instance.newQueryWithoutScopes().find(key);
|
|
16305
|
+
}
|
|
16306
|
+
}
|
|
16307
|
+
const query = typeof model.withoutGlobalScopes === "function" ? model.withoutGlobalScopes() : model;
|
|
16308
|
+
return query.find(key);
|
|
16309
|
+
}
|
|
15983
16310
|
function classNameOf(registry2, cls) {
|
|
15984
16311
|
const existing = registry2.nameOf(cls);
|
|
15985
16312
|
if (existing !== void 0) return existing;
|
|
@@ -16049,7 +16376,12 @@ function serializeValue(value2, registry2, path = "data", seen = /* @__PURE__ */
|
|
|
16049
16376
|
if (!object.exists) {
|
|
16050
16377
|
throw new JobSerializationError(`Cannot serialize [${path}]: the [${name2}] model hasn't been saved, so it has no key to store.`);
|
|
16051
16378
|
}
|
|
16052
|
-
|
|
16379
|
+
const encoded = { [TAG]: "model", class: name2, key: serializeValue(object.getKey(), registry2, `${path}.key`, seen) ?? null };
|
|
16380
|
+
const connection = object.getConnectionName?.();
|
|
16381
|
+
if (connection !== void 0) encoded.connection = connection;
|
|
16382
|
+
const relations = queueableRelations(object);
|
|
16383
|
+
if (relations.length > 0) encoded.relations = relations;
|
|
16384
|
+
return encoded;
|
|
16053
16385
|
}
|
|
16054
16386
|
if (isPlainObject2(object)) {
|
|
16055
16387
|
const fields = serializeFields(object, registry2, path, seen);
|
|
@@ -16105,9 +16437,10 @@ async function restoreValue(value2, registry2) {
|
|
|
16105
16437
|
const name = value2.class;
|
|
16106
16438
|
const model = resolveClass(registry2, name);
|
|
16107
16439
|
const key = await restoreValue(value2.key, registry2);
|
|
16108
|
-
const
|
|
16109
|
-
const found = await query.find(key);
|
|
16440
|
+
const found = await findForRestoration(model, key, typeof value2.connection === "string" ? value2.connection : void 0);
|
|
16110
16441
|
if (found === void 0 || found === null) throw new MissingModelError(name, [key]);
|
|
16442
|
+
const relations = Array.isArray(value2.relations) ? value2.relations.map(String) : [];
|
|
16443
|
+
if (relations.length > 0) await (found.loadMissing ?? found.load)?.call(found, ...relations);
|
|
16111
16444
|
return found;
|
|
16112
16445
|
}
|
|
16113
16446
|
case "instance": {
|
|
@@ -17224,7 +17557,7 @@ var DatabaseBatchRepository = class {
|
|
|
17224
17557
|
var defaultWorkerOptions = () => ({
|
|
17225
17558
|
name: "default",
|
|
17226
17559
|
backoff: 0,
|
|
17227
|
-
memory:
|
|
17560
|
+
memory: 512,
|
|
17228
17561
|
timeout: 60,
|
|
17229
17562
|
sleep: 3,
|
|
17230
17563
|
maxTries: 1,
|
|
@@ -17482,6 +17815,142 @@ var Worker = class _Worker {
|
|
|
17482
17815
|
}
|
|
17483
17816
|
}
|
|
17484
17817
|
};
|
|
17818
|
+
var defaultListenerOptions = () => ({
|
|
17819
|
+
name: "default",
|
|
17820
|
+
backoff: 0,
|
|
17821
|
+
memory: 512,
|
|
17822
|
+
timeout: 60,
|
|
17823
|
+
sleep: 3,
|
|
17824
|
+
maxTries: 1,
|
|
17825
|
+
rest: 0,
|
|
17826
|
+
stopWhenEmpty: false
|
|
17827
|
+
});
|
|
17828
|
+
function lineSplitter(emit) {
|
|
17829
|
+
let rest = "";
|
|
17830
|
+
return {
|
|
17831
|
+
push(chunk) {
|
|
17832
|
+
const lines = (rest + chunk).split("\n");
|
|
17833
|
+
rest = lines.pop() ?? "";
|
|
17834
|
+
for (const line of lines) emit(line.endsWith("\r") ? line.slice(0, -1) : line);
|
|
17835
|
+
},
|
|
17836
|
+
end() {
|
|
17837
|
+
if (rest !== "") emit(rest);
|
|
17838
|
+
rest = "";
|
|
17839
|
+
}
|
|
17840
|
+
};
|
|
17841
|
+
}
|
|
17842
|
+
function currentRuntime() {
|
|
17843
|
+
const script = process.argv[1];
|
|
17844
|
+
if (script === void 0) throw new QueueError("queue:listen can't tell which script started this process, so it can't start workers.");
|
|
17845
|
+
return { command: process.execPath, args: [...process.execArgv, script] };
|
|
17846
|
+
}
|
|
17847
|
+
var Listener = class _Listener {
|
|
17848
|
+
constructor(manager2, config2) {
|
|
17849
|
+
this.manager = manager2;
|
|
17850
|
+
this.config = config2;
|
|
17851
|
+
}
|
|
17852
|
+
manager;
|
|
17853
|
+
config;
|
|
17854
|
+
static EXIT_SUCCESS = 0;
|
|
17855
|
+
shouldQuit = false;
|
|
17856
|
+
child;
|
|
17857
|
+
resting;
|
|
17858
|
+
/** Runs until stopped, the queue is empty (with stopWhenEmpty) or the memory limit is reached. Returns the exit code. */
|
|
17859
|
+
async listen(connection, queue, options) {
|
|
17860
|
+
const stopListening = this.listenForSignals();
|
|
17861
|
+
try {
|
|
17862
|
+
const command = this.makeCommand(connection, queue, options);
|
|
17863
|
+
while (!this.shouldQuit) {
|
|
17864
|
+
if (options.stopWhenEmpty && await this.isEmpty(connection, queue)) break;
|
|
17865
|
+
if (this.shouldQuit) break;
|
|
17866
|
+
await this.runProcess(command, options.timeout);
|
|
17867
|
+
if (this.shouldQuit || this.memoryExceeded(options.memory)) break;
|
|
17868
|
+
if (options.rest > 0) await this.rest(options.rest);
|
|
17869
|
+
}
|
|
17870
|
+
return _Listener.EXIT_SUCCESS;
|
|
17871
|
+
} finally {
|
|
17872
|
+
stopListening();
|
|
17873
|
+
}
|
|
17874
|
+
}
|
|
17875
|
+
/** Laravel's createCommand(): the runtime, the CLI script and `queue:work <connection> --once …`, plus `--timeout`. */
|
|
17876
|
+
makeCommand(connection, queue, options) {
|
|
17877
|
+
const { command, args } = this.config.runtime ?? currentRuntime();
|
|
17878
|
+
const backoff = Array.isArray(options.backoff) ? options.backoff.join(",") : String(options.backoff);
|
|
17879
|
+
return [
|
|
17880
|
+
command,
|
|
17881
|
+
...args,
|
|
17882
|
+
"queue:work",
|
|
17883
|
+
connection,
|
|
17884
|
+
"--once",
|
|
17885
|
+
`--name=${options.name}`,
|
|
17886
|
+
`--queue=${queue}`,
|
|
17887
|
+
`--backoff=${backoff}`,
|
|
17888
|
+
`--memory=${options.memory}`,
|
|
17889
|
+
`--sleep=${options.sleep}`,
|
|
17890
|
+
`--tries=${options.maxTries}`,
|
|
17891
|
+
`--timeout=${options.timeout}`
|
|
17892
|
+
];
|
|
17893
|
+
}
|
|
17894
|
+
/** Stops after the running process, which gets the same signal (SIGTERM/SIGINT/SIGQUIT call this). */
|
|
17895
|
+
stop(signal = "SIGTERM") {
|
|
17896
|
+
this.shouldQuit = true;
|
|
17897
|
+
this.child?.kill(signal);
|
|
17898
|
+
this.resting?.abort();
|
|
17899
|
+
}
|
|
17900
|
+
memoryExceeded(limitMb) {
|
|
17901
|
+
return limitMb > 0 && process.memoryUsage().heapUsed / 1024 / 1024 >= limitMb;
|
|
17902
|
+
}
|
|
17903
|
+
listenForSignals() {
|
|
17904
|
+
const signals = ["SIGTERM", "SIGINT", "SIGQUIT"];
|
|
17905
|
+
const handlers = signals.map((signal) => [signal, () => this.stop(signal)]);
|
|
17906
|
+
for (const [signal, handler3] of handlers) process.on(signal, handler3);
|
|
17907
|
+
return () => {
|
|
17908
|
+
for (const [signal, handler3] of handlers) process.off(signal, handler3);
|
|
17909
|
+
};
|
|
17910
|
+
}
|
|
17911
|
+
async isEmpty(connection, queue) {
|
|
17912
|
+
const queues = this.manager.connection(connection);
|
|
17913
|
+
for (const name of queue.split(",")) if (await queues.size(name.trim()) > 0) return false;
|
|
17914
|
+
return true;
|
|
17915
|
+
}
|
|
17916
|
+
runProcess([command, ...args], timeout) {
|
|
17917
|
+
const output = this.config.output ?? (() => {
|
|
17918
|
+
});
|
|
17919
|
+
return new Promise((resolve3, reject) => {
|
|
17920
|
+
const child = (this.config.spawn ?? spawnProcess)(command, args, { cwd: this.config.commandPath, env: process.env, stdio: ["ignore", "pipe", "pipe"] });
|
|
17921
|
+
this.child = child;
|
|
17922
|
+
const stdout = lineSplitter((line) => output("out", line));
|
|
17923
|
+
const stderr = lineSplitter((line) => output("err", line));
|
|
17924
|
+
child.stdout?.setEncoding("utf8").on("data", (chunk) => stdout.push(chunk));
|
|
17925
|
+
child.stderr?.setEncoding("utf8").on("data", (chunk) => stderr.push(chunk));
|
|
17926
|
+
const timer = timeout > 0 ? setTimeout(() => {
|
|
17927
|
+
output("err", `The process "${[command, ...args].join(" ")}" exceeded the timeout of ${timeout} seconds.`);
|
|
17928
|
+
child.kill("SIGKILL");
|
|
17929
|
+
}, timeout * 1e3) : void 0;
|
|
17930
|
+
let settled = false;
|
|
17931
|
+
const settle = () => {
|
|
17932
|
+
if (settled) return false;
|
|
17933
|
+
settled = true;
|
|
17934
|
+
clearTimeout(timer);
|
|
17935
|
+
this.child = void 0;
|
|
17936
|
+
stdout.end();
|
|
17937
|
+
stderr.end();
|
|
17938
|
+
return true;
|
|
17939
|
+
};
|
|
17940
|
+
child.once("error", (error) => settle() && reject(error));
|
|
17941
|
+
child.once("close", () => settle() && resolve3());
|
|
17942
|
+
});
|
|
17943
|
+
}
|
|
17944
|
+
async rest(seconds) {
|
|
17945
|
+
this.resting = new AbortController();
|
|
17946
|
+
try {
|
|
17947
|
+
await sleep22(seconds * 1e3, void 0, { signal: this.resting.signal });
|
|
17948
|
+
} catch {
|
|
17949
|
+
} finally {
|
|
17950
|
+
this.resting = void 0;
|
|
17951
|
+
}
|
|
17952
|
+
}
|
|
17953
|
+
};
|
|
17485
17954
|
var EXTENSIONS2 = [".ts", ".js", ".mts", ".mjs"];
|
|
17486
17955
|
function files2(directory) {
|
|
17487
17956
|
const found = [];
|
|
@@ -17520,6 +17989,22 @@ function localTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
|
17520
17989
|
const pad2 = (n) => String(n).padStart(2, "0");
|
|
17521
17990
|
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;
|
|
17522
17991
|
}
|
|
17992
|
+
function processingMessage(queue) {
|
|
17993
|
+
return `Processing jobs from the [${queue}] ${Str.plural("queue", queue.split(",").length)}.`;
|
|
17994
|
+
}
|
|
17995
|
+
function listenerOptionsFrom(option) {
|
|
17996
|
+
const defaults = defaultListenerOptions();
|
|
17997
|
+
return {
|
|
17998
|
+
name: text2(option("name")) ?? defaults.name,
|
|
17999
|
+
backoff: text2(option("backoff")) ?? defaults.backoff,
|
|
18000
|
+
memory: number2(option("memory"), defaults.memory),
|
|
18001
|
+
timeout: number2(option("timeout"), defaults.timeout),
|
|
18002
|
+
sleep: number2(option("sleep"), defaults.sleep),
|
|
18003
|
+
maxTries: number2(option("tries"), defaults.maxTries),
|
|
18004
|
+
rest: number2(option("rest"), defaults.rest),
|
|
18005
|
+
stopWhenEmpty: option("stop-when-empty") === true
|
|
18006
|
+
};
|
|
18007
|
+
}
|
|
17523
18008
|
function workerOptionsFrom(option) {
|
|
17524
18009
|
const defaults = defaultWorkerOptions();
|
|
17525
18010
|
return {
|
|
@@ -17550,7 +18035,7 @@ function registerQueueCommands(kernel, context) {
|
|
|
17550
18035
|
return false;
|
|
17551
18036
|
};
|
|
17552
18037
|
define2(
|
|
17553
|
-
"queue:work {connection? : The name of the queue connection to work} {--name=default : The name of the worker} {--queue= : The names of the queues to work} {--once : Only process the next job on the queue} {--stop-when-empty : Stop when the queue is empty} {--backoff=0 : Seconds to wait before retrying a job that failed} {--max-jobs=0 : The number of jobs to process before stopping} {--max-time=0 : The maximum number of seconds the worker should run} {--memory=
|
|
18038
|
+
"queue:work {connection? : The name of the queue connection to work} {--name=default : The name of the worker} {--queue= : The names of the queues to work} {--once : Only process the next job on the queue} {--stop-when-empty : Stop when the queue is empty} {--backoff=0 : Seconds to wait before retrying a job that failed} {--max-jobs=0 : The number of jobs to process before stopping} {--max-time=0 : The maximum number of seconds the worker should run} {--memory=512 : The memory limit in megabytes, measured as V8 heap in use (a Node app on tsx uses about 115 MB at idle)} {--sleep=3 : Seconds to sleep when no job is available} {--rest=0 : Seconds to rest between jobs} {--timeout=60 : The number of seconds a child process can run} {--tries=1 : Number of times to attempt a job before logging it failed}",
|
|
17554
18039
|
"Start processing jobs on the queue as a daemon",
|
|
17555
18040
|
async (out) => {
|
|
17556
18041
|
const connection = text2(out.argument("connection")) ?? defaultConnection();
|
|
@@ -17567,13 +18052,34 @@ function registerQueueCommands(kernel, context) {
|
|
|
17567
18052
|
exception: (error, job) => out.error(`${job ? `${name(job)}: ` : ""}${errorClass(error)}`)
|
|
17568
18053
|
});
|
|
17569
18054
|
const options = workerOptionsFrom((option) => out.option(option));
|
|
17570
|
-
out.info(
|
|
18055
|
+
out.info(processingMessage(queue));
|
|
17571
18056
|
if (out.option("once") === true) {
|
|
17572
18057
|
return worker.runNextJob(connection, queue, options);
|
|
17573
18058
|
}
|
|
17574
18059
|
return worker.daemon(connection, queue, options);
|
|
17575
18060
|
}
|
|
17576
18061
|
);
|
|
18062
|
+
define2(
|
|
18063
|
+
"queue:listen {connection? : The name of connection} {--name=default : The name of the worker} {--backoff=0 : The number of seconds to wait before retrying a job that encountered an uncaught exception} {--memory=512 : The memory limit in megabytes, measured as V8 heap in use (a Node app on tsx uses about 115 MB at idle)} {--queue= : The queue to listen on} {--sleep=3 : Number of seconds to sleep when no job is available} {--rest=0 : Number of seconds to rest between jobs} {--timeout=60 : The number of seconds a child process can run} {--tries=1 : Number of times to attempt a job before logging it failed} {--stop-when-empty : Stop when the queue is empty}",
|
|
18064
|
+
"Listen to a given queue",
|
|
18065
|
+
async (out) => {
|
|
18066
|
+
const connection = text2(out.argument("connection")) ?? defaultConnection();
|
|
18067
|
+
const queue = text2(out.option("queue")) ?? defaultQueue(connection);
|
|
18068
|
+
const banner = processingMessage(queue);
|
|
18069
|
+
out.info(banner);
|
|
18070
|
+
const listener = new Listener(container.make(QueueManager), {
|
|
18071
|
+
commandPath: context.app.basePath(),
|
|
18072
|
+
spawn: context.spawn,
|
|
18073
|
+
// Each `queue:work` starts with the same line as this command; it's shown once.
|
|
18074
|
+
output: (type, line) => {
|
|
18075
|
+
if (line === banner) return;
|
|
18076
|
+
if (type === "out") out.line(line);
|
|
18077
|
+
else out.error(line);
|
|
18078
|
+
}
|
|
18079
|
+
});
|
|
18080
|
+
return listener.listen(connection, queue, listenerOptionsFrom((option) => out.option(option)));
|
|
18081
|
+
}
|
|
18082
|
+
);
|
|
17577
18083
|
define2("queue:restart", "Restart queue worker daemons after their current job", async (out) => {
|
|
17578
18084
|
if (!container.bound(CacheManager)) {
|
|
17579
18085
|
out.error("queue:restart needs a cache store. Register the CacheServiceProvider.");
|
|
@@ -18040,6 +18546,32 @@ var RouteDefinition = class {
|
|
|
18040
18546
|
this.#compiled = void 0;
|
|
18041
18547
|
return this;
|
|
18042
18548
|
}
|
|
18549
|
+
/** Laravel's whereAlpha(): ASCII letters only. One parameter name or several. */
|
|
18550
|
+
whereAlpha(parameters) {
|
|
18551
|
+
return this.#assign(parameters, "[a-zA-Z]+");
|
|
18552
|
+
}
|
|
18553
|
+
/** Laravel's whereAlphaNumeric(): ASCII letters and digits. */
|
|
18554
|
+
whereAlphaNumeric(parameters) {
|
|
18555
|
+
return this.#assign(parameters, "[a-zA-Z0-9]+");
|
|
18556
|
+
}
|
|
18557
|
+
/** Laravel's whereNumber(): digits only. */
|
|
18558
|
+
whereNumber(parameters) {
|
|
18559
|
+
return this.#assign(parameters, "[0-9]+");
|
|
18560
|
+
}
|
|
18561
|
+
/** Laravel's whereUlid(): 26 Crockford base-32 characters, the first at most 7. */
|
|
18562
|
+
whereUlid(parameters) {
|
|
18563
|
+
return this.#assign(parameters, "[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}");
|
|
18564
|
+
}
|
|
18565
|
+
/** Laravel's whereUuid(): five groups of hex digits (8-4-4-4-12), any version. */
|
|
18566
|
+
whereUuid(parameters) {
|
|
18567
|
+
return this.#assign(parameters, "[\\da-fA-F]{8}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{12}");
|
|
18568
|
+
}
|
|
18569
|
+
/** Laravel's whereIn(): one of the values. Unlike Laravel, each value is matched literally (`c++` is not a pattern). */
|
|
18570
|
+
whereIn(parameters, values) {
|
|
18571
|
+
const first = typeof parameters === "string" ? parameters : parameters[0];
|
|
18572
|
+
if (values.length === 0 && first !== void 0) throw new Error(`Routing requirement for "${first}" cannot be empty.`);
|
|
18573
|
+
return this.#assign(parameters, values.map((value2) => escapeRegex(String(value2))).join("|"));
|
|
18574
|
+
}
|
|
18043
18575
|
gatherMiddleware() {
|
|
18044
18576
|
return [...this.#middleware];
|
|
18045
18577
|
}
|
|
@@ -18070,6 +18602,10 @@ var RouteDefinition = class {
|
|
|
18070
18602
|
if (this.uri === "/") return [];
|
|
18071
18603
|
return this.uri.split("/").map((segment) => WHOLE_OPTIONAL.test(segment) ? 2 : segment.includes("{") ? 1 : 0);
|
|
18072
18604
|
}
|
|
18605
|
+
#assign(parameters, pattern) {
|
|
18606
|
+
const names = typeof parameters === "string" ? [parameters] : parameters;
|
|
18607
|
+
return this.where(Object.fromEntries(names.map((name) => [name, pattern])));
|
|
18608
|
+
}
|
|
18073
18609
|
#regex(patterns, version) {
|
|
18074
18610
|
if (this.#compiled !== void 0 && this.#compiled.version === version) return this.#compiled.regex;
|
|
18075
18611
|
const wheres = { ...patterns, ...this.#wheres };
|
|
@@ -20887,6 +21423,8 @@ export {
|
|
|
20887
21423
|
HasManyThrough,
|
|
20888
21424
|
HasOne,
|
|
20889
21425
|
HasOneOrMany,
|
|
21426
|
+
HasUlids,
|
|
21427
|
+
HasUuids,
|
|
20890
21428
|
Hash,
|
|
20891
21429
|
HashAlgorithmError,
|
|
20892
21430
|
HashManager,
|
|
@@ -21051,6 +21589,7 @@ export {
|
|
|
21051
21589
|
Queue2 as Queue,
|
|
21052
21590
|
QueueBase,
|
|
21053
21591
|
QueueError,
|
|
21592
|
+
Listener as QueueListener,
|
|
21054
21593
|
QueueManager2 as QueueManager,
|
|
21055
21594
|
QueueServiceProvider,
|
|
21056
21595
|
QueueUnavailableError,
|
|
@@ -21085,7 +21624,8 @@ export {
|
|
|
21085
21624
|
S3Filesystem,
|
|
21086
21625
|
SSR_RENDER_FAILED,
|
|
21087
21626
|
STORAGE_LINK_SIGNATURE,
|
|
21088
|
-
|
|
21627
|
+
Schedule5 as Schedule,
|
|
21628
|
+
ScheduleClearCacheCommand,
|
|
21089
21629
|
ScheduleImpl,
|
|
21090
21630
|
ScheduleListCommand,
|
|
21091
21631
|
ScheduleNameRequiredError,
|
|
@@ -21117,6 +21657,7 @@ export {
|
|
|
21117
21657
|
StartSession,
|
|
21118
21658
|
Storage2 as Storage,
|
|
21119
21659
|
Str,
|
|
21660
|
+
Stringable,
|
|
21120
21661
|
SyncJob,
|
|
21121
21662
|
SyncQueue,
|
|
21122
21663
|
TagsNotSupportedError,
|
|
@@ -21225,6 +21766,7 @@ export {
|
|
|
21225
21766
|
decodePayload,
|
|
21226
21767
|
decrypt,
|
|
21227
21768
|
defaultAttributeName,
|
|
21769
|
+
defaultListenerOptions,
|
|
21228
21770
|
defaultLockFactory,
|
|
21229
21771
|
defaultProviders,
|
|
21230
21772
|
defaultWorkerOptions,
|
|
@@ -21290,6 +21832,7 @@ export {
|
|
|
21290
21832
|
isUploadedFileLike,
|
|
21291
21833
|
joinDiskPath,
|
|
21292
21834
|
keyGenerateHandler,
|
|
21835
|
+
listenerOptionsFrom,
|
|
21293
21836
|
live,
|
|
21294
21837
|
loadRelations,
|
|
21295
21838
|
loadRoutesFrom,
|