-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathentity.ts
136 lines (124 loc) · 4.16 KB
/
entity.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import EntityData from "./entity-data";
import EntityValue from "./entity-value";
import EntityField from "./fields/entity-field";
import EntityBooleanField from "./fields/entity-boolean-field";
import EntityDateField from "./fields/entity-date-field";
import EntityNumberField from "./fields/entity-number-field";
import EntityPointField from "./fields/entity-point-field";
import EntityStringArrayField from "./fields/entity-string-array-field";
import EntityStringField from "./fields/entity-string-field";
import EntityTextField from "./fields/entity-text-field";
import EntityFieldConstructor from "./fields/entity-field-constructor";
import Schema from "../schema/schema";
import SchemaDefinition from "../schema/definition/schema-definition";
import FieldDefinition from "../schema/definition/field-definition";
import SchemaFieldType from "../schema/definition/schema-field-type";
import { RedisJsonData, RedisHashData } from "../client";
const ENTITY_FIELD_CONSTRUCTORS: Record<SchemaFieldType, EntityFieldConstructor> = {
'string': EntityStringField,
'number': EntityNumberField,
'boolean': EntityBooleanField,
'text': EntityTextField,
'date': EntityDateField,
'point': EntityPointField,
'string[]': EntityStringArrayField
}
/**
* An Entity is the class from which objects that Redis OM maps to are made. You need
* to subclass Entity in your application:
*
* ```typescript
* class Foo extends Entity {}
* ```
*/
export default abstract class Entity {
/** The generated entity ID. */
readonly entityId: string;
private schemaDef: SchemaDefinition;
private prefix: string;
private entityFields: Record<string, EntityField> = {};
/**
* Creates an new Entity.
* @internal
*/
constructor(schema: Schema<any>, id: string, data: EntityData = {}) {
this.schemaDef = schema.definition;
this.prefix = schema.prefix;
this.entityId = id;
this.createFields(data);
}
/**
* Create the fields on the Entity.
* @internal
*/
private createFields(data: EntityData) {
Object.keys(this.schemaDef).forEach(fieldName => {
const fieldDef: FieldDefinition = this.schemaDef[fieldName];
const fieldType = fieldDef.type;
const fieldAlias = fieldDef.alias ?? fieldName;
const fieldValue = data[fieldAlias] ?? null;
const entityField = new ENTITY_FIELD_CONSTRUCTORS[fieldType](fieldName, fieldDef, fieldValue);
this.entityFields[fieldAlias] = entityField;
})
};
/**
* @returns The keyname this {@link Entity} is stored with in Redis.
*/
get keyName(): string {
return `${this.prefix}:${this.entityId}`;
}
/**
* Converts this {@link Entity} to a JavaScript object suitable for stringification.
* @returns a JavaScript object.
*/
toJSON() {
const json: Record<string, any> = { entityId: this.entityId }
Object.keys(this.schemaDef).forEach(field => {
json[field] = (this as Record<string, any>)[field];
})
return json;
}
/**
* Converts this {@link Entity} to a JavaScript object suitable for writing to RedisJSON.
* @internal
*/
toRedisJson(): RedisJsonData {
let data: RedisJsonData = {};
Object.keys(this.entityFields).forEach(field => {
const entityField: EntityField = this.entityFields[field];
data = { ...data, ...entityField.toRedisJson() };
})
return data;
}
/**
* Loads this {@link Entity} from Redis JSON data.
* @internal
*/
fromRedisJson(data: RedisJsonData) {
if (!data) return data;
Object.keys(data).forEach(field => {
this.entityFields[field].fromRedisJson(data[field]);
})
}
/**
* Converts this {@link Entity} to a JavaScript object suitable for writing to a Redis Hash.
* @internal
*/
toRedisHash(): RedisHashData {
let data: RedisHashData = {};
Object.keys(this.entityFields).forEach(field => {
const entityField: EntityField = this.entityFields[field];
data = { ...data, ...entityField.toRedisHash() };
})
return data;
}
/**
* Loads this {@link Entity} from Redis Hash data.
* @internal
*/
fromRedisHash(data: RedisHashData) {
Object.keys(data).forEach(field => {
this.entityFields[field].fromRedisHash(data[field]);
})
}
}