masquerade-orm 0.8.1 → 0.8.3
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 +17 -17
- package/bin/universalTsInit.js +59 -59
- package/docs/deletion.md +4 -4
- package/docs/find.md +274 -264
- package/docs/getting-started-javascript.md +13 -4
- package/docs/getting-started-typescript.md +6 -4
- package/docs/in-depth-class-definitions.md +7 -7
- package/docs/jsdoc-ux-tips.md +251 -16
- package/docs/managing-the-database.md +1 -1
- package/index.d.ts +7 -7
- package/package.json +1 -1
- package/src/changeLogger/changeLogger.js +2 -2
- package/src/entity/entity.js +3 -3
- package/src/entity/find/find.js +7 -7
- package/src/entity/find/scopeProxies.js +2 -2
- package/src/entity/find/where/{relationalWhere.js → templateWhere.js} +18 -18
- package/src/entity/find/where/where.js +4 -4
- package/src/misc/classes.js +59 -5
- package/src/misc/ormStore.js +3 -0
- package/src/misc/types.d.ts +2 -2
- package/src/proxies/instanceProxy.js +42 -78
- package/src/webpack/masquerade-loader.js +16 -14
- package/src/webpack/plugin.js +42 -43
- package/testing/postgres.test.js +2 -2
- package/testing/sqlite.test.js +1 -2
- package/testing/testInit.js +34 -0
- package/testing/testing-classes.js +2 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
**TypseScript**
|
|
7
7
|
```ts
|
|
8
|
-
import { Entity, integer } from 'masquerade'
|
|
8
|
+
import { Entity, integer } from 'masquerade-orm'
|
|
9
9
|
|
|
10
10
|
type MyJSON = {
|
|
11
11
|
booleanField: boolean
|
|
@@ -45,8 +45,8 @@ class ExampleClass extends Entity {
|
|
|
45
45
|
```
|
|
46
46
|
**JavaScript**
|
|
47
47
|
```js
|
|
48
|
-
import { Entity } from 'masquerade'
|
|
49
|
-
/**@typedef {import('masquerade').integer} integer */
|
|
48
|
+
import { Entity } from 'masquerade-orm'
|
|
49
|
+
/**@typedef {import('masquerade-orm').integer} integer */
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* @typedef {Object} MyJSON
|
|
@@ -63,7 +63,7 @@ class ExampleClass extends Entity {
|
|
|
63
63
|
/**@type {number}*/ float = 15.7
|
|
64
64
|
|
|
65
65
|
// Allowed
|
|
66
|
-
/**@type {(string | undefined)[]}*/ stringArrWithUndefineds = [
|
|
66
|
+
/**@type { (string | undefined)[] }*/ stringArrWithUndefineds = [
|
|
67
67
|
'hello', 'world' , undefined
|
|
68
68
|
]
|
|
69
69
|
|
|
@@ -117,7 +117,7 @@ Both approaches will allow for proper detection and persisting of such changes.
|
|
|
117
117
|
## 2) Overriding the Default Id-Type
|
|
118
118
|
|
|
119
119
|
```js
|
|
120
|
-
import { Entity } from 'masquerade'
|
|
120
|
+
import { Entity } from 'masquerade-orm'
|
|
121
121
|
|
|
122
122
|
class ClassA extends Entity {
|
|
123
123
|
// to avoid bugs put 'ormClassSettings_' as the first property.
|
|
@@ -131,7 +131,7 @@ The above code lets you override the default id-type that is assigned to all Ent
|
|
|
131
131
|
Setting the `idType` is only possible on a **direct child of Entity**.
|
|
132
132
|
|
|
133
133
|
```ts
|
|
134
|
-
import { Entity } from 'masquerade'
|
|
134
|
+
import { Entity } from 'masquerade-orm'
|
|
135
135
|
|
|
136
136
|
class ClassA extends Entity {
|
|
137
137
|
// properties and constructor...
|
|
@@ -152,7 +152,7 @@ At the moment, this is the only class setting supported, but it may evolve in th
|
|
|
152
152
|
### How to create an `abstract class` when using JSDoc?
|
|
153
153
|
Put the decorator `/**@abstract*/` right above the constructor of the class.
|
|
154
154
|
```js
|
|
155
|
-
import { Entity } from 'masquerade'
|
|
155
|
+
import { Entity } from 'masquerade-orm'
|
|
156
156
|
|
|
157
157
|
class User extends Entity {
|
|
158
158
|
// properties...
|
package/docs/jsdoc-ux-tips.md
CHANGED
|
@@ -1,17 +1,252 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
# JSDoc - UX Tips
|
|
2
|
+
|
|
3
|
+
#### ** Note: The following guide is for Visual Studio Code users **
|
|
4
|
+
|
|
5
|
+
This guide will instruct you on how to adjust your VS Code settings to vastly improve your experience with JSDoc annotation.
|
|
6
|
+
|
|
7
|
+
Here is how your code will look like after applying the settings:
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### 1) Install the [`Inline fold`](https://marketplace.visualstudio.com/items?itemName=moalamri.inline-fold) Extension
|
|
15
|
+
|
|
16
|
+
Either click the link in the title or run the following command in the terminal:
|
|
17
|
+
```bash
|
|
18
|
+
code --install-extension moalamri.inline-fold
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2) Modify `User Settings (JSON)`
|
|
22
|
+
**First Step**
|
|
23
|
+
- Windows / Linux: Ctrl + Shift + P
|
|
24
|
+
- macOS: Cmd + Shift + P
|
|
25
|
+
|
|
26
|
+
**Second Step**
|
|
27
|
+
|
|
28
|
+
Type `Preferences: Open User Settings (JSON)` and press Enter.
|
|
29
|
+
|
|
30
|
+
**Third Step**
|
|
31
|
+
|
|
32
|
+
Copy the lines below into the JSON and save.
|
|
33
|
+
```JSON
|
|
34
|
+
{
|
|
35
|
+
"inlineFold.regex": "(\\/\\*\\*@\\w+\\s+\\{|(?<=\\/\\*\\*@\\w+\\s+\\{.*)\\}\\s*\\w*\\*\\/)",
|
|
36
|
+
"inlineFold.regexGroup": "1",
|
|
37
|
+
"inlineFold.maskChar": "",
|
|
38
|
+
"inlineFold.after": "",
|
|
39
|
+
"inlineFold.unfoldOnLineSelect": true,
|
|
40
|
+
"inlineFold.unfoldedOpacity": 1
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 3) Create Snippet File
|
|
45
|
+
**First Step**
|
|
46
|
+
- Windows / Linux: Ctrl + Shift + P
|
|
47
|
+
- macOS: Cmd + Shift + P
|
|
48
|
+
|
|
49
|
+
**Second Step**
|
|
50
|
+
|
|
51
|
+
Type `Snippets: Configure Snippets` and press Enter.
|
|
52
|
+
|
|
53
|
+
**Third Step**
|
|
54
|
+
|
|
55
|
+
Choose the `New Global Snippets file...` option and press Enter.
|
|
56
|
+
|
|
57
|
+
**Fourth Step**
|
|
58
|
+
|
|
59
|
+
Name you snippet file, for example, `JSDoc_UX`.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
**Fifth Step**
|
|
63
|
+
|
|
64
|
+
Copy the JSON below and save.
|
|
65
|
+
```JSON
|
|
66
|
+
{
|
|
67
|
+
"@type let": {
|
|
68
|
+
"scope": "javascript,typescript",
|
|
69
|
+
"prefix": "let",
|
|
70
|
+
"body": [
|
|
71
|
+
"/**@type {${1}}*/ let $0"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"@type const": {
|
|
75
|
+
"scope": "javascript,typescript",
|
|
76
|
+
"prefix": "const",
|
|
77
|
+
"body": [
|
|
78
|
+
"/**@type {${1}}*/ const $0"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"@type string": {
|
|
82
|
+
"scope": "javascript,typescript",
|
|
83
|
+
"prefix": "string",
|
|
84
|
+
"body": [
|
|
85
|
+
"/**@type {string${1}}*/$0"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
"@type number": {
|
|
89
|
+
"scope": "javascript,typescript",
|
|
90
|
+
"prefix": "number",
|
|
91
|
+
"body": [
|
|
92
|
+
"/**@type {number${1}}*/$0"
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"@type boolean": {
|
|
96
|
+
"scope": "javascript,typescript",
|
|
97
|
+
"prefix": "boolean",
|
|
98
|
+
"body": [
|
|
99
|
+
"/**@type {boolean${1}}*/$0"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"@type any": {
|
|
103
|
+
"scope": "javascript,typescript",
|
|
104
|
+
"prefix": "any",
|
|
105
|
+
"body": [
|
|
106
|
+
"/**@type {any${1}}*/$0"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"@type Map": {
|
|
110
|
+
"scope": "javascript,typescript",
|
|
111
|
+
"prefix": "Map",
|
|
112
|
+
"body": [
|
|
113
|
+
"/**@type {Map<${1}>}*/$0"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"@type Function": {
|
|
117
|
+
"scope": "javascript,typescript",
|
|
118
|
+
"prefix": "Function",
|
|
119
|
+
"body": [
|
|
120
|
+
"/**@type {Function${1}}*/$0"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"@type": {
|
|
124
|
+
"scope": "javascript,typescript",
|
|
125
|
+
"prefix": "type",
|
|
126
|
+
"body": [
|
|
127
|
+
"/**@type {${1}}*/$0"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
"@return": {
|
|
131
|
+
"scope": "javascript,typescript",
|
|
132
|
+
"prefix": "return",
|
|
133
|
+
"body": [
|
|
134
|
+
"/**@return {${1}}*/$0"
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
"@typedef import": {
|
|
138
|
+
"scope": "javascript,typescript",
|
|
139
|
+
"prefix": "importTypedef",
|
|
140
|
+
"body": [
|
|
141
|
+
"/**@typedef {import('${1}').$2} $3*/$0"
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"@typedef": {
|
|
145
|
+
"scope": "javascript,typescript",
|
|
146
|
+
"prefix": "typedef",
|
|
147
|
+
"body": [
|
|
148
|
+
"/**",
|
|
149
|
+
"* @typedef {Object} ${1:MyObject}",
|
|
150
|
+
"* @property {${2:boolean}} ${3:booleanField}",
|
|
151
|
+
"* @property {${4:object}} ${5:nestedObj}",
|
|
152
|
+
"*/"
|
|
153
|
+
],
|
|
154
|
+
"description": "JSDoc typedef for an object"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
**Note:** You can change the `prefix` fields if you do not like the shortcut names.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
### 4) Configure the `jsconfig.json` file
|
|
162
|
+
|
|
163
|
+
Add the following lines to your `jsconfig.json` (or `tsconfig.json`) file:
|
|
164
|
+
```JSON
|
|
165
|
+
"allowJs": true,
|
|
166
|
+
"checkJs": true
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
## Using the Shortcuts
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
### Importing Types
|
|
174
|
+
|
|
175
|
+
- **Use `importTypedef`**
|
|
176
|
+
```js
|
|
177
|
+
// importing from a package
|
|
178
|
+
/**@typedef {import('masquerade-orm').OrmConfigObj} OrmConfigObjAlias*/
|
|
179
|
+
// importing from some file
|
|
180
|
+
/**@typedef {import('./path/to/file').YourImportedType} YourImportedTypeAlias*/
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+

|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
### Typing Variables
|
|
187
|
+
- **Use `type` / `string` / `number` / `boolean` (etc)**
|
|
188
|
+
```js
|
|
189
|
+
/**@type {string}*/ someString = '123'
|
|
190
|
+
/**@type {number}*/ someNumber = 567
|
|
191
|
+
```
|
|
192
|
+

|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
### `Object` Type Deinition Template
|
|
196
|
+
- **Use `typedef`**
|
|
197
|
+
```js
|
|
198
|
+
/**
|
|
199
|
+
* @typedef {Object} YourObject
|
|
200
|
+
* @property {string} someString
|
|
201
|
+
* @property {number} someNum
|
|
202
|
+
*/
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+

|
|
206
|
+
|
|
207
|
+
### Defining Classes
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
import { Entity } from 'masquerade-orm'
|
|
211
|
+
/**@typedef {import('masquerade-orm').Unique} Unique*/
|
|
212
|
+
|
|
213
|
+
class User extends Entity {
|
|
214
|
+
/**@type {string | Unique}*/ username
|
|
215
|
+
/**@type {string | Unique}*/ email
|
|
216
|
+
/**@type {string}*/ password
|
|
217
|
+
/**@type {boolean}*/ isBanned = false
|
|
218
|
+
/**@satisfies {UserMetadata}*/ metadata = {
|
|
219
|
+
twoFactorAuth: false,
|
|
220
|
+
createdAt: new Date()
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
constructor(
|
|
224
|
+
/**@type {string}*/ username,
|
|
225
|
+
/**@type {string}*/ email,
|
|
226
|
+
/**@type {string}*/ password) {
|
|
227
|
+
super()
|
|
228
|
+
this.username = username
|
|
229
|
+
this.email = email
|
|
230
|
+
this.password = password
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @typedef {Object} UserMetadata
|
|
236
|
+
* @property {boolean} twoFactorAuth
|
|
237
|
+
* @property {Date} createdAt
|
|
238
|
+
*/
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
<h1 align="center">All done!</h1>
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
<br>
|
|
245
|
+
<div align="center">
|
|
246
|
+
<strong>
|
|
247
|
+
© 2026
|
|
248
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
249
|
+
-
|
|
250
|
+
Released under the MIT License
|
|
251
|
+
</strong>
|
|
17
252
|
</div>
|
|
@@ -9,7 +9,7 @@ We offer a simple way to clean up your database using the `DbManager` class and
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
```js
|
|
12
|
-
import { DbManager } from 'masquerade'
|
|
12
|
+
import { DbManager } from 'masquerade-orm'
|
|
13
13
|
// will drop all unused columns in the database
|
|
14
14
|
await DbManager.dropUnusedColumns()
|
|
15
15
|
// will drop all unused columns in entity_table
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export {ORM} from "./src/ORM/ORM
|
|
3
|
-
export {Entity} from './src/entity/entity'
|
|
4
|
-
export {DbManager} from "./src/ORM/DbManager"
|
|
5
|
-
export {sql, AND, OR} from "./src/entity/find/where/whereArgsFunctions"
|
|
6
|
-
export {MasqueradePlugin} from "./src/webpack/plugin"
|
|
7
|
-
export {Unique, integer, OrmConfigObj} from './src/misc/types'
|
|
1
|
+
|
|
2
|
+
export {ORM} from "./src/ORM/ORM"
|
|
3
|
+
export {Entity} from './src/entity/entity'
|
|
4
|
+
export {DbManager} from "./src/ORM/DbManager"
|
|
5
|
+
export {sql, AND, OR} from "./src/entity/find/where/whereArgsFunctions"
|
|
6
|
+
export {MasqueradePlugin} from "./src/webpack/plugin"
|
|
7
|
+
export {Unique, integer, OrmConfigObj} from './src/misc/types'
|
package/package.json
CHANGED
|
@@ -20,8 +20,8 @@ export class ChangeLogger {
|
|
|
20
20
|
static async save() {
|
|
21
21
|
const dbChanges = OrmStore.store.dbChangesObj
|
|
22
22
|
if (!Object.keys(dbChanges).length || ChangeLogger.currentlySaving) return
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
|
|
24
|
+
ChangeLogger.currentlySaving = true
|
|
25
25
|
let paramIndex = 1
|
|
26
26
|
const { sqlClient, dbConnection } = OrmStore.store
|
|
27
27
|
const deletedInstancesArr = dbChanges.deletedInstancesArr
|
package/src/entity/entity.js
CHANGED
|
@@ -11,7 +11,7 @@ import { aliasedFindWiki2QueryRes, parseFindWiki, destructureAndValidateArg } fr
|
|
|
11
11
|
import { deproxifyScopeProxy, classWiki2ScopeProxy } from "./find/scopeProxies.js"
|
|
12
12
|
import { postgresCreateProxyArray } from "./find/sqlClients/postgresFuncs.js"
|
|
13
13
|
import { sqliteCreateProxyArray } from "./find/sqlClients/sqliteFuncs.js"
|
|
14
|
-
import {
|
|
14
|
+
import { mergeTemplateWhereScope } from "./find/where/templateWhere.js"
|
|
15
15
|
import { mergeWhereScope } from "./find/where/where.js"
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -68,11 +68,11 @@ export class Entity {
|
|
|
68
68
|
|
|
69
69
|
let classWiki = classWikiDict[this.name]
|
|
70
70
|
if (!classWiki) throw new Error(`The class '${this.name}' has not been included in the ORM boot method.`)
|
|
71
|
-
const [relationsArg, whereArg,
|
|
71
|
+
const [relationsArg, whereArg, templateWhereArg] = destructureAndValidateArg(findObj)
|
|
72
72
|
let findWiki
|
|
73
73
|
const baseProxyMap = classWiki2ScopeProxy(classWiki)
|
|
74
74
|
if (whereArg) mergeWhereScope(baseProxyMap, whereArg)
|
|
75
|
-
if (
|
|
75
|
+
if (templateWhereArg) findWiki = mergeTemplateWhereScope(baseProxyMap, templateWhereArg)
|
|
76
76
|
findWiki = deproxifyScopeProxy(baseProxyMap)
|
|
77
77
|
|
|
78
78
|
const [aliasedFindMap, joinStatements, whereObj] = parseFindWiki(findWiki)
|
package/src/entity/find/find.js
CHANGED
|
@@ -4,14 +4,14 @@ import { rowObj2InstanceProxy } from "../../proxies/instanceProxy.js"
|
|
|
4
4
|
import { createRelationalArrayProxy } from "../../proxies/relationalArrayProxy.js"
|
|
5
5
|
import { generateQueryStrWithCTEs } from "./queryBuilder.js"
|
|
6
6
|
import { junctionJoin, parentJoin } from "./joins.js"
|
|
7
|
-
import { relationalWhereFuncs2Statements } from "./where/
|
|
7
|
+
import { relationalWhereFuncs2Statements } from "./where/templateWhere.js"
|
|
8
8
|
import { whereValues2Statements } from "./where/where.js"
|
|
9
9
|
import { OrmStore } from "../../misc/ormStore.js"
|
|
10
10
|
|
|
11
11
|
export const proxyType = Symbol('proxyType')
|
|
12
12
|
|
|
13
13
|
export function destructureAndValidateArg(findObj) {
|
|
14
|
-
let { relations: eagerLoad, where,
|
|
14
|
+
let { relations: eagerLoad, where, templateWhere } = findObj
|
|
15
15
|
|
|
16
16
|
if (eagerLoad) {
|
|
17
17
|
const type = getType(eagerLoad)
|
|
@@ -25,11 +25,11 @@ export function destructureAndValidateArg(findObj) {
|
|
|
25
25
|
else if (Object.keys(where).length === 0) where = undefined
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
if (
|
|
29
|
-
const type = getType(
|
|
30
|
-
if (type !== "function") throw new Error(`\nInvalid value in the '
|
|
28
|
+
if (templateWhere) {
|
|
29
|
+
const type = getType(templateWhere)
|
|
30
|
+
if (type !== "function") throw new Error(`\nInvalid value in the 'templateWhere' field of the 'find' function's argument. Expected a function.`)
|
|
31
31
|
}
|
|
32
|
-
return [eagerLoad, where,
|
|
32
|
+
return [eagerLoad, where, templateWhere]
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export function removeRelationFromUnusedRelations(classMap, key) {
|
|
@@ -63,7 +63,7 @@ export function parseFindWiki(findWiki, aliasBase = 'a', aliasArr = [], joinStat
|
|
|
63
63
|
returnedWiki.junctions[key] = parseFindWiki(joinedTable, aliasBase, aliasArr, joinStatements, whereObj, selectArr)[0]
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
if (returnedWiki.
|
|
66
|
+
if (returnedWiki.templateWhere) relationalWhereFuncs2Statements(returnedWiki, whereObj)
|
|
67
67
|
if (returnedWiki.where) whereValues2Statements(returnedWiki, whereObj)
|
|
68
68
|
return [returnedWiki, joinStatements, whereObj, selectArr]
|
|
69
69
|
}
|
|
@@ -40,7 +40,7 @@ export function classWiki2ScopeProxy(classWiki) {
|
|
|
40
40
|
|| key === "uncalledJunctions_"
|
|
41
41
|
|| key === "junctions_"
|
|
42
42
|
|| key === "where_"
|
|
43
|
-
|| key === "
|
|
43
|
+
|| key === "templateWhere_"
|
|
44
44
|
|| key === "isArray_"
|
|
45
45
|
) return target[key]
|
|
46
46
|
else if (key === proxyType) return 'categorizingProxy'
|
|
@@ -56,5 +56,5 @@ export function findPropOnScopeProxy(scopeProxy, key, rootClassName) {
|
|
|
56
56
|
else if (scopeProxy.uncalledJunctions_ && scopeProxy.uncalledJunctions_[key]) return [scopeProxy.uncalledJunctions_[key], scopeProxy, "uncalledJunctions_"]
|
|
57
57
|
else if (scopeProxy.junctions_ && scopeProxy.junctions_[key]) return [scopeProxy.junctions_[key], scopeProxy, "junctions_"]
|
|
58
58
|
else if (scopeProxy.parent_) return findPropOnScopeProxy(scopeProxy.parent_, key, rootClassName)
|
|
59
|
-
else throw new Error(`\n'${key}' is not a valid property of class ${rootClassName}. Please fix the find function's argument. \nhint: use
|
|
59
|
+
else throw new Error(`\n'${key}' is not a valid property of class ${rootClassName}. Please fix the find function's argument. \nhint: use IntelliSense.`)
|
|
60
60
|
}
|
|
@@ -5,7 +5,7 @@ import { proxyType, removeRelationFromUnusedRelations } from "../find.js"
|
|
|
5
5
|
import { deproxifyScopeProxy, findPropOnScopeProxy, classWiki2ScopeObj } from "../scopeProxies.js"
|
|
6
6
|
|
|
7
7
|
export function relationalWhereFuncs2Statements(mapObj, whereObj, queryStr = ``) {
|
|
8
|
-
const relationalWhereFunc = mapObj.
|
|
8
|
+
const relationalWhereFunc = mapObj.templateWhere
|
|
9
9
|
let AliasObj4func = createFullAndFlatAliasObj(mapObj)
|
|
10
10
|
const sqlWhereObj = relationalWhereFunc(AliasObj4func)
|
|
11
11
|
while (sqlWhereObj.params.length + sqlWhereObj.strings.length > 0) {
|
|
@@ -49,24 +49,24 @@ function createFullAndFlatAliasObj(mapObj, fullFlatAliasObj = {}) {
|
|
|
49
49
|
return fullFlatAliasObj
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export function
|
|
52
|
+
export function mergeTemplateWhereScope(proxyMap, relationalWhereFunc) {
|
|
53
53
|
if (typeof relationalWhereFunc !== "function") throw new Error(`Relational where expects a function.`)
|
|
54
54
|
let mapObj = deproxifyScopeProxy(proxyMap)
|
|
55
55
|
const classWiki = OrmStore.store.classWikiDict[mapObj.className_]
|
|
56
|
-
const relationalWhereMapProxy =
|
|
56
|
+
const relationalWhereMapProxy = createTemplateWhereProxy(mapObj, classWiki)
|
|
57
57
|
relationalWhereFunc(relationalWhereMapProxy)
|
|
58
58
|
mapObj = deproxifyScopeProxy(relationalWhereMapProxy)
|
|
59
|
-
mapObj.
|
|
60
|
-
return
|
|
59
|
+
mapObj.templateWhere_ = relationalWhereFunc
|
|
60
|
+
return reproxyWikiPostTemplateWhere(mapObj, classWiki)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
function
|
|
64
|
-
if (mapObj.parent_) mapObj.parent_ =
|
|
63
|
+
function reproxyWikiPostTemplateWhere(mapObj, classWiki) {
|
|
64
|
+
if (mapObj.parent_) mapObj.parent_ = reproxyWikiPostTemplateWhere(mapObj.parent_, classWiki.parent)
|
|
65
65
|
|
|
66
66
|
if (mapObj.junctions_) {
|
|
67
67
|
const mapRelations = mapObj.junctions_
|
|
68
68
|
for (const key of Object.keys(mapRelations))
|
|
69
|
-
mapRelations[key] =
|
|
69
|
+
mapRelations[key] = reproxyWikiPostTemplateWhere(mapRelations[key], classWiki.junctions[key])
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const proxy = new Proxy(mapObj, {
|
|
@@ -78,7 +78,7 @@ function reproxyMapObjPostRelationalWhere(mapObj, classWiki) {
|
|
|
78
78
|
|| key === "uncalledJunctions_"
|
|
79
79
|
|| key === "junctions_"
|
|
80
80
|
|| key === "where_"
|
|
81
|
-
|| key === "
|
|
81
|
+
|| key === "templateWhere_"
|
|
82
82
|
|| key === "isArray_"
|
|
83
83
|
) return target[key]
|
|
84
84
|
else if (key === "raw_") return target
|
|
@@ -89,20 +89,20 @@ function reproxyMapObjPostRelationalWhere(mapObj, classWiki) {
|
|
|
89
89
|
return proxy
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export function
|
|
92
|
+
export function createTemplateWhereProxy(mapObj, classWiki) {
|
|
93
93
|
if (classWiki.parent) {
|
|
94
94
|
let parent
|
|
95
95
|
if (!mapObj.parent_) parent = classWiki2ScopeObj(classWiki)
|
|
96
96
|
else parent = mapObj.parent_
|
|
97
97
|
const parentOrmMap = classWiki.parent
|
|
98
|
-
mapObj.parent_ =
|
|
98
|
+
mapObj.parent_ = createTemplateWhereProxy(parent, parentOrmMap)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
if (mapObj.junctions_) {
|
|
102
102
|
const mapRelations = mapObj.junctions_
|
|
103
103
|
for (const key of Object.keys(mapRelations)) {
|
|
104
104
|
const relationOrmMap = classWiki.junctions[key]
|
|
105
|
-
mapRelations[key] =
|
|
105
|
+
mapRelations[key] = createTemplateWhereProxy(mapRelations[key], relationOrmMap)
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -115,28 +115,28 @@ export function createRelationalWhereProxy(mapObj, classWiki) {
|
|
|
115
115
|
|| key === "uncalledJunctions_"
|
|
116
116
|
|| key === "junctions_"
|
|
117
117
|
|| key === "where_"
|
|
118
|
-
|| key === "
|
|
118
|
+
|| key === "templateWhere_"
|
|
119
119
|
|| key === "isArray_"
|
|
120
120
|
) return target[key]
|
|
121
121
|
else if (key === "raw_") return target
|
|
122
122
|
else if (key === proxyType) return 'relationalWhereProxy'
|
|
123
|
-
else return
|
|
123
|
+
else return findPropOnTemplateWhereProxy(target, key, classWiki)
|
|
124
124
|
}
|
|
125
125
|
})
|
|
126
126
|
return proxy
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
export function
|
|
129
|
+
export function findPropOnTemplateWhereProxy(mapObj, key, classWiki) {
|
|
130
130
|
if (mapObj.uncalledJunctions_[key]) {
|
|
131
131
|
const relation = mapObj.uncalledJunctions_[key]
|
|
132
132
|
const formattedRelationObj = classWiki2ScopeObj(relation)
|
|
133
133
|
removeRelationFromUnusedRelations(mapObj, key)
|
|
134
134
|
const proxyRelations = mapObj.junctions_ ??= {}
|
|
135
|
-
proxyRelations[key] =
|
|
135
|
+
proxyRelations[key] = createTemplateWhereProxy(formattedRelationObj, classWiki.junctions[key])
|
|
136
136
|
return proxyRelations[key]
|
|
137
137
|
}
|
|
138
138
|
else if (mapObj.columns_[key]) return mapObj.columns_[key]
|
|
139
139
|
else if (mapObj.junctions_[key]) return mapObj.junctions_[key]
|
|
140
|
-
else if (mapObj.parent_) return
|
|
141
|
-
else throw new Error(`\n'${key}' is not a valid property of class ${classWiki.className}. Please fix the find function's
|
|
140
|
+
else if (mapObj.parent_) return findPropOnTemplateWhereProxy(mapObj.parent_, key, classWiki.parent)
|
|
141
|
+
else throw new Error(`\n'${key}' is not a valid property of class ${classWiki.className}. Please fix the find function's templateWhere. \nhint: use intellisense by pressing CNTRL + space to see all viable options.`)
|
|
142
142
|
}
|
|
@@ -4,7 +4,7 @@ import { array2String, getType, nonSnake2Snake } from "../../../misc/miscFunctio
|
|
|
4
4
|
import { OrmStore } from "../../../misc/ormStore.js"
|
|
5
5
|
import { removeRelationFromUnusedRelations } from "../find.js"
|
|
6
6
|
import { classWiki2ScopeProxy } from "../scopeProxies.js"
|
|
7
|
-
import {
|
|
7
|
+
import { mergeTemplateWhereScope } from "./templateWhere.js"
|
|
8
8
|
/**@typedef {import('../../../misc/classes').AndArray} AndArray */
|
|
9
9
|
/**@typedef {import('../../../misc/classes').AndArray} OrArray */
|
|
10
10
|
|
|
@@ -209,7 +209,7 @@ export function mergeWhereScope(proxyMap, whereObj) {
|
|
|
209
209
|
for (const [key, whereVal] of entries) {
|
|
210
210
|
|
|
211
211
|
if (key === "_relationalWhere") {
|
|
212
|
-
proxyMap =
|
|
212
|
+
proxyMap = mergeTemplateWhereScope(proxyMap, whereVal)
|
|
213
213
|
continue
|
|
214
214
|
}
|
|
215
215
|
|
|
@@ -236,8 +236,8 @@ export function mergeWhereScope(proxyMap, whereObj) {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
const passedMap = classMap.junctions_[key]
|
|
239
|
-
if (whereValType === "function") passedMap.
|
|
240
|
-
else if (whereValType === "array") passedMap.
|
|
239
|
+
if (whereValType === "function") passedMap.templateWhere_ = [whereVal]
|
|
240
|
+
else if (whereValType === "array") passedMap.templateWhere_ = whereVal
|
|
241
241
|
else mergeWhereScope(passedMap, whereVal)
|
|
242
242
|
}
|
|
243
243
|
}
|
package/src/misc/classes.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**@typedef {import('./types').PrimitivesNoNull} PrimitivesNoNull*/
|
|
2
2
|
|
|
3
|
+
import { OrmStore } from './ormStore.js'
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* @template T
|
|
@@ -51,13 +53,65 @@ export class Alias {
|
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
export class LazyPromise {
|
|
54
|
-
constructor(
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
constructor(instance, property, promiseType, executor) {
|
|
57
|
+
// if (typeof executor !== 'function') {
|
|
58
|
+
// throw new TypeError(
|
|
59
|
+
// `LazyPromise executor must be a function, got ${typeof executor}`
|
|
60
|
+
// )
|
|
61
|
+
// }
|
|
62
|
+
this.instanceContext = {
|
|
63
|
+
instanceId: instance.id,
|
|
64
|
+
instanceClass: instance.constructor.name,
|
|
65
|
+
property,
|
|
66
|
+
promiseType
|
|
67
|
+
}
|
|
68
|
+
this._executor = executor
|
|
69
|
+
this._promise = null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_getPromise() {
|
|
73
|
+
if (!this._promise) {
|
|
74
|
+
this._promise = new Promise((resolve, reject) => {
|
|
75
|
+
try {
|
|
76
|
+
this._executor(resolve, reject)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
reject(err)
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
return this._promise
|
|
83
|
+
}
|
|
57
84
|
|
|
85
|
+
then(onFulfilled, onRejected) {
|
|
86
|
+
return this._getPromise().then(onFulfilled, onRejected)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
catch(onRejected) {
|
|
90
|
+
return this._getPromise().catch(onRejected)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
finally(onFinally) {
|
|
94
|
+
return this._getPromise().finally(onFinally)
|
|
58
95
|
}
|
|
59
96
|
|
|
60
97
|
toString() {
|
|
61
|
-
return `Promise<${this.
|
|
98
|
+
return `Promise<${this.instanceContext.promiseType}>`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
push(...items) {
|
|
102
|
+
const { instanceClass, instanceId, property, promiseType } = this.instanceContext
|
|
103
|
+
const cleanedType = promiseType.endsWith('[]') ? promiseType.slice(0, -2) : promiseType
|
|
104
|
+
const addedIds = []
|
|
105
|
+
for (const item of items) {
|
|
106
|
+
if (item.constructor.name !== cleanedType) throw new Error(`${item} is of type ${item.constructor.name} but must be of type ${cleanedType}.`)
|
|
107
|
+
addedIds.push(item.id)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const changesObj = OrmStore.store.dbChangesObj
|
|
111
|
+
changesObj[instanceClass] ??= {}
|
|
112
|
+
const instanceChangeObj = changesObj[instanceClass][instanceId] ??= {}
|
|
113
|
+
const relationsLogger = instanceChangeObj[property] ??= { added: [], removed: [] }
|
|
114
|
+
relationsLogger.added.push(...addedIds)
|
|
62
115
|
}
|
|
63
|
-
|
|
116
|
+
|
|
117
|
+
}
|