mares-tcomb-domain-helper
Version:
domain layer에서 tcomb를 이용하여 구현시, private method가 담기는 helper의 최상단 클래스입니다.
268 lines (244 loc) • 6.68 kB
JavaScript
const t = require('tcomb-validation')
const _ = require('lodash')
let MaresTcombError = require('mares-tcomb-error')
let MaresValidationError = require('mares-validation-error')
class BaseDomainHelper {
/**
* constructor
* @param Model - mongoose model
*/
constructor(Model) {
this.Model = Model
}
/**
* validate schema
* @param self
* @param object
* @throws {MaresTcombError}
*/
static validate(self, object) {
let err = t.validate(object, self)
this.errors = err.errors
if (err.errors && err.errors.length > 0) {
throw new MaresTcombError(err.errors)
}
}
/**
* validate all
* @param self
* @param object
* @returns {Array}
* @throws {MaresTcombError}
*/
static validateAll(self, object) {
try {
if (object instanceof Array) {
return _.map(object, (item) => {
this.validate(self, item)
})
} else {
this.validate(self, object)
}
} catch (e) {
throw new MaresTcombError(e)
}
}
/**
* domain schema를 validation 하면서 생성한다.
* @param self
* @param {Object} object
* @param {Object} [options = {}] - validation 여부
* @returns {*}
* @throws {MaresTcombError}
*/
static generate(self, object, options = {}) {
if (options.validation === undefined) options.validation = true
try {
if (object instanceof Array) {
return _.map(object, (item) => {
if (options.validation === true) {
this.validate(self, item)
}
return self(item)
})
} else {
if (options.validation === true) {
this.validate(self, object)
}
return self(object)
}
} catch (e) {
throw new MaresTcombError(e)
}
}
/**
* return tcomb error codes
* @returns {*}
*/
static getCodes() {
return MaresTcombError.codes
}
/**
* 객체 변경
* @param {Model} domain
* @param {Object} object
* @returns {domain.constructor}
*/
static combine(domain, object) {
let clone = _.cloneDeep(object)
_.map(domain, (prop, key) => {
if (object[key] === undefined) {
clone[key] = domain[key]
}
})
return this.generate(domain.constructor, clone)
}
/**
* 객체 내부 파라미터 모두 변경
* @param {Model} domain - base Domain model
* @param {Object} object - combine Object
* @param {String[]} deeplyCombineArrayNames - deeply combine array names
* @returns {domain.constructor}
*/
static deeplyCombine(domain, object, deeplyCombineArrayNames = []) {
if (deeplyCombineArrayNames.length > 0) {
for (let i = 0; i < deeplyCombineArrayNames.length; ++i) {
deeplyCombineArrayNames[i] = 'base.'+deeplyCombineArrayNames[i]
}
}
/**
* 재귀적으로 객체를 전부 합친다.
* @param {Object | Array | string | boolean etc} domainThing
* @param {Object | Array | string | boolean etc}} [combiningThing]
* @param {String[]} deeplyCombineArrayfields - deeply combine array name
*/
const recursivelyCombine = (domainThing, combiningThing, deeplyCombineArrayNames, prefixName) => {
let clone = _.cloneDeep(combiningThing)
if (domainThing instanceof Array && (deeplyCombineArrayNames.length !== 0 && deeplyCombineArrayNames.indexOf(prefixName) !== -1)) {
_.map(domainThing, (prop, key) => {
if (clone[key] === undefined) {
clone[key] = prop
} else if (clone[key] === null) {
return null
} else {
let NewPrefixName = prefixName + '.' + key
clone[key] = recursivelyCombine(prop, clone[key], deeplyCombineArrayNames, NewPrefixName)
}
})
} else if ((domainThing instanceof Object) && !(domainThing instanceof Array)) {
_.map(domainThing, (prop, key) => {
if (clone[key] === undefined) {
clone[key] = prop
} else if (clone[key] === null) {
return null
} else {
let NewPrefixName = prefixName + '.' + key
clone[key] = recursivelyCombine(prop, clone[key], deeplyCombineArrayNames, NewPrefixName)
}
})
} else if (clone === undefined) {
clone = domainThing
}
return clone
}
let clone = _.cloneDeep(object)
clone = recursivelyCombine(domain, clone, deeplyCombineArrayNames, 'base')
return this.generate(domain.constructor, clone)
}
/**
* throw mares validation error.
* @param status
* @param code
* @throws {MaresError}
*/
static throwRefineError(status, code) {
throw new MaresValidationError(status, {code})
}
/**
* throw mares validation error object.
* @param status
* @param code
* @param param
* @param value
* @param domain
* @throws {MaresError}
*/
static throwRefineErrorObject(status, {code, param = null, value = null, domain = null}) {
throw new MaresValidationError(status, {
code,
param,
value,
domain
})
}
/**
* throw mares validation error object.
* @param {number} status - status code
* @param {Array} array - error array
* @param {string} array.code - error code. invalidId와 같은 세부 code
* @param {string | null} [array.param = null] - 요청 field
* @param {string | null} [array.value = null] - 요청 value
* @param {string | null} [array.domain = null] - domain
*/
static throwRefineErrorArray(status, array) {
throw new MaresValidationError(status, array)
}
/**
* throw mares validation error object for instance.
* @param status
* @param code
*/
throwRefineErrorObject(status, {code, param = null, value = null, domain = null}) {
BaseDomainHelper.throwRefineErrorObject(status, {
code,
param,
value,
domain
})
}
/**
* throw mares validation error for instance.
* @param status
* @param code
*/
throwRefineError(status, code) {
BaseDomainHelper.throwRefineError(status, code)
}
/**
* register tcomb object for instance.
* @param object
* @param {Object} options
* @param {boolean} options.validation
* @returns {*}
*/
generate(object, options = {}) {
return BaseDomainHelper.generate(this.Model, object, options)
}
/**
* 객체 변경
* @param {Model} domain - domain object
* @param {Object} object - 변경할 오브젝트
* @returns {*}
*/
combine(domain, object) {
return BaseDomainHelper.combine(domain, object)
}
/**
* 객체 내부 파라미터 모두 변경 for instance
* @param {Model} domain - base Domain model
* @param {Object} object - combine Object
* @returns {domain.constructor}
*/
deeplyCombine(domain, object) {
return BaseDomainHelper.deeplyCombine(domain, object)
}
/**
* 객체 내부 파라미터 검사
* @param {Model} domain - base Domain model
* @param {Object} object - validate object
*/
validate(domain, object) {
return BaseDomainHelper.validate(domain, object)
}
}
module.exports = BaseDomainHelper