metal-orm 1.0.70 → 1.0.72
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/dist/index.cjs +23 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/orm/entity.ts +74 -47
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metal-orm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.72",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"engines": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"scripts"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
26
27
|
"build": "tsup",
|
|
27
28
|
"check": "tsc --noEmit",
|
|
28
29
|
"gen:entities": "node scripts/generate-entities.mjs",
|
package/src/orm/entity.ts
CHANGED
|
@@ -7,13 +7,20 @@ import { RelationIncludeOptions } from '../query-builder/relation-types.js';
|
|
|
7
7
|
import { populateHydrationCache } from './entity-hydration.js';
|
|
8
8
|
import { getRelationWrapper, RelationEntityFactory } from './entity-relations.js';
|
|
9
9
|
|
|
10
|
-
export { relationLoaderCache } from './entity-relation-cache.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
export { relationLoaderCache } from './entity-relation-cache.js';
|
|
11
|
+
|
|
12
|
+
const isRelationWrapperLoaded = (value: unknown): boolean => {
|
|
13
|
+
if (!value || typeof value !== 'object') return false;
|
|
14
|
+
return Boolean((value as { loaded?: boolean }).loaded);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type JsonSource<TTable extends TableDef> = EntityInstance<TTable> & Record<string, unknown>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates an entity proxy with lazy loading capabilities.
|
|
21
|
+
* @template TTable - The table type
|
|
22
|
+
* @template TLazy - The lazy relation keys
|
|
23
|
+
* @param ctx - The entity context
|
|
17
24
|
* @param table - The table definition
|
|
18
25
|
* @param row - The database row
|
|
19
26
|
* @param lazyRelations - Optional lazy relations
|
|
@@ -28,26 +35,39 @@ export const createEntityProxy = <
|
|
|
28
35
|
row: Record<string, unknown>,
|
|
29
36
|
lazyRelations: TLazy[] = [] as TLazy[],
|
|
30
37
|
lazyRelationOptions: Map<string, RelationIncludeOptions> = new Map()
|
|
31
|
-
): EntityInstance<TTable> => {
|
|
32
|
-
const target: Record<string, unknown> = { ...row };
|
|
33
|
-
const meta: EntityMeta<TTable> = {
|
|
34
|
-
ctx,
|
|
35
|
-
table,
|
|
38
|
+
): EntityInstance<TTable> => {
|
|
39
|
+
const target: Record<string, unknown> = { ...row };
|
|
40
|
+
const meta: EntityMeta<TTable> = {
|
|
41
|
+
ctx,
|
|
42
|
+
table,
|
|
36
43
|
lazyRelations: [...lazyRelations],
|
|
37
44
|
lazyRelationOptions: new Map(lazyRelationOptions),
|
|
38
45
|
relationCache: new Map(),
|
|
39
|
-
relationHydration: new Map(),
|
|
40
|
-
relationWrappers: new Map()
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
relationHydration: new Map(),
|
|
47
|
+
relationWrappers: new Map()
|
|
48
|
+
};
|
|
49
|
+
const createRelationEntity: RelationEntityFactory = (relationTable, relationRow) =>
|
|
50
|
+
createEntityFromRow(meta.ctx, relationTable, relationRow);
|
|
51
|
+
|
|
52
|
+
const buildJson = (self: JsonSource<TTable>): Record<string, unknown> => {
|
|
53
|
+
const json: Record<string, unknown> = {};
|
|
54
|
+
for (const key of Object.keys(target)) {
|
|
55
|
+
json[key] = self[key];
|
|
56
|
+
}
|
|
57
|
+
for (const [relationName, wrapper] of meta.relationWrappers) {
|
|
58
|
+
if (Object.prototype.hasOwnProperty.call(json, relationName)) continue;
|
|
59
|
+
if (isRelationWrapperLoaded(wrapper)) {
|
|
60
|
+
json[relationName] = wrapper;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return json;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
Object.defineProperty(target, ENTITY_META, {
|
|
67
|
+
value: meta,
|
|
68
|
+
enumerable: false,
|
|
69
|
+
writable: false
|
|
70
|
+
});
|
|
51
71
|
|
|
52
72
|
const handler: ProxyHandler<object> = {
|
|
53
73
|
get(targetObj, prop, receiver) {
|
|
@@ -55,21 +75,28 @@ export const createEntityProxy = <
|
|
|
55
75
|
return meta;
|
|
56
76
|
}
|
|
57
77
|
|
|
58
|
-
if (prop === '$load') {
|
|
59
|
-
return async (relationName: RelationKey<TTable>) => {
|
|
60
|
-
const wrapper = getRelationWrapper(meta, relationName, receiver, createRelationEntity);
|
|
61
|
-
if (wrapper && typeof wrapper.load === 'function') {
|
|
62
|
-
return wrapper.load();
|
|
63
|
-
}
|
|
64
|
-
return undefined;
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
if (prop === '$load') {
|
|
79
|
+
return async (relationName: RelationKey<TTable>) => {
|
|
80
|
+
const wrapper = getRelationWrapper(meta, relationName, receiver, createRelationEntity);
|
|
81
|
+
if (wrapper && typeof wrapper.load === 'function') {
|
|
82
|
+
return wrapper.load();
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (prop === 'toJSON') {
|
|
89
|
+
if (prop in targetObj) {
|
|
90
|
+
return Reflect.get(targetObj, prop, receiver);
|
|
91
|
+
}
|
|
92
|
+
return () => buildJson(receiver as JsonSource<TTable>);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (typeof prop === 'string' && table.relations[prop]) {
|
|
96
|
+
return getRelationWrapper(meta, prop as RelationKey<TTable>, receiver, createRelationEntity);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return Reflect.get(targetObj, prop, receiver);
|
|
73
100
|
},
|
|
74
101
|
|
|
75
102
|
set(targetObj, prop, value, receiver) {
|
|
@@ -77,14 +104,14 @@ export const createEntityProxy = <
|
|
|
77
104
|
if (typeof prop === 'string' && table.columns[prop]) {
|
|
78
105
|
ctx.markDirty(receiver);
|
|
79
106
|
}
|
|
80
|
-
return result;
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const proxy = new Proxy(target, handler) as EntityInstance<TTable>;
|
|
85
|
-
populateHydrationCache(proxy, row, meta);
|
|
86
|
-
return proxy;
|
|
87
|
-
};
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const proxy = new Proxy(target, handler) as EntityInstance<TTable>;
|
|
112
|
+
populateHydrationCache(proxy, row, meta);
|
|
113
|
+
return proxy;
|
|
114
|
+
};
|
|
88
115
|
|
|
89
116
|
/**
|
|
90
117
|
* Creates an entity instance from a database row.
|