var Q = require('q'); /** * OKQuery! * Takes a query spec for a resource and maps it the proper read * methods of that resource. This is simply to separate the notions * of queries and resources. */ function OKQuery(options) { if (!(this instanceof OKQuery)) return new OKQuery(options); options = options || {}; if (!options.resource) throw new Error('No resource provided to query'); var resource = options.resource; var type = resource.type; var query = options.query || '*'; Object.defineProperty(this, 'resource', { value: resource, writable: false }); Object.defineProperty(this, 'type', { value: resource.type, writable: false }); this.get = createQuery(resource, query, { default: options.default }); } function createQuery(resource, query, options) { options = options || {}; var query; if (isDynamic(query)) { query = queryDynamic(resource); } else if (isSet(query)) { query = queryAll(resource); } else { query = querySingle(resource, query); } if (options.default) query = withDefault(query, options.default); return query; } function queryDynamic(resource) { return function(id) { return resource.get(id); } } function queryAll(resource) { return function() { return resource.all(); } } function querySingle(resource, id) { return function() { return resource.get(id); } } function withDefault(queryFn, resultDefault) { return function() { return Q.Promise(function(resolve, reject) { queryFn().then(function(data) { data = data || resultDefault; resolve(data); }, reject); }); }; } function isDynamic(query) { return query && query.charAt(0) === ':'; } function isSet(query) { return query && query === '*'; } module.exports = OKQuery;