UNPKG

base-domain

Version:

simple module to help build Domain-Driven Design

210 lines (153 loc) 5 kB
Base = require './base' ResourceClientInterface = require './resource-client-interface' Entity = require './entity' ###* Base repository class of DDD pattern. Responsible for perpetuation of models. BaseRepository has a client, which access to data resource (RDB, NoSQL, memory, etc...) the parent "Base" class just simply gives a @getFacade() method. @class BaseRepository @extends Base @module base-domain ### class BaseRepository extends Base ###* model name to handle @property modelName @static @protected @type String ### @modelName: null ###* client accessing to data resource (RDB, NoSQL, memory, etc...) mock object is input by default. Extenders must set this property to achieve perpetuation @property client @abstract @protected @type ResourceClientInterface ### client: new ResourceClientInterface() ###* constructor @constructor @return ### constructor: -> modelName = @constructor.modelName facade = @getFacade() @factory = facade.createFactory(modelName) ###* get model class this factory handles @method getModelClass @return {Class} ### getModelClass: -> modelName = @constructor.modelName @getFacade().getModel(modelName) ###* Update or insert a model instance @method save @public @param {Entity|Object} entity @param {ResourceClientInterface} [client=@client] @return {Promise<Entity>} entity (different instance from input) ### save: (entity, client) -> if entity not instanceof Entity entity = @factory.createFromObject entity client ?= @client # set "createdAt-compatible property when id is not set # FIXME createdAt is not set when creating with id (#1) isCreate = not entity.id? data = entity.toPlainObject() @appendTimeStamp(data, isCreate) client.upsert(data).then (obj) => return @factory.createFromObject(obj, entity) ###* get object by ID. @method get @public @param {any} id @param {ResourceClientInterface} [client=@client] @return {Promise<Entity>} entity ### get: (id, client) -> client ?= @client client.findById(id).then (obj) => return @factory.createFromObject(obj) ###* Find all model instances that match params @method query @public @param {Object} [params] query parameters @param {ResourceClientInterface} [client=@client] @return {Promise<Array>} array of entities ### query: (params, client) -> client ?= @client client.find(params).then (objs) => return (@factory.createFromObject(obj) for obj in objs) ###* Find one model instance that matches params, Same as query, but limited to one result @method singleQuery @public @param {Object} [params] query parameters @param {ResourceClientInterface} [client=@client] @return {Promise<Entity>} entity ### singleQuery: (params, client) -> client ?= @client client.findOne(params).then (obj) => return @factory.createFromObject(obj) ###* Destroy the given entity (which must have "id" value) @method delete @public @param {Entity} entity @param {ResourceClientInterface} [client=@client] @return {Promise<Boolean>} isDeleted ### delete: (entity, client) -> client ?= @client client.destroyById(entity.id).then => return true ###* Update set of attributes. @method update @public @param {any} id id of the entity to update @param {Object} data key-value pair to update (notice: this must not be instance of Entity) @param {ResourceClientInterface} [client=@client] @return {Promise<Entity>} updated entity ### update: (id, data, client) -> if data instanceof Entity throw @getFacade().error """ update entity with BaseRepository#update() is not allowed. use BaseRepository#save(entity) instead """ client ?= @client isCreate = false @appendTimeStamp(data, isCreate) client.updateAttributes(id, data).then (obj) => return @factory.createFromObject(obj) ###* add createdAt, updatedAt to given data @method appendTimeStamp @protected @param {Object} data @param {Boolean} [isCreate=false] @return {Object} data ### appendTimeStamp: (data, isCreate = false) -> Model = @getModelClass() propCreatedAt = Model.getPropOfCreatedAt() propUpdatedAt = Model.getPropOfUpdatedAt() if isCreate and propCreatedAt data[propCreatedAt] = new Date().toISOString() if propUpdatedAt data[propUpdatedAt] = new Date().toISOString() return data module.exports = BaseRepository