base-domain
Version:
simple module to help build Domain-Driven Design
142 lines (100 loc) • 4.1 kB
text/coffeescript
'use strict'
BaseModel = require './base-model'
EntityPool = require '../entity-pool'
###*
include submodels
Includer
base-domain
###
class Includer
###*
{Object} options
{Boolean} [options.async=true] get async values
{Boolean} [options.entityPool] entityPool, to detect circular references
{Array(String)} [options.noParentRepos] array of modelNames which needs "noParent" option when calling root.createPreferredRepository()
{Array(String)} [options.props] include only given props
###
constructor: (, = {}) ->
if not .entityPool?
= true
.entityPool = new EntityPool
{ } =
.async ?= true
ModelClass = .constructor
= .facade.getModelProps(ModelClass.getName())
{ , , } =
splitEntityProps: ->
repos = {}
syncs = []
asyncs = []
entityProps = .getEntityProps()
if .props
entityProps = (p for p in entityProps when p in .props)
for entityProp in entityProps when
subModelName = .getSubModelName(entityProp)
repo =
repos[entityProp] = repo
if repo.constructor.isSync
syncs.push entityProp
else
asyncs.push entityProp
return { syncs: syncs, asyncs: asyncs, repos: repos }
###*
include sub entities
include
{Promise}
###
include: (createNew = false) ->
if .constructor.isEntity
modelName = .constructor.getName()
if .get(modelName, .id)
return Promise.resolve()
.set()
model =
if not .async or .length is 0
return Promise.resolve(model)
# if already frozen
if .constructor.isImmutable and not createNew and Object.isFrozen()
console.error('frozen model.')
return Promise.resolve(model)
newAsyncProps = {}
promises = .map (prop) =>
.then (subModel) =>
return if not subModel?
.set(subModel)
newAsyncProps[prop] = subModel
return Promise.all(promises).then =>
getSubModel: (prop, isAsync) ->
subIdProp = .getIdPropByEntityProp(prop)
subModelName = .getSubModelName(prop)
subId = [subIdProp]
if subModel = .get(subModelName, subId)
return if isAsync then Promise.resolve(subModel) else subModel
return [prop].get([subIdProp], include: )
includeSync: (createNew = false) ->
newProps = {}
.forEach (prop) =>
subModel =
return if not subModel?
.set(subModel)
newProps[prop] = subModel
return
isNotIncludedProp: (entityProp) ->
subIdProp = .getIdPropByEntityProp(entityProp)
return not [entityProp]? && [subIdProp]?
applyNewProps: (newProps, createNew) ->
if createNew
return .$set(newProps)
else
return .set(newProps)
createPreferredRepository: (modelName) ->
options = {}
if Array.isArray(.noParentRepos) and modelName in .noParentRepos
options.noParent ?= true
try
return .root.createPreferredRepository(modelName, options)
catch e
return null
module.exports = Includer