UNPKG

soda-js

Version:

js library for accessing a soda2 api

531 lines (472 loc) 13.8 kB
// Generated by CoffeeScript 1.6.3 var Connection, Consumer, Dataset, EventEmitter, Operation, Producer, Query, addExpr, base64Lookup, eelib, expr, extend, handleLiteral, handleOrder, httpClient, isArray, isNumber, isString, rawToBase64, toBase64, toQuerystring, __slice = [].slice, __hasProp = {}.hasOwnProperty; eelib = require('eventemitter2'); EventEmitter = eelib.EventEmitter2 || eelib; httpClient = require('superagent'); isString = function(obj) { return typeof obj === 'string'; }; isArray = function(obj) { return Array.isArray(obj); }; isNumber = function(obj) { return !isNaN(parseFloat(obj)); }; extend = function() { var k, source, sources, target, v, _i, _len; target = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : []; for (_i = 0, _len = sources.length; _i < _len; _i++) { source = sources[_i]; for (k in source) { v = source[k]; target[k] = v; } } return null; }; toBase64 = typeof Buffer !== "undefined" && Buffer !== null ? function(str) { return new Buffer(str).toString('base64'); } : (base64Lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), rawToBase64 = typeof btoa !== "undefined" && btoa !== null ? btoa : function(str) { var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, result; result = []; i = 0; while (i < str.length) { chr1 = str.charCodeAt(i++); chr2 = str.charCodeAt(i++); chr3 = str.charCodeAt(i++); if (Math.max(chr1, chr2, chr3) > 0xFF) { throw new Error('Invalid character!'); } enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } result.push(base64Lookup[enc1]); result.push(base64Lookup[enc2]); result.push(base64Lookup[enc3]); result.push(base64Lookup[enc4]); } return result.join(''); }, function(str) { return rawToBase64(unescape(encodeURIComponent(str))); }); handleLiteral = function(literal) { if (isString(literal)) { return "'" + literal + "'"; } else if (isNumber(literal)) { return literal; } else { return literal; } }; handleOrder = function(order) { if (/( asc$| desc$)/i.test(order)) { return order; } else { return order + ' asc'; } }; addExpr = function(target, args) { var arg, k, v, _i, _len, _results; _results = []; for (_i = 0, _len = args.length; _i < _len; _i++) { arg = args[_i]; if (isString(arg)) { _results.push(target.push(arg)); } else { _results.push((function() { var _results1; _results1 = []; for (k in arg) { v = arg[k]; _results1.push(target.push("" + k + " = " + (handleLiteral(v)))); } return _results1; })()); } } return _results; }; expr = { and: function() { var clause, clauses; clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = clauses.length; _i < _len; _i++) { clause = clauses[_i]; _results.push("(" + clause + ")"); } return _results; })()).join(' and '); }, or: function() { var clause, clauses; clauses = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = clauses.length; _i < _len; _i++) { clause = clauses[_i]; _results.push("(" + clause + ")"); } return _results; })()).join(' or '); }, gt: function(column, literal) { return "" + column + " > " + (handleLiteral(literal)); }, gte: function(column, literal) { return "" + column + " >= " + (handleLiteral(literal)); }, lt: function(column, literal) { return "" + column + " < " + (handleLiteral(literal)); }, lte: function(column, literal) { return "" + column + " <= " + (handleLiteral(literal)); }, eq: function(column, literal) { return "" + column + " = " + (handleLiteral(literal)); } }; toQuerystring = function(obj) { var key, str, val; str = []; for (key in obj) { if (!__hasProp.call(obj, key)) continue; val = obj[key]; str.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); } return str.join('&'); }; Connection = (function() { function Connection(dataSite, sodaOpts) { var _ref; this.dataSite = dataSite; this.sodaOpts = sodaOpts != null ? sodaOpts : {}; if (!/^[a-z0-9-_.]+(:[0-9]+)?$/i.test(this.dataSite)) { throw new Error('dataSite does not appear to be valid! Please supply a domain name, eg data.seattle.gov'); } this.emitterOpts = (_ref = this.sodaOpts.emitterOpts) != null ? _ref : { wildcard: true, delimiter: '.', maxListeners: 15 }; this.networker = function(opts, data) { var client, url, _this = this; url = "https://" + this.dataSite + opts.path; client = httpClient(opts.method, url); if (data != null) { client.set('Accept', "application/json"); } if (data != null) { client.set('Content-type', "application/json"); } if (this.sodaOpts.apiToken != null) { client.set('X-App-Token', this.sodaOpts.apiToken); } if ((this.sodaOpts.username != null) && (this.sodaOpts.password != null)) { client.set('Authorization', "Basic " + toBase64("" + this.sodaOpts.username + ":" + this.sodaOpts.password)); } if (this.sodaOpts.accessToken != null) { client.set('Authorization', "OAuth " + accessToken); } if (opts.query != null) { client.query(opts.query); } if (data != null) { client.send(data); } return function(responseHandler) { return client.end(responseHandler || _this.getDefaultHandler()); }; }; } Connection.prototype.getDefaultHandler = function() { var emitter, handler; this.emitter = emitter = new EventEmitter(this.emitterOpts); return handler = function(error, response) { var _ref; if (response.ok) { if (response.accepted) { emitter.emit('progress', response.body); setTimeout((function() { return this.consumer.networker(opts)(handler); }), 5000); } else { emitter.emit('success', response.body); } } else { emitter.emit('error', (_ref = response.body) != null ? _ref : response.text); } return emitter.emit('complete', response); }; }; return Connection; })(); Consumer = (function() { function Consumer(dataSite, sodaOpts) { this.dataSite = dataSite; this.sodaOpts = sodaOpts != null ? sodaOpts : {}; this.connection = new Connection(this.dataSite, this.sodaOpts); } Consumer.prototype.query = function() { return new Query(this); }; Consumer.prototype.getDataset = function(id) { var emitter; return emitter = new EventEmitter(this.emitterOpts); }; return Consumer; })(); Producer = (function() { function Producer(dataSite, sodaOpts) { this.dataSite = dataSite; this.sodaOpts = sodaOpts != null ? sodaOpts : {}; this.connection = new Connection(this.dataSite, this.sodaOpts); } Producer.prototype.operation = function() { return new Operation(this); }; return Producer; })(); Operation = (function() { function Operation(producer) { this.producer = producer; } Operation.prototype.withDataset = function(datasetId) { this._datasetId = datasetId; return this; }; Operation.prototype.truncate = function() { var opts; opts = { method: 'delete' }; opts.path = "/resource/" + this._datasetId; return this._exec(opts); }; Operation.prototype.add = function(data) { var obj, opts, _data, _i, _len; opts = { method: 'post' }; opts.path = "/resource/" + this._datasetId; _data = JSON.parse(JSON.stringify(data)); delete _data[':id']; delete _data[':delete']; for (_i = 0, _len = _data.length; _i < _len; _i++) { obj = _data[_i]; delete obj[':id']; delete obj[':delete']; } return this._exec(opts, _data); }; Operation.prototype["delete"] = function(id) { var opts; opts = { method: 'delete' }; opts.path = "/resource/" + this._datasetId + "/" + id; return this._exec(opts); }; Operation.prototype.update = function(id, data) { var opts; opts = { method: 'post' }; opts.path = "/resource/" + this._datasetId + "/" + id; return this._exec(opts, data); }; Operation.prototype.replace = function(id, data) { var opts; opts = { method: 'put' }; opts.path = "/resource/" + this._datasetId + "/" + id; return this._exec(opts, data); }; Operation.prototype.upsert = function(data) { var opts; opts = { method: 'post' }; opts.path = "/resource/" + this._datasetId; return this._exec(opts, data); }; Operation.prototype._exec = function(opts, data) { if (this._datasetId == null) { throw new Error('no dataset given to work against!'); } this.producer.connection.networker(opts, data)(); return this.producer.connection.emitter; }; return Operation; })(); Query = (function() { function Query(consumer) { this.consumer = consumer; this._select = []; this._where = []; this._group = []; this._having = []; this._order = []; this._offset = this._limit = this._q = null; } Query.prototype.withDataset = function(datasetId) { this._datasetId = datasetId; return this; }; Query.prototype.soql = function(query) { this._soql = query; return this; }; Query.prototype.select = function() { var select, selects, _i, _len; selects = 1 <= arguments.length ? __slice.call(arguments, 0) : []; for (_i = 0, _len = selects.length; _i < _len; _i++) { select = selects[_i]; this._select.push(select); } return this; }; Query.prototype.where = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; addExpr(this._where, args); return this; }; Query.prototype.having = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; addExpr(this._having, args); return this; }; Query.prototype.group = function() { var group, groups, _i, _len; groups = 1 <= arguments.length ? __slice.call(arguments, 0) : []; for (_i = 0, _len = groups.length; _i < _len; _i++) { group = groups[_i]; this._group.push(group); } return this; }; Query.prototype.order = function() { var order, orders, _i, _len; orders = 1 <= arguments.length ? __slice.call(arguments, 0) : []; for (_i = 0, _len = orders.length; _i < _len; _i++) { order = orders[_i]; this._order.push(handleOrder(order)); } return this; }; Query.prototype.offset = function(offset) { this._offset = offset; return this; }; Query.prototype.limit = function(limit) { this._limit = limit; return this; }; Query.prototype.q = function(q) { this._q = q; return this; }; Query.prototype.getOpts = function() { var k, opts, queryComponents, v; opts = { method: 'get' }; if (this._datasetId == null) { throw new Error('no dataset given to work against!'); } opts.path = "/resource/" + this._datasetId + ".json"; queryComponents = this._buildQueryComponents(); opts.query = {}; for (k in queryComponents) { v = queryComponents[k]; opts.query['$' + k] = v; } return opts; }; Query.prototype.getURL = function() { var opts, query; opts = this.getOpts(); query = toQuerystring(opts.query); return ("https://" + this.consumer.dataSite + opts.path) + (query ? "?" + query : ""); }; Query.prototype.getRows = function() { var opts; opts = this.getOpts(); this.consumer.connection.networker(opts)(); return this.consumer.connection.emitter; }; Query.prototype._buildQueryComponents = function() { var query; query = {}; if (this._soql != null) { query.query = this._soql; } else { if (this._select.length > 0) { query.select = this._select.join(', '); } if (this._where.length > 0) { query.where = expr.and.apply(this, this._where); } if (this._group.length > 0) { query.group = this._group.join(', '); } if (this._having.length > 0) { if (!(this._group.length > 0)) { throw new Error('Having provided without group by!'); } query.having = expr.and.apply(this, this._having); } if (this._order.length > 0) { query.order = this._order.join(', '); } if (isNumber(this._offset)) { query.offset = this._offset; } if (isNumber(this._limit)) { query.limit = this._limit; } if (this._q) { query.q = this._q; } } return query; }; return Query; })(); Dataset = (function() { function Dataset(data, client) { this.data = data; this.client = client; } return Dataset; })(); extend(typeof exports !== "undefined" && exports !== null ? exports : this.soda, { Consumer: Consumer, Producer: Producer, expr: expr, _internal: { Connection: Connection, Query: Query, Operation: Operation, util: { toBase64: toBase64, handleLiteral: handleLiteral, handleOrder: handleOrder } } });