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
package/src/misc/ormStore.js
CHANGED
package/src/misc/types.d.ts
CHANGED
|
@@ -204,7 +204,7 @@ type NonRelationsProperties<T> = Exclude<keyof T, RelationsProperties<T>>
|
|
|
204
204
|
export type FindObj<T> = {
|
|
205
205
|
relations?: Partial<RelationsOnly<T>>
|
|
206
206
|
where?: WhereProperties<T>
|
|
207
|
-
|
|
207
|
+
templateWhere?: sqlArrowFnTable<T> | (sqlArrowFn<T> | null)[] | null
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// ---------------------------------------------------------
|
|
@@ -455,7 +455,7 @@ type ArrColumnsRawParams =
|
|
|
455
455
|
// export type FindObj<T> = {
|
|
456
456
|
// relations?: Partial<RelationsOnly<T>>
|
|
457
457
|
// where?: WhereProperties<T>
|
|
458
|
-
//
|
|
458
|
+
// templateWhere?: sqlArrowFn<T> | sqlArrowFn<T>[]
|
|
459
459
|
// }
|
|
460
460
|
|
|
461
461
|
// // ---------------------------------------------------------
|
|
@@ -65,8 +65,8 @@ export function rowObj2InstanceProxy(resultObj, findWiki, Entities) {
|
|
|
65
65
|
while (!currentWiki.uncalledJunctions[property]) currentWiki = currentWiki.parent
|
|
66
66
|
const uncalledJunctionObj = currentWiki.uncalledJunctions[property]
|
|
67
67
|
const nameOfMapWithJunction = uncalledJunctionObj.className
|
|
68
|
-
const
|
|
69
|
-
instance[property] = new LazyPromise(
|
|
68
|
+
const promiseType = uncalledJunctionObj.isArray ? nameOfMapWithJunction + `[]` : nameOfMapWithJunction
|
|
69
|
+
instance[property] = new LazyPromise(instance, property, promiseType, (resolve, reject) => promiseExecutor(instance, property, resolve, reject))
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -76,43 +76,57 @@ export function rowObj2InstanceProxy(resultObj, findWiki, Entities) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
ORM[FinalizationRegistrySymb].register(proxy, [proxy.constructor.name, proxy.id])
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function instanceProxyGetHandler(target, key, classWiki) {
|
|
85
|
-
const val = target[key]
|
|
86
|
-
if (!(val instanceof LazyPromise)) return val
|
|
87
|
-
|
|
79
|
+
function promiseExecutor(target, key, resolve, reject) {
|
|
80
|
+
if (ChangeLogger.scheduledFlush) ChangeLogger.save().then()
|
|
88
81
|
const { sqlClient, dbConnection } = OrmStore.store
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (classification === "Join") joinedTable = classWiki.junctions[key]
|
|
93
|
-
else joinedTable = mapWithProp.junctions[key]
|
|
94
|
-
|
|
95
|
-
const isArrayOfInstances = joinedClassMap.isArray
|
|
82
|
+
const classWiki = OrmStore.getClassWiki(target)
|
|
83
|
+
const [classification, joinedClassWiki, mapWithProp] = getPropertyClassification(key, classWiki)
|
|
84
|
+
const isArrayOfInstances = joinedClassWiki.isArray
|
|
96
85
|
|
|
97
86
|
let queryStr = `SELECT entity.* FROM ${nonSnake2Snake(mapWithProp.className)}___${nonSnake2Snake(key)}_jt jt` +
|
|
98
|
-
` LEFT JOIN ${nonSnake2Snake(
|
|
87
|
+
` LEFT JOIN ${nonSnake2Snake(joinedClassWiki.className)} entity ON jt.joined_id = entity.id WHERE jt.joining_id = `
|
|
99
88
|
queryStr += sqlClient === "postgresql" ? `$1` : `?`
|
|
100
89
|
|
|
101
90
|
let queryFunc
|
|
102
91
|
if (sqlClient === "postgresql") queryFunc = (queryStr, id) => dbConnection.query(queryStr, [id])
|
|
103
92
|
else queryFunc = (queryStr, id) => dbConnection.prepare(queryStr).all(id)
|
|
104
93
|
|
|
105
|
-
let promise
|
|
106
94
|
try {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
95
|
+
Promise.resolve(queryFunc(queryStr, target.id))
|
|
96
|
+
.then(rows => {
|
|
97
|
+
const { className, columns, junctions } = joinedClassWiki
|
|
98
|
+
const findWiki = { className, columns, uncalledJunctions: junctions }
|
|
99
|
+
let currentWiki = joinedClassWiki
|
|
100
|
+
let currentScopedMap = findWiki
|
|
101
|
+
while (currentWiki.parent) {
|
|
102
|
+
const { className, columns, junctions } = currentWiki.parent
|
|
103
|
+
currentScopedMap.parent = { className, columns, uncalledJunctions: junctions }
|
|
104
|
+
currentScopedMap = currentScopedMap.parent
|
|
105
|
+
currentWiki = currentWiki.parent
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const proxyArr = []
|
|
109
|
+
for (const row of rows) {
|
|
110
|
+
const rowWithCamelCasedProps = Object.fromEntries(Object.entries(row).map(([key, val]) => [snake2Pascal(key, true), val]))
|
|
111
|
+
proxyArr.push(rowObj2InstanceProxy(rowWithCamelCasedProps, findWiki, OrmStore.store.entities))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (isArrayOfInstances) target[key] = createRelationalArrayProxy(target, key, proxyArr, classWiki.className)
|
|
115
|
+
else target[key] = proxyArr[0]
|
|
116
|
+
|
|
117
|
+
resolve(target[key])
|
|
118
|
+
})
|
|
119
|
+
.catch(reject)
|
|
110
120
|
}
|
|
111
|
-
catch (
|
|
112
|
-
coloredBackgroundConsoleLog(`Lazy loading failed. ${
|
|
121
|
+
catch (err) {
|
|
122
|
+
coloredBackgroundConsoleLog(`Lazy loading failed. ${err}`, 'failure')
|
|
123
|
+
reject(err)
|
|
113
124
|
}
|
|
125
|
+
}
|
|
114
126
|
|
|
115
|
-
|
|
127
|
+
export function insertProxyIntoEntityMap(proxy, entityMap) {
|
|
128
|
+
entityMap.set(proxy.id, new WeakRef(proxy))
|
|
129
|
+
ORM[FinalizationRegistrySymb].register(proxy, [proxy.constructor.name, proxy.id])
|
|
116
130
|
}
|
|
117
131
|
|
|
118
132
|
export function instanceProxySetHandler(target, key, value, eventListenersObj, classWiki) {
|
|
@@ -356,57 +370,6 @@ export function createLazyLoadQueryStr(property, classWiki) {
|
|
|
356
370
|
}
|
|
357
371
|
|
|
358
372
|
|
|
359
|
-
export function createLazyPromise(target, key, queryRes, classWiki, isArrayOfInstances, client) {
|
|
360
|
-
return new Promise(async (resolve) => {
|
|
361
|
-
let resultArr
|
|
362
|
-
try {
|
|
363
|
-
if (client === "postgresql") resultArr = (await queryRes).rows
|
|
364
|
-
else resultArr = queryRes
|
|
365
|
-
|
|
366
|
-
if (!resultArr.length) {
|
|
367
|
-
if (isArrayOfInstances) {
|
|
368
|
-
target[key] = []
|
|
369
|
-
resolve([])
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
target[key] = undefined
|
|
373
|
-
resolve(undefined)
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const { className, columns, junctions } = classWiki
|
|
378
|
-
const findWiki = { className, columns, uncalledJunctions: junctions }
|
|
379
|
-
let currentWiki = classWiki
|
|
380
|
-
let currentScopedMap = findWiki
|
|
381
|
-
while (currentWiki.parent) {
|
|
382
|
-
const { className, columns, junctions } = currentWiki.parent
|
|
383
|
-
currentScopedMap.parent = { className, columns, uncalledJunctions: junctions }
|
|
384
|
-
currentScopedMap = currentScopedMap.parent
|
|
385
|
-
currentWiki = currentWiki.parent
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
const proxyArr = []
|
|
389
|
-
for (const row of resultArr) {
|
|
390
|
-
const rowWithCamelCasedProps = Object.fromEntries(Object.entries(row).map(([key, val]) => [snake2Pascal(key, true), val]))
|
|
391
|
-
proxyArr.push(rowObj2InstanceProxy(rowWithCamelCasedProps, findWiki, OrmStore.store.entities))
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (isArrayOfInstances) {
|
|
395
|
-
target[key] = createRelationalArrayProxy(target, key, proxyArr, classWiki.className)
|
|
396
|
-
resolve(target[key])
|
|
397
|
-
}
|
|
398
|
-
else {
|
|
399
|
-
target[key] = proxyArr[0]
|
|
400
|
-
resolve(target[key])
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
catch (e) {
|
|
404
|
-
coloredBackgroundConsoleLog(`Lazy loading failed. ${e}\n`, `failure`)
|
|
405
|
-
}
|
|
406
|
-
})
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
373
|
export function uncalledPropertySetHandler(target, key, value, columnClassificationArr) {
|
|
411
374
|
const [propertyType, propertyTypeObj, mapWithProp] = columnClassificationArr
|
|
412
375
|
const joiningId = target.id
|
|
@@ -496,7 +459,8 @@ export function proxifyEntityInstanceObj(instance, uncalledRelationalProperties)
|
|
|
496
459
|
else if (key === "eEmitter_") return emitter
|
|
497
460
|
else if (key === "eListener_") return eventListenersObj
|
|
498
461
|
else if (key === "_isDeleted_") return target[key]
|
|
499
|
-
return
|
|
462
|
+
return target[key]
|
|
463
|
+
//return instanceProxyGetHandler(target, key, classWiki)
|
|
500
464
|
},
|
|
501
465
|
set: (target, /**@type {string}*/ key, value) => {
|
|
502
466
|
instanceProxySetHandler(target, key, value, eventListenersObj, classWiki)
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { store } from "./store"
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default function (source) {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
1
|
+
import { store } from "./store.js"
|
|
2
|
+
import { SyntaxKind } from "typescript"
|
|
3
|
+
import ts from "typescript"
|
|
4
|
+
|
|
5
|
+
export default function (source) {
|
|
6
|
+
const sourceFile = ts.createSourceFile("", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS)
|
|
7
|
+
const nodes = sourceFile.statements
|
|
8
|
+
for (const node of nodes) {
|
|
9
|
+
if (!node) continue
|
|
10
|
+
//@ts-ignore
|
|
11
|
+
const isValid = (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && node.heritageClauses
|
|
12
|
+
//@ts-ignore
|
|
13
|
+
if (isValid) store.nodeArr.push(node)
|
|
14
|
+
}
|
|
15
|
+
return source
|
|
16
|
+
}
|
package/src/webpack/plugin.js
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
import { store } from "./store.js"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1
|
+
|
|
2
|
+
import { store } from "./store.js"
|
|
3
|
+
import { nodeArr2ClassDict } from "../ORM/bootOrm.js"
|
|
4
|
+
|
|
5
|
+
export class MasqueradePlugin {
|
|
6
|
+
apply(compiler) {
|
|
7
|
+
compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {
|
|
8
|
+
compilation.hooks.processAssets.tap(
|
|
9
|
+
{
|
|
10
|
+
name: this.constructor.name,
|
|
11
|
+
stage: compilation.constructor.PROCESS_ASSETS_STAGE_ADDITIONS,
|
|
12
|
+
},
|
|
13
|
+
(assets) => {
|
|
14
|
+
const classDict = nodeArr2ClassDict(store.nodeArr)
|
|
15
|
+
const prefix = `globalThis.masqueradeClassDict_ = ${JSON.stringify(classDict)};\n`
|
|
16
|
+
|
|
17
|
+
for (const entry of compilation.entrypoints.values()) {
|
|
18
|
+
for (const file of entry.getFiles()) {
|
|
19
|
+
if (!file.endsWith(".js")) continue
|
|
20
|
+
|
|
21
|
+
const asset = compilation.getAsset(file)
|
|
22
|
+
const source = asset.source.source()
|
|
23
|
+
|
|
24
|
+
compilation.updateAsset(
|
|
25
|
+
file,
|
|
26
|
+
new compiler.webpack.sources.RawSource(prefix + source)
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
package/testing/postgres.test.js
CHANGED
|
@@ -3,14 +3,14 @@ import test from 'node:test'
|
|
|
3
3
|
import assert from "node:assert"
|
|
4
4
|
import * as classes from './testing-classes.js'
|
|
5
5
|
import { resetPostgresDb, initORM, createConfigObj } from "./testInit.js"
|
|
6
|
-
import { sql } from '
|
|
6
|
+
import { sql } from '../src/entity/find/where/whereArgsFunctions.js'
|
|
7
7
|
import { generateFamiliesAndHouses } from "./generationFuncs.js"
|
|
8
8
|
import { validateUpdatedAt } from "./miscFunctions.js"
|
|
9
9
|
import { OrmStore } from '../src/misc/ormStore.js'
|
|
10
10
|
|
|
11
11
|
const { House, Person, NonRelationalClass2 } = classes
|
|
12
12
|
|
|
13
|
-
const configObj = createConfigObj()
|
|
13
|
+
const configObj = createConfigObj('postgres', '123456789')
|
|
14
14
|
await resetPostgresDb(configObj.dbConnection)
|
|
15
15
|
await initORM(configObj, classes)
|
|
16
16
|
let dbChanges = OrmStore.store.dbChangesObj
|
package/testing/sqlite.test.js
CHANGED
|
@@ -3,7 +3,7 @@ import test from 'node:test'
|
|
|
3
3
|
import assert from "node:assert"
|
|
4
4
|
import * as classes from './testing-classes.js'
|
|
5
5
|
import { initORM, createConfigObj } from "./testInit.js"
|
|
6
|
-
import { sql } from '
|
|
6
|
+
import { sql } from '../src/entity/find/where/whereArgsFunctions.js'
|
|
7
7
|
import { generateFamiliesAndHouses } from "./generationFuncs.js"
|
|
8
8
|
import { validateUpdatedAt } from "./miscFunctions.js"
|
|
9
9
|
import { OrmStore } from '../src/misc/ormStore.js'
|
|
@@ -254,4 +254,3 @@ test.after(async () => {
|
|
|
254
254
|
await fs.rm("./test", { force: true })
|
|
255
255
|
console.log('db reset')
|
|
256
256
|
})
|
|
257
|
-
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ORM } from "../index.js"
|
|
2
|
+
import { DatabaseSync } from 'node:sqlite'
|
|
3
|
+
import { Pool } from 'pg'
|
|
4
|
+
/**@typedef {import('../index.js').OrmConfigObj} OrmConfigObj */
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function createConfigObj(client, /**@type {undefined | string}*/ dbPaswword = undefined) {
|
|
8
|
+
if (client === `sqlite`) return {
|
|
9
|
+
dbConnection: new DatabaseSync('test'),
|
|
10
|
+
idTypeDefault: "INT"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
dbConnection: new Pool({
|
|
15
|
+
user: 'postgres', // e.g., 'postgres'
|
|
16
|
+
host: 'localhost', // database host
|
|
17
|
+
database: 'masquerade-test', // database name
|
|
18
|
+
password: `${dbPaswword}`, // your password
|
|
19
|
+
port: 5432, // default PostgreSQL port
|
|
20
|
+
}),
|
|
21
|
+
idTypeDefault: "INT"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function initORM(configObj, ...classes) {
|
|
26
|
+
await ORM.javascriptBoot(configObj, ...classes)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function resetPostgresDb(pool) {
|
|
30
|
+
await pool.query(
|
|
31
|
+
`DROP SCHEMA public CASCADE;
|
|
32
|
+
CREATE SCHEMA public;`
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Entity } from '
|
|
1
|
+
import { Entity } from '../index.js'
|
|
2
2
|
import { jsonGenerator } from './miscFunctions.js'
|
|
3
|
-
/**@typedef {import('
|
|
3
|
+
/**@typedef {import('../index.js').integer} integer */
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class House extends Entity {
|