Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit d0c0bde9764e6449a3a1cc4c40febc2bff6267a6 0 parents
@tenorviol authored
Showing with 191 additions and 0 deletions.
  1. +118 −0 lib/Parse.js
  2. +4 −0 makefile
  3. +69 −0 test/Parse.test.js
118 lib/Parse.js
@@ -0,0 +1,118 @@
+var qs = require('querystring');
+
+module.exports = Parse;
+
+function Parse(application_id, master_key) {
+ this._application_id = application_id;
+ this._master_key = master_key;
+}
+
+Parse.prototype = {
+ _api_protocol: require('https'),
+ _api_host: 'api.parse.com',
+ _api_port: 443,
+
+ // add object to class store
+ insert: function (className, object, callback) {
+ parseRequest.call(this, 'POST', '/1/classes/' + className, object, callback);
+ },
+
+ // get objects from class store
+ find: function (className, query, callback) {
+ if (typeof query === 'string') {
+ parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback);
+ } else {
+ parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback);
+ }
+ },
+
+ // update an object in the class store
+ update: function (className, objectId, object, callback) {
+ parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback);
+ },
+
+ // remove an object from the class store
+ 'delete': function (className, objectId, callback) {
+ parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback);
+ }
+};
+
+// Parse.com https api request
+function parseRequest(method, path, data, callback) {
+ var auth = 'Basic ' + new Buffer(this._application_id + ':' + this._master_key).toString('base64');
+ var headers = {
+ Authorization: auth,
+ Connection: 'Keep-alive'
+ };
+ var body = null;
+
+ switch (method) {
+ case 'GET':
+ if (data) {
+ path += '?' + qs.stringify(data);
+ }
+ break;
+ case 'POST':
+ case 'PUT':
+ body = JSON.stringify(data);
+ headers['Content-type'] = 'application/json';
+ headers['Content-length'] = body.length;
+ break;
+ case 'DELETE':
+ headers['Content-length'] = 0;
+ break;
+ default:
+ throw new Error('Unknown method, "' + method + '"');
+ }
+
+ var options = {
+ host: this._api_host,
+ port: this._api_port,
+ headers: headers,
+ path: path,
+ method: method
+ };
+
+ var req = this._api_protocol.request(options, function (res) {
+ if (!callback) {
+ return;
+ }
+
+ if (res.statusCode < 200 || res.statusCode >= 300) {
+ var err = new Error('HTTP error ' + res.statusCode);
+ err.arguments = arguments;
+ err.type = res.statusCode;
+ err.options = options;
+ err.body = body;
+ return callback(err);
+ }
+
+ var json = '';
+ res.setEncoding('utf8');
+
+ res.on('data', function (chunk) {
+ json += chunk;
+ });
+
+ res.on('end', function () {
+ var err = null;
+ var data = null;
+ try {
+ var data = JSON.parse(json);
+ } catch (err) {
+ }
+ callback(err, data);
+ });
+
+ res.on('close', function (err) {
+ callback(err);
+ });
+ });
+
+ body && req.write(body);
+ req.end();
+
+ req.on('error', function (err) {
+ callback && callback(err);
+ });
+}
4 makefile
@@ -0,0 +1,4 @@
+test: nodeunit
+
+nodeunit:
+ nodeunit test/Parse.test.js
69 test/Parse.test.js
@@ -0,0 +1,69 @@
+var Parse = require('../lib/Parse.js');
+
+// use environment variables APPLICATION_ID and MASTER_KEY to test against
+var application_id = process.env.APPLICATION_ID;
+var master_key = process.env.MASTER_KEY;
+
+// require the environment variables, or exit with explanation
+if (!application_id || !master_key) {
+ console.log('Set the following environment variables for the test Parse app');
+ console.log(' export APPLICATION_ID=...');
+ console.log(' export MASTER_KEY=...');
+ process.exit(1);
+}
+
+// global objects to test against
+var parse = new Parse(application_id, master_key);
+var className = 'foo';
+var object = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type
+var stub;
+
+exports.insert = function (assert) {
+ parse.insert(className, object, function (err, response) {
+ err && console.log(err);
+ assert.ok(response);
+ stub = response;
+ assert.done();
+ });
+};
+
+exports.find = function (assert) {
+ parse.find(className, stub.objectId, function (err, response) {
+ assert.equal(object.foo, response.foo);
+ assert.done();
+ });
+};
+
+exports['find many'] = function (assert) {
+ parse.find(className, stub, function (err, response) {
+ assert.equal(1, response.results.length);
+ assert.equal(stub.objectId, response.results[0].objectId);
+ assert.equal(stub.createdAt, response.results[0].createdAt);
+ assert.equal(object.foo, response.results[0].foo);
+ assert.done();
+ });
+};
+
+exports.update = function (assert) {
+ do {
+ var num = Math.floor(Math.random() * 10000);
+ } while (num == object.foo);
+ object.foo = num;
+
+ parse.update(className, stub.objectId, object, function (err, response) {
+ err && console.log(err);
+ assert.ok(response);
+ exports.find(assert);
+ });
+};
+
+exports['delete'] = function (assert) {
+ parse['delete'](className, stub.objectId, function (err) {
+ err && console.log(err);
+ assert.ok(!err);
+ parse.find(className, stub.objectId, function (err, response) {
+ assert.equal(404, err.type);
+ assert.done();
+ });
+ });
+};
Please sign in to comment.
Something went wrong with that request. Please try again.