masquerade-orm 0.1.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/LICENSE +21 -0
- package/README.md +149 -0
- package/bin/universalTsInit.js +59 -0
- package/docs/deletion.md +186 -0
- package/docs/find.md +265 -0
- package/docs/getting-started-javascript.md +112 -0
- package/docs/getting-started-typescript.md +159 -0
- package/docs/in-depth-class-definitions.md +193 -0
- package/docs/jsdoc-ux-tips.md +17 -0
- package/docs/managing-the-database.md +37 -0
- package/docs/saving-to-database.md +37 -0
- package/index.d.ts +7 -0
- package/index.js +11 -0
- package/jsconfig.json +29 -0
- package/package.json +40 -0
- package/src/ORM/DbManager.js +76 -0
- package/src/ORM/ORM.js +181 -0
- package/src/ORM/bootOrm.js +929 -0
- package/src/changeLogger/changeLogger.js +55 -0
- package/src/changeLogger/save.js +237 -0
- package/src/changeLogger/sqlClients/postgres.js +97 -0
- package/src/changeLogger/sqlClients/sqlite.js +120 -0
- package/src/entity/delete/delete.js +20 -0
- package/src/entity/delete/getDependents.js +46 -0
- package/src/entity/entity.d.ts +46 -0
- package/src/entity/entity.js +228 -0
- package/src/entity/find/find.js +157 -0
- package/src/entity/find/joins.js +52 -0
- package/src/entity/find/queryBuilder.js +95 -0
- package/src/entity/find/relations.js +23 -0
- package/src/entity/find/scopeProxies.js +60 -0
- package/src/entity/find/sqlClients/postgresFuncs.js +171 -0
- package/src/entity/find/sqlClients/sqliteFuncs.js +211 -0
- package/src/entity/find/where/relationalWhere.js +142 -0
- package/src/entity/find/where/where.js +244 -0
- package/src/entity/find/where/whereArgsFunctions.js +49 -0
- package/src/misc/classes.js +63 -0
- package/src/misc/constants.js +42 -0
- package/src/misc/miscFunctions.js +167 -0
- package/src/misc/ormStore.js +18 -0
- package/src/misc/types.d.ts +560 -0
- package/src/proxies/instanceProxy.js +544 -0
- package/src/proxies/nonRelationalArrayProxy.js +76 -0
- package/src/proxies/objectProxy.js +50 -0
- package/src/proxies/relationalArrayProxy.js +130 -0
- package/src/webpack/masquerade-loader.js +14 -0
- package/src/webpack/plugin.js +43 -0
- package/src/webpack/store.js +2 -0
- package/src/webpack/webpack.config.js +41 -0
- package/testing/dev-doc.md +7 -0
- package/testing/generationFuncs.js +21 -0
- package/testing/miscFunctions.js +97 -0
- package/testing/postgres.test.js +254 -0
- package/testing/sqlite.test.js +257 -0
- package/testing/testing-classes.js +102 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
|
|
2
|
+
# Defining Classes
|
|
3
|
+
|
|
4
|
+
## 1) Declaring the Class:
|
|
5
|
+
```js
|
|
6
|
+
import { Entity } from 'masquerade'
|
|
7
|
+
|
|
8
|
+
class YourClass extends Entity {
|
|
9
|
+
// class properties
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
The class **MUST** extend `Entity` or a descendent of `Entity`.
|
|
13
|
+
|
|
14
|
+
## 2) Making a Table Column Nullable:
|
|
15
|
+
```js
|
|
16
|
+
/**@type {string | undefined}*/ propertyName
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 3) Making a Table Column Unique:
|
|
20
|
+
```js
|
|
21
|
+
/**@typedef {import('masquerade').integer} integer */
|
|
22
|
+
/**@type {string | Unique}*/ propertyName
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 4) Relational Properties
|
|
26
|
+
Assuming we have the following classes extending Entity: `User`, `Chat` and `Message`.
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
import { Entity } from 'masquerade'
|
|
30
|
+
|
|
31
|
+
class Example extends Entity {
|
|
32
|
+
// one-to-one relationship with a User instance
|
|
33
|
+
/** @type {User} */ user
|
|
34
|
+
|
|
35
|
+
// One-to-one relationship with a User instance.
|
|
36
|
+
// May be undefined if no relationship is established yet.
|
|
37
|
+
/** @type {User | undefined} */ optionalUser
|
|
38
|
+
|
|
39
|
+
// one-to-many relationship with Message instances
|
|
40
|
+
/** @type {Message[]} */ messages
|
|
41
|
+
|
|
42
|
+
// One-to-many relationship with Chat instances.
|
|
43
|
+
// May be undefined if no relationships are established yet.
|
|
44
|
+
/** @type {Chat[] | undefined} */ optionalChats
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
Each relational property will create a junction table named `className___propName_jt`.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Booting Up the ORM
|
|
51
|
+
|
|
52
|
+
## 1) Database Connection Driver:
|
|
53
|
+
|
|
54
|
+
**SQLite**
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { DatabaseSync } from 'node:sqlite'
|
|
58
|
+
const yourDbConnection = new DatabaseSync('your-db-name')
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Postgresql**
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import pkg from 'pg'
|
|
65
|
+
const { Pool } = pkg
|
|
66
|
+
|
|
67
|
+
// Create a pool instance
|
|
68
|
+
const yourDbConnection = new Pool({
|
|
69
|
+
user: 'your_db_user', // e.g., 'postgres'
|
|
70
|
+
host: 'localhost', // database host
|
|
71
|
+
database: 'your_db_name', // database name
|
|
72
|
+
password: 'your_db_password', // your password
|
|
73
|
+
port: 5432, // default PostgreSQL port
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 2) Configuration Object:
|
|
78
|
+
```js
|
|
79
|
+
/**@typedef {import('masquerade').OrmConfigObj} OrmConfigObj*/
|
|
80
|
+
|
|
81
|
+
/** @type {OrmConfigObj} */ const ormConfig = {
|
|
82
|
+
dbConnection: yourDbConnection,
|
|
83
|
+
idTypeDefault: 'UUID', // | 'INT' | 'BIGINT'
|
|
84
|
+
skipTableCreation: true // optional, false by default
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`idTypeDefault` sets the default id-type on all classes.
|
|
89
|
+
To manually set the id-type on a class, read **[Defining Classes: In-Depth - Chapter 2](https://github.com/MasqueradeORM/MasqueradeORM/blob/master/docs/in-depth-class-definitions.md#2-overriding-the-default-id-type)**.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
## 3) Boot ORM:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
import * as classes from './classes.js'
|
|
96
|
+
import * as moreClasses from './moreClasses.js'
|
|
97
|
+
import { someClass } from './aSingleClass.js'
|
|
98
|
+
await ORM.javascriptBoot(ormConfig, classes, moreClasses, someClass)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
<h1 align="center">All done!</h1>
|
|
103
|
+
|
|
104
|
+
<br>
|
|
105
|
+
<div align="center">
|
|
106
|
+
<strong>
|
|
107
|
+
© 2026
|
|
108
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
109
|
+
-
|
|
110
|
+
Released under the MIT License
|
|
111
|
+
</strong>
|
|
112
|
+
</div>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
|
|
2
|
+
# Defining Classes
|
|
3
|
+
|
|
4
|
+
## 1) Declaring the Class:
|
|
5
|
+
```js
|
|
6
|
+
import { Entity } from 'masquerade'
|
|
7
|
+
|
|
8
|
+
class YourClass extends Entity {
|
|
9
|
+
// class properties
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
The class **MUST** extend `Entity` or a descendent of `Entity`.
|
|
13
|
+
## 2) Making a Table Column Nullable:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
propertyName?: string
|
|
17
|
+
// OR propertyName: string | undefined
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 3) Making a Table Column Unique:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Unique } from 'masquerade'
|
|
24
|
+
propertyName: string | Unique
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 4) Relational Properties
|
|
28
|
+
Assuming we have the following classes extending Entity: `User`, `Chat` and `Message`.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { Entity } from 'masquerade'
|
|
32
|
+
|
|
33
|
+
class Example extends Entity {
|
|
34
|
+
// one-to-one relationship with a User instance
|
|
35
|
+
user: User
|
|
36
|
+
|
|
37
|
+
// one-to-one relationship with a User instance,
|
|
38
|
+
// but may be undefined if no relationship is established yet
|
|
39
|
+
optionalUser?: User
|
|
40
|
+
|
|
41
|
+
// one-to-many relationship with Message instances
|
|
42
|
+
messages: Message[]
|
|
43
|
+
|
|
44
|
+
// one-to-many relationship with Chat instances,
|
|
45
|
+
// but may be undefined if no relationships are established yet
|
|
46
|
+
optionalChats?: Chat[]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
Each relational property will create a junction table named `className___propName_jt`.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Booting Up the ORM
|
|
53
|
+
|
|
54
|
+
## 1) Database Connection Driver:
|
|
55
|
+
|
|
56
|
+
**SQLite**
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { DatabaseSync } from 'node:sqlite'
|
|
60
|
+
const yourDbConnection = new DatabaseSync('your-db-name')
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Postgresql**
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import pkg from 'pg'
|
|
67
|
+
const { Pool } = pkg
|
|
68
|
+
|
|
69
|
+
// Create a pool instance
|
|
70
|
+
const yourDbConnection = new Pool({
|
|
71
|
+
user: 'your_db_user', // e.g., 'postgres'
|
|
72
|
+
host: 'localhost', // database host
|
|
73
|
+
database: 'your_db_name', // database name
|
|
74
|
+
password: 'your_db_password', // your password
|
|
75
|
+
port: 5432, // default PostgreSQL port
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 2) Configuration Object:
|
|
80
|
+
```ts
|
|
81
|
+
import type { OrmConfigObj } from "masquerade"
|
|
82
|
+
|
|
83
|
+
const ormConfig: OrmConfigObj = {
|
|
84
|
+
dbConnection: yourDbConnection,
|
|
85
|
+
idTypeDefault: 'UUID', // | 'INT' | 'BIGINT'
|
|
86
|
+
skipTableCreation: true // optional, false by default
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`idTypeDefault` sets the default id-type on all classes.
|
|
91
|
+
To manually set the id-type on a class, read **[Defining Classes: In-Depth - Chapter 2](https://github.com/MasqueradeORM/MasqueradeORM/blob/master/docs/in-depth-class-definitions.md#2-overriding-the-default-id-type)**.
|
|
92
|
+
|
|
93
|
+
## 3) Build Step
|
|
94
|
+
|
|
95
|
+
### A) Universal Build Step:
|
|
96
|
+
|
|
97
|
+
First run ```bash npx orm-ts-setup``` in your terminal before your compile step. Then, compile and import ```UniversalTsSetup``` into your entry point, and run it before the boot method. Detailed example below in **[Section 4](https://github.com/MasqueradeORM/MasqueradeORM/blob/master/docs/getting-started-typescript.md#4-boot-orm)**.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
**Note:**
|
|
102
|
+
Any changes to classes that are descendents of `Entity` require `UniversalTsSetup` to be rebuilt.
|
|
103
|
+
To keep the ORM in sync with your entity definitions, include `npx orm-ts-setup` in your build step.
|
|
104
|
+
|
|
105
|
+
**Example:** ```bash
|
|
106
|
+
npx orm-ts-setup && tsc```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### B) Webpack Build Step:
|
|
110
|
+
```js
|
|
111
|
+
// in your webpack.config file add:
|
|
112
|
+
import { MasqueradePlugin } from './plugin.js'
|
|
113
|
+
|
|
114
|
+
//other fields
|
|
115
|
+
plugins: [
|
|
116
|
+
//other plugins...
|
|
117
|
+
new MasqueradePlugin() //this should be last
|
|
118
|
+
],
|
|
119
|
+
module: {
|
|
120
|
+
rules: [
|
|
121
|
+
{
|
|
122
|
+
test: /\.tsx?$/,
|
|
123
|
+
// add 'masquerade-loader' in the 'use' field
|
|
124
|
+
use: ['ts-loader', 'masquerade-loader'],
|
|
125
|
+
exclude: /node_modules/,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
//other fields
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Note:** The universal build step will work for projects using webpack as well.
|
|
133
|
+
|
|
134
|
+
## 4) Boot ORM:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import * as classes from "./classes"
|
|
138
|
+
import * as moreClasses from "./moreClasses"
|
|
139
|
+
import { SomeClass } from "./aSingleClass"
|
|
140
|
+
|
|
141
|
+
if (!usingWebpack) {
|
|
142
|
+
import { UniversalTsSetup } from "some/path/ormTypeScriptSetup"
|
|
143
|
+
UniversalTsSetup()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
await ORM.typescriptBoot(ormConfig, classes, moreClasses, someClass)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
<h1 align="center">All done!</h1>
|
|
150
|
+
|
|
151
|
+
<br>
|
|
152
|
+
<div align="center">
|
|
153
|
+
<strong>
|
|
154
|
+
© 2026
|
|
155
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
156
|
+
-
|
|
157
|
+
Released under the MIT License
|
|
158
|
+
</strong>
|
|
159
|
+
</div>
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
|
|
2
|
+
# Defining Classes: In-Depth
|
|
3
|
+
|
|
4
|
+
## 1) Special Property Typing Cases
|
|
5
|
+
|
|
6
|
+
**TypseScript**
|
|
7
|
+
```ts
|
|
8
|
+
import { Entity, integer } from 'masquerade'
|
|
9
|
+
|
|
10
|
+
type MyJSON = {
|
|
11
|
+
booleanField: boolean
|
|
12
|
+
stringArr: string[]
|
|
13
|
+
nestedObj: object
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class ExampleClass extends Entity {
|
|
17
|
+
|
|
18
|
+
// Maps to INTEGER column
|
|
19
|
+
integer: integer = 57
|
|
20
|
+
|
|
21
|
+
// Maps to REAL/DOUBLE PRECISION column
|
|
22
|
+
float: number = 15.7
|
|
23
|
+
|
|
24
|
+
// Allowed
|
|
25
|
+
stringArrWithUndefineds: (string | undefined)[] = [
|
|
26
|
+
'hello', 'world' , undefined
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
// Can use `satisfies` instead
|
|
30
|
+
json: MyJSON & object = {
|
|
31
|
+
booleanField: false,
|
|
32
|
+
stringArr: ['a', 'b', 'c'],
|
|
33
|
+
nestedObj: {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Can use `satisfies` instead
|
|
37
|
+
jsonArr: (MyJSON & object)[] = [
|
|
38
|
+
{
|
|
39
|
+
booleanField: false,
|
|
40
|
+
stringArr: ['a', 'b', 'c'],
|
|
41
|
+
nestedObj: {}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
**JavaScript**
|
|
47
|
+
```js
|
|
48
|
+
import { Entity } from 'masquerade'
|
|
49
|
+
/**@typedef {import('masquerade').integer} integer */
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {Object} MyJSON
|
|
53
|
+
* @property {boolean} booleanField
|
|
54
|
+
* @property {string[]} stringArr
|
|
55
|
+
* @property {object} nestedObj
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
class ExampleClass extends Entity {
|
|
59
|
+
// Will map to an INTEGER column
|
|
60
|
+
/**@type {integer}*/ integer = 57
|
|
61
|
+
|
|
62
|
+
// Will map to an REAL/DOUBLE PRECISION column
|
|
63
|
+
/**@type {number}*/ float = 15.7
|
|
64
|
+
|
|
65
|
+
// Allowed
|
|
66
|
+
/**@type {(string | undefined)[]}*/ stringArrWithUndefineds = [
|
|
67
|
+
'hello', 'world' , undefined
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
// MUST use 'satisfies'
|
|
71
|
+
/**@satisfies {MyJSON}*/ json = {
|
|
72
|
+
booleanField: false,
|
|
73
|
+
stringArr: ['a', 'b', 'c']
|
|
74
|
+
nestedObj: {}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// MUST use 'satisfies'
|
|
78
|
+
/**@satisfies {MyJSON[]}*/ jsonArr = [{
|
|
79
|
+
booleanField: false,
|
|
80
|
+
stringArr: ['a', 'b', 'c'],
|
|
81
|
+
nestedObj: {}
|
|
82
|
+
}]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Operational Edge Cases in Regards to the `json` and `jsonArr` Properties
|
|
87
|
+
|
|
88
|
+
The ORM can keep track of **assigments** on the first layer of an `object` (`MyJSON` object in the our case).
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const newInstance = new ExampleClass()
|
|
92
|
+
// These will mutate the instances
|
|
93
|
+
// but the ORM will not detect these changes.
|
|
94
|
+
// The objects need assigment, not mutation.
|
|
95
|
+
newInstance.json.stringArr.push('d')
|
|
96
|
+
newInstance.jsonArr.stringArr.push('d')
|
|
97
|
+
// The below mutation IS an assigment, but it is
|
|
98
|
+
// nested, and therefore will also not be persisted.
|
|
99
|
+
newInstance.json.nestedObj.someProp = 'hola mundo'
|
|
100
|
+
|
|
101
|
+
// First solution - property assigment
|
|
102
|
+
const jsonStringArr = newInstance.json.stringArr
|
|
103
|
+
const captureNesting = newInstance.json.nestedObj
|
|
104
|
+
newInstance.json.stringArr = [...jsonStringArr]
|
|
105
|
+
newInstance.jsonArr.stringArr = [...jsonStringArr]
|
|
106
|
+
newInstance.nestedObj = { ...captureNesting }
|
|
107
|
+
// why destructure? if an assigment is
|
|
108
|
+
// strict-equal the ORM will ignore it.
|
|
109
|
+
|
|
110
|
+
// Second solution - reassigning on the instance
|
|
111
|
+
newInstance.json = { ...newInstance.json }
|
|
112
|
+
newInstance.jsonArr = [...newInstance.jsonArr]
|
|
113
|
+
```
|
|
114
|
+
Both approaches will allow for proper detection and persisting of such changes.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## 2) Overriding the Default Id-Type
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
import { Entity } from 'masquerade'
|
|
121
|
+
|
|
122
|
+
class ClassA extends Entity {
|
|
123
|
+
// to avoid bugs put 'ormClassSettings_' as the first property.
|
|
124
|
+
static ormClassSettings_ = {idType: 'INT'} // | 'UUID' | 'BIGINT'
|
|
125
|
+
// properties and constructor...
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The above code lets you override the default id-type that is assigned to all Entity's descendants from the the ORM-config object passed to the `ORM.boot` function.
|
|
130
|
+
|
|
131
|
+
Setting the `idType` is only possible on a **direct child of Entity**.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { Entity } from 'masquerade'
|
|
135
|
+
|
|
136
|
+
class ClassA extends Entity {
|
|
137
|
+
// properties and constructor...
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class ClassB extends ClassA {
|
|
141
|
+
static ormClassSettings_ = {idType: 'INT'}
|
|
142
|
+
// properties and constructor...
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
In the example above, `idType` has no effect because `ClassB` does not extend `Entity`. If `static ormClassSettings_ = {idType: 'INT'}` was instead on `ClassA`, the id type of `ClassA` and all of its descendants would have an id type of `integer`.
|
|
146
|
+
|
|
147
|
+
At the moment, this is the only class setting supported, but it may evolve in the future.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## 3) Abstract Classes
|
|
151
|
+
|
|
152
|
+
### How to create an `abstract class` when using JSDoc?
|
|
153
|
+
Put the decorator `/**@abstract*/` right above the constructor of the class.
|
|
154
|
+
```js
|
|
155
|
+
import { Entity } from 'masquerade'
|
|
156
|
+
|
|
157
|
+
class User extends Entity {
|
|
158
|
+
// properties...
|
|
159
|
+
|
|
160
|
+
/**@abstract*/
|
|
161
|
+
constructor() {
|
|
162
|
+
super()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### How is an abstract class mapped to the database?
|
|
168
|
+
Abstract classes do not get a table on the database. Instead, the non-abstract descendant classes of the abstract class will inherit all its properties/columns.
|
|
169
|
+
For example, `abstract ClassA` has two children, `abstract ClassB` and `non-abstract ClassC`, with *ClassB* having a `non-abstract` child `ClassD`.
|
|
170
|
+
this means *ClassD's* table will inherit columns from both *ClassA* and *ClassB*, while *ClassC's* table will inherit columns from *ClassA*.
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
## 4) Guidelines for Classes
|
|
175
|
+
|
|
176
|
+
Classes that are connected to the ORM and mapped to database tables must follow a few simple rules:
|
|
177
|
+
- **Rule 1:** Class must either directly extend Entity (imported from the package) or extend another class that has Entity as an ancestor.
|
|
178
|
+
- **Rule 2:** Class properties must have a single “main” type: a `primitive`, a `primitive array`, an `object`, or a class that follows **Rule 1**.
|
|
179
|
+
- **Rule 3:** Class names must be PascalCasde.
|
|
180
|
+
- **Rule 4:** Class property names must be camelCased.
|
|
181
|
+
|
|
182
|
+
As long as these rules are adhered to, the class is valid.
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
<br>
|
|
186
|
+
<div align="center">
|
|
187
|
+
<strong>
|
|
188
|
+
© 2026
|
|
189
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
190
|
+
-
|
|
191
|
+
Released under the MIT License
|
|
192
|
+
</strong>
|
|
193
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Miscellaneous
|
|
2
|
+
- **Importing types from package**
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
/**@typedef {import('masquerade').OrmConfigObj} OrmConfigObj*/
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<br>
|
|
10
|
+
<div align="center">
|
|
11
|
+
<strong>
|
|
12
|
+
© 2026
|
|
13
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
14
|
+
-
|
|
15
|
+
Released under the MIT License
|
|
16
|
+
</strong>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Managing Database Tables
|
|
4
|
+
|
|
5
|
+
With time, databases can get messy with unused tables or columns that need dropping.
|
|
6
|
+
On booting, the ORM will warn you of any such tables or columns, to allow you to keep track of any redundancies.
|
|
7
|
+
|
|
8
|
+
We offer a simple way to clean up your database using the `DbManager` class and its static methods.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { DbManager } from 'masquerade'
|
|
13
|
+
// will drop all unused columns in the database
|
|
14
|
+
await DbManager.dropUnusedColumns()
|
|
15
|
+
// will drop all unused columns in entity_table
|
|
16
|
+
await DbManager.dropUnusedColumns('entity_table')
|
|
17
|
+
|
|
18
|
+
// will delete unused entity tables in the database
|
|
19
|
+
await DbManager.dropUnusedTables()
|
|
20
|
+
// will delete the table 'unused_entity_table' (won't delete a table that is connected to the ORM)
|
|
21
|
+
await DbManager.dropUnusedTables('unused_entity_table')
|
|
22
|
+
|
|
23
|
+
// will delete unused junction tables in the database
|
|
24
|
+
await DbManager.dropUnusedJunctions()
|
|
25
|
+
// will delete the table 'unused_junction_table' (won't delete a table that is connected to the ORM)
|
|
26
|
+
await DbManager.dropUnusedJunctions('unused_junction_table')
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
<br>
|
|
30
|
+
<div align="center">
|
|
31
|
+
<strong>
|
|
32
|
+
© 2026
|
|
33
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
34
|
+
-
|
|
35
|
+
Released under the MIT License
|
|
36
|
+
</strong>
|
|
37
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Saving to the Database
|
|
2
|
+
In MasqueradeORM there is no explicit save call.
|
|
3
|
+
|
|
4
|
+
The code below is all that is needed to persist a new class instance in the database:
|
|
5
|
+
```js
|
|
6
|
+
new YourClass()
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The code below is all that is needed to persist any mutation to a class instance:
|
|
10
|
+
```js
|
|
11
|
+
// toggles a boolean value and persists the change
|
|
12
|
+
yourInstance.booleanValue = !yourInstance.booleanValue
|
|
13
|
+
|
|
14
|
+
// overwrites a 1-to-1 relationship and persists it
|
|
15
|
+
yourInstance.exampleRelation = new ExampleRelation()
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**How does this work under the hood?**
|
|
19
|
+
|
|
20
|
+
When you mutate a class instance, changing a value or adding/removing a relation, the ORM doesn’t write to the database immediately.
|
|
21
|
+
Instead, it tracks those changes and batches them together to optimize the save operation.
|
|
22
|
+
|
|
23
|
+
Whenever the server is about to perform an async operation (for example, when execution hits an await), the ORM assumes that a database read might happen next. Before that happens, it automatically saves everything that’s pending.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Below is the order of operations:
|
|
27
|
+
**create/change data → hit an async boundary → ORM saves → safe to read**
|
|
28
|
+
|
|
29
|
+
<br>
|
|
30
|
+
<div align="center">
|
|
31
|
+
<strong>
|
|
32
|
+
© 2026
|
|
33
|
+
<a href="https://github.com/MasqueradeORM">MasqueradeORM </a>
|
|
34
|
+
-
|
|
35
|
+
Released under the MIT License
|
|
36
|
+
</strong>
|
|
37
|
+
</div>
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
export {ORM} from "./src/ORM/ORM.js"
|
|
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/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
export {ORM} from "./src/ORM/ORM.js"
|
|
3
|
+
export {Entity} from './src/entity/entity.js'
|
|
4
|
+
export {DbManager} from "./src/ORM/DbManager.js"
|
|
5
|
+
export {sql, AND, OR} from "./src/entity/find/where/whereArgsFunctions.js"
|
|
6
|
+
export {MasqueradePlugin} from "./src/webpack/plugin.js"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/** @typedef {import('./src/misc/types.d.ts').Unique} Unique */
|
|
10
|
+
/** @typedef {import('./src/misc/types.d.ts').integer} integer */
|
|
11
|
+
|
package/jsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Enable latest features
|
|
4
|
+
"lib": ["ESNext", "DOM"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
// Bundler mode
|
|
9
|
+
"moduleResolution": "bundler",
|
|
10
|
+
"verbatimModuleSyntax": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
//Preferences
|
|
13
|
+
"strict": true,
|
|
14
|
+
"allowUnreachableCode": false,
|
|
15
|
+
"noImplicitAny": false,
|
|
16
|
+
"strictNullChecks": true,
|
|
17
|
+
"noImplicitReturns": false,
|
|
18
|
+
"noUncheckedIndexedAccess": false,
|
|
19
|
+
"noUnusedLocals": false,
|
|
20
|
+
"noUnusedParameters": false,
|
|
21
|
+
"checkJs": true,
|
|
22
|
+
"types": ["node"],
|
|
23
|
+
"outDir": "dist",
|
|
24
|
+
"paths": {
|
|
25
|
+
"@/*": ["./src/*"]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"exclude": ["./node_modules/**/*"]
|
|
29
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "masquerade-orm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight ORM compatible with SQLite and Postgresql in Node.js",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "Masquerade-Orm"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"default": "./index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"orm-ts-setup": "./bin/universalTsInit.js"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Masquerade-Orm",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "index.js",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "node server.js"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"pg": "^8.11.2",
|
|
31
|
+
"typescript": "^5.9.3",
|
|
32
|
+
"uuidv7": "^1.0.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^25.0.3"
|
|
36
|
+
},
|
|
37
|
+
"prettier": {
|
|
38
|
+
"semi": false
|
|
39
|
+
}
|
|
40
|
+
}
|