You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					129 lines
				
				3.2 KiB
			
		
		
			
		
	
	
					129 lines
				
				3.2 KiB
			| 
											3 years ago
										 | 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 |