@trullock/firebase-common 0.4.0 → 1.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/package.json +2 -2
- package/src/automapper.js +54 -24
- package/tests/getters.js +47 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trullock/firebase-common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Collection of common firebase helpers",
|
|
5
5
|
"homepage": "https://github.com/trullock/firebase#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"test": "
|
|
24
|
+
"test": "node ./tests/getters.js"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
}
|
package/src/automapper.js
CHANGED
|
@@ -28,18 +28,24 @@ export function registerMigration(shouldApply, apply)
|
|
|
28
28
|
})
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function
|
|
31
|
+
function getClassMappingByType(type)
|
|
32
32
|
{
|
|
33
33
|
for(let [key, value] of Object.entries(classes))
|
|
34
34
|
{
|
|
35
|
-
if(type == value)
|
|
36
|
-
|
|
35
|
+
if(type == value.type)
|
|
36
|
+
{
|
|
37
|
+
return {
|
|
38
|
+
name: key,
|
|
39
|
+
type,
|
|
40
|
+
getters: value.getters
|
|
41
|
+
};
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
throw new Error(`Could not serialize type ${type.name}. Did you call registerClassForPersistence() or registerMapping()?`);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
function
|
|
48
|
+
function getClassMappingByName(name)
|
|
43
49
|
{
|
|
44
50
|
return classes[name] || null
|
|
45
51
|
}
|
|
@@ -47,22 +53,29 @@ function deserialiseClassName(name)
|
|
|
47
53
|
/**
|
|
48
54
|
* Register a class with AutoMapper for persistence
|
|
49
55
|
* @param {Class} type The type of the class
|
|
50
|
-
* @param {
|
|
51
|
-
* @param {string} parent Optional: The name of the parent class, if present
|
|
56
|
+
* @param {Array} name O
|
|
52
57
|
*/
|
|
53
|
-
export function registerClassForPersistence(type,
|
|
58
|
+
export function registerClassForPersistence(type, persistedGetters)
|
|
59
|
+
{
|
|
60
|
+
return doRegisterClassForPersistence(type, null, null, persistedGetters || [])
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function doRegisterClassForPersistence(type, name, parent, persistedGetters)
|
|
54
64
|
{
|
|
55
65
|
let key = name ? name : type.name;
|
|
56
66
|
if(parent)
|
|
57
67
|
key = parent + '.' + name;
|
|
58
68
|
|
|
59
|
-
classes[key] =
|
|
69
|
+
classes[key] = {
|
|
70
|
+
type,
|
|
71
|
+
getters: persistedGetters.filter(pg => pg.type == type).map(pg => pg.property)
|
|
72
|
+
};
|
|
60
73
|
|
|
61
74
|
// static nested classes
|
|
62
75
|
for(let [k, value] of Object.entries(type))
|
|
63
76
|
{
|
|
64
77
|
if(value?.toString()?.substr(0, 5) == 'class')
|
|
65
|
-
|
|
78
|
+
doRegisterClassForPersistence(value, k, key, persistedGetters)
|
|
66
79
|
}
|
|
67
80
|
}
|
|
68
81
|
|
|
@@ -114,7 +127,30 @@ export function autoMapToFirestore(obj)
|
|
|
114
127
|
let retval = {};
|
|
115
128
|
|
|
116
129
|
if(obj.constructor.toString()?.substr(0, 5) == 'class')
|
|
117
|
-
|
|
130
|
+
{
|
|
131
|
+
let mapping = getClassMappingByType(obj.constructor)
|
|
132
|
+
retval._type = mapping.name
|
|
133
|
+
|
|
134
|
+
for(let getter of mapping.getters)
|
|
135
|
+
{
|
|
136
|
+
let value = obj[getter];
|
|
137
|
+
|
|
138
|
+
let mapped = false;
|
|
139
|
+
for(let mapping of mappings)
|
|
140
|
+
{
|
|
141
|
+
let result = mapping.toFirestore(getter, value)
|
|
142
|
+
if(result !== undefined)
|
|
143
|
+
{
|
|
144
|
+
retval[getter] = result;
|
|
145
|
+
mapped = true;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if(!mapped)
|
|
151
|
+
retval[getter] = autoMapToFirestore(value);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
118
154
|
|
|
119
155
|
for(let [key, value] of Object.entries(obj))
|
|
120
156
|
{
|
|
@@ -156,21 +192,12 @@ export function autoMapFromFirestore(obj)
|
|
|
156
192
|
if(obj?.constructor == Object)
|
|
157
193
|
{
|
|
158
194
|
let dest = {};
|
|
159
|
-
|
|
160
|
-
let type = null;
|
|
195
|
+
let mapping = null;
|
|
161
196
|
|
|
162
197
|
if(obj._type)
|
|
163
198
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
try
|
|
167
|
-
{
|
|
168
|
-
dest = new type();
|
|
169
|
-
}
|
|
170
|
-
catch(e)
|
|
171
|
-
{
|
|
172
|
-
dest = {};
|
|
173
|
-
}
|
|
199
|
+
mapping = getClassMappingByName(obj._type)
|
|
200
|
+
dest = new mapping.type();
|
|
174
201
|
}
|
|
175
202
|
|
|
176
203
|
for(let [key, value] of Object.entries(obj))
|
|
@@ -178,12 +205,15 @@ export function autoMapFromFirestore(obj)
|
|
|
178
205
|
if(key == '_type')
|
|
179
206
|
continue;
|
|
180
207
|
|
|
208
|
+
if(mapping?.getters?.indexOf(key) > -1)
|
|
209
|
+
continue;
|
|
210
|
+
|
|
181
211
|
for(let migration of migrations)
|
|
182
212
|
{
|
|
183
|
-
if(!migration.shouldApply(key, obj, value, dest, type))
|
|
213
|
+
if(!migration.shouldApply(key, obj, value, dest, mapping.type))
|
|
184
214
|
continue;
|
|
185
215
|
|
|
186
|
-
value = migration.apply(key, obj, value, dest, type);
|
|
216
|
+
value = migration.apply(key, obj, value, dest, mapping.type);
|
|
187
217
|
}
|
|
188
218
|
|
|
189
219
|
let handled = false;
|
package/tests/getters.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import { autoMapFromFirestore, autoMapToFirestore, registerClassForPersistence } from "../src/automapper.js";
|
|
3
|
+
import assert from "node:assert";
|
|
4
|
+
|
|
5
|
+
class MyObj {
|
|
6
|
+
get age() {
|
|
7
|
+
return 18;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
name = 'Mr Test'
|
|
11
|
+
inner = new MyObj.MyInnerObj()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
static MyInnerObj = class {
|
|
15
|
+
get height() {
|
|
16
|
+
return 180;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
size = 'Large'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
let myObj = new MyObj();
|
|
25
|
+
|
|
26
|
+
registerClassForPersistence(MyObj, [
|
|
27
|
+
{
|
|
28
|
+
type: MyObj.MyInnerObj,
|
|
29
|
+
property: 'height'
|
|
30
|
+
}
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
let mapped = autoMapToFirestore(myObj);
|
|
34
|
+
|
|
35
|
+
test('should automap defined getters to Firebase', t => {
|
|
36
|
+
assert.deepEqual(mapped, {
|
|
37
|
+
_type: 'MyObj',
|
|
38
|
+
name: 'Mr Test',
|
|
39
|
+
inner: { _type: 'MyObj.MyInnerObj', height: 180, size: 'Large' }
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
let unmapped = autoMapFromFirestore(mapped)
|
|
44
|
+
|
|
45
|
+
test('should ignore automap defined getters from Firebase', t => {
|
|
46
|
+
assert.deepEqual(unmapped, myObj)
|
|
47
|
+
})
|