-
Notifications
You must be signed in to change notification settings - Fork 39
/
property.ts
128 lines (110 loc) · 3.16 KB
/
property.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
import { BaseProperty, PropertyType } from 'adminjs'
const ID_PROPERTY = '_id'
const VERSION_KEY_PROPERTY = '__v'
class Property extends BaseProperty {
// TODO: Fix typings
public mongoosePath: any;
/**
* Crates an object from mongoose schema path
*
* @param {SchemaString} path
* @param {String[]} path.enumValues
* @param {String} path.regExp
* @param {String} path.path
* @param {String} path.instance
* @param {Object[]} path.validators
* @param {Object[]} path.setters
* @param {Object[]} path.getters
* @param {Object} path.options
* @param {Object} path._index
* @param {number} position
*
* @private
*
* @example
*
* const schema = new mongoose.Schema({
* email: String,
* })
*
* property = new Property(schema.paths.email))
*/
constructor(path, position = 0) {
super({ path: path.path, position })
this.mongoosePath = path
}
instanceToType(mongooseInstance) {
switch (mongooseInstance) {
case 'String':
return 'string'
case 'Boolean':
return 'boolean'
case 'Number':
return 'number'
case 'Date':
return 'datetime'
case 'Embedded':
return 'mixed'
case 'ObjectID':
if (this.reference()) {
return 'reference'
}
return 'id' as PropertyType
case 'Decimal128':
return 'float'
default:
return 'string'
}
}
name() {
return this.mongoosePath.path
}
isEditable() {
return this.name() !== VERSION_KEY_PROPERTY && this.name() !== ID_PROPERTY
}
reference() {
const ref = this.isArray()
? this.mongoosePath.caster.options?.ref
: this.mongoosePath.options?.ref
if (typeof ref === 'function') return ref.modelName
return ref
}
isVisible() {
return this.name() !== VERSION_KEY_PROPERTY
}
isId() {
return this.name() === ID_PROPERTY
}
availableValues() {
return this.mongoosePath.enumValues?.length ? this.mongoosePath.enumValues : null
}
isArray() {
return this.mongoosePath.instance === 'Array'
}
subProperties() {
if (this.type() === 'mixed') {
const subPaths = Object.values(this.mongoosePath.caster.schema.paths)
return subPaths.map(p => new Property(p))
}
return []
}
type() {
if (this.isArray()) {
let { instance } = this.mongoosePath.caster
// For array of embedded schemas mongoose returns null for caster.instance
// That is why we have to check if caster has a schema
if (!instance && this.mongoosePath.caster.schema) {
instance = 'Embedded'
}
return this.instanceToType(instance)
}
return this.instanceToType(this.mongoosePath.instance)
}
isSortable() {
return this.type() !== 'mixed' && !this.isArray()
}
isRequired() {
return !!this.mongoosePath.validators?.find?.(validator => validator.type === 'required')
}
}
export default Property