tspace-mysql 1.9.1 → 1.9.2

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.
Files changed (84) hide show
  1. package/README.md +246 -23
  2. package/dist/lib/core/Abstracts/AbstractBuilder.d.ts +16 -16
  3. package/dist/lib/core/Abstracts/AbstractBuilder.js.map +1 -1
  4. package/dist/lib/core/Abstracts/AbstractDB.d.ts +1 -1
  5. package/dist/lib/core/Abstracts/AbstractModel.d.ts +7 -2
  6. package/dist/lib/core/Abstracts/AbstractModel.js.map +1 -1
  7. package/dist/lib/core/Blueprint.d.ts +14 -14
  8. package/dist/lib/core/Blueprint.js +2 -4
  9. package/dist/lib/core/Blueprint.js.map +1 -1
  10. package/dist/lib/core/Builder.d.ts +52 -34
  11. package/dist/lib/core/Builder.js +76 -44
  12. package/dist/lib/core/Builder.js.map +1 -1
  13. package/dist/lib/core/Cache/index.js +32 -13
  14. package/dist/lib/core/Cache/index.js.map +1 -1
  15. package/dist/lib/core/Contracts/Audit.d.ts +4 -4
  16. package/dist/lib/core/Contracts/Audit.js.map +1 -1
  17. package/dist/lib/core/Contracts/Logger.d.ts +3 -3
  18. package/dist/lib/core/Contracts/Logger.js.map +1 -1
  19. package/dist/lib/core/DB.d.ts +2 -2
  20. package/dist/lib/core/DB.js +6 -19
  21. package/dist/lib/core/DB.js.map +1 -1
  22. package/dist/lib/core/Driver/index.d.ts +7 -5
  23. package/dist/lib/core/Driver/index.js +4 -2
  24. package/dist/lib/core/Driver/index.js.map +1 -1
  25. package/dist/lib/core/Driver/mariadb/MariadbDriver.js +14 -6
  26. package/dist/lib/core/Driver/mariadb/MariadbDriver.js.map +1 -1
  27. package/dist/lib/core/Driver/mariadb/MariadbQueryBuilder.d.ts +3 -3
  28. package/dist/lib/core/Driver/mariadb/MariadbQueryBuilder.js +24 -7
  29. package/dist/lib/core/Driver/mariadb/MariadbQueryBuilder.js.map +1 -1
  30. package/dist/lib/core/Driver/mongodb/MongodbDriver.js +18 -12
  31. package/dist/lib/core/Driver/mongodb/MongodbDriver.js.map +1 -1
  32. package/dist/lib/core/Driver/mongodb/MongodbQueryBuilder.d.ts +3 -3
  33. package/dist/lib/core/Driver/mongodb/MongodbQueryBuilder.js +9 -1
  34. package/dist/lib/core/Driver/mongodb/MongodbQueryBuilder.js.map +1 -1
  35. package/dist/lib/core/Driver/mysql/MysqlDriver.js +15 -7
  36. package/dist/lib/core/Driver/mysql/MysqlDriver.js.map +1 -1
  37. package/dist/lib/core/Driver/mysql/MysqlQueryBuilder.d.ts +3 -3
  38. package/dist/lib/core/Driver/mysql/MysqlQueryBuilder.js +24 -7
  39. package/dist/lib/core/Driver/mysql/MysqlQueryBuilder.js.map +1 -1
  40. package/dist/lib/core/Driver/postgres/PostgresDriver.js +14 -6
  41. package/dist/lib/core/Driver/postgres/PostgresDriver.js.map +1 -1
  42. package/dist/lib/core/Driver/postgres/PostgresQueryBuilder.d.ts +3 -3
  43. package/dist/lib/core/Driver/postgres/PostgresQueryBuilder.js +22 -7
  44. package/dist/lib/core/Driver/postgres/PostgresQueryBuilder.js.map +1 -1
  45. package/dist/lib/core/Driver/sqlite/SqliteDriver.d.ts +1 -0
  46. package/dist/lib/core/Driver/sqlite/SqliteDriver.js +25 -4
  47. package/dist/lib/core/Driver/sqlite/SqliteDriver.js.map +1 -1
  48. package/dist/lib/core/Driver/sqlite/SqliteQueryBuilder.d.ts +2 -0
  49. package/dist/lib/core/Driver/sqlite/SqliteQueryBuilder.js +27 -21
  50. package/dist/lib/core/Driver/sqlite/SqliteQueryBuilder.js.map +1 -1
  51. package/dist/lib/core/Join.d.ts +63 -5
  52. package/dist/lib/core/Join.js +92 -15
  53. package/dist/lib/core/Join.js.map +1 -1
  54. package/dist/lib/core/JoinModel.d.ts +65 -9
  55. package/dist/lib/core/JoinModel.js +79 -50
  56. package/dist/lib/core/JoinModel.js.map +1 -1
  57. package/dist/lib/core/Meta.d.ts +7 -7
  58. package/dist/lib/core/Meta.js +10 -9
  59. package/dist/lib/core/Meta.js.map +1 -1
  60. package/dist/lib/core/Model.d.ts +225 -57
  61. package/dist/lib/core/Model.js +375 -89
  62. package/dist/lib/core/Model.js.map +1 -1
  63. package/dist/lib/core/Queue.d.ts +16 -7
  64. package/dist/lib/core/Queue.js +69 -29
  65. package/dist/lib/core/Queue.js.map +1 -1
  66. package/dist/lib/core/RelationManager.d.ts +4 -4
  67. package/dist/lib/core/RelationManager.js +141 -16
  68. package/dist/lib/core/RelationManager.js.map +1 -1
  69. package/dist/lib/core/Repository.d.ts +1 -1
  70. package/dist/lib/core/Repository.js +5 -1
  71. package/dist/lib/core/Repository.js.map +1 -1
  72. package/dist/lib/core/Schema.d.ts +13 -13
  73. package/dist/lib/core/Schema.js +12 -0
  74. package/dist/lib/core/Schema.js.map +1 -1
  75. package/dist/lib/core/StateManager.d.ts +6 -0
  76. package/dist/lib/core/StateManager.js +1 -0
  77. package/dist/lib/core/StateManager.js.map +1 -1
  78. package/dist/lib/core/UtilityTypes.d.ts +69 -74
  79. package/dist/lib/core/UtilityTypes.js.map +1 -1
  80. package/dist/lib/types/index.d.ts +52 -9
  81. package/dist/lib/utils/index.d.ts +2 -1
  82. package/dist/lib/utils/index.js +26 -3
  83. package/dist/lib/utils/index.js.map +1 -1
  84. package/package.json +1 -1
