tspace-mysql 1.5.7 → 1.5.9
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/README.md +223 -12
- package/build/lib/connection/options.js +1 -1
- package/build/lib/core/Abstracts/AbstractModel.d.ts +4 -2
- package/build/lib/core/Abstracts/AbstractModel.js.map +1 -1
- package/build/lib/core/Blueprint.d.ts +100 -67
- package/build/lib/core/Blueprint.js +306 -243
- package/build/lib/core/Blueprint.js.map +1 -1
- package/build/lib/core/Builder.d.ts +146 -146
- package/build/lib/core/Builder.js +146 -146
- package/build/lib/core/DB.d.ts +43 -43
- package/build/lib/core/DB.js +43 -43
- package/build/lib/core/Handlers/Relation.js +2 -2
- package/build/lib/core/Handlers/Relation.js.map +1 -1
- package/build/lib/core/Model.d.ts +271 -236
- package/build/lib/core/Model.js +375 -305
- package/build/lib/core/Model.js.map +1 -1
- package/build/lib/core/Operator.js +1 -1
- package/build/lib/core/Repository.d.ts +3 -3
- package/build/lib/core/Repository.js.map +1 -1
- package/build/lib/core/UtilityTypes.d.ts +45 -5
- package/build/lib/utils/index.js +1 -1
- package/build/lib/utils/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ npm install tspace-mysql -g
|
|
|
63
63
|
- [Observer](#observer)
|
|
64
64
|
- [Logger](#logger)
|
|
65
65
|
- [Hooks](#hooks)
|
|
66
|
-
- [SoftDelete](#
|
|
66
|
+
- [SoftDelete](#softdelete)
|
|
67
67
|
- [Schema](#schema)
|
|
68
68
|
- [Schema Model](#schema-model)
|
|
69
69
|
- [Validation](#validation)
|
|
@@ -73,8 +73,10 @@ npm install tspace-mysql -g
|
|
|
73
73
|
- [One To Many](#one-to-many)
|
|
74
74
|
- [Belongs To](#belongs-to)
|
|
75
75
|
- [Many To Many](#many-to-many)
|
|
76
|
+
- [Relation](#relation)
|
|
76
77
|
- [Deeply Nested Relations](#deeply-nested-relations)
|
|
77
78
|
- [Relation Exists](#relation-exists)
|
|
79
|
+
- [Relation Trashed](#relation-trashed)
|
|
78
80
|
- [Built in Relation Functions](#built-in-relation-functions)
|
|
79
81
|
- [Decorator](#decorator)
|
|
80
82
|
- [Type Safety](#type-safety)
|
|
@@ -543,7 +545,6 @@ const users = await new DB("users")
|
|
|
543
545
|
)
|
|
544
546
|
.findMany();
|
|
545
547
|
/*
|
|
546
|
-
|
|
547
548
|
SELECT * FROM `users`
|
|
548
549
|
WHERE `users`.`id`
|
|
549
550
|
IN (
|
|
@@ -1414,6 +1415,10 @@ class User extends Model {
|
|
|
1414
1415
|
const user = await new User().where('user_id',1).findOne()
|
|
1415
1416
|
// SELECT * FROM `users` WHERE `users`.`userId` = '1' and `users`.`deletedAtCustom` IS NULL LIMIT 1;
|
|
1416
1417
|
|
|
1418
|
+
// find in trashed
|
|
1419
|
+
const user = await new User().trashed().findMany()
|
|
1420
|
+
// SELECT * FROM `users` WHERE `users`.`userId` = '1' and `users`.`deletedAtCustom` IS NOT NULL;
|
|
1421
|
+
|
|
1417
1422
|
```
|
|
1418
1423
|
|
|
1419
1424
|
### Relationships
|
|
@@ -1572,10 +1577,82 @@ const userUsingFunction = await new User().roles().findOne()
|
|
|
1572
1577
|
// user?.roles => [{...}]
|
|
1573
1578
|
```
|
|
1574
1579
|
|
|
1580
|
+
#### Relation
|
|
1581
|
+
|
|
1582
|
+
Relationships are connections between entities.
|
|
1583
|
+
Let's consider an example of a relationship:
|
|
1584
|
+
|
|
1585
|
+
```js
|
|
1586
|
+
|
|
1587
|
+
+-------------+--------------+----------------------------+
|
|
1588
|
+
| table users |
|
|
1589
|
+
+-------------+--------------+----------------------------+
|
|
1590
|
+
| id | username | email |
|
|
1591
|
+
|-------------|--------------|----------------------------|
|
|
1592
|
+
| 1 | tspace1 | tspace1@gmail.com |
|
|
1593
|
+
| 2 | tspace2 | tspace2@gmail.com |
|
|
1594
|
+
| 3 | tspace3 | tspace3@gmail.com |
|
|
1595
|
+
+-------------+--------------+----------------------------+
|
|
1596
|
+
|
|
1597
|
+
+-------------+--------------+----------------------------+
|
|
1598
|
+
| table posts |
|
|
1599
|
+
+-------------+--------------+----------------------------+
|
|
1600
|
+
| id | user_id | title |
|
|
1601
|
+
|-------------|--------------|----------------------------|
|
|
1602
|
+
| 1 | 1 | posts 1 |
|
|
1603
|
+
| 2 | 1 | posts 2 |
|
|
1604
|
+
| 3 | 3 | posts 3 |
|
|
1605
|
+
+-------------+--------------+----------------------------+
|
|
1606
|
+
|
|
1607
|
+
import { Model } from 'tspace-mysql'
|
|
1608
|
+
|
|
1609
|
+
class User extends Model {
|
|
1610
|
+
constructor(){
|
|
1611
|
+
super()
|
|
1612
|
+
this.hasMany({ name : 'posts' , model : Post })
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
class Post extends Model {
|
|
1617
|
+
constructor(){
|
|
1618
|
+
super()
|
|
1619
|
+
this.belongsTo({ name : 'user' , model : User })
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
await new User()
|
|
1624
|
+
.relations('posts')
|
|
1625
|
+
.findOne()
|
|
1626
|
+
// SELECT * FROM `users` LIMIT 1;
|
|
1627
|
+
// SELECT * FROM `posts` WHERE `posts`.`userId` IN (...);
|
|
1628
|
+
|
|
1629
|
+
/*
|
|
1630
|
+
* @returns
|
|
1631
|
+
* {
|
|
1632
|
+
* id : 1,
|
|
1633
|
+
* username: "tspace1",
|
|
1634
|
+
* email : "tspace1@gmail.com",
|
|
1635
|
+
* posts : [
|
|
1636
|
+
* {
|
|
1637
|
+
* id : 1 ,
|
|
1638
|
+
* user_id : 1,
|
|
1639
|
+
* title : "post 1"
|
|
1640
|
+
* },
|
|
1641
|
+
* {
|
|
1642
|
+
* id : 2 ,
|
|
1643
|
+
* user_id : 1,
|
|
1644
|
+
* title : "post 2"
|
|
1645
|
+
* }
|
|
1646
|
+
* ]
|
|
1647
|
+
* }
|
|
1648
|
+
*/
|
|
1649
|
+
|
|
1650
|
+
```
|
|
1651
|
+
|
|
1575
1652
|
#### Deeply Nested Relations
|
|
1576
1653
|
|
|
1577
|
-
Relationships can involve deep connections.
|
|
1578
|
-
Let's example of a deep relationship:
|
|
1654
|
+
Relationships can involve deep connections.
|
|
1655
|
+
Let's consider an example of a deep relationship:
|
|
1579
1656
|
|
|
1580
1657
|
```js
|
|
1581
1658
|
import { Model } from 'tspace-mysql'
|
|
@@ -1700,6 +1777,9 @@ class Post extends Model {
|
|
|
1700
1777
|
}
|
|
1701
1778
|
// normal relations
|
|
1702
1779
|
await new User().relations('posts').findMany()
|
|
1780
|
+
// SELECT * FROM `users` WHERE `users`.`deleted_at`;
|
|
1781
|
+
// SELECT * FROM `posts` WHERE `posts`.`userId` IN (...) AND `posts`.`deleted_at` IS NULL;
|
|
1782
|
+
|
|
1703
1783
|
/*
|
|
1704
1784
|
* @returns [
|
|
1705
1785
|
* {
|
|
@@ -1730,6 +1810,11 @@ await new User().relations('posts').findMany()
|
|
|
1730
1810
|
*/
|
|
1731
1811
|
|
|
1732
1812
|
await new User().relationsExists('posts').findMany()
|
|
1813
|
+
// SELECT * FROM `users` WHERE `users`.`deleted_at` IS NULL
|
|
1814
|
+
// AND EXISTS (SELECT 1 FROM `posts` WHERE `users`.`id` = `posts`.`user_id` AND `posts`.`deletedA_at` IS NULL );
|
|
1815
|
+
|
|
1816
|
+
// SELECT * FROM `posts` WHERE `posts`.`user_id` IN (...) AND `posts`.`deleted_at` IS NULL;
|
|
1817
|
+
|
|
1733
1818
|
/*
|
|
1734
1819
|
* @returns [
|
|
1735
1820
|
* {
|
|
@@ -1748,6 +1833,130 @@ await new User().relationsExists('posts').findMany()
|
|
|
1748
1833
|
* because posts id 1 and id 3 has been removed from database (using soft delete)
|
|
1749
1834
|
*/
|
|
1750
1835
|
|
|
1836
|
+
```
|
|
1837
|
+
|
|
1838
|
+
#### Relation Trashed
|
|
1839
|
+
Relationships can return results only if they are deleted in table, considering soft deletes.
|
|
1840
|
+
Let's illustrate this with an example:
|
|
1841
|
+
```js
|
|
1842
|
+
|
|
1843
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1844
|
+
| table users | |
|
|
1845
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1846
|
+
| id | username | email | deleted_at |
|
|
1847
|
+
|-------------|--------------|----------------------------|--------------------|
|
|
1848
|
+
| 1 | tspace1 | tspace1@gmail.com | |
|
|
1849
|
+
| 2 | tspace2 | tspace2@gmail.com | |
|
|
1850
|
+
| 3 | tspace3 | tspace3@gmail.com |2020-07-15 00:00:00 |
|
|
1851
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1852
|
+
|
|
1853
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1854
|
+
| table posts | |
|
|
1855
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1856
|
+
| id | user_id | title | deleted_at |
|
|
1857
|
+
|-------------|--------------|----------------------------|--------------------|
|
|
1858
|
+
| 1 | 1 | posts 1 |2020-07-15 00:00:00 |
|
|
1859
|
+
| 2 | 2 | posts 2 | |
|
|
1860
|
+
| 3 | 3 | posts 3 |2020-07-15 00:00:00 |
|
|
1861
|
+
+-------------+--------------+----------------------------+--------------------+
|
|
1862
|
+
|
|
1863
|
+
import { Model } from 'tspace-mysql'
|
|
1864
|
+
|
|
1865
|
+
class User extends Model {
|
|
1866
|
+
constructor(){
|
|
1867
|
+
super()
|
|
1868
|
+
this.hasMany({ name : 'posts' , model : Post })
|
|
1869
|
+
this.useSoftDelete()
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
+--------------------------------------------------------------------------+
|
|
1874
|
+
|
|
1875
|
+
class Post extends Model {
|
|
1876
|
+
constructor(){
|
|
1877
|
+
super()
|
|
1878
|
+
this.hasMany({ name : 'comments' , model : Comment })
|
|
1879
|
+
this.belongsTo({ name : 'user' , model : User })
|
|
1880
|
+
this.useSoftDelete()
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
// normal relations
|
|
1885
|
+
await new User().relations('posts').findMany()
|
|
1886
|
+
// SELECT * FROM `users` WHERE `users`.`deleted_at` IS NULL;
|
|
1887
|
+
// SELECT * FROM `posts` WHERE `posts`.`user_id` IN (...) AND `posts`.`deleted_at` IS NULL;
|
|
1888
|
+
|
|
1889
|
+
/*
|
|
1890
|
+
* @returns [
|
|
1891
|
+
* {
|
|
1892
|
+
* id : 1,
|
|
1893
|
+
* username: "tspace1",
|
|
1894
|
+
* email : "tspace1@gmail.com",
|
|
1895
|
+
* posts : []
|
|
1896
|
+
* }
|
|
1897
|
+
* {
|
|
1898
|
+
* id : 2,
|
|
1899
|
+
* username: "tspace2",
|
|
1900
|
+
* email : "tspace2@gmail.com",
|
|
1901
|
+
* posts : [
|
|
1902
|
+
* {
|
|
1903
|
+
* id : 2,
|
|
1904
|
+
* user_id : 2,
|
|
1905
|
+
* title : "posts 2"
|
|
1906
|
+
* }
|
|
1907
|
+
* ]
|
|
1908
|
+
* }
|
|
1909
|
+
* ]
|
|
1910
|
+
*/
|
|
1911
|
+
|
|
1912
|
+
// relationsTrashed
|
|
1913
|
+
await new User().relationsTrashed('posts').findMany()
|
|
1914
|
+
// SELECT * FROM `users` WHERE `users`.`deleted_at` IS NULL;
|
|
1915
|
+
// SELECT * FROM `posts` WHERE `posts`.`user_id` IN (...) AND `posts`.`deleted_at` IS NOT NULL;
|
|
1916
|
+
|
|
1917
|
+
/*
|
|
1918
|
+
* @returns [
|
|
1919
|
+
* {
|
|
1920
|
+
* id : 1,
|
|
1921
|
+
* username: "tspace1",
|
|
1922
|
+
* email : "tspace1@gmail.com",
|
|
1923
|
+
* posts : [
|
|
1924
|
+
* {
|
|
1925
|
+
* id : 1,
|
|
1926
|
+
* user_id : 1,
|
|
1927
|
+
* title : "posts 1"
|
|
1928
|
+
* }
|
|
1929
|
+
* ]
|
|
1930
|
+
* }
|
|
1931
|
+
* {
|
|
1932
|
+
* id : 2,
|
|
1933
|
+
* username: "tspace2",
|
|
1934
|
+
* email : "tspace2@gmail.com",
|
|
1935
|
+
* posts : []
|
|
1936
|
+
* }
|
|
1937
|
+
* ]
|
|
1938
|
+
*/
|
|
1939
|
+
|
|
1940
|
+
// relationsTrashed + trashed
|
|
1941
|
+
await new User().relationsTrashed('posts').trashed().findMany()
|
|
1942
|
+
// SELECT * FROM `users` WHERE `users`.`deleted_at` IS NOT NULL;
|
|
1943
|
+
// SELECT * FROM `posts` WHERE `posts`.`user_id` IN (...) AND `posts`.`deleted_at` IS NOT NULL;
|
|
1944
|
+
/*
|
|
1945
|
+
* @returns [
|
|
1946
|
+
* {
|
|
1947
|
+
* id : 3,
|
|
1948
|
+
* username: "tspace3",
|
|
1949
|
+
* email : "tspace3@gmail.com",
|
|
1950
|
+
* posts : [
|
|
1951
|
+
* {
|
|
1952
|
+
* id : 3,
|
|
1953
|
+
* user_id : 3,
|
|
1954
|
+
* title : "posts 3"
|
|
1955
|
+
* }
|
|
1956
|
+
* ]
|
|
1957
|
+
* }
|
|
1958
|
+
* ]
|
|
1959
|
+
*/
|
|
1751
1960
|
|
|
1752
1961
|
```
|
|
1753
1962
|
|
|
@@ -2341,7 +2550,7 @@ for(const user of users) {
|
|
|
2341
2550
|
+--------------------------------------------------------------------------+
|
|
2342
2551
|
// If you don't want to set types for every returning method such as 'findOne', 'findMany', and so on...
|
|
2343
2552
|
|
|
2344
|
-
import { Model , Blueprint , TSchema , TRelation
|
|
2553
|
+
import { Model , Blueprint , TSchema , TRelation } from 'tspace-mysql'
|
|
2345
2554
|
import { Phone } from '../Phone'
|
|
2346
2555
|
|
|
2347
2556
|
const schemaUser = {
|
|
@@ -2358,8 +2567,8 @@ const schemaUser = {
|
|
|
2358
2567
|
type TSchemaUser = TSchema<typeof schemaUser>
|
|
2359
2568
|
|
|
2360
2569
|
type TRelationUser = TRelation<{
|
|
2361
|
-
phones :
|
|
2362
|
-
phone :
|
|
2570
|
+
phones : Phone[]
|
|
2571
|
+
phone : Phone
|
|
2363
2572
|
}>
|
|
2364
2573
|
|
|
2365
2574
|
// Add this '<TSchemaUser, RelationUserType>' to activate the type for the Model.
|
|
@@ -2379,7 +2588,7 @@ export { User }
|
|
|
2379
2588
|
+--------------------------------------------------------------------------+
|
|
2380
2589
|
|
|
2381
2590
|
// in file Phone.ts
|
|
2382
|
-
import { Model , Blueprint , TSchema , TRelation
|
|
2591
|
+
import { Model , Blueprint , TSchema , TRelation } from 'tspace-mysql'
|
|
2383
2592
|
import { User } from './User.ts'
|
|
2384
2593
|
|
|
2385
2594
|
const schemaPhone = {
|
|
@@ -2394,7 +2603,7 @@ const schemaPhone = {
|
|
|
2394
2603
|
type TSchemaPhone = TSchema<typeof schemaPhone>
|
|
2395
2604
|
|
|
2396
2605
|
type TRelationPhone = TRelation<{
|
|
2397
|
-
user :
|
|
2606
|
+
user : User[]
|
|
2398
2607
|
}>
|
|
2399
2608
|
|
|
2400
2609
|
class Phone extends Model<
|
|
@@ -2452,7 +2661,8 @@ const users = await new User()
|
|
|
2452
2661
|
|
|
2453
2662
|
## Repository
|
|
2454
2663
|
```js
|
|
2455
|
-
Repository is a mechanism that encapsulates all database operations related to a specific model.
|
|
2664
|
+
Repository is a mechanism that encapsulates all database operations related to a specific model.
|
|
2665
|
+
It provides methods for querying, inserting, updating, and deleting records in the database associated with the model.
|
|
2456
2666
|
|
|
2457
2667
|
** The Repository check always type safety if model is used the type of schema
|
|
2458
2668
|
|
|
@@ -2517,10 +2727,10 @@ const userHasPhones = await userRepository.findOne({
|
|
|
2517
2727
|
relations : ['post'],
|
|
2518
2728
|
relationQuery:{
|
|
2519
2729
|
name : 'post',
|
|
2520
|
-
callback: () => ({
|
|
2730
|
+
callback: () : TRepository<Phone> => ({ // add type for the callback know to check type of the model
|
|
2521
2731
|
select: ['id', 'userId', 'name'],
|
|
2522
2732
|
relations : ['user']
|
|
2523
|
-
})
|
|
2733
|
+
})
|
|
2524
2734
|
}
|
|
2525
2735
|
})
|
|
2526
2736
|
|
|
@@ -2656,6 +2866,7 @@ import { Schema , Blueprint , DB } from 'tspace-mysql'
|
|
|
2656
2866
|
(async () => {
|
|
2657
2867
|
await new Schema().table('users', {
|
|
2658
2868
|
id : new Blueprint().int().notNull().primary().autoIncrement(),
|
|
2869
|
+
// or id : new Blueprint().serial().primary(),
|
|
2659
2870
|
uuid : new Blueprint().varchar(120).null()
|
|
2660
2871
|
name : new Blueprint().varchar(120).default('name'),
|
|
2661
2872
|
email : new Blueprint().varchar(255).unique().notNull(),
|
|
@@ -28,7 +28,7 @@ const env = {
|
|
|
28
28
|
DATABASE: ENV.DB_DATABASE || ENV.TSPACE_DATABASE,
|
|
29
29
|
CONNECTION_LIMIT: ENV.DB_CONNECTION_LIMIT || ENV.TSPACE_CONNECTION_LIMIT || 30,
|
|
30
30
|
QUEUE_LIMIT: ENV.DB_QUEUE_LIMIT || ENV.TSPACE_QUEUE_LIMIT || 0,
|
|
31
|
-
TIMEOUT: ENV.DB_TIMEOUT || ENV.TSPACE_TIMEOUT || 1000 *
|
|
31
|
+
TIMEOUT: ENV.DB_TIMEOUT || ENV.TSPACE_TIMEOUT || 1000 * 90,
|
|
32
32
|
CHARSET: ENV.DB_CHARSET || ENV.TSPACE_CHARSET || 'utf8mb4',
|
|
33
33
|
CONNECTION_ERROR: ENV.DB_CONNECTION_ERROR || ENV.TSPACE_CONNECTION_ERROR || false,
|
|
34
34
|
WAIT_FOR_CONNECTIONS: ENV.DB_WAIT_FOR_CONNECTIONS || ENV.TSPACE_WAIT_FOR_CONNECTIONS || true,
|
|
@@ -58,17 +58,19 @@ declare abstract class AbstractModel<T, R> extends Builder {
|
|
|
58
58
|
abstract registry(func: Record<string, Function>): this;
|
|
59
59
|
abstract onlyTrashed(): this;
|
|
60
60
|
abstract trashed(): this;
|
|
61
|
-
abstract restore(): Promise<
|
|
61
|
+
abstract restore(): Promise<T[]>;
|
|
62
62
|
abstract with<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
63
63
|
abstract withQuery<K extends R extends object ? keyof R : string, TModel extends Model>(nameRelations: K, callback: (query: TModel) => TModel): this;
|
|
64
64
|
abstract withExists<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
65
65
|
abstract withTrashed<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
66
66
|
abstract withAll<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
67
|
+
abstract withCount<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
67
68
|
abstract has<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
68
69
|
abstract relations<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
69
|
-
abstract
|
|
70
|
+
abstract relationQuery<K extends R extends object ? keyof R : string, TModel extends Model>(nameRelations: K, callback: (query: TModel) => TModel): this;
|
|
70
71
|
abstract relationsExists<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
71
72
|
abstract relationsAll<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
73
|
+
abstract relationsCount<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
72
74
|
abstract relationsTrashed<K extends R extends object ? keyof R : string>(...nameRelations: K[]): this;
|
|
73
75
|
}
|
|
74
76
|
export { AbstractModel };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractModel.js","sourceRoot":"","sources":["../../../../src/lib/core/Abstracts/AbstractModel.ts"],"names":[],"mappings":";;;AAEA,wCAAoC;AAIpC,MAAe,aAAmB,SAAQ,iBAAO;
|
|
1
|
+
{"version":3,"file":"AbstractModel.js","sourceRoot":"","sources":["../../../../src/lib/core/Abstracts/AbstractModel.ts"],"names":[],"mappings":";;;AAEA,wCAAoC;AAIpC,MAAe,aAAmB,SAAQ,iBAAO;CAyEhD;AAEQ,sCAAa;AACtB,kBAAe,aAAa,CAAA"}
|