@bunyad/orm 0.1.0-alpha.0 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/model.js CHANGED
@@ -355,7 +355,7 @@ export class Model {
355
355
  /** When false, `save()` skips `created_at` / `updated_at`. */
356
356
  static timestamps = true;
357
357
  /**
358
- * Laravel `$casts` property — prefer `static casts()` when adding enums / Attribute.
358
+ * `$casts` property — prefer `static casts()` when adding enums / Attribute.
359
359
  * May be a plain object or a method returning the map.
360
360
  */
361
361
  static casts = {};
@@ -366,19 +366,19 @@ export class Model {
366
366
  */
367
367
  static relations = {};
368
368
  /**
369
- * Laravel `$touches` — relation names whose related models get `touch()` after
369
+ * `$touches` — relation names whose related models get `touch()` after
370
370
  * this model is saved (or soft-deleted). Honor `withoutTouching`.
371
371
  */
372
372
  static touches = [];
373
- /** Laravel `$hidden`. */
373
+ /** `$hidden`. */
374
374
  static hidden = [];
375
- /** Laravel `$visible` allow-list (empty = all non-hidden). */
375
+ /** `$visible` allow-list (empty = all non-hidden). */
376
376
  static visible = [];
377
- /** Laravel `$appends` — accessors included in `toArray()`. */
377
+ /** `$appends` — accessors included in `toArray()`. */
378
378
  static appends = [];
379
- /** Laravel `$fillable`. */
379
+ /** `$fillable`. */
380
380
  static fillable = [];
381
- /** Laravel `$guarded` — default guard all until fillable is set. */
381
+ /** `$guarded` — default guard all until fillable is set. */
382
382
  static guarded = ["*"];
383
383
  /** Set in constructor / hydrate — avoid empty `{}` alloc before assign. */
384
384
  #original;
@@ -395,7 +395,7 @@ export class Model {
395
395
  #visible = null;
396
396
  /** Per-instance connection override (`$model->setConnection()`). */
397
397
  #connection;
398
- /** Laravel `$exists` — true after retrieve / successful insert. */
398
+ /** `$exists` — true after retrieve / successful insert. */
399
399
  get exists() {
400
400
  return this.#exists;
401
401
  }
@@ -444,7 +444,7 @@ export class Model {
444
444
  return out;
445
445
  }
446
446
  /**
447
- * Laravel `getAttribute` — throws when `preventAccessingMissingAttributes` is on
447
+ * `getAttribute` — throws when `preventAccessingMissingAttributes` is on
448
448
  * and the key was not retrieved / does not exist (relations exempt).
449
449
  */
450
450
  getAttribute(key) {
@@ -478,18 +478,18 @@ export class Model {
478
478
  }
479
479
  return undefined;
480
480
  }
481
- /** Laravel `isDirty`. */
481
+ /** `isDirty`. */
482
482
  isDirty(...attributes) {
483
483
  const dirty = this.getDirty();
484
484
  if (attributes.length === 0)
485
485
  return Object.keys(dirty).length > 0;
486
486
  return attributes.some((key) => Object.prototype.hasOwnProperty.call(dirty, key));
487
487
  }
488
- /** Laravel `isClean`. */
488
+ /** `isClean`. */
489
489
  isClean(...attributes) {
490
490
  return !this.isDirty(...attributes);
491
491
  }
492
- /** Laravel `getDirty`. */
492
+ /** `getDirty`. */
493
493
  getDirty() {
494
494
  const dirty = {};
495
495
  const original = this.#original ?? {};
@@ -505,11 +505,11 @@ export class Model {
505
505
  return { ...original };
506
506
  return original[key];
507
507
  }
508
- /** Laravel `getChanges` — attributes changed by the last save. */
508
+ /** `getChanges` — attributes changed by the last save. */
509
509
  getChanges() {
510
510
  return this.#changes ? { ...this.#changes } : {};
511
511
  }
512
- /** Laravel `wasChanged`. */
512
+ /** `wasChanged`. */
513
513
  wasChanged(...attributes) {
514
514
  const changes = this.#changes;
515
515
  if (!changes)
@@ -518,50 +518,50 @@ export class Model {
518
518
  return Object.keys(changes).length > 0;
519
519
  return attributes.some((key) => Object.prototype.hasOwnProperty.call(changes, key));
520
520
  }
521
- /** Laravel `wasRecentlyCreated`. */
521
+ /** `wasRecentlyCreated`. */
522
522
  wasRecentlyCreated() {
523
523
  return this.#wasRecentlyCreated;
524
524
  }
525
- /** Laravel `append`. */
525
+ /** `append`. */
526
526
  append(...attributes) {
527
527
  const current = this.getAppends();
528
528
  this.#appends = [...new Set([...current, ...attributes.flat()])];
529
529
  return this;
530
530
  }
531
- /** Laravel `setAppends`. */
531
+ /** `setAppends`. */
532
532
  setAppends(attributes) {
533
533
  this.#appends = [...attributes];
534
534
  return this;
535
535
  }
536
- /** Laravel `getAppends`. */
536
+ /** `getAppends`. */
537
537
  getAppends() {
538
538
  if (this.#appends)
539
539
  return [...this.#appends];
540
540
  return [...(this.constructor.appends ?? [])];
541
541
  }
542
- /** Laravel `getHidden`. */
542
+ /** `getHidden`. */
543
543
  getHidden() {
544
544
  if (this.#hidden)
545
545
  return [...this.#hidden];
546
546
  return [...(this.constructor.hidden ?? [])];
547
547
  }
548
- /** Laravel `getVisible`. */
548
+ /** `getVisible`. */
549
549
  getVisible() {
550
550
  if (this.#visible)
551
551
  return [...this.#visible];
552
552
  return [...(this.constructor.visible ?? [])];
553
553
  }
554
- /** Laravel `setHidden`. */
554
+ /** `setHidden`. */
555
555
  setHidden(attributes) {
556
556
  this.#hidden = [...attributes];
557
557
  return this;
558
558
  }
559
- /** Laravel `setVisible`. */
559
+ /** `setVisible`. */
560
560
  setVisible(attributes) {
561
561
  this.#visible = [...attributes];
562
562
  return this;
563
563
  }
564
- /** Laravel `makeVisible` — show attributes for this instance. */
564
+ /** `makeVisible` — show attributes for this instance. */
565
565
  makeVisible(...attributes) {
566
566
  const attrs = attributes.flat();
567
567
  const hidden = new Set(this.getHidden());
@@ -574,7 +574,7 @@ export class Model {
574
574
  }
575
575
  return this;
576
576
  }
577
- /** Laravel `makeHidden` — hide attributes for this instance. */
577
+ /** `makeHidden` — hide attributes for this instance. */
578
578
  makeHidden(...attributes) {
579
579
  const attrs = attributes.flat();
580
580
  this.#hidden = [...new Set([...this.getHidden(), ...attrs])];
@@ -586,7 +586,7 @@ export class Model {
586
586
  return this;
587
587
  }
588
588
  /**
589
- * Run a callback without touching timestamps (Laravel `Model::withoutTimestamps`).
589
+ * Run a callback without touching timestamps (`Model::withoutTimestamps`).
590
590
  */
591
591
  static async withoutTimestamps(callback) {
592
592
  const previous = this.timestamps;
@@ -605,23 +605,23 @@ export class Model {
605
605
  static isIgnoringTouch() {
606
606
  return isIgnoringTouch(this);
607
607
  }
608
- /** Laravel `Model::preventLazyLoading`. */
608
+ /** `Model::preventLazyLoading`. */
609
609
  static preventLazyLoading(prevent = true) {
610
610
  setPreventLazyLoading(prevent);
611
611
  }
612
- /** Laravel `Model::preventSilentlyDiscardingAttributes`. */
612
+ /** `Model::preventSilentlyDiscardingAttributes`. */
613
613
  static preventSilentlyDiscardingAttributes(prevent = true) {
614
614
  setPreventSilentlyDiscardingAttributes(prevent);
615
615
  }
616
- /** Laravel `Model::preventAccessingMissingAttributes`. */
616
+ /** `Model::preventAccessingMissingAttributes`. */
617
617
  static preventAccessingMissingAttributes(prevent = true) {
618
618
  setPreventAccessingMissingAttributes(prevent);
619
619
  }
620
- /** Laravel `Model::shouldBeStrict` — enable/disable the strictness trio. */
620
+ /** `Model::shouldBeStrict` — enable/disable the strictness trio. */
621
621
  static shouldBeStrict(should = true) {
622
622
  setShouldBeStrict(should);
623
623
  }
624
- /** Laravel `Model::addGlobalScope`. */
624
+ /** `Model::addGlobalScope`. */
625
625
  static addGlobalScope(nameOrScope, scope) {
626
626
  if (typeof nameOrScope === "function") {
627
627
  registerGlobalScope(this, nameOrScope.name || `scope_${Date.now()}`, nameOrScope);
@@ -631,28 +631,28 @@ export class Model {
631
631
  throw new Error("addGlobalScope requires a callback.");
632
632
  registerGlobalScope(this, nameOrScope, scope);
633
633
  }
634
- /** Laravel `Model::addGlobalScope` removal helper. */
634
+ /** `Model::addGlobalScope` removal helper. */
635
635
  static removeGlobalScope(name) {
636
636
  unregisterGlobalScope(this, name);
637
637
  }
638
638
  /**
639
- * Laravel `boot` — runs once per model class before first use.
639
+ * `boot` — runs once per model class before first use.
640
640
  * Prefer registering listeners in `booted()`.
641
641
  */
642
642
  static boot() { }
643
643
  /**
644
- * Laravel `booted` — runs once after `boot`. Typical place for `static::created(...)`.
644
+ * `booted` — runs once after `boot`. Typical place for `static::created(...)`.
645
645
  */
646
646
  static booted() { }
647
647
  /** Ensure this model class has been booted. */
648
648
  static bootIfNotBooted() {
649
649
  bootIfNotBooted(this);
650
650
  }
651
- /** Laravel `Model::observe`. */
651
+ /** `Model::observe`. */
652
652
  static observe(observer) {
653
653
  observeModel(this, observer);
654
654
  }
655
- /** Laravel `Model::withoutEvents`. */
655
+ /** `Model::withoutEvents`. */
656
656
  static withoutEvents(callback) {
657
657
  return withoutModelEvents(this, callback);
658
658
  }
@@ -779,7 +779,7 @@ export class Model {
779
779
  static getConnection() {
780
780
  return resolveConnection(this.connection);
781
781
  }
782
- /** Laravel `$model->setConnection($name)`. */
782
+ /** `$model->setConnection($name)`. */
783
783
  setConnection(connection) {
784
784
  this.#connection = connection;
785
785
  return this;
@@ -799,7 +799,7 @@ export class Model {
799
799
  return manager;
800
800
  }
801
801
  /**
802
- * Laravel `Model::on($connection)` — same model, different named connection.
802
+ * `Model::on($connection)` — same model, different named connection.
803
803
  */
804
804
  static on(connection) {
805
805
  return this.newQuery({ connection });
@@ -814,21 +814,21 @@ export class Model {
814
814
  const query = new Ctor(this, options);
815
815
  return withLocalScopeProxy(query);
816
816
  }
817
- /** Laravel `withoutGlobalScopes()`. */
817
+ /** `withoutGlobalScopes()`. */
818
818
  static withoutGlobalScopes(names) {
819
819
  return this.newQuery({
820
820
  withoutGlobalScopes: names ?? true,
821
821
  });
822
822
  }
823
- /** Laravel `withoutGlobalScope($name)`. */
823
+ /** `withoutGlobalScope($name)`. */
824
824
  static withoutGlobalScope(name) {
825
825
  return this.newQuery({ withoutGlobalScopes: [name] });
826
826
  }
827
- /** Laravel `Model::query()` — scoped `ModelQuery` (not a raw table builder). */
827
+ /** `Model::query()` — scoped `ModelQuery` (not a raw table builder). */
828
828
  static query(options) {
829
829
  return this.newQuery(options);
830
830
  }
831
- /** Laravel `Model::find`. */
831
+ /** `Model::find`. */
832
832
  static find(id) {
833
833
  this.bootIfNotBooted();
834
834
  if (canFastFind(this)) {
@@ -839,12 +839,12 @@ export class Model {
839
839
  .where(this.primaryKey, id)
840
840
  .first();
841
841
  }
842
- /** Laravel `getRouteKeyName()` — column used for implicit route binding. */
842
+ /** `getRouteKeyName()` — column used for implicit route binding. */
843
843
  static getRouteKeyName() {
844
844
  return this.primaryKey;
845
845
  }
846
846
  /**
847
- * Laravel `resolveRouteBinding` — find by PK or custom `{param:column}` field.
847
+ * `resolveRouteBinding` — find by PK or custom `{param:column}` field.
848
848
  */
849
849
  static resolveRouteBinding(value, field) {
850
850
  const column = field ?? this.getRouteKeyName();
@@ -855,7 +855,7 @@ export class Model {
855
855
  return this.newQuery().where(column, value).first();
856
856
  }
857
857
  /**
858
- * Laravel SoftDeletes `resolveSoftDeletableRouteBinding` — same as
858
+ * `resolveSoftDeletableRouteBinding` — same as
859
859
  * `resolveRouteBinding` but includes soft-deleted rows (`withTrashed()`).
860
860
  * Used by the router when the route opts in via `withTrashed()`.
861
861
  */
@@ -885,20 +885,20 @@ export class Model {
885
885
  model.#exists = true;
886
886
  return model;
887
887
  }
888
- /** Laravel `Model::findOrFail`. */
888
+ /** `Model::findOrFail`. */
889
889
  static async findOrFail(id) {
890
890
  const model = await this.find(id);
891
891
  if (!model)
892
892
  throw new ModelNotFoundException();
893
893
  return model;
894
894
  }
895
- /** Laravel `Model::all`. */
895
+ /** `Model::all`. */
896
896
  static async all() {
897
897
  this.bootIfNotBooted();
898
898
  return this.newQuery().get();
899
899
  }
900
900
  /**
901
- * Laravel `Model::get` — same as `query().get()` / `all()`.
901
+ * `Model::get` — same as `query().get()` / `all()`.
902
902
  * Typed helper for autocomplete; Proxy also forwards other terminals.
903
903
  */
904
904
  static get() {
@@ -995,30 +995,30 @@ export class Model {
995
995
  return q.whereDate(column, opOrValue);
996
996
  return q.whereDate(column, String(opOrValue), value);
997
997
  }
998
- /** Laravel `Model::whereNot(closure)`. */
998
+ /** `Model::whereNot(closure)`. */
999
999
  static whereNot(callback) {
1000
1000
  this.bootIfNotBooted();
1001
1001
  return this.newQuery().whereNot(callback);
1002
1002
  }
1003
- /** Laravel `Model::orWhereNot(closure)`. */
1003
+ /** `Model::orWhereNot(closure)`. */
1004
1004
  static orWhereNot(callback) {
1005
1005
  this.bootIfNotBooted();
1006
1006
  return this.newQuery().orWhereNot(callback);
1007
1007
  }
1008
- /** Laravel `withTrashed()`. */
1008
+ /** `withTrashed()`. */
1009
1009
  static withTrashed() {
1010
1010
  this.bootIfNotBooted();
1011
1011
  return this.newQuery({
1012
1012
  withTrashed: true,
1013
1013
  });
1014
1014
  }
1015
- /** Laravel `onlyTrashed()`. */
1015
+ /** `onlyTrashed()`. */
1016
1016
  static onlyTrashed() {
1017
1017
  return this.newQuery({
1018
1018
  onlyTrashed: true,
1019
1019
  });
1020
1020
  }
1021
- /** Laravel `withoutTrashed()`. */
1021
+ /** `withoutTrashed()`. */
1022
1022
  static withoutTrashed() {
1023
1023
  return this.newQuery({
1024
1024
  withTrashed: false,
@@ -1035,27 +1035,27 @@ export class Model {
1035
1035
  eagerLoad: normalizeWithRelations(relations),
1036
1036
  });
1037
1037
  }
1038
- /** Laravel `Model::whereHas`. */
1038
+ /** `Model::whereHas`. */
1039
1039
  static whereHas(relation, callback) {
1040
1040
  this.bootIfNotBooted();
1041
1041
  return this.newQuery().whereHas(relation, callback);
1042
1042
  }
1043
- /** Laravel `Model::whereDoesntHave`. */
1043
+ /** `Model::whereDoesntHave`. */
1044
1044
  static whereDoesntHave(relation, callback) {
1045
1045
  this.bootIfNotBooted();
1046
1046
  return this.newQuery().whereDoesntHave(relation, callback);
1047
1047
  }
1048
- /** Laravel `Model::orWhereHas`. */
1048
+ /** `Model::orWhereHas`. */
1049
1049
  static orWhereHas(relation, callback) {
1050
1050
  this.bootIfNotBooted();
1051
1051
  return this.newQuery().orWhereHas(relation, callback);
1052
1052
  }
1053
- /** Laravel `Model::whereRelation`. */
1053
+ /** `Model::whereRelation`. */
1054
1054
  static whereRelation(relation, column, opOrValue, value) {
1055
1055
  this.bootIfNotBooted();
1056
1056
  return this.newQuery().whereRelation(relation, column, opOrValue, value);
1057
1057
  }
1058
- /** Laravel `Model::orWhereRelation`. */
1058
+ /** `Model::orWhereRelation`. */
1059
1059
  static orWhereRelation(relation, column, opOrValue, value) {
1060
1060
  this.bootIfNotBooted();
1061
1061
  return this.newQuery().orWhereRelation(relation, column, opOrValue, value);
@@ -1065,7 +1065,7 @@ export class Model {
1065
1065
  this.bootIfNotBooted();
1066
1066
  return this.newQuery().withCount(...relations);
1067
1067
  }
1068
- /** Laravel `Model::withSum`. */
1068
+ /** `Model::withSum`. */
1069
1069
  static withSum(relation, column) {
1070
1070
  this.bootIfNotBooted();
1071
1071
  return this.newQuery().withSum(relation, column);
@@ -1110,40 +1110,40 @@ export class Model {
1110
1110
  this.bootIfNotBooted();
1111
1111
  return this.newQuery().whereKey(id);
1112
1112
  }
1113
- /** Laravel `Model::whereUuid`. */
1113
+ /** `Model::whereUuid`. */
1114
1114
  static whereUuid(column, value) {
1115
1115
  this.bootIfNotBooted();
1116
1116
  return this.newQuery().whereUuid(column, value);
1117
1117
  }
1118
- /** Laravel `Model::whereUlid`. */
1118
+ /** `Model::whereUlid`. */
1119
1119
  static whereUlid(column, value) {
1120
1120
  this.bootIfNotBooted();
1121
1121
  return this.newQuery().whereUlid(column, value);
1122
1122
  }
1123
- /** Laravel `Model::join`. */
1123
+ /** `Model::join`. */
1124
1124
  static join(table, first, op, second) {
1125
1125
  this.bootIfNotBooted();
1126
1126
  return this.newQuery().join(table, first, op, second);
1127
1127
  }
1128
- /** Laravel `Model::leftJoin`. */
1128
+ /** `Model::leftJoin`. */
1129
1129
  static leftJoin(table, first, op, second) {
1130
1130
  this.bootIfNotBooted();
1131
1131
  return this.newQuery().leftJoin(table, first, op, second);
1132
1132
  }
1133
- /** Laravel `Model::paginate`. */
1133
+ /** `Model::paginate`. */
1134
1134
  static async paginate(perPage = 15, page, options = {}) {
1135
1135
  return this.newQuery().paginate(perPage, page, options);
1136
1136
  }
1137
- /** Laravel `Model::cursorPaginate`. */
1137
+ /** `Model::cursorPaginate`. */
1138
1138
  static async cursorPaginate(perPage = 15, cursor = null, options = {}) {
1139
1139
  return this.newQuery().cursorPaginate(perPage, cursor, options);
1140
1140
  }
1141
- /** Laravel `Model::create` (respects `$fillable` / `$guarded`). */
1141
+ /** `Model::create` (respects `$fillable` / `$guarded`). */
1142
1142
  static create(attributes) {
1143
1143
  this.bootIfNotBooted();
1144
1144
  return this.forceCreate(filterFillable(this, attributes));
1145
1145
  }
1146
- /** Laravel `Model::forceCreate` — insert every given attribute, ignoring `$fillable`. */
1146
+ /** `Model::forceCreate` — insert every given attribute, ignoring `$fillable`. */
1147
1147
  static forceCreate(useAttrs) {
1148
1148
  this.bootIfNotBooted();
1149
1149
  // Assign raw attributes (skip get-casts) so mutators like Attribute.set can run on save.
@@ -1176,7 +1176,7 @@ export class Model {
1176
1176
  }
1177
1177
  return after(saved);
1178
1178
  }
1179
- /** Laravel `firstOrNew`. */
1179
+ /** `firstOrNew`. */
1180
1180
  static async firstOrNew(attributes, values = {}) {
1181
1181
  let q = this.newQuery();
1182
1182
  for (const [column, value] of Object.entries(attributes)) {
@@ -1187,7 +1187,7 @@ export class Model {
1187
1187
  return existing;
1188
1188
  return new this({ ...attributes, ...values });
1189
1189
  }
1190
- /** Laravel `firstOrCreate`. */
1190
+ /** `firstOrCreate`. */
1191
1191
  static async firstOrCreate(attributes, values = {}) {
1192
1192
  let q = this.newQuery();
1193
1193
  for (const [column, value] of Object.entries(attributes)) {
@@ -1198,7 +1198,7 @@ export class Model {
1198
1198
  return existing;
1199
1199
  return this.create({ ...attributes, ...values });
1200
1200
  }
1201
- /** Laravel `updateOrCreate`. */
1201
+ /** `updateOrCreate`. */
1202
1202
  static async updateOrCreate(attributes, values = {}) {
1203
1203
  let q = this.newQuery();
1204
1204
  for (const [column, value] of Object.entries(attributes)) {
@@ -1220,21 +1220,21 @@ export class Model {
1220
1220
  return this.newQuery().insert(values);
1221
1221
  }
1222
1222
  /**
1223
- * Laravel `Model::upsert` — bulk insert-or-update on unique conflict.
1223
+ * `Model::upsert` — bulk insert-or-update on unique conflict.
1224
1224
  * Delegates to `ModelQuery.upsert` (timestamps stamped when enabled).
1225
1225
  */
1226
1226
  static async upsert(values, uniqueBy, update = null) {
1227
1227
  this.bootIfNotBooted();
1228
1228
  return this.newQuery().upsert(values, uniqueBy, update);
1229
1229
  }
1230
- /** Laravel `$model->fill($attributes)`. */
1230
+ /** `$model->fill($attributes)`. */
1231
1231
  fill(attributes) {
1232
1232
  const ctor = this.constructor;
1233
1233
  const finalAttrs = filterFillable(ctor, attributes);
1234
1234
  assignOwn(this, ctor.castAttributes(finalAttrs, "get"));
1235
1235
  return this;
1236
1236
  }
1237
- /** Laravel `$model->update($attributes)`. */
1237
+ /** `$model->update($attributes)`. */
1238
1238
  async update(attributes) {
1239
1239
  this.fill(attributes);
1240
1240
  await this.save();
@@ -1441,16 +1441,16 @@ export class Model {
1441
1441
  }
1442
1442
  this.syncOriginal();
1443
1443
  await fireModelEvent(this, "saved");
1444
- // Laravel finishSave → touchOwners (Relation.touch honors withoutTouching on related).
1444
+ // finishSave → touchOwners (Relation.touch honors withoutTouching on related).
1445
1445
  await this.touchOwners();
1446
1446
  return this;
1447
1447
  }
1448
- /** Laravel `$model->saveQuietly()`. */
1448
+ /** `$model->saveQuietly()`. */
1449
1449
  async saveQuietly() {
1450
1450
  const ctor = this.constructor;
1451
1451
  return ctor.withoutEvents(() => this.save());
1452
1452
  }
1453
- /** Laravel `$model->refresh()`. */
1453
+ /** `$model->refresh()`. */
1454
1454
  async refresh() {
1455
1455
  const ctor = this.constructor;
1456
1456
  const key = ctor.primaryKey;
@@ -1464,7 +1464,7 @@ export class Model {
1464
1464
  return this;
1465
1465
  }
1466
1466
  /**
1467
- * Laravel-style refresh under row lock (`lockForUpdate`).
1467
+ * Refresh under row lock (`lockForUpdate`).
1468
1468
  * Reloads this instance from a locked select of the same primary key.
1469
1469
  */
1470
1470
  async refreshForUpdate() {
@@ -1482,7 +1482,7 @@ export class Model {
1482
1482
  }
1483
1483
  return this;
1484
1484
  }
1485
- /** Laravel `$model->fresh()`. */
1485
+ /** `$model->fresh()`. */
1486
1486
  async fresh() {
1487
1487
  const ctor = this.constructor;
1488
1488
  const key = ctor.primaryKey;
@@ -1502,7 +1502,7 @@ export class Model {
1502
1502
  await eagerLoadModels([this], missing);
1503
1503
  return this;
1504
1504
  }
1505
- /** Laravel `$model->relationLoaded($key)`. */
1505
+ /** `$model->relationLoaded($key)`. */
1506
1506
  relationLoaded(key) {
1507
1507
  return Object.prototype.hasOwnProperty.call(this, key);
1508
1508
  }
@@ -1526,14 +1526,14 @@ export class Model {
1526
1526
  }
1527
1527
  }
1528
1528
  /**
1529
- * Laravel `$model->touches($relation)` — whether `$touches` lists this relation.
1529
+ * `$model->touches($relation)` — whether `$touches` lists this relation.
1530
1530
  */
1531
1531
  touches(relation) {
1532
1532
  const ctor = this.constructor;
1533
1533
  return (ctor.touches ?? []).includes(relation);
1534
1534
  }
1535
1535
  /**
1536
- * Laravel `$model->touchOwners()` — touch each relation in `$touches`.
1536
+ * `$model->touchOwners()` — touch each relation in `$touches`.
1537
1537
  * Uses `relation.touch()` when available (BelongsTo / HasOne / HasMany);
1538
1538
  * otherwise loads the related model and calls `touch()` on it.
1539
1539
  */
@@ -1556,7 +1556,7 @@ export class Model {
1556
1556
  }
1557
1557
  }
1558
1558
  /**
1559
- * Laravel `$model->touch()` — bump `updated_at` (no-op while `withoutTouching`).
1559
+ * `$model->touch()` — bump `updated_at` (no-op while `withoutTouching`).
1560
1560
  * Saving also runs `$touches` / `touchOwners()` for listed relations.
1561
1561
  */
1562
1562
  async touch() {
@@ -1574,7 +1574,7 @@ export class Model {
1574
1574
  return true;
1575
1575
  }
1576
1576
  /**
1577
- * Relation query builder (`$model->product()` in Laravel).
1577
+ * Relation query builder (`$model->product()`).
1578
1578
  *
1579
1579
  * Define relations on `static relations` and declare the loaded property:
1580
1580
  * `declare product: Product | null` — then use `model.product` after `with('product')`,
@@ -1605,7 +1605,7 @@ export class Model {
1605
1605
  }
1606
1606
  throw new Error(`Call to undefined relationship [${name}] on model [${ctor.name ?? "Model"}].`);
1607
1607
  }
1608
- /** Laravel `$model->replicate()`. */
1608
+ /** `$model->replicate()`. */
1609
1609
  replicate(except = []) {
1610
1610
  const ctor = this.constructor;
1611
1611
  ctor.bootIfNotBooted();
@@ -1618,7 +1618,7 @@ export class Model {
1618
1618
  attrs[k] = v;
1619
1619
  }
1620
1620
  const copy = new ctor(attrs);
1621
- // Fire sync-style; listeners may be async but replicate is sync in Laravel.
1621
+ // Fire sync-style; listeners may be async but replicate is sync.
1622
1622
  void fireModelEvent(copy, "replicating");
1623
1623
  return copy;
1624
1624
  }
@@ -1633,7 +1633,7 @@ export class Model {
1633
1633
  await fireModelEvent(this, "trashed");
1634
1634
  return;
1635
1635
  }
1636
- // Laravel delete(): touchOwners before performDeleteOnModel.
1636
+ // delete(): touchOwners before performDeleteOnModel.
1637
1637
  await this.touchOwners();
1638
1638
  await this.#performForceDelete();
1639
1639
  await fireModelEvent(this, "deleted");
@@ -1664,7 +1664,7 @@ export class Model {
1664
1664
  await fireModelEvent(this, "forceDeleted");
1665
1665
  await fireModelEvent(this, "deleted");
1666
1666
  }
1667
- /** Laravel `$model->deleteQuietly()`. */
1667
+ /** `$model->deleteQuietly()`. */
1668
1668
  async deleteQuietly() {
1669
1669
  const ctor = this.constructor;
1670
1670
  await ctor.withoutEvents(() => this.delete());
@@ -1705,7 +1705,7 @@ export class Model {
1705
1705
  const value = this[col];
1706
1706
  return value != null && value !== "";
1707
1707
  }
1708
- /** Laravel `$model->toArray()`. */
1708
+ /** `$model->toArray()`. */
1709
1709
  toArray() {
1710
1710
  const ctor = this.constructor;
1711
1711
  const hiddenList = this.getHidden();
@@ -1746,7 +1746,7 @@ export class Model {
1746
1746
  }
1747
1747
  return this[key];
1748
1748
  }
1749
- /** Laravel `$model->loadCount(...$relations)`. */
1749
+ /** `$model->loadCount(...$relations)`. */
1750
1750
  async loadCount(...relations) {
1751
1751
  const names = relations.flat();
1752
1752
  if (names.length === 0)
@@ -1758,7 +1758,7 @@ export class Model {
1758
1758
  }
1759
1759
  return this;
1760
1760
  }
1761
- /** Laravel `$model->loadSum($relation, $column)`. */
1761
+ /** `$model->loadSum($relation, $column)`. */
1762
1762
  async loadSum(relation, column) {
1763
1763
  const parsed = parseRelationAlias(relation);
1764
1764
  const value = await aggregateRelation(this, parsed.relation, "sum", column);
@@ -1783,7 +1783,7 @@ export class Model {
1783
1783
  this[parsed.alias ?? `${parsed.relation}_max_${column}`] = value;
1784
1784
  return this;
1785
1785
  }
1786
- /** Laravel `$model->loadExists(...$relations)`. */
1786
+ /** `$model->loadExists(...$relations)`. */
1787
1787
  async loadExists(...relations) {
1788
1788
  for (const relation of relations.flat()) {
1789
1789
  const parsed = parseRelationAlias(relation);
@@ -1799,7 +1799,7 @@ export class Model {
1799
1799
  toJson() {
1800
1800
  return this.toJSON();
1801
1801
  }
1802
- /** Laravel `$model->increment($column, $amount)`. */
1802
+ /** `$model->increment($column, $amount)`. */
1803
1803
  async increment(column, amount = 1) {
1804
1804
  const row = this;
1805
1805
  const current = Number(row[column] ?? 0);
@@ -1807,11 +1807,11 @@ export class Model {
1807
1807
  await this.save();
1808
1808
  return this;
1809
1809
  }
1810
- /** Laravel `$model->decrement($column, $amount)`. */
1810
+ /** `$model->decrement($column, $amount)`. */
1811
1811
  async decrement(column, amount = 1) {
1812
1812
  return this.increment(column, -amount);
1813
1813
  }
1814
- /** Laravel `Model::destroy($ids)`. */
1814
+ /** `Model::destroy($ids)`. */
1815
1815
  static async destroy(ids) {
1816
1816
  const list = Array.isArray(ids) ? ids : [ids];
1817
1817
  let n = 0;
@@ -1825,7 +1825,7 @@ export class Model {
1825
1825
  return n;
1826
1826
  }
1827
1827
  /**
1828
- * Laravel `Model::forceDestroy($ids)` — permanent delete by key(s).
1828
+ * `Model::forceDestroy($ids)` — permanent delete by key(s).
1829
1829
  * Soft-delete models are found via `withTrashed()` so trashed rows are included.
1830
1830
  */
1831
1831
  static async forceDestroy(ids) {
@@ -1842,18 +1842,18 @@ export class Model {
1842
1842
  }
1843
1843
  return n;
1844
1844
  }
1845
- /** Laravel `$this->hasMany(Related::class)`. */
1845
+ /** `$this->hasMany(Related::class)`. */
1846
1846
  hasMany(related, foreignKey, localKey) {
1847
1847
  const key = foreignKey ?? `${singular(this.constructor.table)}_id`;
1848
1848
  return new HasMany(this, related, key, localKey);
1849
1849
  }
1850
- /** Laravel `$this->hasOne(Related::class)`. */
1850
+ /** `$this->hasOne(Related::class)`. */
1851
1851
  hasOne(related, foreignKey, localKey) {
1852
1852
  const key = foreignKey ?? `${singular(this.constructor.table)}_id`;
1853
1853
  return new HasOne(this, related, key, localKey);
1854
1854
  }
1855
1855
  /**
1856
- * Laravel `$this->hasManyThrough(Related::class, Through::class)`.
1856
+ * `$this->hasManyThrough(Related::class, Through::class)`.
1857
1857
  * Parent → Through (firstKey) → Related (secondKey).
1858
1858
  */
1859
1859
  hasManyThrough(related, through, firstKey, secondKey, localKey, secondLocalKey) {
@@ -1861,18 +1861,18 @@ export class Model {
1861
1861
  return new HasManyThrough(this, related, through, firstKey ?? `${singular(parentCtor.table)}_id`, secondKey ?? `${singular(through.table)}_id`, localKey ?? parentCtor.primaryKey, secondLocalKey ?? through.primaryKey);
1862
1862
  }
1863
1863
  /**
1864
- * Laravel `$this->hasOneThrough(Related::class, Through::class)`.
1864
+ * `$this->hasOneThrough(Related::class, Through::class)`.
1865
1865
  */
1866
1866
  hasOneThrough(related, through, firstKey, secondKey, localKey, secondLocalKey) {
1867
1867
  const parentCtor = this.constructor;
1868
1868
  return new HasOneThrough(this, related, through, firstKey ?? `${singular(parentCtor.table)}_id`, secondKey ?? `${singular(through.table)}_id`, localKey ?? parentCtor.primaryKey, secondLocalKey ?? through.primaryKey);
1869
1869
  }
1870
- /** Laravel `$this->belongsTo(Related::class)`. */
1870
+ /** `$this->belongsTo(Related::class)`. */
1871
1871
  belongsTo(related, foreignKey, ownerKey) {
1872
1872
  const key = foreignKey ?? `${singular(related.table)}_id`;
1873
1873
  return new BelongsTo(this, related, key, ownerKey);
1874
1874
  }
1875
- /** Laravel `$this->belongsToMany(Related::class, pivot)`. */
1875
+ /** `$this->belongsToMany(Related::class, pivot)`. */
1876
1876
  belongsToMany(related, table, foreignPivotKey, relatedPivotKey) {
1877
1877
  const parent = this.constructor;
1878
1878
  const pivot = table ??
@@ -1903,15 +1903,15 @@ export class Model {
1903
1903
  : [name, primaryMorph].filter((value, index, all) => all.indexOf(value) === index);
1904
1904
  return new MorphToMany(this, related, table, foreign, relatedKey, morphTypeColumn, morphTypes, options.pivotTenantKey, options.parentTenantKey ?? options.pivotTenantKey);
1905
1905
  }
1906
- /** Laravel `$this->morphMany(Related::class, name)`. */
1906
+ /** `$this->morphMany(Related::class, name)`. */
1907
1907
  morphMany(related, name, type, id, localKey) {
1908
1908
  return new MorphMany(this, related, type ?? `${name}_type`, id ?? `${name}_id`, morphTypeFor(this.constructor), localKey);
1909
1909
  }
1910
- /** Laravel `$this->morphOne(Related::class, name)`. */
1910
+ /** `$this->morphOne(Related::class, name)`. */
1911
1911
  morphOne(related, name, type, id, localKey) {
1912
1912
  return new MorphOne(this, related, type ?? `${name}_type`, id ?? `${name}_id`, morphTypeFor(this.constructor), localKey);
1913
1913
  }
1914
- /** Laravel `$this->morphTo($name)`. */
1914
+ /** `$this->morphTo($name)`. */
1915
1915
  morphTo(name, type, id, ownerKey) {
1916
1916
  return new MorphTo(this, type ?? `${name}_type`, id ?? `${name}_id`, ownerKey);
1917
1917
  }