@@ -48,7 +48,8 @@ const Cache_1 = require("./Cache");
48
48
  const JoinModel_1 = require("./JoinModel");
49
49
  const constants_1 = require("../constants");
50
50
  const Decorator_1 = require("./Decorator");
51
- const Repository_1 = __importDefault(require("./Repository"));
51
+ const Join_1 = require("./Join");
52
+ const Repository_1 = require("./Repository");
52
53
  let globalSettings = {
53
54
  softDelete: false,
54
55
  debug: false,
@@ -213,7 +214,7 @@ class Model extends AbstractModel_1.AbstractModel {
213
214
  *
214
215
  */
215
216
  static async find(primaryKey, options = {}) {
216
- return await (0, Repository_1.default)(this).find(primaryKey, options);
217
+ return await (0, Repository_1.Repository)(this).find(primaryKey, options);
217
218
  }
218
219
  /**
219
220
  *
@@ -253,7 +254,7 @@ class Model extends AbstractModel_1.AbstractModel {
253
254
  *
254
255
  */
255
256
  static async findOne(options = {}) {
256
- return await (0, Repository_1.default)(this).findOne(options);
257
+ return await (0, Repository_1.Repository)(this).findOne(options);
257
258
  }
258
259
  /**
259
260
  *
@@ -293,7 +294,7 @@ class Model extends AbstractModel_1.AbstractModel {
293
294
  *
294
295
  */
295
296
  static async findMany(options = {}) {
296
- return await (0, Repository_1.default)(this).findMany(options);
297
+ return await (0, Repository_1.Repository)(this).findMany(options);
297
298
  }
298
299
  /**
299
300
  *
@@ -336,7 +337,7 @@ class Model extends AbstractModel_1.AbstractModel {
336
337
  * })
337
338
  */
338
339
  static async paginate(options = {}) {
339
- return await (0, Repository_1.default)(this).paginate(options);
340
+ return await (0, Repository_1.Repository)(this).paginate(options);
340
341
  }
341
342
  /**
342
343
  * The 'exists' method is used to determine if any records exist in the database table that match the query conditions.
@@ -371,7 +372,7 @@ class Model extends AbstractModel_1.AbstractModel {
371
372
  *
372
373
  */
373
374
  static async exists(options) {
374
- return await (0, Repository_1.default)(this).exists(options);
375
+ return await (0, Repository_1.Repository)(this).exists(options);
375
376
  }
376
377
  /**
377
378
  * The 'toQuery' method is used to retrieve the raw SQL query that would be executed by a query builder instance without actually executing it.
@@ -406,7 +407,7 @@ class Model extends AbstractModel_1.AbstractModel {
406
407
  *
407
408
  */
408
409
  static toQuery(options) {
409
- return (0, Repository_1.default)(this).toString(options);
410
+ return (0, Repository_1.Repository)(this).toString(options);
410
411
  }
411
412
  /**
412
413
  * The 'create' method is used to insert a new record into a database table associated.
@@ -419,7 +420,7 @@ class Model extends AbstractModel_1.AbstractModel {
419
420
  * @return {promise<T.Result<M>>}
420
421
  */
421
422
  static async create(options) {
422
- return (0, Repository_1.default)(this).create(options);
423
+ return (0, Repository_1.Repository)(this).create(options);
423
424
  }
424
425
  /**
425
426
  * The 'createMany' method is used to insert a new records into a database table associated.
@@ -432,7 +433,7 @@ class Model extends AbstractModel_1.AbstractModel {
432
433
  * @return {promise<TS[]>}
433
434
  */
434
435
  static async createMany(options) {
435
- return (0, Repository_1.default)(this).createMany(options);
436
+ return (0, Repository_1.Repository)(this).createMany(options);
436
437
  }
437
438
  /**
438
439
  *
@@ -447,7 +448,8 @@ class Model extends AbstractModel_1.AbstractModel {
447
448
  * @return {promise<NR extends true ? undefined : T.Result<M>[]>}
448
449
  */
449
450
  static async createOrUpdate(options) {
450
- return (0, Repository_1.default)(this).createOrUpdate(options);
451
+ //@ts-ignore
452
+ return (0, Repository_1.Repository)(this).createOrUpdate(options);
451
453
  }
452
454
  /**
453
455
  * The 'createNotExists' method to insert data into a database table while ignoring any duplicate key constraint violations.
@@ -463,7 +465,7 @@ class Model extends AbstractModel_1.AbstractModel {
463
465
  * @return {promise<T | null>}
464
466
  */
465
467
  static async createNotExists(options) {
466
- return (0, Repository_1.default)(this).createNotExists(options);
468
+ return (0, Repository_1.Repository)(this).createNotExists(options);
467
469
  }
468
470
  /**
469
471
  *
@@ -478,7 +480,7 @@ class Model extends AbstractModel_1.AbstractModel {
478
480
  * @return {promise<T.Result<M>>}
479
481
  */
480
482
  static async createOrSelect(options) {
481
- return (0, Repository_1.default)(this).createOrSelect(options);
483
+ return (0, Repository_1.Repository)(this).createOrSelect(options);
482
484
  }
483
485
  /**
484
486
  * The 'update' method is used to update existing records in a database table that are associated.
@@ -494,7 +496,7 @@ class Model extends AbstractModel_1.AbstractModel {
494
496
  * @return {promise< NR extends true ? undefined : T.Result<M> | null>}
495
497
  */
496
498
  static async update(options) {
497
- return (0, Repository_1.default)(this).update(options);
499
+ return (0, Repository_1.Repository)(this).update(options);
498
500
  }
499
501
  /**
500
502
  * The 'updateMany' method is used to update existing records in a database table that are associated.
@@ -510,7 +512,7 @@ class Model extends AbstractModel_1.AbstractModel {
510
512
  * @return {promise<T.Result<M>[]>}
511
513
  */
512
514
  static async updateMany(options) {
513
- return (0, Repository_1.default)(this).updateMany(options);
515
+ return (0, Repository_1.Repository)(this).updateMany(options);
514
516
  }
515
517
  /**
516
518
  * The 'cache' method is used get the functions from the Cache
@@ -549,6 +551,91 @@ class Model extends AbstractModel_1.AbstractModel {
549
551
  },
550
552
  };
551
553
  }
554
+ /**
555
+ * The 'lockTable' method is used table lock and execute the callback within the lock scope.
556
+ *
557
+ * The lock is automatically released after the callback completes,
558
+ * regardless of whether it resolves or throws an error.
559
+ *
560
+ * READ:
561
+ * - Other sessions can read.
562
+ * - Other sessions must wait before writing.
563
+ * - SELECT: allowed
564
+ * - INSERT: waits
565
+ * - UPDATE: waits
566
+ * - DELETE: waits
567
+ *
568
+ * WRITE:
569
+ * - Other sessions must wait before reading or writing.
570
+ * - SELECT: waits
571
+ * - INSERT: waits
572
+ * - UPDATE: waits
573
+ * - DELETE: waits
574
+ *
575
+ * The lock is released automatically after the callback completes.
576
+ *
577
+ * @Note
578
+ * This approach is not recommended in clustered or load-balance environments,
579
+ * because locks are session-bound and requests may be routed to different database connections.
580
+ *
581
+ * @template T
582
+ * @param {'READ'|'WRITE'} mode Lock mode.
583
+ * @param {(query: this) => Promise<T>} handler Function executed while the table is locked.
584
+ * @returns {Promise<T>} The value returned by the callback.
585
+ *
586
+ * @example
587
+ * await User.lockTable('READ', async (query) => {
588
+ * query.get();
589
+ * return
590
+ * });
591
+ *
592
+ * @example
593
+ * await User.lockTable('WRITE', async (query) => {
594
+ * // Avoid creating a new query instance inside the lock.
595
+ * // The new instance uses a different connection/session and
596
+ * // may wait for the current table lock to be released.
597
+ *
598
+ * new User().insert({
599
+ * first_name: 'John',
600
+ * last_name: 'Doe'
601
+ * }).save();
602
+ *
603
+ * // Use the locked query instance instead.
604
+ * await query.insert({
605
+ * first_name: 'John',
606
+ * last_name: 'Doe'
607
+ * }).save();
608
+ * });
609
+ */
610
+ static async lockTable(mode, handler) {
611
+ const trx = await DB_1.DB.beginTransaction();
612
+ try {
613
+ await trx.startTransaction();
614
+ const model = new this()
615
+ .bind(trx);
616
+ const sqlLockTable = model
617
+ ._queryBuilder()
618
+ .lockTable(mode);
619
+ await model.rawQuery(sqlLockTable);
620
+ const results = await handler(model);
621
+ const sqlUnlockTable = model
622
+ ._queryBuilder()
623
+ .unlockTable();
624
+ if (sqlUnlockTable != null) {
625
+ await model
626
+ .rawQuery(sqlUnlockTable);
627
+ }
628
+ await trx.commit();
629
+ return results;
630
+ }
631
+ catch (err) {
632
+ await trx.rollback();
633
+ throw err;
634
+ }
635
+ finally {
636
+ await trx.end();
637
+ }
638
+ }
552
639
  /**
553
640
  * The 'boot' method is a special method that you can define within a model.
554
641
  * @example
@@ -1300,7 +1387,7 @@ class Model extends AbstractModel_1.AbstractModel {
1300
1387
  this.$state.set("AUDIT", userId);
1301
1388
  return this;
1302
1389
  }
1303
- meta(meta) {
1390
+ metaTag(meta) {
1304
1391
  this.$state.set("META", meta);
1305
1392
  return this;
1306
1393
  }
@@ -1376,6 +1463,12 @@ class Model extends AbstractModel_1.AbstractModel {
1376
1463
  this.$state.set("SELECT", select);
1377
1464
  return this;
1378
1465
  }
1466
+ /**
1467
+ *
1468
+ * @override
1469
+ * @param {string[]} ...columns
1470
+ * @returns {this} this
1471
+ */
1379
1472
  addSelect(...columns) {
1380
1473
  let select = columns.map((c) => {
1381
1474
  const column = String(c);
@@ -1551,11 +1644,11 @@ class Model extends AbstractModel_1.AbstractModel {
1551
1644
  * @param {string} column
1552
1645
  * @returns {string} return table.column
1553
1646
  */
1554
- bindColumn(column, pattern = true) {
1647
+ bindColumn(column, opts = { pattern: true }) {
1555
1648
  if (!/\./.test(column)) {
1556
1649
  if (column === "*")
1557
1650
  return "*";
1558
- const c = pattern ? this._valuePattern(column) : column;
1651
+ const c = opts.pattern ? this._valuePattern(column) : column;
1559
1652
  const alias = this.$state.get("ALIAS");
1560
1653
  return [
1561
1654
  alias == null || alias === ""
@@ -1566,7 +1659,7 @@ class Model extends AbstractModel_1.AbstractModel {
1566
1659
  ].join("");
1567
1660
  }
1568
1661
  let [table, c] = column.split(".");
1569
- c = pattern ? this._valuePattern(c) : c;
1662
+ c = opts.pattern ? this._valuePattern(c) : c;
1570
1663
  if (c === "*") {
1571
1664
  return `\`${table.replace(/`/g, "")}\`.*`;
1572
1665
  }
@@ -1766,7 +1859,6 @@ class Model extends AbstractModel_1.AbstractModel {
1766
1859
  */
1767
1860
  async _queryStatement(sql, { retry = false } = {}) {
1768
1861
  try {
1769
- sql = this._queryBuilder().format([sql]);
1770
1862
  const getResults = async (sql) => {
1771
1863
  if (this.$state.get("DEBUG")) {
1772
1864
  const startTime = +new Date();
@@ -1812,7 +1904,6 @@ class Model extends AbstractModel_1.AbstractModel {
1812
1904
  */
1813
1905
  async _actionStatement(sql, { retry = false } = {}) {
1814
1906
  try {
1815
- sql = this._queryBuilder().format([sql]);
1816
1907
  const getResults = async (sql) => {
1817
1908
  if (this.$state.get("DEBUG")) {
1818
1909
  const startTime = +new Date();
@@ -2292,6 +2383,55 @@ class Model extends AbstractModel_1.AbstractModel {
2292
2383
  this.$relation.callback(String(nameRelation), callback);
2293
2384
  return this;
2294
2385
  }
2386
+ /**
2387
+ *
2388
+ * The 'withQueryExists' method is particularly useful when you want to filter or add conditions records based on related data.
2389
+ *
2390
+ * Use relation '${name}' registry models then return callback queries
2391
+ * @param {string} nameRelation name relation in registry in your model
2392
+ * @param {function} callback query callback
2393
+ * @param {object} options pivot the query
2394
+ * @example
2395
+ * import { Model } from 'tspace-mysql'
2396
+ * class User extends Model {
2397
+ * constructor(){
2398
+ * super()
2399
+ * this.hasMany({ name : 'posts' , model : Post })
2400
+ * }
2401
+ * }
2402
+ *
2403
+ * class Post extends Model {
2404
+ * constructor(){
2405
+ * super()
2406
+ * this.hasMany({ name : 'comments' , model : Comment })
2407
+ * this.belongsTo({ name : 'user' , model : User })
2408
+ * }
2409
+ * }
2410
+ *
2411
+ * class Comment extends Model {
2412
+ * constructor(){
2413
+ * super()
2414
+ * this.hasMany({ name : 'users' , model : User })
2415
+ * this.belongsTo({ name : 'post' , model : Post })
2416
+ * }
2417
+ * }
2418
+ *
2419
+ * await new User().with('posts')
2420
+ * .withQueryExists('posts', (query : Post) => {
2421
+ * return query.with('comments','user')
2422
+ * .withQuery('comments', (query : Comment) => {
2423
+ * return query.with('user','post')
2424
+ * })
2425
+ * .withQueryExists('user', (query : User) => {
2426
+ * return query.with('posts').withQueryExists('posts',(query : Post)=> {
2427
+ * return query.with('comments','user')
2428
+ * // relation n, n, ...n
2429
+ * })
2430
+ * })
2431
+ * })
2432
+ * .findMany()
2433
+ * @returns {this} this
2434
+ */
2295
2435
  withQueryExists(nameRelation, callback, options = { pivot: false }) {
2296
2436
  this.withExists(nameRelation);
2297
2437
  if (options.pivot) {
@@ -2416,6 +2556,36 @@ class Model extends AbstractModel_1.AbstractModel {
2416
2556
  const instance = this.$relation.returnCallback(String(name));
2417
2557
  return instance == null ? null : instance;
2418
2558
  }
2559
+ /**
2560
+ * The 'ofMany' method is used to transform a many relationship,
2561
+ * into a single related model by selecting one record using an aggregate
2562
+ * function such as MAX or MIN on the specified column.
2563
+ *
2564
+ * @note
2565
+ * This method is not supported on `belongsToMany` relationships.
2566
+ *
2567
+ * @param {string} column The column used for aggregation (e.g. `"id"`, `"created_at"`).
2568
+ * @param {"MAX" | "MIN"} aggregate The aggregate function used to select the record.
2569
+ * @param {((query: Model) => void) | undefined} callback A callback used to apply additional constraints to the aggregate query.
2570
+ *
2571
+ * Only filtering methods are supported. Methods that modify the result set,
2572
+ * such as `select` `orderBy`, `groupBy`, `limit`, `offset`, `union`, and `having`, are not supported.
2573
+ * @returns this
2574
+ */
2575
+ ofMany(column, aggregate, callback) {
2576
+ const cb = callback == null
2577
+ ? null
2578
+ : callback(new Model().copyModel(this));
2579
+ if (cb instanceof Promise) {
2580
+ throw new Error("'ofMany' does not support Promises");
2581
+ }
2582
+ this.$state.set('OF_MANY', {
2583
+ column: this.bindColumn(String(column)),
2584
+ aggregate,
2585
+ query: cb
2586
+ });
2587
+ return this;
2588
+ }
2419
2589
  /**
2420
2590
  * The 'hasOne' relationship defines a one-to-one relationship between two database tables.
2421
2591
  *
@@ -2564,6 +2734,70 @@ class Model extends AbstractModel_1.AbstractModel {
2564
2734
  });
2565
2735
  return this;
2566
2736
  }
2737
+ /**
2738
+ * The 'createRelation' method is useful for Creates a relation accessor for a model.
2739
+ *
2740
+ * This method defines how a model relates to another model
2741
+ * (hasOne, hasMany, belongsTo, belongsToMany) and returns
2742
+ * a function that can be used to modify the relation query.
2743
+ *
2744
+ * Example:
2745
+ * ```ts
2746
+ * public posts = this.createRelation(Post, {
2747
+ * type: 'hasMany',
2748
+ * foreignKey: 'user_id',
2749
+ * });
2750
+ *
2751
+ * user.posts(q => q.where('id', 1));
2752
+ * ```
2753
+ *
2754
+ * @template M - Target model type
2755
+ * @template K - Optional relation name type
2756
+ *
2757
+ * @param model - The related model constructor
2758
+ * @param options - Relation configuration options
2759
+ * @param options.type - Type of relation (hasOne, hasMany, belongsTo, belongsToMany)
2760
+ * @param options.name - Optional relation name (when applicable)
2761
+ * @param options.as - Alias for relation
2762
+ * @param options.localKey - Local key for the relation
2763
+ * @param options.foreignKey - Foreign key for the relation
2764
+ * @param options.freezeTable - Override pivot/table name
2765
+ * @param options.pivot - Pivot table name (for many-to-many)
2766
+ * @param options.oldVersion - Enable legacy relation behavior
2767
+ *
2768
+ * @returns A function that accepts a query modifier and returns the relation result
2769
+ */
2770
+ createRelation(model, options) {
2771
+ return (modifier) => {
2772
+ const opts = {
2773
+ name: options.name,
2774
+ as: options.as,
2775
+ localKey: options.localKey,
2776
+ foreignKey: options.foreignKey,
2777
+ freezeTable: options.freezeTable
2778
+ };
2779
+ switch (options.type) {
2780
+ case 'hasOne': {
2781
+ return this.hasOneBuilder({ model, ...opts }, modifier);
2782
+ }
2783
+ case 'hasMany': {
2784
+ return this.hasManyBuilder({ model, ...opts }, modifier);
2785
+ }
2786
+ case 'belongsTo': {
2787
+ return this.belongsToBuilder({ model, ...opts }, modifier);
2788
+ }
2789
+ case 'belongsToMany': {
2790
+ return this.belongsToManyBuilder({
2791
+ model,
2792
+ ...opts,
2793
+ pivot: options.pivot,
2794
+ oldVersion: options.oldVersion,
2795
+ modelPivot: options.modelPivot
2796
+ }, modifier);
2797
+ }
2798
+ }
2799
+ };
2800
+ }
2567
2801
  /**
2568
2802
  * The 'hasOneBuilder' method is useful for creating 'hasOne' relationship to function
2569
2803
  *
@@ -2702,7 +2936,7 @@ class Model extends AbstractModel_1.AbstractModel {
2702
2936
  : `${deletedAt} = NULL`;
2703
2937
  this.$state.set("UPDATE", [`${query}`]);
2704
2938
  this.$state.set("SAVE", "UPDATE");
2705
- return (await this.save());
2939
+ return (await this.bind(this.$pool.get()).save());
2706
2940
  }
2707
2941
  /**
2708
2942
  *
@@ -3644,13 +3878,20 @@ class Model extends AbstractModel_1.AbstractModel {
3644
3878
  * @returns {this}
3645
3879
  */
3646
3880
  join(localKey, referenceKey) {
3647
- if (typeof localKey === "function" &&
3648
- typeof localKey === "function" &&
3649
- this._isModel(localKey) &&
3650
- this._isModel(referenceKey)) {
3651
- return this.joinModel(localKey, referenceKey);
3881
+ if (typeof localKey === 'string') {
3882
+ this._handleJoin("INNER_JOIN", localKey, referenceKey);
3883
+ return this;
3884
+ }
3885
+ if (typeof localKey === "function" && !this._isModel(localKey)) {
3886
+ const cb = localKey;
3887
+ const callback = cb(new Join_1.Join(this, "INNER_JOIN"));
3888
+ this.$state.set("JOIN", [
3889
+ ...this.$state.get("JOIN"),
3890
+ callback["toString"](),
3891
+ ]);
3892
+ return this;
3652
3893
  }
3653
- this._handleJoin("INNER_JOIN", localKey, referenceKey);
3894
+ this.joinModel(localKey, referenceKey);
3654
3895
  return this;
3655
3896
  }
3656
3897
  /**
@@ -3661,13 +3902,20 @@ class Model extends AbstractModel_1.AbstractModel {
3661
3902
  * @returns {this}
3662
3903
  */
3663
3904
  rightJoin(localKey, referenceKey) {
3664
- if (typeof localKey === "function" &&
3665
- typeof localKey === "function" &&
3666
- this._isModel(localKey) &&
3667
- this._isModel(referenceKey)) {
3668
- return this.joinModel(localKey, referenceKey);
3905
+ if (typeof localKey === 'string') {
3906
+ this._handleJoin("RIGHT_JOIN", localKey, referenceKey);
3907
+ return this;
3908
+ }
3909
+ if (typeof localKey === "function" && !this._isModel(localKey)) {
3910
+ const cb = localKey;
3911
+ const callback = cb(new Join_1.Join(this, "RIGHT_JOIN"));
3912
+ this.$state.set("JOIN", [
3913
+ ...this.$state.get("JOIN"),
3914
+ callback["toString"](),
3915
+ ]);
3916
+ return this;
3669
3917
  }
3670
- this._handleJoin("RIGHT_JOIN", localKey, referenceKey);
3918
+ this.rightJoinModel(localKey, referenceKey);
3671
3919
  return this;
3672
3920
  }
3673
3921
  /**
@@ -3678,13 +3926,20 @@ class Model extends AbstractModel_1.AbstractModel {
3678
3926
  * @returns {this}
3679
3927
  */
3680
3928
  leftJoin(localKey, referenceKey) {
3681
- if (typeof localKey === "function" &&
3682
- typeof localKey === "function" &&
3683
- this._isModel(localKey) &&
3684
- this._isModel(referenceKey)) {
3685
- return this.joinModel(localKey, referenceKey);
3929
+ if (typeof localKey === 'string') {
3930
+ this._handleJoin("LEFT_JOIN", localKey, referenceKey);
3931
+ return this;
3932
+ }
3933
+ if (typeof localKey === "function" && !this._isModel(localKey)) {
3934
+ const cb = localKey;
3935
+ const callback = cb(new Join_1.Join(this, "LEFT_JOIN"));
3936
+ this.$state.set("JOIN", [
3937
+ ...this.$state.get("JOIN"),
3938
+ callback["toString"](),
3939
+ ]);
3940
+ return this;
3686
3941
  }
3687
- this._handleJoin("LEFT_JOIN", localKey, referenceKey);
3942
+ this.leftJoinModel(localKey, referenceKey);
3688
3943
  return this;
3689
3944
  }
3690
3945
  /**
@@ -3694,13 +3949,20 @@ class Model extends AbstractModel_1.AbstractModel {
3694
3949
  * @returns {this}
3695
3950
  */
3696
3951
  crossJoin(localKey, referenceKey) {
3697
- if (typeof localKey === "function" &&
3698
- typeof localKey === "function" &&
3699
- this._isModel(localKey) &&
3700
- this._isModel(referenceKey)) {
3701
- return this.joinModel(localKey, referenceKey);
3952
+ if (typeof localKey === 'string') {
3953
+ this._handleJoin("CROSS_JOIN", localKey, referenceKey);
3954
+ return this;
3702
3955
  }
3703
- this._handleJoin("CROSS_JOIN", localKey, referenceKey);
3956
+ if (typeof localKey === "function" && !this._isModel(localKey)) {
3957
+ const cb = localKey;
3958
+ const callback = cb(new Join_1.Join(this, "CROSS_JOIN"));
3959
+ this.$state.set("JOIN", [
3960
+ ...this.$state.get("JOIN"),
3961
+ callback["toString"](),
3962
+ ]);
3963
+ return this;
3964
+ }
3965
+ this.crossJoinModel(localKey, referenceKey);
3704
3966
  return this;
3705
3967
  }
3706
3968
  /**
@@ -3746,8 +4008,10 @@ class Model extends AbstractModel_1.AbstractModel {
3746
4008
  ]);
3747
4009
  return this;
3748
4010
  }
3749
- if (m2 == null)
3750
- return this;
4011
+ if (this._isModel(m1) && m2 == null) {
4012
+ m2 = m1;
4013
+ m1 = this;
4014
+ }
3751
4015
  const { alias1, alias2, table1, table2, model1, model2, localKey, foreignKey, } = this._handleJoinModel(m1, m2);
3752
4016
  this.join(`${alias1 === "" ? table1 : `${table1}|${alias1}`}.${localKey}`, `${alias2 === "" ? table2 : `${table2}|${alias2}`}.${foreignKey}`);
3753
4017
  if (model1["$state"].get("MODEL_NAME") !== this["$state"].get("MODEL_NAME")) {
@@ -3810,8 +4074,10 @@ class Model extends AbstractModel_1.AbstractModel {
3810
4074
  ]);
3811
4075
  return this;
3812
4076
  }
3813
- if (m2 == null)
3814
- return this;
4077
+ if (this._isModel(m1) && m2 == null) {
4078
+ m2 = m1;
4079
+ m1 = this;
4080
+ }
3815
4081
  const { alias1, alias2, table1, table2, model1, model2, localKey, foreignKey, } = this._handleJoinModel(m1, m2);
3816
4082
  this.leftJoin(`${alias1 === "" ? table1 : `${table1}|${alias1}`}.${localKey}`, `${alias2 === "" ? table2 : `${table2}|${alias2}`}.${foreignKey}`);
3817
4083
  if (model1["$state"].get("MODEL_NAME") !== this["$state"].get("MODEL_NAME")) {
@@ -3856,18 +4122,19 @@ class Model extends AbstractModel_1.AbstractModel {
3856
4122
  /**
3857
4123
  *
3858
4124
  * @override
3859
- * @param {string=} column [column=id]
4125
+ * @param {string=} c [column=id]
3860
4126
  * @returns {promise<number>}
3861
4127
  */
3862
4128
  async count(c) {
3863
4129
  await this._prepareQueryPipeline();
3864
4130
  const distinct = this.$state.get("DISTINCT");
3865
4131
  let column = c == null ? this.$state.get('PRIMARY_KEY') : String(c);
3866
- column === "*"
3867
- ? "*"
3868
- : distinct
3869
- ? `${this.$constants("DISTINCT")} ${this.bindColumn(column)}`
3870
- : `${this.bindColumn(column)}`;
4132
+ column =
4133
+ column === "*"
4134
+ ? "*"
4135
+ : distinct
4136
+ ? `${this.$constants("DISTINCT")} ${this.bindColumn(column)}`
4137
+ : `${this.bindColumn(column)}`;
3871
4138
  this.selectRaw([
3872
4139
  `${this.$constants("COUNT")}(${column})`,
3873
4140
  `${this.$constants("AS")}`,
@@ -3880,7 +4147,7 @@ class Model extends AbstractModel_1.AbstractModel {
3880
4147
  /**
3881
4148
  *
3882
4149
  * @override
3883
- * @param {string=} column [column=id]
4150
+ * @param {string=} c [column=id]
3884
4151
  * @returns {promise<number>}
3885
4152
  */
3886
4153
  async avg(c) {
@@ -3899,7 +4166,7 @@ class Model extends AbstractModel_1.AbstractModel {
3899
4166
  /**
3900
4167
  *
3901
4168
  * @override
3902
- * @param {string=} column [column=id]
4169
+ * @param {string=} c [column=id]
3903
4170
  * @returns {promise<number>}
3904
4171
  */
3905
4172
  async sum(c) {
@@ -3918,7 +4185,7 @@ class Model extends AbstractModel_1.AbstractModel {
3918
4185
  /**
3919
4186
  *
3920
4187
  * @override
3921
- * @param {string=} column [column=id]
4188
+ * @param {string=} c [column=id]
3922
4189
  * @returns {promise<number>}
3923
4190
  */
3924
4191
  async max(c) {
@@ -4032,10 +4299,8 @@ class Model extends AbstractModel_1.AbstractModel {
4032
4299
  this.unset({ where: true, limit: true })
4033
4300
  .select(PK)
4034
4301
  .whereSubQuery(PK, new Model()
4035
- .from(DB_1.DB.raw(`
4036
- (${from}) AS ${TEMP}`))
4037
- .selectRaw(PK)
4038
- .toString());
4302
+ .from(DB_1.DB.raw(`(${from}) AS ${TEMP}`))
4303
+ .selectRaw(PK));
4039
4304
  this.$state.set("DELETE", true);
4040
4305
  const result = await this._actionStatement(this._queryBuilder().remove());
4041
4306
  const r = Boolean(this._resultHandler(result?.$meta?.affected || false));
@@ -4081,7 +4346,6 @@ class Model extends AbstractModel_1.AbstractModel {
4081
4346
  async toArray(column) {
4082
4347
  if (column == null)
4083
4348
  column = "id";
4084
- this.selectRaw(`${this.bindColumn(column)}`);
4085
4349
  const sql = this._queryBuilder().select();
4086
4350
  const result = await this._queryStatement(sql);
4087
4351
  const toArray = result.map((data) => data[column]);
@@ -4215,17 +4479,21 @@ class Model extends AbstractModel_1.AbstractModel {
4215
4479
  }
4216
4480
  /**
4217
4481
  * @override
4218
- * @param {object?} paginationOptions by default page = 1 , limit = 15
4219
- * @property {number} paginationOptions.limit
4220
- * @property {number} paginationOptions.page
4482
+ * @param {object?} opts by default page = 1 , limit = 15
4483
+ * @property {number?} opts.limit
4484
+ * @property {number?} opts.page
4485
+ * @property {boolean?} opts.distinct
4221
4486
  * @returns {promise<Pagination>} Pagination
4222
4487
  */
4223
- async pagination(paginationOptions) {
4488
+ async pagination(opts) {
4224
4489
  let limit = 15;
4225
4490
  let page = 1;
4226
- if (paginationOptions != null) {
4227
- limit = this.$utils.softNumber(paginationOptions?.limit || limit);
4228
- page = this.$utils.softNumber(paginationOptions?.page || page);
4491
+ if (opts?.distinct) {
4492
+ this.distinct();
4493
+ }
4494
+ if (opts != null) {
4495
+ limit = this.$utils.softNumber(opts?.limit || limit);
4496
+ page = this.$utils.softNumber(opts?.page || page);
4229
4497
  }
4230
4498
  await this._prepareQueryPipeline();
4231
4499
  const offset = (page - 1) * limit;
@@ -4244,13 +4512,14 @@ class Model extends AbstractModel_1.AbstractModel {
4244
4512
  /**
4245
4513
  *
4246
4514
  * @override
4247
- * @param {?object} paginationOptions by default page = 1 , limit = 15
4248
- * @property {number} paginationOptions.limit
4249
- * @property {number} paginationOptions.page
4515
+ * @param {?object} opts by default page = 1 , limit = 15
4516
+ * @property {number?} opts.limit
4517
+ * @property {number?} opts.page
4518
+ * @property {boolean?} opts.distinct
4250
4519
  * @returns {promise<Pagination>} Pagination
4251
4520
  */
4252
- async paginate(paginationOptions) {
4253
- return await this.pagination(paginationOptions);
4521
+ async paginate(opts) {
4522
+ return await this.pagination(opts);
4254
4523
  }
4255
4524
  /**
4256
4525
  * @override
@@ -4325,9 +4594,6 @@ class Model extends AbstractModel_1.AbstractModel {
4325
4594
  * @returns {this} this
4326
4595
  */
4327
4596
  insert(data) {
4328
- if (!Object.keys(data).length) {
4329
- throw this._assertError("This method must require at least 1 argument.");
4330
- }
4331
4597
  this.$state.set("DATA", this._formatedInputData(data));
4332
4598
  if (this.$state.get("TRANSFORMS") == null) {
4333
4599
  this._queryInsertModel();
@@ -4800,6 +5066,7 @@ class Model extends AbstractModel_1.AbstractModel {
4800
5066
  .from(table)
4801
5067
  .debug(debug)
4802
5068
  .createMultiple(data)
5069
+ .bind(this.$pool.get())
4803
5070
  .void()
4804
5071
  .save();
4805
5072
  }));
@@ -5324,7 +5591,7 @@ class Model extends AbstractModel_1.AbstractModel {
5324
5591
  columns.push(this.bindColumn(key));
5325
5592
  continue;
5326
5593
  }
5327
- columns.push(this.bindColumn(schemaColumn.column, false));
5594
+ columns.push(this.bindColumn(schemaColumn.column, { pattern: false }));
5328
5595
  }
5329
5596
  if (!columns.length)
5330
5597
  return this;
@@ -5538,7 +5805,6 @@ class Model extends AbstractModel_1.AbstractModel {
5538
5805
  .copyModel(this, { where: true, join: true })
5539
5806
  .bind(this.$pool.get())
5540
5807
  .debug(this.$state.get("DEBUG"))
5541
- .unset({ alias: true })
5542
5808
  .count(this.$state.get("PRIMARY_KEY"));
5543
5809
  let lastPage = Math.ceil(total / limit) || 0;
5544
5810
  lastPage = lastPage > 1 ? lastPage : 1;
@@ -6315,8 +6581,16 @@ class Model extends AbstractModel_1.AbstractModel {
6315
6581
  return blueprint;
6316
6582
  }
6317
6583
  _handleJoinModel(m1, m2) {
6318
- let model1 = typeof m1 === "object" ? new m1.model() : new m1();
6319
- let model2 = typeof m2 === "object" ? new m2.model() : new m2();
6584
+ let model1 = typeof m1 === "object"
6585
+ ? m1 instanceof Model
6586
+ ? m1
6587
+ : new m1.model()
6588
+ : new m1();
6589
+ let model2 = typeof m2 === "object"
6590
+ ? m2 instanceof Model
6591
+ ? m2
6592
+ : new m2.model()
6593
+ : new m2();
6320
6594
  let localKey = typeof m1 === "object"
6321
6595
  ? m1.key != null && m1.key !== ""
6322
6596
  ? String(m1.key)
@@ -6328,18 +6602,30 @@ class Model extends AbstractModel_1.AbstractModel {
6328
6602
  : ""
6329
6603
  : "";
6330
6604
  let alias1 = typeof m1 === "object"
6331
- ? m1.alias != null && m1.alias !== ""
6332
- ? m1.alias
6333
- : ""
6605
+ ? m1 instanceof Model
6606
+ ? model1.$state.get("ALIAS") ?? ""
6607
+ : m1.alias != null && m1.alias !== ""
6608
+ ? m1.alias
6609
+ : ""
6334
6610
  : "";
6335
6611
  let alias2 = typeof m2 === "object"
6336
- ? m2.alias != null && m2.alias !== ""
6337
- ? m2.alias
6338
- : ""
6612
+ ? m2 instanceof Model
6613
+ ? model2.$state.get("ALIAS") ?? ""
6614
+ : m2.alias != null && m2.alias !== ""
6615
+ ? m2.alias
6616
+ : ""
6339
6617
  : "";
6340
6618
  if (alias1 !== "") {
6341
6619
  if (model1["$state"].get("MODEL_NAME") === this["$state"].get("MODEL_NAME")) {
6342
6620
  this.alias(alias1);
6621
+ const selecteds = this.$state.get("SELECT");
6622
+ const formated = [];
6623
+ for (const selected of selecteds) {
6624
+ const table = this.getTableName();
6625
+ formated.push(selected.replace(table, alias1));
6626
+ }
6627
+ if (formated.length)
6628
+ this.$state.set("SELECT", formated);
6343
6629
  }
6344
6630
  model1.alias(alias1);
6345
6631
  }
@@ -6389,7 +6675,7 @@ class Model extends AbstractModel_1.AbstractModel {
6389
6675
  _initialModel() {
6390
6676
  this.$cache = Cache_1.Cache;
6391
6677
  this.$state = new StateManager_1.StateManager("model");
6392
- this.meta("MAIN");
6678
+ this.metaTag("MAIN");
6393
6679
  this._makeTableName();
6394
6680
  this.$relation = new RelationManager_1.RelationManager(this);
6395
6681
  if (globalSettings.debug)