var Q = require('q'); /** * OKResource! * TODO Would be nicer to compose this with an existing resource * module, but haven't found a good fit. Should keep an eye on * 'resource' by bigcompany for an update. */ function OKResource(options) { if (!(this instanceof OKResource)) return new OKResource(options); options = options || {}; if (!options.type) throw new Error('No resource type provided to OKResource') if (!options.schema) throw new Error('No schema provided to OKResource'); if (!options.db) throw new Error('No DB provided to OKResource'); var schema = options.schema; var type = options.type; this._db = options.db; // Define properties which are part of the API Object.defineProperty(this, 'schema', { value: schema, writable: false }); Object.defineProperty(this, 'spec', { value: schema.spec, writable: false }); Object.defineProperty(this, 'type', { value: type, writable: false }); } /** * Throws an error if data does not conform to schema */ OKResource.prototype.assertValid = function(data) { this.schema.assertValid(data); }; OKResource.prototype.all = function() { return this._db.getAll(this.type); }; OKResource.prototype.create = function(data) { return this._db.create(this.type, data); }; OKResource.prototype.destroy = function(data) { return this._db.remove(this.type, data.id, data); }; OKResource.prototype.find = function(query) { return this._db.find(this.type, query); }; OKResource.prototype.get = function(id) { return this._db.get(this.type, id); }; OKResource.prototype.update = function(data) { data = data || {}; return this._db.put(this.type, data.id, data); }; OKResource.prototype.updateOrCreate = function(data) { data = data || {}; var type = this.type; var db = this._db; return Q.promise(function(resolve, reject) { db.get(type, data.id).then(function(cached) { if (cached) db.put(type, data.id, data).then(resolve, reject); else db.create(type, data).then(resolve, reject); }, reject); }); }; module.exports = OKResource;