From 1874bb483451bfa3091896f3357bcadee5b2856b Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Mon, 4 Jun 2012 15:06:04 -0400 Subject: [PATCH 01/95] updated Parse.js --- lib/Parse.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 14c8b88..600fd34 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -17,20 +17,65 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/classes/' + className, object, callback); }, + // add files + insertFile: function(fileName, data, contentType, callback){ + parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); + }, + // get objects from class store find: function (className, query, callback) { if (typeof query === 'string') { - parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); + parseRequest.call(this, 'GET', '/1/' + className + '/' + query, null, callback); } else { - parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); + parseRequest.call(this, 'GET', '/1/' + className, { where: JSON.stringify(query) }, callback); } }, + // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class + getUser: function (userName, passWord, callback) { + parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); + }, + + // get an object belonging to a certain User + getFileByUser: function(userId, callback) { + queryString = 'where={"user":' + '"' + userId + '"' + '}' + encodedString = encodeURIComponent(queryString); + parseRequest.call(this, 'GET', '/1/classes/contracts?' + encodedString, null, callback) + }, + + // insert an object into Parse + insertCustom: function (className, object, callback) { + parseRequest.call(this, 'POST', '/1/' + className, object, callback); + }, + // update an object in the class store update: function (className, objectId, object, callback) { parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); }, + + // update a User's email address + updateUserEmail: function(objectId, data, callback) { + data = { email: data } + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + }, + + // update a User's username + updateUserName: function(objectId, data, callback) { + data = { username: data } + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + }, + + // reset a User's password + passwordReset: function (data, callback) { + data = { email: data } + parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) + }, + // delete a file. Note: file still shows up on the parse databrowser, but attempting to access it will result in a 401 + deleteFile: function (fileName, callback) { + parseRequest.call(this, 'DELETE', '/1/files/' + fileName, null, callback) + }, + // remove an object from the class store 'delete': function (className, objectId, callback) { parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); @@ -38,12 +83,13 @@ Parse.prototype = { }; // Parse.com https api request -function parseRequest(method, path, data, callback) { +function parseRequest(method, path, data, callback, contentType) { 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) { @@ -54,8 +100,14 @@ function parseRequest(method, path, data, callback) { break; case 'POST': case 'PUT': - body = JSON.stringify(data); + if(contentType){ + body = data; + headers['Content-type'] = contentType; + console.log('Sending data type: ' + contentType + ' of length: ' + body.length); + }else{ headers['Content-type'] = 'application/json'; + body = JSON.stringify(data); + } headers['Content-length'] = body.length; break; case 'DELETE': @@ -109,10 +161,15 @@ function parseRequest(method, path, data, callback) { }); }); + if(contentType) + { + body && req.write(body,'binary'); + }else{ body && req.write(body); + } req.end(); req.on('error', function (err) { callback && callback(err); }); -} +} \ No newline at end of file From af07af6173133d9fb141625f634fb634f09e8ca4 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Mon, 25 Jun 2012 22:16:16 -0400 Subject: [PATCH 02/95] added destroyFilesByUser and findCustom --- lib/Parse.js | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 600fd34..6ea3141 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -30,6 +30,15 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/' + className, { where: JSON.stringify(query) }, callback); } }, + + // get objects from classes that you create + findCustom: 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); + } + }, // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class getUser: function (userName, passWord, callback) { @@ -37,10 +46,10 @@ Parse.prototype = { }, // get an object belonging to a certain User - getFileByUser: function(userId, callback) { + getFileByUser: function(userId, className, callback) { queryString = 'where={"user":' + '"' + userId + '"' + '}' encodedString = encodeURIComponent(queryString); - parseRequest.call(this, 'GET', '/1/classes/contracts?' + encodedString, null, callback) + parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback) }, // insert an object into Parse @@ -49,28 +58,38 @@ Parse.prototype = { }, // update an object in the class store - update: function (className, objectId, object, callback) { - parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); + update: function (className, objectId, data, objectToUpdate, dataBody, callback) { + objectToUpdate = objectToUpdate; + dataBody = dataBody; + data = { objectToUpdate: dataBody } + parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback); }, - // update a User's email address + // update a User object's email address updateUserEmail: function(objectId, data, callback) { data = { email: data } parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) }, - // update a User's username + // update a User object's username* updateUserName: function(objectId, data, callback) { data = { username: data } parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) }, - // reset a User's password + // reset a User object's password passwordReset: function (data, callback) { data = { email: data } parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) }, + // because deleteFile does not remove objects from db, this hack replaces the username so that it doesn't show up in collections by user-predicate + destroyFilesByUser: function (objectId, className, username, data, callback) { + userObjectIdKey = userObjectIdKey; //the key for your user's objectId + data = { userObjectIdKey: data } + parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback) + }, + // delete a file. Note: file still shows up on the parse databrowser, but attempting to access it will result in a 401 deleteFile: function (fileName, callback) { parseRequest.call(this, 'DELETE', '/1/files/' + fileName, null, callback) From 068991fd42d053f2b2ec8fcccfaf22f57c1de895 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Mon, 25 Jun 2012 22:25:21 -0400 Subject: [PATCH 03/95] added two methods --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 6ea3141..75d96f3 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -84,7 +84,7 @@ Parse.prototype = { }, // because deleteFile does not remove objects from db, this hack replaces the username so that it doesn't show up in collections by user-predicate - destroyFilesByUser: function (objectId, className, username, data, callback) { + destroyFilesByUser: function (objectId, className, userObjectIdKey, data, callback) { userObjectIdKey = userObjectIdKey; //the key for your user's objectId data = { userObjectIdKey: data } parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback) From 41dcfbcaa72ac938358a10ad0cff37affd897f9b Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Wed, 27 Jun 2012 00:03:27 -0400 Subject: [PATCH 04/95] updated readme.md --- lib/Parse.js | 17 +++++++---------- readme.md | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 75d96f3..b624ab3 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -22,7 +22,7 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); }, - // get objects from class store + // get an object from the class store find: function (className, query, callback) { if (typeof query === 'string') { parseRequest.call(this, 'GET', '/1/' + className + '/' + query, null, callback); @@ -31,12 +31,12 @@ Parse.prototype = { } }, - // get objects from classes that you create - findCustom: function (className, query, callback) { + // get a collection of objects + findMany: function (className, query, callback) { if (typeof query === 'string') { - parseRequest.call(this, 'GET', '/1/classes' + className + '/' + query, null, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); } else { - parseRequest.call(this, 'GET', '/1/classes' + className, { where: JSON.stringify(query) }, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); } }, @@ -58,11 +58,8 @@ Parse.prototype = { }, // update an object in the class store - update: function (className, objectId, data, objectToUpdate, dataBody, callback) { - objectToUpdate = objectToUpdate; - dataBody = dataBody; - data = { objectToUpdate: dataBody } - parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback); + update: function (className, objectId, object, callback) { + parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); }, // update a User object's email address diff --git a/readme.md b/readme.md index c7912ea..9c235d1 100644 --- a/readme.md +++ b/readme.md @@ -35,7 +35,7 @@ examples ### find many // all Foo objects with foo = 'bar' - app.find('Foo', { foo: 'bar' }, function (err, response) { + app.findMany('Foo', { foo: 'bar' }, function (err, response) { console.log(response); }); From 611af015ed93032860cd860dfd963ca202eff48a Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Wed, 27 Jun 2012 23:26:26 -0400 Subject: [PATCH 05/95] updated deleteFileByUser --- lib/Parse.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index b624ab3..e4f6b1a 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -17,12 +17,12 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/classes/' + className, object, callback); }, - // add files + // add files insertFile: function(fileName, data, contentType, callback){ parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); }, - // get an object from the class store + // get an object from the class store find: function (className, query, callback) { if (typeof query === 'string') { parseRequest.call(this, 'GET', '/1/' + className + '/' + query, null, callback); @@ -31,7 +31,7 @@ Parse.prototype = { } }, - // get a collection of objects + // get a collection of objects findMany: function (className, query, callback) { if (typeof query === 'string') { parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); @@ -52,7 +52,7 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback) }, - // insert an object into Parse + // insert an object into Parse insertCustom: function (className, object, callback) { parseRequest.call(this, 'POST', '/1/' + className, object, callback); }, @@ -80,10 +80,9 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) }, - // because deleteFile does not remove objects from db, this hack replaces the username so that it doesn't show up in collections by user-predicate - destroyFilesByUser: function (objectId, className, userObjectIdKey, data, callback) { - userObjectIdKey = userObjectIdKey; //the key for your user's objectId - data = { userObjectIdKey: data } + // This hack replaces the username so that it doesn't show up in collections by user-predicate. Be sure to substitute 'user' with your key + destroyFilesByUser: function (objectId, className, data, callback) { + data = { user: data } parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback) }, From 8a3fe3833c4875dd81493385f538b92368bd96d2 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Wed, 27 Jun 2012 23:33:57 -0400 Subject: [PATCH 06/95] updated delete function --- lib/Parse.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index e4f6b1a..474bf4e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -79,20 +79,9 @@ Parse.prototype = { data = { email: data } parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) }, - - // This hack replaces the username so that it doesn't show up in collections by user-predicate. Be sure to substitute 'user' with your key - destroyFilesByUser: function (objectId, className, data, callback) { - data = { user: data } - parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, data, callback) - }, - - // delete a file. Note: file still shows up on the parse databrowser, but attempting to access it will result in a 401 - deleteFile: function (fileName, callback) { - parseRequest.call(this, 'DELETE', '/1/files/' + fileName, null, callback) - }, // remove an object from the class store - 'delete': function (className, objectId, callback) { + delete: function (className, objectId, callback) { parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); } }; From d500a69b9888a4b19ca78366e7cd7a8a19a9aa69 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Wed, 27 Jun 2012 23:48:23 -0400 Subject: [PATCH 07/95] updated readme --- readme.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/readme.md b/readme.md index 9c235d1..40768a3 100644 --- a/readme.md +++ b/readme.md @@ -25,6 +25,16 @@ examples console.log(response); }); +### insert a file + + // add a Foo object, { foo: 'bar' } + app.insertFile(fileName, data, fileType, function (err, response) { + fileLink = response.url + parseName = response.name + app.insert('Foo', { "foo" : fileLink, "bar" : parseName }, function(erro, res){ + }) + }); + ### find one // the Foo with id = 'someId' From a42a3d9f66b809968f27c47d278d17ab4a2b55d3 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Fri, 29 Jun 2012 22:42:07 -0400 Subject: [PATCH 08/95] updated npm --- readme.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 40768a3..8ba82b9 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ Node Parse API install ------- - npm install parse-api + npm install node-parse-api examples -------- @@ -27,10 +27,9 @@ examples ### insert a file - // add a Foo object, { foo: 'bar' } app.insertFile(fileName, data, fileType, function (err, response) { - fileLink = response.url - parseName = response.name + fileLink = response.url; + parseName = response.name; app.insert('Foo', { "foo" : fileLink, "bar" : parseName }, function(erro, res){ }) }); From cf2801421d0b82146d1b579774934db694e46747 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Fri, 29 Jun 2012 22:50:25 -0400 Subject: [PATCH 09/95] updated NPM --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f130dd0..ae7586c 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "parse-api", + "name": "node-parse-api", "description": "API for accessing Parse.com applications", "version": "0.1.0", - "author": "Chris Johnson ", - "repository": "git://github.com/tenorviol/node-parse-api", + "author": "Chris Johnson , Michael Leveton , Seth Gholson", + "repository": "git://github.com/leveton/node-parse-api", "main": "index", "engines": { "node": ">= 0.4.0" } } \ No newline at end of file From 3c09766ce3c9c801c6eba4277231ae007f84e2fc Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Fri, 29 Jun 2012 22:51:36 -0400 Subject: [PATCH 10/95] updated version --- npm-debug.log | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..95262f0 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,128 @@ +info it worked if it ends with ok +verbose cli [ 'node', '/home/ghilly/.nvm/v0.6.9/bin/npm', 'publish' ] +info using npm@1.1.0-3 +info using node@v0.6.9 +verbose config file /home/ghilly/.npmrc +verbose config file /home/ghilly/.nvm/v0.6.9/etc/npmrc +verbose config file /home/ghilly/.nvm/v0.6.9/lib/node_modules/npm/npmrc +verbose publish [ '.' ] +verbose caching /home/ghilly/Documents/node/node-parse-api/package.json +verbose loadDefaults node-parse-api@0.1.0 +info prepublish node-parse-api@0.1.0 +verbose cache add [ '.', null ] +silly cache add: name, spec, args [ undefined, '.', [ '.', null ] ] +verbose parsed url { pathname: '.', path: '.', href: '.' } +verbose caching package.json +verbose loadDefaults node-parse-api@0.1.0 +verbose pack /home/ghilly/Documents/node/node-parse-api +verbose pack /home/ghilly/Documents/node/node-parse-api /tmp/npm-1341024639569/1341024639568-0.9406838221475482/tmp.tgz +silly makeList /home/ghilly/Documents/node/node-parse-api +silly dir, dirLen [ '/home/ghilly/Documents/node/node-parse-api', 43 ] +verbose tarball /tmp/npm-1341024639569/1341024639568-0.9406838221475482/tmp.tgz +verbose parent /home/ghilly/Documents/node/node-parse-api +verbose mkdir (expected) error ENOENT, no such file or directory '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm' +verbose mkdir done: /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm 755 +verbose unpack_ uid, gid [ undefined, undefined ] +verbose unpackTarget /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package +silly gunzTarPerm modes [ '755', '644' ] +silly afterUntar undefined +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/package.json +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/makefile +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/readme.md +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/index.js +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/test +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/test/Parse.test.js +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/lib +silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/lib/Parse.js +verbose gunzed /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api +verbose rm'ed /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package +verbose renamed [ '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api', +verbose renamed '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/package' ] +verbose caching /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package/package.json +verbose loadDefaults node-parse-api@0.1.0 +verbose tarball contents [ 'tmp.tgz', 'package' ] +verbose from cache /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package/package.json +verbose pack /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package +verbose pack /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz +silly makeList /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package +silly dir, dirLen [ '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/package', +silly dir, dirLen 64 ] +verbose tarball /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz +verbose parent /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package +verbose mkdir (expected) error ENOENT, no such file or directory '/home/ghilly/.npm/node-parse-api/0.1.0/___package.npm' +verbose mkdir done: /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm 755 +verbose unpack_ uid, gid [ undefined, undefined ] +verbose unpackTarget /home/ghilly/.npm/node-parse-api/0.1.0/package +silly gunzTarPerm modes [ '755', '644' ] +silly afterUntar undefined +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/package.json +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/makefile +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/readme.md +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/index.js +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/test +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/test/Parse.test.js +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/lib +silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/lib/Parse.js +verbose gunzed /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package +verbose rm'ed /home/ghilly/.npm/node-parse-api/0.1.0/package +verbose renamed [ '/home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package', +verbose renamed '/home/ghilly/.npm/node-parse-api/0.1.0/package' ] +verbose caching /home/ghilly/.npm/node-parse-api/0.1.0/package/package.json +verbose loadDefaults node-parse-api@0.1.0 +silly updated sha bytes 2994 +info shasum 6d9fee3bc4cf199ab732ae29e0d414e16f91f103 +info shasum /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz +verbose from cache /home/ghilly/.npm/node-parse-api/0.1.0/package/package.json +verbose chmod /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz 644 +verbose chown [ '/home/ghilly/.npm/node-parse-api/0.1.0/package.tgz', +verbose chown 1000, +verbose chown 1000 ] +silly publish { name: 'node-parse-api', +silly publish description: 'API for accessing Parse.com applications', +silly publish version: '0.1.0', +silly publish author: { name: 'Chris Johnson', email: 'tenorviol@yahoo.com' }, +silly publish repository: +silly publish { type: 'git', +silly publish url: 'git://github.com/leveton/node-parse-api.git' }, +silly publish main: 'index', +silly publish engines: { node: '>= 0.4.0' }, +silly publish _npmUser: { name: 'leveton', email: 'mleveton@prepcloud.com' }, +silly publish _id: 'node-parse-api@0.1.0', +silly publish dependencies: {}, +silly publish devDependencies: {}, +silly publish optionalDependencies: {}, +silly publish _engineSupported: true, +silly publish _npmVersion: '1.1.0-3', +silly publish _nodeVersion: 'v0.6.9', +silly publish _defaultsLoaded: true, +silly publish dist: +silly publish { shasum: '6d9fee3bc4cf199ab732ae29e0d414e16f91f103', +silly publish tarball: 'http://registry.npmjs.org/node-parse-api/-/node-parse-api-0.1.0.tgz' } } +verbose raw, before any munging node-parse-api +verbose url resolving [ 'https://registry.npmjs.org/', './node-parse-api' ] +verbose url resolved https://registry.npmjs.org/node-parse-api +http PUT https://registry.npmjs.org/node-parse-api +http 409 https://registry.npmjs.org/node-parse-api +verbose raw, before any munging node-parse-api +verbose url resolving [ 'https://registry.npmjs.org/', './node-parse-api' ] +verbose url resolved https://registry.npmjs.org/node-parse-api +http GET https://registry.npmjs.org/node-parse-api +http 200 https://registry.npmjs.org/node-parse-api +info Already published node-parse-api@0.1.0 +verbose uploading bin dists [] +ERR! publish fail Cannot publish over existing version. +ERR! publish fail Bump the 'version' field, set the --force flag, or +ERR! publish fail npm unpublish 'node-parse-api@0.1.0' +ERR! publish fail and try again +ERR! +ERR! System Linux 2.6.38-15-generic +ERR! command "node" "/home/ghilly/.nvm/v0.6.9/bin/npm" "publish" +ERR! cwd /home/ghilly/Documents/node/node-parse-api +ERR! node -v v0.6.9 +ERR! npm -v 1.1.0-3 +ERR! code EPUBLISHCONFLICT +ERR! message publish fail +ERR! errno {} +verbose exit [ 1, true ] diff --git a/package.json b/package.json index ae7586c..927636a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "API for accessing Parse.com applications", - "version": "0.1.0", + "version": "0.1.1", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From a10a359b55af5a2ee6b7c8fd8a6ad6aeaa671113 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Sun, 1 Jul 2012 17:07:40 -0400 Subject: [PATCH 11/95] updated README --- readme.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/readme.md b/readme.md index 8ba82b9..998287b 100644 --- a/readme.md +++ b/readme.md @@ -59,3 +59,19 @@ examples app.delete('Foo', 'someId', function (err) { // nothing to see here }); + +### reset a password + + parse.passwordReset(userEmail, function(err, response){ + console.log(response); + }); + +### update User email + + parse.updateUserEmail(objectId, email, function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } + }); \ No newline at end of file From ce7ba92eafa50ded3fb20512598d5d9741b1ddf7 Mon Sep 17 00:00:00 2001 From: Michael Leveton Date: Sun, 8 Jul 2012 01:07:28 -0400 Subject: [PATCH 12/95] updated ReadMe --- readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 998287b..c2902e8 100644 --- a/readme.md +++ b/readme.md @@ -62,13 +62,15 @@ examples ### reset a password - parse.passwordReset(userEmail, function(err, response){ + //email is built into Parse's special User class + app.passwordReset(email, function(err, response){ console.log(response); }); ### update User email - parse.updateUserEmail(objectId, email, function(err, response){ + //email is built into Parse's special User class + app.updateUserEmail(objectId, email, function(err, response){ if (err) { console.log(err); } else { From 4fb3ad60a247632d92622b800197b515f4123ad8 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Wed, 12 Dec 2012 08:16:52 -0500 Subject: [PATCH 13/95] added insert installation method --- lib/Parse.js | 6 ++++++ readme.md | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 474bf4e..6f2f0b6 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -83,6 +83,12 @@ Parse.prototype = { // remove an object from the class store delete: function (className, objectId, callback) { parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); + }, + + // upload installation data + insertInstallationData: function (deviceType, deviceToken, callback) { + data = { deviceType: deviceType, deviceToken: deviceToken} + parseRequest.call(this, 'POST', '/1/installations/', data, callback); } }; diff --git a/readme.md b/readme.md index c2902e8..6d20c75 100644 --- a/readme.md +++ b/readme.md @@ -76,4 +76,15 @@ examples } else { console.log(response); } + }); + +### insert installation data + + //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. The other args are optional + app.insertInstallationData("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } }); \ No newline at end of file From 8451d77b2275d5b7ea80d527462634a4d422a914 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Thu, 13 Dec 2012 08:51:00 -0500 Subject: [PATCH 14/95] added timeZone and channels installations --- lib/Parse.js | 37 ++++++++++++++++++++++++++++++++++++- readme.md | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 6f2f0b6..327eba5 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -87,7 +87,42 @@ Parse.prototype = { // upload installation data insertInstallationData: function (deviceType, deviceToken, callback) { - data = { deviceType: deviceType, deviceToken: deviceToken} + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken } + } + else { + data = { deviceType: deviceType, installationId: deviceToken } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithTimeZone: function (deviceType, deviceToken, timeZone, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithChannels: function (deviceType, deviceToken, channels, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, channels: channels } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, channels: channels } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithTimeZoneAndChannels: function (deviceType, deviceToken, timeZone, channels, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone, channels: channels } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels } + } parseRequest.call(this, 'POST', '/1/installations/', data, callback); } }; diff --git a/readme.md b/readme.md index 6d20c75..ded81c2 100644 --- a/readme.md +++ b/readme.md @@ -80,11 +80,46 @@ examples ### insert installation data - //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. The other args are optional + //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. app.insertInstallationData("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", function(err, response){ if (err) { console.log(err); } else { console.log(response); } + }); + +### insert installation data with timeZone + + //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. + app.insertInstallationDataWithTimeZone("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } + }); + +### insert installation data with channels + + //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the channels array. + arr = ["news", "sports"]; + app.insertInstallationDataWithChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", arr, function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } + }); + +### insert installation data with timeZone and channels + + //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. 4th is the channels array. + arr = ["news", "sports"]; + app.insertInstallationDataWithTimeZoneAndChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", arr, function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } }); \ No newline at end of file From dd95f60ae221ac6a97964f4209773a5086c08b49 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Fri, 14 Dec 2012 08:06:16 -0500 Subject: [PATCH 15/95] updated package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 927636a..0901656 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "API for accessing Parse.com applications", - "version": "0.1.1", + "version": "0.1.3", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 8bab19acda85e4b07cb5ee1cc4d9a12c6ab8b579 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Fri, 14 Dec 2012 11:56:55 -0500 Subject: [PATCH 16/95] updated markdown --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ded81c2..581fdd2 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ examples ### setup - var Parse = require('parse-api').Parse; + var Parse = require('node-parse-api').Parse; var APP_ID = ...; var MASTER_KEY = ...; From c8583a2cac3751ea1926b0e347bb426db4678647 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Fri, 14 Dec 2012 12:02:46 -0500 Subject: [PATCH 17/95] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0901656..0283f06 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "API for accessing Parse.com applications", - "version": "0.1.3", + "version": "0.1.5", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 22746ada217168205aaf6bdf3f57fc9081466f86 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Thu, 10 Jan 2013 08:58:32 -0500 Subject: [PATCH 18/95] Added tenorviols fix for non-ascii character uploading bug --- .DS_Store | Bin 0 -> 6148 bytes lib/Parse.js | 19 ++++--------------- package.json | 4 ++-- 3 files changed, 6 insertions(+), 17 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f9f60d0a8f94f19a9f55d4bcbfeaf7866207ada5 GIT binary patch literal 6148 zcmeH~Jr2S!425mzfW*>~F$)La1`&c2Z~;_UkSZ}C_8gt(pM}DVD)cPbU+mOs`-Y|# z5#2wpJCR;QR&b+iElf<2FJ+XQ4A;kH9PangN^Xm!72v&0_H&z{0#twsPys4H1!kl` z9^|X_jGl>)LItS6JQT3+LxCG>vIYIqf#4$m*rDu(wa*e@u>x3=Er<$CqZN!+^)bZi z-VT<$t|nVB+C_8t(7dzS6a&*}7cEF&S{)2jfC@|$SVrF4`G16eoBt;*OsN1B_%j8x zJDd)Cyi}g8AFpTib5?EL;GkcQ@b(jc#E#+(+ztE17GO=bASy8a2)GOkRN$uyyZ{;| B5o7=W literal 0 HcmV?d00001 diff --git a/lib/Parse.js b/lib/Parse.js index 327eba5..3cbd7f6 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -145,15 +145,9 @@ function parseRequest(method, path, data, callback, contentType) { break; case 'POST': case 'PUT': - if(contentType){ - body = data; - headers['Content-type'] = contentType; - console.log('Sending data type: ' + contentType + ' of length: ' + body.length); - }else{ - headers['Content-type'] = 'application/json'; - body = JSON.stringify(data); - } - headers['Content-length'] = body.length; + body = typeof data === 'object' ? JSON.stringify(data) : data; + //headers['Content-length'] = body.length; + headers['Content-type'] = contentType || 'application/json'; break; case 'DELETE': headers['Content-length'] = 0; @@ -206,12 +200,7 @@ function parseRequest(method, path, data, callback, contentType) { }); }); - if(contentType) - { - body && req.write(body,'binary'); - }else{ - body && req.write(body); - } + body && req.write(body, contentType ? 'binary' : 'utf8'); req.end(); req.on('error', function (err) { diff --git a/package.json b/package.json index 0283f06..6750347 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", - "description": "API for accessing Parse.com applications", - "version": "0.1.5", + "description": "A Parse.com REST API client for Node.js", + "version": "0.1.7", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From c242dee75562bf4ac19cd030b57f20f06d93f02d Mon Sep 17 00:00:00 2001 From: Omar Al-Jadda Date: Fri, 11 Jan 2013 07:27:49 -0800 Subject: [PATCH 19/95] find: function needs /classes/ at the end --- lib/Parse.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 3cbd7f6..e51f513 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -25,9 +25,9 @@ Parse.prototype = { // get an object from the class store find: function (className, query, callback) { if (typeof query === 'string') { - parseRequest.call(this, 'GET', '/1/' + className + '/' + query, null, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); } else { - parseRequest.call(this, 'GET', '/1/' + className, { where: JSON.stringify(query) }, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); } }, @@ -206,4 +206,4 @@ function parseRequest(method, path, data, callback, contentType) { req.on('error', function (err) { callback && callback(err); }); -} \ No newline at end of file +} From 2f0c43f947321621d982f11895c0bdb7c2496266 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Tue, 12 Feb 2013 15:08:44 -0500 Subject: [PATCH 20/95] added roles, counting, and push notifications --- lib/Parse.js | 49 +++++++++++++++++++- readme.md | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 3 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index e51f513..524247f 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -33,7 +33,7 @@ Parse.prototype = { // get a collection of objects findMany: function (className, query, callback) { - if (typeof query === 'string') { + 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); @@ -124,6 +124,49 @@ Parse.prototype = { data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels } } parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + countObjects: function (className, query, callback) { + if (typeof(query) === "function") { + parseRequest.call(this, 'GET', '/1/classes/' + className, null, query); + } + 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); + } + }, + + insertRole: function (data, callback) { + parseRequest.call(this, 'POST', '/1/roles/', data, callback); + }, + + getRole: function (objectId, callback) { + parseRequest.call(this, 'GET', '/1/roles/' + objectId, null, callback); + }, + + getRoles: function (params, callback) { + if (typeof(params) === "function") { + parseRequest.call(this, 'GET', '/1/roles/', null, params); + } + if (typeof(params) === "string") { + parseRequest.call(this, 'GET', '/1/roles/' + params, null, callback); + } else { + params = JSON.stringify(params); + parseRequest.call(this, 'GET', '/1/roles/', params, callback); + } + }, + + updateRole: function (objectId, data, callback) { + parseRequest.call(this, 'PUT', '/1/roles/' + objectId, data, callback); + }, + + deleteRole: function (objectId, callback) { + parseRequest.call(this, 'DELETE', '/1/roles/' + objectId, callback); + }, + + sendPush: function (data, callback) { + parseRequest.call(this, 'POST', '/1/push/', data, callback); } }; @@ -178,6 +221,10 @@ function parseRequest(method, path, data, callback, contentType) { return callback(err); } + // if ((!err) && (res.statusCode === 200 || res.statusCode === 201)) { + // res.success = res.statusCode; + // } + var json = ''; res.setEncoding('utf8'); diff --git a/readme.md b/readme.md index 581fdd2..313aa36 100644 --- a/readme.md +++ b/readme.md @@ -18,13 +18,25 @@ examples var app = new Parse(APP_ID, MASTER_KEY); -### insert +### insert an object // add a Foo object, { foo: 'bar' } app.insert('Foo', { foo: 'bar' }, function (err, response) { console.log(response); }); +### insert a User + + app.insertCustom('users', { foo: 'bar' }, function (err, response) { + console.log(response); + }); + +### insert a User with GeoPoints + + app.insertCustom('users', { foo: 'bar', location: {__type: 'GeoPoint', latitude: , longitude: } }, function (err, response) { + console.log(response); + }); + ### insert a file app.insertFile(fileName, data, fileType, function (err, response) { @@ -48,6 +60,13 @@ examples console.log(response); }); +### count the number of objects + + //just use findMany, and call results.length on the response + app.findMany('Foo', { user: '' }, function (err, response) { + console.log(response.results.length); +}); + ### update app.update('Foo', 'someId', { foo: 'fubar' }, function (err, response) { @@ -122,4 +141,104 @@ examples } else { console.log(response); } - }); \ No newline at end of file + }); + +### create a role for a particular user + + //create a data object that links the user object's objectId to the role + +var data = { + name: 'Administrator', + ACL: { + "*": { + "read": true + } + }, + roles: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_Role", + "objectId": "" + } + ] + }, + users: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" + } + ] + } +}; + + app.insertRole(data, function(err, resp){ + console.log(resp); + }); + +### get a role + + //pass the role object's objectId + app.getRole("", function(err, resp){ + console.log(resp); + }); + +### update a role + //pass the objectId of the role, data contains the user's objectId + +var data = { + users: { + "__op": "RemoveRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" + } + ] + } +}; + + app.updateRole("", data, function(err, resp){ + console.log(resp); + }); + +### delete a role + + //pass the objectId of the role + app.deleteRole("", function(err, resp){ + + }); + +### get all the roles + + app.getRoles(function(err, resp){ //like so + console.log(resp); + + }); + +### get a role against a cetain param + +var params = { + where: { name: "Administrator" } +}; + + app.getRoles(params, function(err, resp){ + console.log(resp); + }); + +### send a push notification + +var notification = { + channels: [''], + data: { + alert: "sending too many push notifications is obnoxious" + } +}; + app.sendPush(notification, function(err, resp){ + console.log(resp); + }); \ No newline at end of file From 399ac61f27cc359866a21450d355ed6cb43e52c7 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Tue, 12 Feb 2013 15:14:34 -0500 Subject: [PATCH 21/95] Added roles, counting, and push notifications --- readme.md | 134 +++++++++++++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/readme.md b/readme.md index 313aa36..60e8e61 100644 --- a/readme.md +++ b/readme.md @@ -147,72 +147,72 @@ examples //create a data object that links the user object's objectId to the role -var data = { - name: 'Administrator', - ACL: { - "*": { - "read": true - } - }, - roles: { - "__op": "AddRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_Role", - "objectId": "" - } - ] - }, - users: { - "__op": "AddRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_User", - "objectId": "" + var data = { + name: 'Administrator', + ACL: { + "*": { + "read": true + } + }, + roles: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_Role", + "objectId": "" + } + ] + }, + users: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" + } + ] } - ] - } -}; + }; - app.insertRole(data, function(err, resp){ - console.log(resp); - }); + app.insertRole(data, function(err, resp){ + console.log(resp); + }); ### get a role - //pass the role object's objectId - app.getRole("", function(err, resp){ - console.log(resp); - }); + //pass the role object's objectId + app.getRole("", function(err, resp){ + console.log(resp); + }); ### update a role - //pass the objectId of the role, data contains the user's objectId - -var data = { - users: { - "__op": "RemoveRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_User", - "objectId": "" - } - ] - } -}; - - app.updateRole("", data, function(err, resp){ - console.log(resp); - }); + //pass the objectId of the role, data contains the user's objectId + + var data = { + users: { + "__op": "RemoveRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" + } + ] + } + }; + + app.updateRole("", data, function(err, resp){ + console.log(resp); + }); ### delete a role - //pass the objectId of the role - app.deleteRole("", function(err, resp){ + //pass the objectId of the role + app.deleteRole("", function(err, resp){ - }); + }); ### get all the roles @@ -223,22 +223,22 @@ var data = { ### get a role against a cetain param -var params = { - where: { name: "Administrator" } -}; + var params = { + where: { name: "Administrator" } + }; - app.getRoles(params, function(err, resp){ - console.log(resp); - }); + app.getRoles(params, function(err, resp){ + console.log(resp); + }); ### send a push notification -var notification = { - channels: [''], - data: { - alert: "sending too many push notifications is obnoxious" - } -}; + var notification = { + channels: [''], + data: { + alert: "sending too many push notifications is obnoxious" + } + }; app.sendPush(notification, function(err, resp){ console.log(resp); }); \ No newline at end of file From c2b6a3335c70d38d9f0866e7f3593e95b873dec6 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Tue, 12 Feb 2013 15:16:44 -0500 Subject: [PATCH 22/95] updated Readme --- readme.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 60e8e61..0834531 100644 --- a/readme.md +++ b/readme.md @@ -216,10 +216,9 @@ examples ### get all the roles - app.getRoles(function(err, resp){ //like so - console.log(resp); - - }); + app.getRoles(function(err, resp){ //like so + console.log(resp); + }); ### get a role against a cetain param @@ -239,6 +238,6 @@ examples alert: "sending too many push notifications is obnoxious" } }; - app.sendPush(notification, function(err, resp){ - console.log(resp); - }); \ No newline at end of file + app.sendPush(notification, function(err, resp){ + console.log(resp); + }); \ No newline at end of file From 8ab57b4a3dbca31bb0526e6b227a70dfd4a49274 Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Tue, 12 Feb 2013 15:19:32 -0500 Subject: [PATCH 23/95] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6750347..a4efbd2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.1.7", + "version": "0.1.9", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 8d7a969c5c3997e3bb1a637a2cf74c4c23b2b32e Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Thu, 14 Feb 2013 08:56:48 -0500 Subject: [PATCH 24/95] fixed readme --- readme.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 0834531..1283004 100644 --- a/readme.md +++ b/readme.md @@ -210,15 +210,11 @@ examples ### delete a role //pass the objectId of the role - app.deleteRole("", function(err, resp){ - - }); + app.deleteRole("", function(err, resp){}); ### get all the roles - app.getRoles(function(err, resp){ //like so - console.log(resp); - }); + app.getRoles(function(err, resp){}); ### get a role against a cetain param @@ -231,7 +227,8 @@ examples }); ### send a push notification - + + //The data param has to follow the data structure as described in the [Parse REST API](https://www.parse.com/docs/rest#push) var notification = { channels: [''], data: { From e0cacda6915432fee3492ecc7e6de020eeb2162b Mon Sep 17 00:00:00 2001 From: Leveton Date: Sat, 15 Jun 2013 12:46:20 -0400 Subject: [PATCH 25/95] updated content-length headers --- lib/Parse.js | 2 ++ package.json | 2 +- readme.md | 10 +++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 524247f..aafb26f 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -187,6 +187,8 @@ function parseRequest(method, path, data, callback, contentType) { } break; case 'POST': + body = typeof data === 'object' ? JSON.stringify(data) : data; + headers['Content-length'] = body.length; case 'PUT': body = typeof data === 'object' ? JSON.stringify(data) : data; //headers['Content-length'] = body.length; diff --git a/package.json b/package.json index a4efbd2..5ba9853 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.1.9", + "version": "0.2.0", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", diff --git a/readme.md b/readme.md index 1283004..3e034d9 100644 --- a/readme.md +++ b/readme.md @@ -237,4 +237,12 @@ examples }; app.sendPush(notification, function(err, resp){ console.log(resp); - }); \ No newline at end of file + }); + +### note on sending dates + + //when inserting a data, you must use the Parse date object structure, i.e.: + { + "__type": "Date", + "iso": new Date("", "", "").toJSON() + } \ No newline at end of file From e75d1c2806112eeab87b3846288ddc92a39506e8 Mon Sep 17 00:00:00 2001 From: Leveton Date: Fri, 21 Jun 2013 01:31:49 -0400 Subject: [PATCH 26/95] fixed PUT headers --- lib/Parse.js | 6 +-- npm-debug.log | 128 -------------------------------------------------- package.json | 2 +- 3 files changed, 4 insertions(+), 132 deletions(-) delete mode 100644 npm-debug.log diff --git a/lib/Parse.js b/lib/Parse.js index aafb26f..b5e685e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -187,11 +187,11 @@ function parseRequest(method, path, data, callback, contentType) { } break; case 'POST': - body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = body.length; + body = typeof data === 'object' ? JSON.stringify(data) : data; + headers['Content-length'] = body.length; case 'PUT': body = typeof data === 'object' ? JSON.stringify(data) : data; - //headers['Content-length'] = body.length; + headers['Content-length'] = body.length; headers['Content-type'] = contentType || 'application/json'; break; case 'DELETE': diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index 95262f0..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,128 +0,0 @@ -info it worked if it ends with ok -verbose cli [ 'node', '/home/ghilly/.nvm/v0.6.9/bin/npm', 'publish' ] -info using npm@1.1.0-3 -info using node@v0.6.9 -verbose config file /home/ghilly/.npmrc -verbose config file /home/ghilly/.nvm/v0.6.9/etc/npmrc -verbose config file /home/ghilly/.nvm/v0.6.9/lib/node_modules/npm/npmrc -verbose publish [ '.' ] -verbose caching /home/ghilly/Documents/node/node-parse-api/package.json -verbose loadDefaults node-parse-api@0.1.0 -info prepublish node-parse-api@0.1.0 -verbose cache add [ '.', null ] -silly cache add: name, spec, args [ undefined, '.', [ '.', null ] ] -verbose parsed url { pathname: '.', path: '.', href: '.' } -verbose caching package.json -verbose loadDefaults node-parse-api@0.1.0 -verbose pack /home/ghilly/Documents/node/node-parse-api -verbose pack /home/ghilly/Documents/node/node-parse-api /tmp/npm-1341024639569/1341024639568-0.9406838221475482/tmp.tgz -silly makeList /home/ghilly/Documents/node/node-parse-api -silly dir, dirLen [ '/home/ghilly/Documents/node/node-parse-api', 43 ] -verbose tarball /tmp/npm-1341024639569/1341024639568-0.9406838221475482/tmp.tgz -verbose parent /home/ghilly/Documents/node/node-parse-api -verbose mkdir (expected) error ENOENT, no such file or directory '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm' -verbose mkdir done: /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm 755 -verbose unpack_ uid, gid [ undefined, undefined ] -verbose unpackTarget /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package -silly gunzTarPerm modes [ '755', '644' ] -silly afterUntar undefined -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/package.json -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/makefile -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/readme.md -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/index.js -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/test -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/test/Parse.test.js -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/lib -silly asyncMap in gTP /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api/lib/Parse.js -verbose gunzed /tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api -verbose rm'ed /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package -verbose renamed [ '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/___package.npm/node-parse-api', -verbose renamed '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/package' ] -verbose caching /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package/package.json -verbose loadDefaults node-parse-api@0.1.0 -verbose tarball contents [ 'tmp.tgz', 'package' ] -verbose from cache /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package/package.json -verbose pack /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package -verbose pack /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz -silly makeList /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package -silly dir, dirLen [ '/tmp/npm-1341024639569/1341024639568-0.9406838221475482/package', -silly dir, dirLen 64 ] -verbose tarball /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz -verbose parent /tmp/npm-1341024639569/1341024639568-0.9406838221475482/package -verbose mkdir (expected) error ENOENT, no such file or directory '/home/ghilly/.npm/node-parse-api/0.1.0/___package.npm' -verbose mkdir done: /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm 755 -verbose unpack_ uid, gid [ undefined, undefined ] -verbose unpackTarget /home/ghilly/.npm/node-parse-api/0.1.0/package -silly gunzTarPerm modes [ '755', '644' ] -silly afterUntar undefined -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/package.json -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/makefile -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/readme.md -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/index.js -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/test -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/test/Parse.test.js -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/lib -silly asyncMap in gTP /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package/lib/Parse.js -verbose gunzed /home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package -verbose rm'ed /home/ghilly/.npm/node-parse-api/0.1.0/package -verbose renamed [ '/home/ghilly/.npm/node-parse-api/0.1.0/___package.npm/package', -verbose renamed '/home/ghilly/.npm/node-parse-api/0.1.0/package' ] -verbose caching /home/ghilly/.npm/node-parse-api/0.1.0/package/package.json -verbose loadDefaults node-parse-api@0.1.0 -silly updated sha bytes 2994 -info shasum 6d9fee3bc4cf199ab732ae29e0d414e16f91f103 -info shasum /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz -verbose from cache /home/ghilly/.npm/node-parse-api/0.1.0/package/package.json -verbose chmod /home/ghilly/.npm/node-parse-api/0.1.0/package.tgz 644 -verbose chown [ '/home/ghilly/.npm/node-parse-api/0.1.0/package.tgz', -verbose chown 1000, -verbose chown 1000 ] -silly publish { name: 'node-parse-api', -silly publish description: 'API for accessing Parse.com applications', -silly publish version: '0.1.0', -silly publish author: { name: 'Chris Johnson', email: 'tenorviol@yahoo.com' }, -silly publish repository: -silly publish { type: 'git', -silly publish url: 'git://github.com/leveton/node-parse-api.git' }, -silly publish main: 'index', -silly publish engines: { node: '>= 0.4.0' }, -silly publish _npmUser: { name: 'leveton', email: 'mleveton@prepcloud.com' }, -silly publish _id: 'node-parse-api@0.1.0', -silly publish dependencies: {}, -silly publish devDependencies: {}, -silly publish optionalDependencies: {}, -silly publish _engineSupported: true, -silly publish _npmVersion: '1.1.0-3', -silly publish _nodeVersion: 'v0.6.9', -silly publish _defaultsLoaded: true, -silly publish dist: -silly publish { shasum: '6d9fee3bc4cf199ab732ae29e0d414e16f91f103', -silly publish tarball: 'http://registry.npmjs.org/node-parse-api/-/node-parse-api-0.1.0.tgz' } } -verbose raw, before any munging node-parse-api -verbose url resolving [ 'https://registry.npmjs.org/', './node-parse-api' ] -verbose url resolved https://registry.npmjs.org/node-parse-api -http PUT https://registry.npmjs.org/node-parse-api -http 409 https://registry.npmjs.org/node-parse-api -verbose raw, before any munging node-parse-api -verbose url resolving [ 'https://registry.npmjs.org/', './node-parse-api' ] -verbose url resolved https://registry.npmjs.org/node-parse-api -http GET https://registry.npmjs.org/node-parse-api -http 200 https://registry.npmjs.org/node-parse-api -info Already published node-parse-api@0.1.0 -verbose uploading bin dists [] -ERR! publish fail Cannot publish over existing version. -ERR! publish fail Bump the 'version' field, set the --force flag, or -ERR! publish fail npm unpublish 'node-parse-api@0.1.0' -ERR! publish fail and try again -ERR! -ERR! System Linux 2.6.38-15-generic -ERR! command "node" "/home/ghilly/.nvm/v0.6.9/bin/npm" "publish" -ERR! cwd /home/ghilly/Documents/node/node-parse-api -ERR! node -v v0.6.9 -ERR! npm -v 1.1.0-3 -ERR! code EPUBLISHCONFLICT -ERR! message publish fail -ERR! errno {} -verbose exit [ 1, true ] diff --git a/package.json b/package.json index 5ba9853..15ce876 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.0", + "version": "0.2.2", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From e6d5bd07281c782badab339787af9a266261b81f Mon Sep 17 00:00:00 2001 From: Anderson Miller Date: Fri, 13 Sep 2013 16:52:15 -0400 Subject: [PATCH 27/95] adding the function addRelation as well as a (very basic) test for the function --- lib/Parse.js | 8 +++++++- test/Parse.test.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index b5e685e..48e8d7e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -76,7 +76,7 @@ Parse.prototype = { // reset a User object's password passwordReset: function (data, callback) { - data = { email: data } + data = { email: data } parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) }, @@ -136,6 +136,12 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); } }, + + addRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { + data = {} + data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; + parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); + }, insertRole: function (data, callback) { parseRequest.call(this, 'POST', '/1/roles/', data, callback); diff --git a/test/Parse.test.js b/test/Parse.test.js index dd2bef0..545ced4 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -15,8 +15,11 @@ if (!application_id || !master_key) { // global objects to test against var parse = new Parse(application_id, master_key); var className = 'NodeParseApiTest'; +var className2 = 'NodeParseApiRelationTest'; var object = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type +var object2 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type var stub; +var stub2; exports.insert = function (assert) { parse.insert(className, object, function (err, response) { @@ -25,8 +28,22 @@ exports.insert = function (assert) { stub = response; assert.done(); }); + + }; +exports['insert 2'] = function(assert){ + parse.insert(className2,object2, function(err,response){ + err && console.log(err); + assert.ok(response); + stub2 = response; + assert.done(); + }); +} + + + + exports.find = function (assert) { parse.find(className, stub.objectId, function (err, response) { assert.equal(object.foo, response.foo); @@ -44,6 +61,9 @@ exports['find many'] = function (assert) { }); }; + + + exports.update = function (assert) { do { var num = Math.floor(Math.random() * 10000); @@ -57,6 +77,15 @@ exports.update = function (assert) { }); }; + +exports['add relation'] = function (assert) { + parse.addRelation("secondObject",className,stub.objectId,className2,stub2.objectId, function (err ,response){ + err && console.log(response); + assert.ok(response); + assert.done(); + }); +} + exports['delete'] = function (assert) { parse['delete'](className, stub.objectId, function (err) { err && console.log(err); From 9ab98674bcd4ee99d5985d8bc54c6193b56d7b13 Mon Sep 17 00:00:00 2001 From: Anderson Miller Date: Fri, 13 Sep 2013 19:22:41 -0400 Subject: [PATCH 28/95] adding a removeRelation function --- lib/Parse.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 48e8d7e..9d7a70a 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -142,6 +142,13 @@ Parse.prototype = { data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); }, + + removeRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { + data = {} + data[relationName] = { __op:"RemoveRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; + parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); + }, + insertRole: function (data, callback) { parseRequest.call(this, 'POST', '/1/roles/', data, callback); From 08d3edb736e5e9b104b9c0e6dc6f815494d8e471 Mon Sep 17 00:00:00 2001 From: Anderson Miller Date: Fri, 13 Sep 2013 19:35:25 -0400 Subject: [PATCH 29/95] adding a getInclusive and a getMany inclusive for grabbing relational objects in queries as well as base objects --- lib/Parse.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 9d7a70a..c2fceea 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -31,6 +31,11 @@ Parse.prototype = { } }, + findInclusive: function (className, query, include, callback) { + query['include'] = include; + parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); + }, + // get a collection of objects findMany: function (className, query, callback) { if (typeof(query) === 'string') { @@ -40,6 +45,11 @@ Parse.prototype = { } }, + findManyInclusive: function (className, query, include, callback) { + query['include'] = include; + parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); + }, + // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class getUser: function (userName, passWord, callback) { parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); From 762e49d7cc79a514c06ce891aab4e1bbdc487551 Mon Sep 17 00:00:00 2001 From: Anderson Miller Date: Mon, 16 Sep 2013 15:06:37 -0400 Subject: [PATCH 30/95] adding batch requests --- lib/Parse.js | 11 +++-------- test/Parse.test.js | 13 +++++++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index c2fceea..a0d4754 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -31,11 +31,6 @@ Parse.prototype = { } }, - findInclusive: function (className, query, include, callback) { - query['include'] = include; - parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); - }, - // get a collection of objects findMany: function (className, query, callback) { if (typeof(query) === 'string') { @@ -45,9 +40,9 @@ Parse.prototype = { } }, - findManyInclusive: function (className, query, include, callback) { - query['include'] = include; - parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); + // do a batch of requests at once + batch: function (requests,callback) { + parseRequest.call(this,'POST','/1/batch',{requests:requests},callback); }, // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class diff --git a/test/Parse.test.js b/test/Parse.test.js index 545ced4..7d8254c 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -18,6 +18,8 @@ var className = 'NodeParseApiTest'; var className2 = 'NodeParseApiRelationTest'; var object = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type var object2 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type +var object3 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type +var object4 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type var stub; var stub2; @@ -42,8 +44,6 @@ exports['insert 2'] = function(assert){ } - - exports.find = function (assert) { parse.find(className, stub.objectId, function (err, response) { assert.equal(object.foo, response.foo); @@ -86,6 +86,15 @@ exports['add relation'] = function (assert) { }); } +exports['batch'] = function (assert) { + requests = [{"method":"PUT","path": "/1/classes/"+className+'/'+stub.objectId, "body": object3},{"method":"PUT","path": "/1/classes/"+className2+'/'+stub2.objectId, "body": object4} ]; + parse.batch(requests, function(err,response){ + err && console.log(response); + assert.ok(response); + assert.done(); + }); +} + exports['delete'] = function (assert) { parse['delete'](className, stub.objectId, function (err) { err && console.log(err); From 4ce3d0041156977a15d588b25dafc3b90dfef46b Mon Sep 17 00:00:00 2001 From: Anderson Miller Date: Fri, 11 Oct 2013 15:45:07 -0400 Subject: [PATCH 31/95] adding a limit/order bit to the findMany query --- lib/Parse.js | 9 +++++++++ test/Parse.test.js | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index a0d4754..501045e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -39,6 +39,15 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); } }, + + // get a collection of objects + findMany: function (className, query,order,limit, callback) { + if (typeof(query) === 'string') { + parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); + } else { + parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); + } + }, // do a batch of requests at once batch: function (requests,callback) { diff --git a/test/Parse.test.js b/test/Parse.test.js index 7d8254c..ddf04ed 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -51,6 +51,15 @@ exports.find = function (assert) { }); }; +exports['find with limit and order'] = function (assert) { + parse.findMany(className,{},'-createdAt',1, function (err1,res1){ + assert.equal(1, res1.results.length); + assert.equal(stub.objectId, res1.results[0].objectId); + assert.equal(stub.createdAt, res1.results[0].createdAt); + assert.done(); + }); +} + exports['find many'] = function (assert) { parse.find(className, stub, function (err, response) { assert.equal(1, response.results.length); From 5e8821888a19c891810396659dc7cbb2b68397a4 Mon Sep 17 00:00:00 2001 From: Akhmad Fathonih Date: Mon, 13 Jan 2014 01:47:43 +0900 Subject: [PATCH 32/95] Use utf8-safe method to calculate body length Parse thrown HTTP 400 when we send utf8 content. Thus, use Buffer.byteLength(body) to correctly calculate body.length --- lib/Parse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 501045e..91336e0 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -215,10 +215,10 @@ function parseRequest(method, path, data, callback, contentType) { break; case 'POST': body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = body.length; + headers['Content-length'] = Buffer.byteLength(body); case 'PUT': body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = body.length; + headers['Content-length'] = Buffer.byteLength(body); headers['Content-type'] = contentType || 'application/json'; break; case 'DELETE': From 118ee748293d541538896ed5dafb18b7182354a8 Mon Sep 17 00:00:00 2001 From: Leveton Date: Wed, 19 Feb 2014 18:49:27 -0500 Subject: [PATCH 33/95] updated to 0.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15ce876..79609e0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.2", + "version": "0.2.4", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 19322c0828082401997ba0cb34f8f7c2da1e9af0 Mon Sep 17 00:00:00 2001 From: Leveton Date: Sun, 16 Mar 2014 11:38:42 -0400 Subject: [PATCH 34/95] updates --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 79609e0..e9b7f0b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.4", + "version": "0.2.6", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", "engines": { "node": ">= 0.4.0" } -} \ No newline at end of file +} From 0f3725b99945572f29733e27f3790538e29f2a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Gald=C3=AAncio?= Date: Tue, 25 Mar 2014 14:45:19 -0300 Subject: [PATCH 35/95] Problems with querystring.escape findMany The query string was escaped, never creating a GET request properly formatted. Also, if I called findMany without the argument limit, the request would be wrong too, since this cannot be empty and MUST be an integer. --- lib/Parse.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 91336e0..9aa8cc3 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -1,5 +1,7 @@ var qs = require('querystring'); +qs.escape = function(q){ return q; }; + module.exports = Parse; function Parse(application_id, master_key) { @@ -45,7 +47,9 @@ Parse.prototype = { if (typeof(query) === 'string') { parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); } else { - parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); + data = {order: order, where: JSON.stringify(query)}; + if (limit) data.limit = limit; + parseRequest.call(this, 'GET', '/1/classes/' + className, data, callback); } }, From 7adb90afe9ef15ef49cd4d03d0ca2ca972b8ea17 Mon Sep 17 00:00:00 2001 From: Christian Monaghan Date: Sun, 20 Apr 2014 09:27:56 -0700 Subject: [PATCH 36/95] Clarified how to use 'findMany' to return all items in a class --- readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.md b/readme.md index 3e034d9..3ce427b 100644 --- a/readme.md +++ b/readme.md @@ -60,6 +60,12 @@ examples console.log(response); }); + + // all Foo objects + app.findMany('Foo', '', function (err, response) { + console.log(response); + }): + ### count the number of objects //just use findMany, and call results.length on the response From ed245b1ebcce078191b6fa02c8b5df2c6cc0196b Mon Sep 17 00:00:00 2001 From: Christian Monaghan Date: Sun, 20 Apr 2014 10:05:47 -0700 Subject: [PATCH 37/95] Removed duplication of findMany function --- lib/Parse.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 9aa8cc3..27684f7 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -34,22 +34,20 @@ Parse.prototype = { }, // get a collection of objects - findMany: 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); + findMany: function (className, query, order, limit, callback) { + // also supports the following api - findMany: function (className, query, callback) + + // if only 3 arguments exist, third argument is the callback, order and limit are undefined + if (arguments.length === 3) { + var callback = order; + var order = undefined; + var limit = undefined; } - }, - - // get a collection of objects - findMany: function (className, query,order,limit, callback) { + if (typeof(query) === 'string') { parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); } else { - data = {order: order, where: JSON.stringify(query)}; - if (limit) data.limit = limit; - parseRequest.call(this, 'GET', '/1/classes/' + className, data, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); } }, From ac1a161e44b3717226816b001c63d44879deb3eb Mon Sep 17 00:00:00 2001 From: Rodrigo Martell Date: Thu, 8 May 2014 15:09:21 +1000 Subject: [PATCH 38/95] Fix readme.md typo Very minor formatting fix for `findMany`. --- readme.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 3ce427b..4c5ea15 100644 --- a/readme.md +++ b/readme.md @@ -68,10 +68,10 @@ examples ### count the number of objects - //just use findMany, and call results.length on the response - app.findMany('Foo', { user: '' }, function (err, response) { - console.log(response.results.length); -}); + // just use findMany, and call results.length on the response + app.findMany('Foo', { user: '' }, function (err, response) { + console.log(response.results.length); + }); ### update @@ -251,4 +251,4 @@ examples { "__type": "Date", "iso": new Date("", "", "").toJSON() - } \ No newline at end of file + } From e4663a28bf20536c11a4768c3a427948b0b1fdbb Mon Sep 17 00:00:00 2001 From: Leveton Date: Sat, 10 May 2014 13:14:24 -0400 Subject: [PATCH 39/95] updated npm --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9b7f0b..b7c4e31 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.6", + "version": "0.2.8", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 34378abcbefaa416b775b786f18b84c9af9ed541 Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Mon, 26 May 2014 14:50:19 +0200 Subject: [PATCH 40/95] Whitespace cleaning --- lib/Parse.js | 40 ++++++++++++++++++++-------------------- readme.md | 32 ++++++++++++++++---------------- test/Parse.test.js | 4 ++-- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 27684f7..a3f020a 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -13,17 +13,17 @@ 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); }, - + // add files insertFile: function(fileName, data, contentType, callback){ parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); }, - + // get an object from the class store find: function (className, query, callback) { if (typeof query === 'string') { @@ -50,17 +50,17 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); } }, - + // do a batch of requests at once batch: function (requests,callback) { parseRequest.call(this,'POST','/1/batch',{requests:requests},callback); }, - + // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class getUser: function (userName, passWord, callback) { parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); }, - + // get an object belonging to a certain User getFileByUser: function(userId, className, callback) { queryString = 'where={"user":' + '"' + userId + '"' + '}' @@ -100,7 +100,7 @@ Parse.prototype = { delete: function (className, objectId, callback) { parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); }, - + // upload installation data insertInstallationData: function (deviceType, deviceToken, callback) { if (deviceType === 'ios'){ @@ -141,7 +141,7 @@ Parse.prototype = { } parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, - + countObjects: function (className, query, callback) { if (typeof(query) === "function") { parseRequest.call(this, 'GET', '/1/classes/' + className, null, query); @@ -152,13 +152,13 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/classes/' + className, { where: JSON.stringify(query) }, callback); } }, - + addRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { data = {} data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); }, - + removeRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { data = {} data[relationName] = { __op:"RemoveRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; @@ -206,9 +206,9 @@ function parseRequest(method, path, data, callback, contentType) { Authorization: auth, Connection: 'Keep-alive' }; - + var body = null; - + switch (method) { case 'GET': if (data) { @@ -229,7 +229,7 @@ function parseRequest(method, path, data, callback, contentType) { default: throw new Error('Unknown method, "' + method + '"'); } - + var options = { host: this._api_host, port: this._api_port, @@ -237,12 +237,12 @@ function parseRequest(method, path, data, callback, contentType) { 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; @@ -251,18 +251,18 @@ function parseRequest(method, path, data, callback, contentType) { err.body = body; return callback(err); } - + // if ((!err) && (res.statusCode === 200 || res.statusCode === 201)) { // res.success = res.statusCode; // } var json = ''; res.setEncoding('utf8'); - + res.on('data', function (chunk) { json += chunk; }); - + res.on('end', function () { var err = null; var data = null; @@ -272,12 +272,12 @@ function parseRequest(method, path, data, callback, contentType) { } callback(err, data); }); - + res.on('close', function (err) { callback(err); }); }); - + body && req.write(body, contentType ? 'binary' : 'utf8'); req.end(); diff --git a/readme.md b/readme.md index 4c5ea15..53eb9f7 100644 --- a/readme.md +++ b/readme.md @@ -12,10 +12,10 @@ examples ### setup var Parse = require('node-parse-api').Parse; - + var APP_ID = ...; var MASTER_KEY = ...; - + var app = new Parse(APP_ID, MASTER_KEY); ### insert an object @@ -25,13 +25,13 @@ examples console.log(response); }); -### insert a User +### insert a User app.insertCustom('users', { foo: 'bar' }, function (err, response) { console.log(response); }); -### insert a User with GeoPoints +### insert a User with GeoPoints app.insertCustom('users', { foo: 'bar', location: {__type: 'GeoPoint', latitude: , longitude: } }, function (err, response) { console.log(response); @@ -87,14 +87,14 @@ examples ### reset a password - //email is built into Parse's special User class + //email is built into Parse's special User class app.passwordReset(email, function(err, response){ console.log(response); }); ### update User email - //email is built into Parse's special User class + //email is built into Parse's special User class app.updateUserEmail(objectId, email, function(err, response){ if (err) { console.log(err); @@ -150,7 +150,7 @@ examples }); ### create a role for a particular user - + //create a data object that links the user object's objectId to the role var data = { @@ -189,7 +189,7 @@ examples ### get a role //pass the role object's objectId - app.getRole("", function(err, resp){ + app.getRole("", function(err, resp){ console.log(resp); }); @@ -206,16 +206,16 @@ examples "objectId": "" } ] - } + } }; - app.updateRole("", data, function(err, resp){ + app.updateRole("", data, function(err, resp){ console.log(resp); }); ### delete a role - - //pass the objectId of the role + + //pass the objectId of the role app.deleteRole("", function(err, resp){}); ### get all the roles @@ -225,7 +225,7 @@ examples ### get a role against a cetain param var params = { - where: { name: "Administrator" } + where: { name: "Administrator" } }; app.getRoles(params, function(err, resp){ @@ -233,7 +233,7 @@ examples }); ### send a push notification - + //The data param has to follow the data structure as described in the [Parse REST API](https://www.parse.com/docs/rest#push) var notification = { channels: [''], @@ -246,9 +246,9 @@ examples }); ### note on sending dates - + //when inserting a data, you must use the Parse date object structure, i.e.: { - "__type": "Date", + "__type": "Date", "iso": new Date("", "", "").toJSON() } diff --git a/test/Parse.test.js b/test/Parse.test.js index ddf04ed..fcd88ff 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -30,7 +30,7 @@ exports.insert = function (assert) { stub = response; assert.done(); }); - + }; @@ -78,7 +78,7 @@ exports.update = function (assert) { 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); From a159c49f85f367c5db76db2b6d728a7f33f734dd Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Mon, 26 May 2014 14:50:35 +0200 Subject: [PATCH 41/95] Add `nodeunit` to dependencies --- package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index b7c4e31..56cd185 100644 --- a/package.json +++ b/package.json @@ -5,5 +5,13 @@ "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", - "engines": { "node": ">= 0.4.0" } + "scripts":{ + "test":"nodeunit" + }, + "engines": { + "node": ">= 0.4.0" + }, + "devDependencies": { + "nodeunit": "~0.9.0" + } } From 4e6b0eb3ec2c75b95130949dd8f8a542bcbd82a1 Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Mon, 26 May 2014 14:50:54 +0200 Subject: [PATCH 42/95] Add `deleteAll` method, test, doc --- lib/Parse.js | 18 ++++++++++++++++++ readme.md | 6 ++++++ test/Parse.test.js | 11 +++++++++++ 3 files changed, 35 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index a3f020a..eadebf7 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -196,6 +196,14 @@ Parse.prototype = { sendPush: function (data, callback) { parseRequest.call(this, 'POST', '/1/push/', data, callback); + }, + + deleteAll: function(modelName, callback){ + var that = this; + this.findMany(modelName, '', function(err, response){ + var requests = toDeleteOps(modelName, response.results); + that.batch(requests, callback); + }); } }; @@ -285,3 +293,13 @@ function parseRequest(method, path, data, callback, contentType) { callback && callback(err); }); } + +function toDeleteOps(className, objects){ + return objects.map(function(object){ + return { + method: 'DELETE', + path: '/1/classes/' + className + '/' + object.objectId, + body: {} + } + }); +} diff --git a/readme.md b/readme.md index 53eb9f7..9028fca 100644 --- a/readme.md +++ b/readme.md @@ -85,6 +85,12 @@ examples // nothing to see here }); +### deleteAll + + app.deleteAll('Foo', function (err) { + // nothing to see here + }); + ### reset a password //email is built into Parse's special User class diff --git a/test/Parse.test.js b/test/Parse.test.js index fcd88ff..f1c3c4a 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -114,3 +114,14 @@ exports['delete'] = function (assert) { }); }); }; + +exports['delete all'] = function(assert){ + parse.insert(className2,object2, function(err,response){ + parse.deleteAll(className2, function(){ + parse.findMany(className2, '', function(err, response){ + assert.equal(0, response.results.length); + assert.done(); + }); + }); + }); +} From f27c8ac2e20cf7458531d05263d44550ee809ec7 Mon Sep 17 00:00:00 2001 From: Zachary Tratar Date: Thu, 24 Jul 2014 20:19:37 -0700 Subject: [PATCH 43/95] Added new functions to use DeviceToken and update InstalationData with channels --- lib/Parse.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index eadebf7..f7d87a7 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -142,6 +142,27 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, + updateInstallationDataChannels: function(objectId, channels, callback) { + parseRequest.call(this, 'PUT', '/1/installations/' + objectId, { + channels: channels + }, callback); + }, + + getInstallationDataForDeviceToken: function(deviceToken, callback) { + parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); + }, + + insertOrUpdateInstallationDataWithChannels: function(deviceType, deviceToken, channels, callback) { + var that = this; + this.getInstallationDataForDeviceToken(deviceToken, function(err, results) { + if (!err && results.results.length) { + that.updateInstallationDataChannels(results.results[0].objectId, channels); + return; + } + that.insertInstallationDataWithChannels(deviceType, deviceToken, channels, callback); + }); + }, + countObjects: function (className, query, callback) { if (typeof(query) === "function") { parseRequest.call(this, 'GET', '/1/classes/' + className, null, query); From b1f62a689230dece4637a608650927e077208e46 Mon Sep 17 00:00:00 2001 From: "Kody J. Peterson" Date: Fri, 15 Aug 2014 17:05:29 -0400 Subject: [PATCH 44/95] Support for "include" When retrieving objects that have pointers to children, you can fetch child objects by using the include option. --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index eadebf7..4622aa3 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -220,7 +220,7 @@ function parseRequest(method, path, data, callback, contentType) { switch (method) { case 'GET': if (data) { - path += '?' + qs.stringify(data); + path += (path.indexOf("?") == -1 ? '?' : '&') + qs.stringify(data); } break; case 'POST': From 8ee6e85ea261522877c09491230130f8f980aad7 Mon Sep 17 00:00:00 2001 From: Leveton Date: Sat, 16 Aug 2014 17:23:57 -0400 Subject: [PATCH 45/95] updated version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56cd185..06567cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.8", + "version": "0.2.9", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 1569452f1b4665efdcdf155648b8685a8dd98d77 Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Sun, 17 Aug 2014 16:10:00 -0400 Subject: [PATCH 46/95] Add and ignore .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + 2 files changed, 1 insertion(+) delete mode 100644 .DS_Store create mode 100644 .gitignore diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index f9f60d0a8f94f19a9f55d4bcbfeaf7866207ada5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzfW*>~F$)La1`&c2Z~;_UkSZ}C_8gt(pM}DVD)cPbU+mOs`-Y|# z5#2wpJCR;QR&b+iElf<2FJ+XQ4A;kH9PangN^Xm!72v&0_H&z{0#twsPys4H1!kl` z9^|X_jGl>)LItS6JQT3+LxCG>vIYIqf#4$m*rDu(wa*e@u>x3=Er<$CqZN!+^)bZi z-VT<$t|nVB+C_8t(7dzS6a&*}7cEF&S{)2jfC@|$SVrF4`G16eoBt;*OsN1B_%j8x zJDd)Cyi}g8AFpTib5?EL;GkcQ@b(jc#E#+(+ztE17GO=bASy8a2)GOkRN$uyyZ{;| B5o7=W diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store From 1be193fffd4abb2a94a6ac461b253a06eeb609b9 Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Sun, 17 Aug 2014 16:12:04 -0400 Subject: [PATCH 47/95] Add a more real example of a user insert --- readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 9028fca..b770641 100644 --- a/readme.md +++ b/readme.md @@ -27,7 +27,10 @@ examples ### insert a User - app.insertCustom('users', { foo: 'bar' }, function (err, response) { + app.insertCustom('users', { + username: 'tom@j.com', + password: 'wow' + }, function (err, response) { console.log(response); }); From e17a7e546d6aa5aefe5d0d64ab7617565243d3a7 Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Sun, 17 Aug 2014 16:12:15 -0400 Subject: [PATCH 48/95] Update install instructions for fork --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index b770641..66764bb 100644 --- a/readme.md +++ b/readme.md @@ -4,8 +4,8 @@ Node Parse API install ------- - npm install node-parse-api - + npm install Leventon/node-parse-api + examples -------- From 211f57d0df13e253d1a84bb8dff46ae134857b64 Mon Sep 17 00:00:00 2001 From: Christoffer Niska Date: Wed, 27 Aug 2014 13:49:00 -0700 Subject: [PATCH 49/95] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 66764bb..1f7bba4 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ Node Parse API install ------- - npm install Leventon/node-parse-api + npm install node-parse-api examples -------- From e883de0b16e85016d9502f92f95cb8ff7aa22b3f Mon Sep 17 00:00:00 2001 From: "Kody J. Peterson" Date: Tue, 30 Sep 2014 22:55:06 -0400 Subject: [PATCH 50/95] Fix 400 error on findMany It seems now parse does not allow the limit to be ''. So, making it 9999 should solve this?? I hate to make it a static number, maybe make it a larger number? --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index d3d6813..addce1b 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -41,7 +41,7 @@ Parse.prototype = { if (arguments.length === 3) { var callback = order; var order = undefined; - var limit = undefined; + var limit = 9999; } if (typeof(query) === 'string') { From 488e01e906d4673ac419e9f2553a9748b3f23c98 Mon Sep 17 00:00:00 2001 From: Leveton Date: Mon, 6 Oct 2014 22:19:42 -0400 Subject: [PATCH 51/95] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06567cb..af5dd70 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.2.9", + "version": "0.3.0", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From f7f3b722b1ae779680e497e266a6c20c82e4cd5b Mon Sep 17 00:00:00 2001 From: Charles Julian Knight Date: Mon, 27 Oct 2014 22:26:20 -0400 Subject: [PATCH 52/95] Added Date functions --- lib/Parse.js | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index addce1b..8d98bb4 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -228,6 +228,37 @@ Parse.prototype = { } }; + +function reformatDatesToParse(object){ + if(typeof object !== 'object') return object; + for( var key in object){ + if(object[key] instanceof Date){ + object[key] = { + "__type": "Date", + "iso": object[key].toISOString() + } + }else if(typeof object[key] === 'object'){ + object[key] = reformatDatesToParse(object[key]); + } + } + return object; +} + +function reformatDatesFromParse(object){ + if(typeof object !== 'object') return object; + for( var key in object){ + if(typeof object[key]==='object'){ + if(object[key]["__type"] && object[key]["__type"]==="Date"){ + object[key] = new Date(object[key]["iso"]); + }else{ + object[key] = reformatDatesFromParse(object[key]); + } + } + } + return object; +} + + // Parse.com https api request function parseRequest(method, path, data, callback, contentType) { var auth = 'Basic ' + new Buffer(this._application_id + ':' + this._master_key).toString('base64'); @@ -238,6 +269,11 @@ function parseRequest(method, path, data, callback, contentType) { var body = null; + //convert javascript date objects to parse format + if(typeof data === 'object'){ + data = reformatDates(data); + } + switch (method) { case 'GET': if (data) { @@ -296,7 +332,7 @@ function parseRequest(method, path, data, callback, contentType) { var err = null; var data = null; try { - var data = JSON.parse(json); + var data = reformatDatesFromParse(JSON.parse(json)); } catch (err) { } callback(err, data); From 4476be2422820f813c2d5e4e7cd2c02cfac13bb8 Mon Sep 17 00:00:00 2001 From: Charles Julian Knight Date: Mon, 27 Oct 2014 22:31:20 -0400 Subject: [PATCH 53/95] stupid typos. Should have made a test case --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 8d98bb4..a2b0954 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -271,7 +271,7 @@ function parseRequest(method, path, data, callback, contentType) { //convert javascript date objects to parse format if(typeof data === 'object'){ - data = reformatDates(data); + data = reformatDatesToParse(data); } switch (method) { From 5a211a83ad1ca5c8ddf54266232edbb888e38fe7 Mon Sep 17 00:00:00 2001 From: Leveton Date: Tue, 28 Oct 2014 23:06:14 -0400 Subject: [PATCH 54/95] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af5dd70..27e5f4d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.0", + "version": "0.3.1", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 35a9906699e0c32dc45a2c8a9b7c68dd71061d2a Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 3 Nov 2014 23:46:40 -0800 Subject: [PATCH 55/95] Override `querystring.escape` only locally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In my opinion, Node’s global `querystring.escape` is just poor API design. Since Node modules are cached in memory, overwriting `querystring.escape` will overwrite it for every other client of that module which can lead to subtle, hard to find bugs. In my case, HTML emails using `querystring.stringify` to escape query string parameters started being truncated due to unescaped `&` once I added `node-parse-api` as a dependency. Workaround: Overwrite `querystring.escape`, use `querystring.stringify`, and then restore `querystring.escape` to original implementation. I filed a bug against Node.js core here: https://github.com/joyent/node/issues/8672 --- lib/Parse.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index a2b0954..1fe1709 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -1,6 +1,5 @@ var qs = require('querystring'); -qs.escape = function(q){ return q; }; module.exports = Parse; @@ -277,7 +276,13 @@ function parseRequest(method, path, data, callback, contentType) { switch (method) { case 'GET': if (data) { + // Avoid globally overriding `querystring.escape`: + // http://nodejs.org/api/querystring.html#querystring_querystring_escape + var originalEscape = qs.escape; + qs.escape = function(q){ return q; }; path += (path.indexOf("?") == -1 ? '?' : '&') + qs.stringify(data); + qs.escape = originalEscape; + } break; case 'POST': From 464c134af3a69dce57a754e6353bf5beda4d785d Mon Sep 17 00:00:00 2001 From: Leveton Date: Thu, 20 Nov 2014 01:27:48 -0500 Subject: [PATCH 56/95] version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27e5f4d..74901f2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.1", + "version": "0.3.2", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From c187165d016f24379e41d44f336d512f9c4b4ebd Mon Sep 17 00:00:00 2001 From: Leveton Date: Thu, 20 Nov 2014 16:43:56 -0500 Subject: [PATCH 57/95] version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 74901f2..9ac3051 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.2", + "version": "0.3.3", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "repository": "git://github.com/leveton/node-parse-api", "main": "index", From 522b0efe63182fdd37f7526834da03a63145c408 Mon Sep 17 00:00:00 2001 From: KlimMalgin Date: Thu, 25 Dec 2014 23:06:16 +0500 Subject: [PATCH 58/95] Add run cloud functions --- lib/Parse.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 1fe1709..40b4db5 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -77,6 +77,11 @@ Parse.prototype = { parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); }, + // run cloud function + cloudRun: function (functionName, params, callback) { + parseRequest.call(this, 'POST', '/1/functions/' + functionName, params, callback); + }, + // update a User object's email address updateUserEmail: function(objectId, data, callback) { data = { email: data } From 30a5e842172dbae46cafd24672c7e1e91fed689b Mon Sep 17 00:00:00 2001 From: Leveton Date: Sat, 24 Jan 2015 12:30:31 -0500 Subject: [PATCH 59/95] 0.3.4 --- .gitignore | 4 ++++ lib/Parse.js | 33 +++++++++++++++++---------------- makefile | 2 +- package.json | 19 +++++++++++++++---- test/Parse.test.js | 14 ++++++++++++++ 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index e43b0f9..5ecf4a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ +# Mac OS X .DS_Store + +# npm +/node_modules/ diff --git a/lib/Parse.js b/lib/Parse.js index 1fe1709..d72d61e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -313,19 +313,6 @@ function parseRequest(method, path, data, callback, contentType) { 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); - } - - // if ((!err) && (res.statusCode === 200 || res.statusCode === 201)) { - // res.success = res.statusCode; - // } - var json = ''; res.setEncoding('utf8'); @@ -334,13 +321,27 @@ function parseRequest(method, path, data, callback, contentType) { }); res.on('end', function () { - var err = null; var data = null; + try { - var data = reformatDatesFromParse(JSON.parse(json)); + data = reformatDatesFromParse(JSON.parse(json)); } catch (err) { + return callback(err); } - callback(err, data); + + if (res.statusCode < 200 || res.statusCode >= 300) { + var message = data.error ? data.error + ' (Code: ' + data.code + ')' : + 'HTTP error' + res.statusCode; + var err = new Error(message); + err.code = data.code; + err.arguments = arguments; + err.type = res.statusCode; + err.options = options; + err.body = body; + return callback(err); + } + + callback(null, data); }); res.on('close', function (err) { diff --git a/makefile b/makefile index 95ac4b7..17fc7b2 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ test: nodeunit nodeunit: - nodeunit test/Parse.test.js + ./node_modules/.bin/nodeunit test/Parse.test.js diff --git a/package.json b/package.json index 9ac3051..8807e39 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,24 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.3", + "version": "0.3.4", "author": "Chris Johnson , Michael Leveton , Seth Gholson", - "repository": "git://github.com/leveton/node-parse-api", + "contributors": [ + "Seth Gholson", + "Daniel Gasienica " + ], "main": "index", - "scripts":{ - "test":"nodeunit" + "scripts": { + "test": "nodeunit" }, + "repository": "https://github.com/leveton/node-parse-api", + "keywords": [ + "parse", + "mbaas", + "rest", + "push notifications", + "api" + ], "engines": { "node": ">= 0.4.0" }, diff --git a/test/Parse.test.js b/test/Parse.test.js index f1c3c4a..e9c8ee1 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -125,3 +125,17 @@ exports['delete all'] = function(assert){ }); }); } + +exports['push notification error'] = function (assert) { + parse.sendPush({ + channels: ['foobar'], + data2: { + alert: 'test message' + } + }, function (error, result) { + assert.ok(error); + assert.equal(result, null); + assert.equal(error.message, 'Missing the push data. (Code: 115)'); + assert.done(); + }); +} From e3c9cec7ff6410109af10373baa94b8af9cdeb3b Mon Sep 17 00:00:00 2001 From: Leveton Date: Sat, 7 Feb 2015 15:17:12 -0500 Subject: [PATCH 60/95] merged pull request #14 --- lib/Parse.js | 665 ++++++++++++++++++++++++--------------------------- package.json | 6 +- readme.md | 15 +- 3 files changed, 331 insertions(+), 355 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 826a8cf..288fe94 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -1,373 +1,338 @@ var qs = require('querystring'); +qs.escape = function(q){ return q; }; module.exports = Parse; -function Parse(application_id, master_key) { - this._application_id = application_id; - this._master_key = master_key; +function Parse(options_or_application_id, master_key) { + this._options = {} + if(master_key){ + this._options.app_id = options_or_application_id; + this._options.master_key = master_key; + }else{ + this._options = options_or_application_id; + } } 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); - }, - - // add files - insertFile: function(fileName, data, contentType, callback){ - parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); - }, - - // get an object from the 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); - } - }, - - // get a collection of objects - findMany: function (className, query, order, limit, callback) { - // also supports the following api - findMany: function (className, query, callback) - - // if only 3 arguments exist, third argument is the callback, order and limit are undefined - if (arguments.length === 3) { - var callback = order; - var order = undefined; - var limit = 9999; - } - - if (typeof(query) === 'string') { - parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); - } else { - parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); - } - }, - - // do a batch of requests at once - batch: function (requests,callback) { - parseRequest.call(this,'POST','/1/batch',{requests:requests},callback); - }, - - // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class - getUser: function (userName, passWord, callback) { - parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); - }, - - // get an object belonging to a certain User - getFileByUser: function(userId, className, callback) { - queryString = 'where={"user":' + '"' + userId + '"' + '}' - encodedString = encodeURIComponent(queryString); - parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback) - }, - - // insert an object into Parse - insertCustom: function (className, object, callback) { - parseRequest.call(this, 'POST', '/1/' + className, object, callback); - }, - - // update an object in the class store - update: function (className, objectId, object, callback) { - parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); - }, - - // run cloud function - cloudRun: function (functionName, params, callback) { - parseRequest.call(this, 'POST', '/1/functions/' + functionName, params, callback); - }, - - // update a User object's email address - updateUserEmail: function(objectId, data, callback) { - data = { email: data } - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) - }, - - // update a User object's username* - updateUserName: function(objectId, data, callback) { - data = { username: data } - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) - }, - - // reset a User object's password - passwordReset: function (data, callback) { - data = { email: data } - parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) - }, - - // remove an object from the class store - delete: function (className, objectId, callback) { - parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); - }, - - // upload installation data - insertInstallationData: function (deviceType, deviceToken, callback) { - if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken } - } - else { - data = { deviceType: deviceType, installationId: deviceToken } - } - parseRequest.call(this, 'POST', '/1/installations/', data, callback); - }, - - insertInstallationDataWithTimeZone: function (deviceType, deviceToken, timeZone, callback) { - if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone } - } - else { - data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone } - } - parseRequest.call(this, 'POST', '/1/installations/', data, callback); - }, - - insertInstallationDataWithChannels: function (deviceType, deviceToken, channels, callback) { - if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, channels: channels } - } - else { - data = { deviceType: deviceType, installationId: deviceToken, channels: channels } - } - parseRequest.call(this, 'POST', '/1/installations/', data, callback); - }, - - insertInstallationDataWithTimeZoneAndChannels: function (deviceType, deviceToken, timeZone, channels, callback) { - if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone, channels: channels } - } - else { - data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels } - } - parseRequest.call(this, 'POST', '/1/installations/', data, callback); - }, - - updateInstallationDataChannels: function(objectId, channels, callback) { - parseRequest.call(this, 'PUT', '/1/installations/' + objectId, { - channels: channels - }, callback); - }, - - getInstallationDataForDeviceToken: function(deviceToken, callback) { - parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); - }, - - insertOrUpdateInstallationDataWithChannels: function(deviceType, deviceToken, channels, callback) { - var that = this; - this.getInstallationDataForDeviceToken(deviceToken, function(err, results) { - if (!err && results.results.length) { - that.updateInstallationDataChannels(results.results[0].objectId, channels); - return; - } - that.insertInstallationDataWithChannels(deviceType, deviceToken, channels, callback); - }); - }, - - countObjects: function (className, query, callback) { - if (typeof(query) === "function") { - parseRequest.call(this, 'GET', '/1/classes/' + className, null, query); - } - 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); + _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); + }, + + // add files + insertFile: function(fileName, data, contentType, callback){ + parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); + }, + + // get an object from the 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); + } + }, + + // get a collection of objects + findMany: function (className, query, order, limit, callback) { + // also supports the following api - findMany: function (className, query, callback) + + // if only 3 arguments exist, third argument is the callback, order and limit are undefined + if (arguments.length === 3) { + var callback = order; + var order = undefined; + var limit = 9999; + } + + if (typeof(query) === 'string') { + parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); + } else { + parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); + } + }, + + // do a batch of requests at once + batch: function (requests,callback) { + parseRequest.call(this,'POST','/1/batch',{requests:requests},callback); + }, + + // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class + getUser: function (userName, passWord, callback) { + parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); + }, + + // get an object belonging to a certain User + getFileByUser: function(userId, className, callback) { + queryString = 'where={"user":' + '"' + userId + '"' + '}' + encodedString = encodeURIComponent(queryString); + parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback) + }, + + // insert an object into Parse + insertCustom: function (className, object, callback) { + parseRequest.call(this, 'POST', '/1/' + className, object, callback); + }, + + // update an object in the class store + update: function (className, objectId, object, callback) { + parseRequest.call(this, 'PUT', '/1/classes/' + className + '/' + objectId, object, callback); + }, + + // update a User object's email address + updateUserEmail: function(objectId, data, callback) { + data = { email: data } + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + }, + + // update a User object's username* + updateUserName: function(objectId, data, callback) { + data = { username: data } + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + }, + + // reset a User object's password + passwordReset: function (data, callback) { + data = { email: data } + parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) + }, + + // remove an object from the class store + delete: function (className, objectId, callback) { + parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); + }, + + // upload installation data + insertInstallationData: function (deviceType, deviceToken, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken } + } + else { + data = { deviceType: deviceType, installationId: deviceToken } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithTimeZone: function (deviceType, deviceToken, timeZone, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithChannels: function (deviceType, deviceToken, channels, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, channels: channels } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, channels: channels } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + insertInstallationDataWithTimeZoneAndChannels: function (deviceType, deviceToken, timeZone, channels, callback) { + if (deviceType === 'ios'){ + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone, channels: channels } + } + else { + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels } + } + parseRequest.call(this, 'POST', '/1/installations/', data, callback); + }, + + updateInstallationDataChannels: function(objectId, channels, callback) { + parseRequest.call(this, 'PUT', '/1/installations/' + objectId, { + channels: channels + }, callback); + }, + + getInstallationDataForDeviceToken: function(deviceToken, callback) { + parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); + }, + + insertOrUpdateInstallationDataWithChannels: function(deviceType, deviceToken, channels, callback) { + var that = this; + this.getInstallationDataForDeviceToken(deviceToken, function(err, results) { + if (!err && results.results.length) { + that.updateInstallationDataChannels(results.results[0].objectId, channels); + return; + } + that.insertInstallationDataWithChannels(deviceType, deviceToken, channels, callback); + }); + }, + + countObjects: function (className, query, callback) { + if (typeof(query) === "function") { + parseRequest.call(this, 'GET', '/1/classes/' + className, null, query); + } + 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); + } + }, + + addRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { + data = {} + data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; + parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); + }, + + removeRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { + data = {} + data[relationName] = { __op:"RemoveRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; + parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); + }, + + + insertRole: function (data, callback) { + parseRequest.call(this, 'POST', '/1/roles/', data, callback); + }, + + getRole: function (objectId, callback) { + parseRequest.call(this, 'GET', '/1/roles/' + objectId, null, callback); + }, + + getRoles: function (params, callback) { + if (typeof(params) === "function") { + parseRequest.call(this, 'GET', '/1/roles/', null, params); + } + if (typeof(params) === "string") { + parseRequest.call(this, 'GET', '/1/roles/' + params, null, callback); + } else { + params = JSON.stringify(params); + parseRequest.call(this, 'GET', '/1/roles/', params, callback); + } + }, + + updateRole: function (objectId, data, callback) { + parseRequest.call(this, 'PUT', '/1/roles/' + objectId, data, callback); + }, + + deleteRole: function (objectId, callback) { + parseRequest.call(this, 'DELETE', '/1/roles/' + objectId, callback); + }, + + sendPush: function (data, callback) { + parseRequest.call(this, 'POST', '/1/push/', data, callback); + }, + + deleteAll: function(modelName, callback){ + var that = this; + this.findMany(modelName, '', function(err, response){ + var requests = toDeleteOps(modelName, response.results); + that.batch(requests, callback); + }); } - }, - - addRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { - data = {} - data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; - parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); - }, - - removeRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { - data = {} - data[relationName] = { __op:"RemoveRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; - parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); - }, - - - insertRole: function (data, callback) { - parseRequest.call(this, 'POST', '/1/roles/', data, callback); - }, - - getRole: function (objectId, callback) { - parseRequest.call(this, 'GET', '/1/roles/' + objectId, null, callback); - }, - - getRoles: function (params, callback) { - if (typeof(params) === "function") { - parseRequest.call(this, 'GET', '/1/roles/', null, params); - } - if (typeof(params) === "string") { - parseRequest.call(this, 'GET', '/1/roles/' + params, null, callback); - } else { - params = JSON.stringify(params); - parseRequest.call(this, 'GET', '/1/roles/', params, callback); - } - }, - - updateRole: function (objectId, data, callback) { - parseRequest.call(this, 'PUT', '/1/roles/' + objectId, data, callback); - }, - - deleteRole: function (objectId, callback) { - parseRequest.call(this, 'DELETE', '/1/roles/' + objectId, callback); - }, - - sendPush: function (data, callback) { - parseRequest.call(this, 'POST', '/1/push/', data, callback); - }, - - deleteAll: function(modelName, callback){ - var that = this; - this.findMany(modelName, '', function(err, response){ - var requests = toDeleteOps(modelName, response.results); - that.batch(requests, callback); - }); - } }; - -function reformatDatesToParse(object){ - if(typeof object !== 'object') return object; - for( var key in object){ - if(object[key] instanceof Date){ - object[key] = { - "__type": "Date", - "iso": object[key].toISOString() - } - }else if(typeof object[key] === 'object'){ - object[key] = reformatDatesToParse(object[key]); - } - } - return object; -} - -function reformatDatesFromParse(object){ - if(typeof object !== 'object') return object; - for( var key in object){ - if(typeof object[key]==='object'){ - if(object[key]["__type"] && object[key]["__type"]==="Date"){ - object[key] = new Date(object[key]["iso"]); - }else{ - object[key] = reformatDatesFromParse(object[key]); - } - } - } - return object; -} - - // Parse.com https api request function parseRequest(method, path, data, callback, contentType) { - var auth = 'Basic ' + new Buffer(this._application_id + ':' + this._master_key).toString('base64'); - var headers = { - Authorization: auth, - Connection: 'Keep-alive' - }; - - var body = null; - - //convert javascript date objects to parse format - if(typeof data === 'object'){ - data = reformatDatesToParse(data); - } - - switch (method) { - case 'GET': - if (data) { - // Avoid globally overriding `querystring.escape`: - // http://nodejs.org/api/querystring.html#querystring_querystring_escape - var originalEscape = qs.escape; - qs.escape = function(q){ return q; }; - path += (path.indexOf("?") == -1 ? '?' : '&') + qs.stringify(data); - qs.escape = originalEscape; - - } - break; - case 'POST': - body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = Buffer.byteLength(body); - case 'PUT': - body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = Buffer.byteLength(body); - headers['Content-type'] = contentType || 'application/json'; - 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; + var headers = { + Connection: 'Keep-alive' + }; + + if(this._options.master_key){ + var auth = 'Basic ' + new Buffer(this._options.app_id + ':' + this._options.master_key).toString('base64'); + headers.Authorization = auth; + }else if(this._options.api_key){ + headers['X-Parse-Application-Id'] = this._options.app_id; + headers['X-Parse-REST-API-Key'] = this._options.api_key; } - var json = ''; - res.setEncoding('utf8'); - - res.on('data', function (chunk) { - json += chunk; - }); - res.on('end', function () { - var data = null; - - try { - data = reformatDatesFromParse(JSON.parse(json)); - } catch (err) { - return callback(err); - } - - if (res.statusCode < 200 || res.statusCode >= 300) { - var message = data.error ? data.error + ' (Code: ' + data.code + ')' : - 'HTTP error' + res.statusCode; - var err = new Error(message); - err.code = data.code; - err.arguments = arguments; - err.type = res.statusCode; - err.options = options; - err.body = body; - return callback(err); - } - - callback(null, data); - }); + var body = null; + + switch (method) { + case 'GET': + if (data) { + path += (path.indexOf("?") == -1 ? '?' : '&') + qs.stringify(data); + } + break; + case 'POST': + body = typeof data === 'object' ? JSON.stringify(data) : data; + headers['Content-length'] = Buffer.byteLength(body); + case 'PUT': + body = typeof data === 'object' ? JSON.stringify(data) : data; + headers['Content-length'] = Buffer.byteLength(body); + headers['Content-type'] = contentType || 'application/json'; + break; + case 'DELETE': + headers['Content-length'] = 0; + break; + default: + throw new Error('Unknown method, "' + method + '"'); + } - res.on('close', function (err) { - callback(err); + 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); + } + + // if ((!err) && (res.statusCode === 200 || res.statusCode === 201)) { + // res.success = res.statusCode; + // } + + 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, contentType ? 'binary' : 'utf8'); - req.end(); + body && req.write(body, contentType ? 'binary' : 'utf8'); + req.end(); - req.on('error', function (err) { - callback && callback(err); - }); + req.on('error', function (err) { + callback && callback(err); + }); } function toDeleteOps(className, objects){ - return objects.map(function(object){ - return { - method: 'DELETE', - path: '/1/classes/' + className + '/' + object.objectId, - body: {} - } - }); -} + return objects.map(function(object){ + return { + method: 'DELETE', + path: '/1/classes/' + className + '/' + object.objectId, + body: {} + } + }); +} \ No newline at end of file diff --git a/package.json b/package.json index 8807e39..f665eb5 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.4", + "version": "0.3.5", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ - "Seth Gholson", - "Daniel Gasienica " + "Daniel Gasienica ", + "Jakub Knejzlík" ], "main": "index", "scripts": { diff --git a/readme.md b/readme.md index 1f7bba4..abb5de5 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ install examples -------- -### setup +### setup with MASTER_KEY (old way) var Parse = require('node-parse-api').Parse; @@ -18,6 +18,17 @@ examples var app = new Parse(APP_ID, MASTER_KEY); +### setup with API_KEY (new way) + + var Parse = require('node-parse-api').Parse; + + var options = { + app_id:'...', + api_key:'...' // master_key:'...' could be used too + } + + var app = new Parse(options); + ### insert an object // add a Foo object, { foo: 'bar' } @@ -260,4 +271,4 @@ examples { "__type": "Date", "iso": new Date("", "", "").toJSON() - } + } \ No newline at end of file From d8d47d99c42deb31cae9ad505f98a71700a69506 Mon Sep 17 00:00:00 2001 From: Leveton Date: Thu, 5 Mar 2015 16:13:32 -0500 Subject: [PATCH 61/95] added MIT License --- readme.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index abb5de5..d670d22 100644 --- a/readme.md +++ b/readme.md @@ -271,4 +271,16 @@ examples { "__type": "Date", "iso": new Date("", "", "").toJSON() - } \ No newline at end of file + } + +# License + +node-parse-api is available under the MIT license. + +Copyright © 2015 Mike Leveton and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From 6cb28069c62a9f5982c7eaa18d685aa0166e9d1d Mon Sep 17 00:00:00 2001 From: Barrington Haynes Date: Wed, 18 Mar 2015 14:31:09 +0000 Subject: [PATCH 62/95] Added getInstallationData --- lib/Parse.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 288fe94..cd9973f 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -153,6 +153,10 @@ Parse.prototype = { }, callback); }, + getInstallationData: function(callback) { + parseRequest.call(this, 'GET', '/1/installations, null, callback); + }, + getInstallationDataForDeviceToken: function(deviceToken, callback) { parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); }, @@ -335,4 +339,4 @@ function toDeleteOps(className, objects){ body: {} } }); -} \ No newline at end of file +} From 22e554bb33463045853350201b96be6454f0c226 Mon Sep 17 00:00:00 2001 From: Barrington Haynes Date: Wed, 18 Mar 2015 14:36:03 +0000 Subject: [PATCH 63/95] Typo --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index cd9973f..49b9331 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -154,7 +154,7 @@ Parse.prototype = { }, getInstallationData: function(callback) { - parseRequest.call(this, 'GET', '/1/installations, null, callback); + parseRequest.call(this, 'GET', '/1/installations', null, callback); }, getInstallationDataForDeviceToken: function(deviceToken, callback) { From 429d4db0d88c21615325b4373a247c60ec909d0d Mon Sep 17 00:00:00 2001 From: Joe Bruggeman Date: Fri, 10 Apr 2015 17:12:58 -0400 Subject: [PATCH 64/95] add skip functionality to findMany --- lib/Parse.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 49b9331..a384836 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -6,10 +6,10 @@ module.exports = Parse; function Parse(options_or_application_id, master_key) { this._options = {} - if(master_key){ + if (master_key) { this._options.app_id = options_or_application_id; this._options.master_key = master_key; - }else{ + } else { this._options = options_or_application_id; } } @@ -39,7 +39,7 @@ Parse.prototype = { }, // get a collection of objects - findMany: function (className, query, order, limit, callback) { + findMany: function (className, query, order, limit, skip, callback) { // also supports the following api - findMany: function (className, query, callback) // if only 3 arguments exist, third argument is the callback, order and limit are undefined @@ -49,10 +49,18 @@ Parse.prototype = { var limit = 9999; } + // if only 5 arguments exist, fifth argument is the callback, skip is undefined + if (arguments.length === 5) { + var callback = skip; + skip = undefined; + } + if (typeof(query) === 'string') { parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); + } else if (skip !== undefined) { + parseRequest.call(this, 'GET', '/1/classes/' + className, { limit: limit, order:order, skip:skip, where: JSON.stringify(query) }, callback); } else { - parseRequest.call(this, 'GET', '/1/classes/' + className, {limit: limit, order:order, where: JSON.stringify(query) }, callback); + parseRequest.call(this, 'GET', '/1/classes/' + className, { limit: limit, order:order, where: JSON.stringify(query) }, callback); } }, From 3aab2e62cc43dbf628145d9ecaf328a71ef74889 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 10:56:21 +0200 Subject: [PATCH 65/95] Fixes some lint errors --- lib/Parse.js | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index a384836..bafdb81 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -5,7 +5,7 @@ qs.escape = function(q){ return q; }; module.exports = Parse; function Parse(options_or_application_id, master_key) { - this._options = {} + this._options = {}; if (master_key) { this._options.app_id = options_or_application_id; this._options.master_key = master_key; @@ -44,14 +44,14 @@ Parse.prototype = { // if only 3 arguments exist, third argument is the callback, order and limit are undefined if (arguments.length === 3) { - var callback = order; - var order = undefined; - var limit = 9999; + callback = order; + order = undefined; + limit = 9999; } // if only 5 arguments exist, fifth argument is the callback, skip is undefined if (arguments.length === 5) { - var callback = skip; + callback = skip; skip = undefined; } @@ -76,9 +76,9 @@ Parse.prototype = { // get an object belonging to a certain User getFileByUser: function(userId, className, callback) { - queryString = 'where={"user":' + '"' + userId + '"' + '}' + queryString = 'where={"user":' + '"' + userId + '"' + '}'; encodedString = encodeURIComponent(queryString); - parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback) + parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback); }, // insert an object into Parse @@ -93,20 +93,20 @@ Parse.prototype = { // update a User object's email address updateUserEmail: function(objectId, data, callback) { - data = { email: data } - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + data = { email: data }; + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); }, // update a User object's username* updateUserName: function(objectId, data, callback) { - data = { username: data } - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback) + data = { username: data }; + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); }, // reset a User object's password passwordReset: function (data, callback) { - data = { email: data } - parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback) + data = { email: data }; + parseRequest.call(this, 'POST', '/1/requestPasswordReset/', data, callback); }, // remove an object from the class store @@ -117,40 +117,40 @@ Parse.prototype = { // upload installation data insertInstallationData: function (deviceType, deviceToken, callback) { if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken } + data = { deviceType: deviceType, deviceToken: deviceToken }; } else { - data = { deviceType: deviceType, installationId: deviceToken } + data = { deviceType: deviceType, installationId: deviceToken }; } parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, insertInstallationDataWithTimeZone: function (deviceType, deviceToken, timeZone, callback) { if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone } + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone }; } else { - data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone } + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone }; } parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, insertInstallationDataWithChannels: function (deviceType, deviceToken, channels, callback) { if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, channels: channels } + data = { deviceType: deviceType, deviceToken: deviceToken, channels: channels }; } else { - data = { deviceType: deviceType, installationId: deviceToken, channels: channels } + data = { deviceType: deviceType, installationId: deviceToken, channels: channels }; } parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, insertInstallationDataWithTimeZoneAndChannels: function (deviceType, deviceToken, timeZone, channels, callback) { if (deviceType === 'ios'){ - data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone, channels: channels } + data = { deviceType: deviceType, deviceToken: deviceToken, timeZone: timeZone, channels: channels }; } else { - data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels } + data = { deviceType: deviceType, installationId: deviceToken, timeZone: timeZone, channels: channels }; } parseRequest.call(this, 'POST', '/1/installations/', data, callback); }, @@ -192,13 +192,13 @@ Parse.prototype = { }, addRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { - data = {} + data = {}; data[relationName] = { __op:"AddRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); }, removeRelation: function( relationName, className1, objectId1, className2, objectId2, callback) { - data = {} + data = {}; data[relationName] = { __op:"RemoveRelation",objects:[{__type:"Pointer",className:className2,objectId:objectId2}]}; parseRequest.call(this,'PUT','/1/classes/' + className1+'/'+objectId1,data,callback); }, @@ -345,6 +345,6 @@ function toDeleteOps(className, objects){ method: 'DELETE', path: '/1/classes/' + className + '/' + object.objectId, body: {} - } + }; }); } From 73a0046d523fa89c6294a4f74abc489384ea56bc Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 11:08:47 +0200 Subject: [PATCH 66/95] Uses Parse error object instead of custom error Parse error object contains more information about what went wrong --- lib/Parse.js | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index bafdb81..20bbf9d 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -296,19 +296,6 @@ function parseRequest(method, path, data, callback, contentType) { 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); - } - - // if ((!err) && (res.statusCode === 200 || res.statusCode === 201)) { - // res.success = res.statusCode; - // } - var json = ''; res.setEncoding('utf8'); @@ -317,13 +304,17 @@ function parseRequest(method, path, data, callback, contentType) { }); res.on('end', function () { - var err = null; - var data = null; + var data; try { - var data = JSON.parse(json); - } catch (err) { + data = JSON.parse(json); + if ( data.code ) { + throw (data); + } + callback(null, data); + } + catch (err) { + callback(err); } - callback(err, data); }); res.on('close', function (err) { From 8df6d3b0b8f3fc38785294d014d5fc19e33fac2c Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 11:26:30 +0200 Subject: [PATCH 67/95] Removes unnecessary lines Fall-through takes care of it, post and put have identical headers --- lib/Parse.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 20bbf9d..9736531 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -269,8 +269,6 @@ function parseRequest(method, path, data, callback, contentType) { } break; case 'POST': - body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = Buffer.byteLength(body); case 'PUT': body = typeof data === 'object' ? JSON.stringify(data) : data; headers['Content-length'] = Buffer.byteLength(body); From 70956a33c3560a1ab059d22b4373f76f756ee028 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 11:26:53 +0200 Subject: [PATCH 68/95] Adds support for buffered files --- lib/Parse.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 9736531..a54ebbb 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -270,8 +270,10 @@ function parseRequest(method, path, data, callback, contentType) { break; case 'POST': case 'PUT': - body = typeof data === 'object' ? JSON.stringify(data) : data; - headers['Content-length'] = Buffer.byteLength(body); + body = contentType ? data : typeof data === 'object' ? JSON.stringify(data) : data; + if ( !contentType ) { + headers['Content-length'] = Buffer.byteLength(body); + } headers['Content-type'] = contentType || 'application/json'; break; case 'DELETE': From b44902ce452ae5b099c31962d37ffeda69412137 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 11:46:18 +0200 Subject: [PATCH 69/95] Adds contributors If they worked on it they should be added as contributors, right? No idea if I got everyone --- package.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f665eb5..915e6d7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,21 @@ "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ "Daniel Gasienica ", - "Jakub Knejzlík" + "Jakub Knejzlík", + "Sam Saccone", + "Arnaud Rinquin", + "Charles Julian Knight", + "Barrington Haynes", + "Christian Monaghan", + "Christoffer Niska", + "Rodrigo Martell", + "Joe Bruggeman", + "Omar A", + "Andrey", + "Rafael Galdêncio", + "Akhmad Fathonih", + "Kody J. Peterson", + "Jo Jordens" ], "main": "index", "scripts": { From 388956cce50f7a555024dd7f3e9e5ddc6d8ef26b Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 13:13:19 +0200 Subject: [PATCH 70/95] Adds insertUser and updateUser insertUser: create new users updateUser: update keys other than username and email --- lib/Parse.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index a54ebbb..cec74af 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -29,6 +29,11 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/files/' + fileName, data, callback, contentType); }, + // create a new user + insertUser: function (data, callback) { + parseRequest.call(this, 'POST', '/1/users/', data, callback); + }, + // get an object from the class store find: function (className, query, callback) { if (typeof query === 'string') { @@ -103,6 +108,11 @@ Parse.prototype = { parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); }, + // update any keys of a User object + updateUser: function (objectId, data, callback) { + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); + }, + // reset a User object's password passwordReset: function (data, callback) { data = { email: data }; From 902f096f52592811d342446e1d79906198822a8a Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 16:31:46 +0200 Subject: [PATCH 71/95] Optimizes find The 'find' method can now be used to find a single object as well as many objects with every combination of query constraints that Parse allows. findMany is now deprecated --- lib/Parse.js | 50 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index cec74af..530983e 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -36,37 +36,59 @@ Parse.prototype = { // get an object from the 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); + var url = '/1/classes/' + className; + var queryType = typeof query; + if ( queryType === 'string' ) { + url += '/' + query; + } else if ( queryType === 'object' ) { + + // if the user wants to add 'include' or 'key' (or other types of) constraints while getting only one object + // objectId can be added to the query object and is deleted after it's appended to the url + if ( query.hasOwnProperty('objectId') ) { + url += '/' + query.objectId; + delete query.objectId; + } + + // check to see if there is a 'where' object in the query object + // the 'where' object need to be stringified by JSON.stringify(), not querystring + if ( query.hasOwnProperty('where') ) { + url += '?where=' + JSON.stringify(query.where); + delete query.where; + } + + // if there are no more constraints left in the query object 'remainingQuery' will be an empty string + var remainingQuery = qs.stringify(query); + if ( remainingQuery ) { + url += ( url.indexOf('?') === -1 ? '?' : '&' ) + remainingQuery; + } + } + parseRequest.call(this, 'GET', url, null, callback); }, // get a collection of objects findMany: function (className, query, order, limit, skip, callback) { - // also supports the following api - findMany: function (className, query, callback) + console.warn('"findMany" is deprecated, use "find" instead.'); // if only 3 arguments exist, third argument is the callback, order and limit are undefined if (arguments.length === 3) { callback = order; - order = undefined; - limit = 9999; } // if only 5 arguments exist, fifth argument is the callback, skip is undefined if (arguments.length === 5) { + query.order = order; + query.limit = limit; callback = skip; - skip = undefined; } - if (typeof(query) === 'string') { - parseRequest.call(this, 'GET', '/1/classes/' + className + '/' + query, null, callback); - } else if (skip !== undefined) { - parseRequest.call(this, 'GET', '/1/classes/' + className, { limit: limit, order:order, skip:skip, where: JSON.stringify(query) }, callback); - } else { - parseRequest.call(this, 'GET', '/1/classes/' + className, { limit: limit, order:order, where: JSON.stringify(query) }, callback); + if ( arguments.length === 6 ) { + query.order = order; + query.limit = limit; + query.skip = skip; } + + this.find(className, query, callback); }, // do a batch of requests at once From 454dc172b39121c2479f892fd7bfc9003197321a Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Tue, 21 Apr 2015 16:52:43 +0200 Subject: [PATCH 72/95] Adds method to retrieve user object content Adds a method to retrieve content of one or more user objects. Retrieving user data is identical to "find" except for the url (granted '/1/classes/_User' works too but '/1/users' is the proper way to do it). Previous getUser method is now replaced by loginUser. --- lib/Parse.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 530983e..b4f2bbc 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -36,7 +36,7 @@ Parse.prototype = { // get an object from the class store find: function (className, query, callback) { - var url = '/1/classes/' + className; + var url = '/1/' + (className === '_User' ? 'users' : 'classes/' + className); var queryType = typeof query; if ( queryType === 'string' ) { url += '/' + query; @@ -68,7 +68,7 @@ Parse.prototype = { // get a collection of objects findMany: function (className, query, order, limit, skip, callback) { - console.warn('"findMany" is deprecated, use "find" instead.'); + console.warn('"findMany" is deprecated, please use "find" instead.'); // if only 3 arguments exist, third argument is the callback, order and limit are undefined if (arguments.length === 3) { @@ -96,9 +96,20 @@ Parse.prototype = { parseRequest.call(this,'POST','/1/batch',{requests:requests},callback); }, - // get a user from the Parse's special User class. See https://parse.com/questions/why-does-querying-for-a-user-create-a-second-user-class - getUser: function (userName, passWord, callback) { - parseRequest.call(this, 'GET', '/1/login/?username=' + userName + '&password=' + passWord, null, callback); + // user login + loginUser: function (username, password, callback) { + parseRequest.call(this, 'GET', '/1/login/?username=' + username + '&password=' + password, null, callback); + }, + + // retrieve contents of one or more user objects + getUser: function (query, callback, deprecatedCallback) { + if ( arguments.length === 3 ) { + console.warn('Logging in with "getUser" is deprecated, please use loginUser instead.'); + console.warn('Use "getUser" to retrieve one or more user object contents without logging in.'); + this.loginUser(query, callback, deprecatedCallback); + } else { + this.find('_User', query, callback); + } }, // get an object belonging to a certain User From e5d30883bfeb0f6f44be79336978d84b083733be Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Wed, 22 Apr 2015 10:49:29 +0200 Subject: [PATCH 73/95] Replaces if-blocks with switch --- lib/Parse.js | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index b4f2bbc..042a87f 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -70,22 +70,18 @@ Parse.prototype = { findMany: function (className, query, order, limit, skip, callback) { console.warn('"findMany" is deprecated, please use "find" instead.'); - // if only 3 arguments exist, third argument is the callback, order and limit are undefined - if (arguments.length === 3) { - callback = order; - } - - // if only 5 arguments exist, fifth argument is the callback, skip is undefined - if (arguments.length === 5) { - query.order = order; - query.limit = limit; - callback = skip; - } - - if ( arguments.length === 6 ) { - query.order = order; - query.limit = limit; - query.skip = skip; + switch ( arguments.length ) { + case 3: callback = order; + break; + case 5: query.order = order; + query.limit = limit; + callback = skip; + break; + case 6: query.order = order; + query.limit = limit; + query.skip = skip; + break; + default: throw new Error('Unexpected number of arguments'); } this.find(className, query, callback); From 28ac73ac7774f70c02206b643e0d8e7c590c9c78 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Wed, 22 Apr 2015 11:22:45 +0200 Subject: [PATCH 74/95] Adds support for sessionToken Session tokens only work with the rest api key. While using the master key you can edit all data anyway. --- lib/Parse.js | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 042a87f..d75851a 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -81,7 +81,7 @@ Parse.prototype = { query.limit = limit; query.skip = skip; break; - default: throw new Error('Unexpected number of arguments'); + default: throw new Error('Unexpected number of arguments.'); } this.find(className, query, callback); @@ -97,11 +97,16 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/login/?username=' + username + '&password=' + password, null, callback); }, + // retrieve current user + me: function (sessionToken, callback) { + parseRequest.call(this, 'GET', '/1/users/me', null, callback, null, sessionToken); + }, + // retrieve contents of one or more user objects getUser: function (query, callback, deprecatedCallback) { if ( arguments.length === 3 ) { console.warn('Logging in with "getUser" is deprecated, please use loginUser instead.'); - console.warn('Use "getUser" to retrieve one or more user object contents without logging in.'); + console.warn('Use "getUser" to retrieve one or more user object contents.'); this.loginUser(query, callback, deprecatedCallback); } else { this.find('_User', query, callback); @@ -126,20 +131,29 @@ Parse.prototype = { }, // update a User object's email address - updateUserEmail: function(objectId, data, callback) { + updateUserEmail: function(objectId, data, sessionToken, callback) { + if ( arguments.length !== 4 ) { + throw new Error('Unexpected number of arguments.'); + } data = { email: data }; - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); }, // update a User object's username* - updateUserName: function(objectId, data, callback) { + updateUserName: function(objectId, data, sessionToken, callback) { + if ( arguments.length !== 4 ) { + throw new Error('Unexpected number of arguments.'); + } data = { username: data }; - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); }, // update any keys of a User object - updateUser: function (objectId, data, callback) { - parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback); + updateUser: function (objectId, data, sessionToken, callback) { + if ( arguments.length !== 4 ) { + throw new Error('Unexpected number of arguments.'); + } + parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); }, // reset a User object's password @@ -285,7 +299,7 @@ Parse.prototype = { }; // Parse.com https api request -function parseRequest(method, path, data, callback, contentType) { +function parseRequest(method, path, data, callback, contentType, sessionToken) { var headers = { Connection: 'Keep-alive' }; @@ -293,9 +307,15 @@ function parseRequest(method, path, data, callback, contentType) { if(this._options.master_key){ var auth = 'Basic ' + new Buffer(this._options.app_id + ':' + this._options.master_key).toString('base64'); headers.Authorization = auth; + if ( sessionToken ) { + throw new Error('Can\'t use session tokens while using the master key.'); + } }else if(this._options.api_key){ headers['X-Parse-Application-Id'] = this._options.app_id; headers['X-Parse-REST-API-Key'] = this._options.api_key; + if ( sessionToken ) { + headers['X-Parse-Session-Token'] = sessionToken; + } } From ee86d7b99fdad5c16ab86ea7d7810f0a062cf497 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Thu, 23 Apr 2015 10:32:32 +0200 Subject: [PATCH 75/95] Adds deleteUser and deleteAllUsers methods --- lib/Parse.js | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index d75851a..fc72423 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -68,7 +68,7 @@ Parse.prototype = { // get a collection of objects findMany: function (className, query, order, limit, skip, callback) { - console.warn('"findMany" is deprecated, please use "find" instead.'); + console.warn('"findMany" is deprecated, use "find" instead.'); switch ( arguments.length ) { case 3: callback = order; @@ -105,7 +105,7 @@ Parse.prototype = { // retrieve contents of one or more user objects getUser: function (query, callback, deprecatedCallback) { if ( arguments.length === 3 ) { - console.warn('Logging in with "getUser" is deprecated, please use loginUser instead.'); + console.warn('Logging in with "getUser" is deprecated, use loginUser instead.'); console.warn('Use "getUser" to retrieve one or more user object contents.'); this.loginUser(query, callback, deprecatedCallback); } else { @@ -167,6 +167,27 @@ Parse.prototype = { parseRequest.call(this, 'DELETE', '/1/classes/' + className + '/' + objectId, null, callback); }, + // remove an object from the class store + deleteUser: function (objectId, callback) { + parseRequest.call(this, 'DELETE', '/1/users/' + objectId, null, callback); + }, + + deleteAll: function(className, callback){ + var that = this; + this.find(className, '', function (err, response) { + var requests = toDeleteOps(className, response.results); + that.batch(requests, callback); + }); + }, + + deleteAllUsers: function(callback){ + var that = this; + this.find('_User', '', function (err, response) { + var requests = toDeleteOps('_User', response.results); + that.batch(requests, callback); + }); + }, + // upload installation data insertInstallationData: function (deviceType, deviceToken, callback) { if (deviceType === 'ios'){ @@ -287,14 +308,6 @@ Parse.prototype = { sendPush: function (data, callback) { parseRequest.call(this, 'POST', '/1/push/', data, callback); - }, - - deleteAll: function(modelName, callback){ - var that = this; - this.findMany(modelName, '', function(err, response){ - var requests = toDeleteOps(modelName, response.results); - that.batch(requests, callback); - }); } }; @@ -393,8 +406,7 @@ function toDeleteOps(className, objects){ return objects.map(function(object){ return { method: 'DELETE', - path: '/1/classes/' + className + '/' + object.objectId, - body: {} + path: '/1/' + ( className === '_User' ? 'users/' : 'classes/' + className + '/' ) + object.objectId }; }); } From f20fe9c5071d59e7e547fb9dbb4e124071988425 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Thu, 23 Apr 2015 13:03:24 +0200 Subject: [PATCH 76/95] Changes and adds new tests Parse.test.js runs tests against the master key, while testRestApiKey.js runs tests against the rest api key to test sesstion tokens for users. --- lib/Parse.js | 6 +- test/Parse.test.js | 316 +++++++++++++++++++++++++++++------------ test/testRestApiKey.js | 78 ++++++++++ 3 files changed, 308 insertions(+), 92 deletions(-) create mode 100644 test/testRestApiKey.js diff --git a/lib/Parse.js b/lib/Parse.js index fc72423..29c8cb1 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -168,8 +168,8 @@ Parse.prototype = { }, // remove an object from the class store - deleteUser: function (objectId, callback) { - parseRequest.call(this, 'DELETE', '/1/users/' + objectId, null, callback); + deleteUser: function (objectId, sessionToken, callback) { + parseRequest.call(this, 'DELETE', '/1/users/' + objectId, null, callback, null, sessionToken); }, deleteAll: function(className, callback){ @@ -379,7 +379,7 @@ function parseRequest(method, path, data, callback, contentType, sessionToken) { var data; try { data = JSON.parse(json); - if ( data.code ) { + if ( data.code || data.error ) { throw (data); } callback(null, data); diff --git a/test/Parse.test.js b/test/Parse.test.js index e9c8ee1..e7414ed 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -1,3 +1,4 @@ +// this file runs tests against the master key var Parse = require('../index').Parse; // use environment variables APPLICATION_ID and MASTER_KEY to test against @@ -16,126 +17,263 @@ if (!application_id || !master_key) { var parse = new Parse(application_id, master_key); var className = 'NodeParseApiTest'; var className2 = 'NodeParseApiRelationTest'; -var object = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type -var object2 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type -var object3 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type -var object4 = { foo: Math.floor(Math.random() * 10000) }; // ERROR: if you change the type -var stub; +var stub1; var stub2; +var stub3; +var stubRelation; -exports.insert = function (assert) { - parse.insert(className, object, function (err, response) { - err && console.log(err); - assert.ok(response); - stub = response; - assert.done(); +exports.insert = function (test) { + var data = { + foo: 'bar0', + baz: 'qux0', + quux: 'quuux' + }; + parse.insert(className, data, function (error, response) { + test.expect(1); + test.ok(!error, 'There shoudn\'t be an error object.'); + stub1 = response; + test.done(); }); - - }; -exports['insert 2'] = function(assert){ - parse.insert(className2,object2, function(err,response){ - err && console.log(err); - assert.ok(response); - stub2 = response; - assert.done(); - }); -} - - -exports.find = function (assert) { - parse.find(className, stub.objectId, function (err, response) { - assert.equal(object.foo, response.foo); - assert.done(); +exports.batchInsert = function (test) { + var batchRequests = [ + { + method: 'POST', + path: '/1/classes/' + className, + body: { + foo: 'bar1', + baz: 'qux1', + quux: 'quuux' + } + }, + { + method: 'POST', + path: '/1/classes/' + className, + body: { + foo: 'bar2', + baz: 'qux2', + quux: 'quuux' + } + } + ]; + parse.batch(batchRequests, function (error, response) { + test.expect(1); + test.ok(!error, 'There shoudn\'t be an error object.'); + stub2 = response[0].success; + stub3 = response[1].success; + test.done(); }); }; -exports['find with limit and order'] = function (assert) { - parse.findMany(className,{},'-createdAt',1, function (err1,res1){ - assert.equal(1, res1.results.length); - assert.equal(stub.objectId, res1.results[0].objectId); - assert.equal(stub.createdAt, res1.results[0].createdAt); - assert.done(); +exports.find = function (test) { + parse.find(className, stub1.objectId, function (err, response) { + test.equal(stub1.objectId, response.objectId); + test.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.findManyNoConstraints = function (test) { + parse.find(className, '', function (error, response) { + test.expect(3); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response.results.length === 3, 'There should be 3 objects in response.results.'); + test.equal(stub1.objectId, response.results[0].objectId, 'The first object should have the same objectId as the stub object.'); + test.done(); }); }; +// order limit skip keys include +exports.findManyWithConstraints = { + order: function (test) { + var query = { + order: '-foo' + }; + parse.find(className, query, function (error, response) { + test.expect(4); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.equal('bar0', response.results[2].foo, 'response.results[2].foo should be "bar0".'); + test.equal('bar1', response.results[1].foo, 'response.results[1].foo should be "bar1".'); + test.equal('bar2', response.results[0].foo, 'response.results[0].foo should be "bar2".'); + test.done(); + }); + }, + 'order keys skip': function (test) { + var query = { + order: 'foo', + keys: 'baz', + skip: 2 + }; + parse.find(className, query, function (error, response) { + test.ok(!error, 'There shoudn\'t be an error object.'); + test.equal('qux2', response.results[0].baz, 'response.results[0].baz should be "qux2".'); + test.done(); + }); + }, + 'order limit': function (test) { + var query = { + order: '-foo', + limit: 2 + }; + parse.find(className, query, function (error, response) { + test.expect(4); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response.results.length === 2, 'There should be 2 objects in response.results.'); + test.equal('bar1', response.results[1].foo, 'response.results[1].foo should be "bar1".'); + test.equal('qux1', response.results[1].baz, 'response.results[1].baz should be "qux1".'); + test.done(); + }); + } +}; +exports.deprecatedFindMany = { + setUp: function (callback) { + this.query = { + quux: 'quuux' + }; + callback(); + }, + '3 arguments': function (test) { + parse.findMany(className, this.query, function (error, response) { + test.expect(2); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response.results.length === 3, 'There should be 3 objects in response.results.'); + test.done(); + }); + }, + '5 arguments': function (test) { + parse.findMany(className, this.query, 'foo', 2, function (error, response) { + test.expect(3); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response.results.length === 2, 'There should be 2 objects in response.results.'); + test.equal('bar0', response.results[0].foo, 'response.results[0].foo should be "bar0".'); + test.done(); + }); + }, + '6 arguments': function (test) { + parse.findMany(className, this.query, 'foo', 2, 1, function (error, response) { + test.expect(3); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response.results.length === 2, 'There should be 2 objects in response.results.'); + test.equal('bar1', response.results[0].foo, 'response.results[0].foo should be "bar1".'); + test.done(); + }); + }, + 'invalid number of arguments': function (test) { + test.expect(1); + test.throws(function () {parse.findMany('foo', 'bar', 'baz', 'qux');}); + test.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); // retest find on the updated object +exports.update = function (test) { + stub1.foo = 'bar00'; + parse.update(className, stub1.objectId, {foo: 'bar00'}, function (error, response) { + test.expect(4); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response); + parse.find(className, stub1.objectId, function (error, response) { + test.ok(!error, 'There shoudn\'t be an error object.'); + test.equal(stub1.foo, response.foo, 'response.foo should be "bar00".'); + test.done(); + }); }); }; +exports.insertClass2 = function (test) { + parse.insert(className2, {foo: 'bar'}, function (error, response) { + test.expect(1); + test.ok(!error, 'There shoudn\'t be an error object.'); + stubRelation = response; + test.done(); + }); +}; -exports['add relation'] = function (assert) { - parse.addRelation("secondObject",className,stub.objectId,className2,stub2.objectId, function (err ,response){ - err && console.log(response); - assert.ok(response); - assert.done(); - }); -} +exports.addRelation = function (test) { + parse.addRelation("secondObject", className2, stubRelation.objectId, className, stub1.objectId, function (error, response) { + test.expect(3); + test.ok(!error, 'There shoudn\'t be an error object.'); -exports['batch'] = function (assert) { - requests = [{"method":"PUT","path": "/1/classes/"+className+'/'+stub.objectId, "body": object3},{"method":"PUT","path": "/1/classes/"+className2+'/'+stub2.objectId, "body": object4} ]; - parse.batch(requests, function(err,response){ - err && console.log(response); - assert.ok(response); - assert.done(); + var query = { + where: { + $relatedTo: { + object: { + __type: 'Pointer', + className: className2, + objectId: stubRelation.objectId + }, + key: 'secondObject' + } + } + }; + parse.find(className, query, function (error, response) { + console.log(response); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.equal(stub1.foo, response.results[0].foo, 'The response object should contain the related object.'); + test.done(); + }); }); -} +}; -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(); +exports.deleteOne = function (test) { + parse.delete(className2, stubRelation.objectId, function (error, response) { + test.expect(3); + test.ok(!error, 'There shouldn\'t be an error object.'); + parse.find(className2, stubRelation.objectId, function (error, response) { + test.ok(error, 'There should be an error object.'); + test.equal(101, error.code, 'error.code should be 101.'); + test.done(); }); }); }; -exports['delete all'] = function(assert){ - parse.insert(className2,object2, function(err,response){ - parse.deleteAll(className2, function(){ - parse.findMany(className2, '', function(err, response){ - assert.equal(0, response.results.length); - assert.done(); - }); - }); +exports.deleteAll = function (test) { + parse.deleteAll(className, function (error, response) { + test.expect(2); + test.ok(!error, 'There shoudn\'t be an error object.'); + test.ok(response[0].hasOwnProperty('success')); + test.done(); }); -} +}; -exports['push notification error'] = function (assert) { +exports.userTests = { + insertUser : function (test) { + test.expect(1); + parse.insertUser({username: 'foo', password: 'bar'}, function (error, response) { + test.ok(!error, 'There shoudn\'t be an error object.'); + test.done(); + }); + }, + getUser: function (test) { + test.expect(2); + parse.getUser({where:{username: 'foo'}}, function (error, response) { + test.ok(!error, 'There shoudn\'t be an error object.'); + test.equal('foo', response.results[0].username, 'response.results[0].username should be foo.'); + test.done(); + }); + }, + deleteUser: function (test) { + test.expect(1); + parse.getUser({where:{username: 'foo'}}, function (error, response) { + parse.deleteUser(response.results[0].objectId, function (error, response) { + test.ok(!error, 'There shoudn\'t be an error object.'); + test.done(); + }); + }); + } +}; + +exports.pushNotificationError = function (test) { parse.sendPush({ channels: ['foobar'], data2: { alert: 'test message' } - }, function (error, result) { - assert.ok(error); - assert.equal(result, null); - assert.equal(error.message, 'Missing the push data. (Code: 115)'); - assert.done(); + }, function (error, response) { + test.expect(3); + test.ok(error); + test.equal(response, null); + test.equal(error.code, 115, 'error.code should be 115.'); + test.done(); }); -} +}; diff --git a/test/testRestApiKey.js b/test/testRestApiKey.js new file mode 100644 index 0000000..01d95da --- /dev/null +++ b/test/testRestApiKey.js @@ -0,0 +1,78 @@ +// this file runs tests against the rest api key +var Parse = require('../index').Parse; + +// use environment variables APPLICATION_ID and MASTER_KEY to test against +var application_id = process.env.APPLICATION_ID; +var rest_api_key = process.env.REST_API_KEY; + +// require the environment variables, or exit with explanation +if (!application_id || !rest_api_key) { + console.log('Set the following environment variables for the test Parse app'); + console.log(' export APPLICATION_ID=...'); + console.log(' export REST_API_KEY=...'); + process.exit(1); +} + +// global objects to test against +var parse = new Parse({app_id: application_id, api_key: rest_api_key}); +var user = {username: 'foo', password: 'bar'}; +var user2 = {username: 'baz', password: 'qux'}; +var userObject; +var user2Object; + +exports.userLogin = function (test) { + test.expect(4); + parse.insertUser(user2, function (error, response) { + test.ok(!error, 'Failed creating user.'); + user2Object = response; + parse.insertUser(user, function (error, response) { + test.ok(!error, 'Failed creating user.'); + userObject = response; + parse.loginUser(user.username, user.password, function (error, response) { + test.ok(!error, 'Login failed.'); + test.equal(user.username, response.username, 'Should be the same username.'); + test.done(); + }); + }); + }); +}; + +exports.editUser = function (test) { + test.expect(3); + parse.updateUser(userObject.objectId, {username: 'foo0'}, userObject.sessionToken, function (error, response) { + userObject.username = 'foo0'; + test.ok(!error); + parse.getUser({objectId: userObject.objectId}, function (error, response) { + test.ok(!error); + test.equal(userObject.username, response.username, 'usernames should be the same.'); + test.done(); + }); + }); +}; + +exports.editUserFail = function (test) { + test.expect(1); + parse.updateUser(user2Object.objectId, {username: 'baz0'}, userObject.sessionToken, function (error, response) { + test.ok(error); + test.done(); + }); +}; + +exports.me = function (test) { + test.expect(1); + parse.me(userObject.sessionToken, function (error, response) { + test.ok(!error); + test.done(); + }); +}; + +exports.deleteUser = function (test) { + test.expect(2); + parse.deleteUser(userObject.objectId, userObject.sessionToken, function (error, response) { + test.ok(!error); + parse.deleteUser(user2Object.objectId, user2Object.sessionToken, function (error, response) { + test.ok(!error); + test.done(); + }); + }); +}; From 237a17946089d88c750ea5eb812c0414bcf1cbf5 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Thu, 23 Apr 2015 15:36:10 +0200 Subject: [PATCH 77/95] Changes getUser to findUser for consistency with find getUser and getFileByUser now redirect to their respective newer version while logging a warning message to the console. Also removes one console.log from Parse.test.js and adds one more contributor. --- lib/Parse.js | 53 +++++++++++++++++++++++++++++++++++----------- package.json | 3 ++- test/Parse.test.js | 1 - 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 29c8cb1..125d002 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -103,23 +103,37 @@ Parse.prototype = { }, // retrieve contents of one or more user objects - getUser: function (query, callback, deprecatedCallback) { - if ( arguments.length === 3 ) { - console.warn('Logging in with "getUser" is deprecated, use loginUser instead.'); - console.warn('Use "getUser" to retrieve one or more user object contents.'); - this.loginUser(query, callback, deprecatedCallback); + findUser: function (query, callback) { + if ( arguments.length !== 2 ) { + throw new Error('Unexpected number of arguments.'); } else { this.find('_User', query, callback); } }, // get an object belonging to a certain User - getFileByUser: function(userId, className, callback) { + findFileByUser: function(userId, className, callback) { queryString = 'where={"user":' + '"' + userId + '"' + '}'; encodedString = encodeURIComponent(queryString); parseRequest.call(this, 'GET', '/1/classes/' + className + '?' + encodedString, null, callback); }, + getUser: function (query, callback, deprecatedCallback) { + console.warn('getUser is deprecated, user findUser instead.'); + if ( arguments.length === 3 ) { + console.warn('Logging in with "getUser" is deprecated, use loginUser instead.'); + console.warn('Use "findUser" to retrieve one or more user object contents.'); + this.loginUser(query, callback, deprecatedCallback); + } else { + this.findUser(query, callback); + } + }, + + getFileByUser: function(userId, className, callback) { + console.warn('getFileByUser is deprecated, user findFileByUser instead.'); + this.findFileByUser(userId, className, callback); + }, + // insert an object into Parse insertCustom: function (className, object, callback) { parseRequest.call(this, 'POST', '/1/' + className, object, callback); @@ -132,8 +146,11 @@ Parse.prototype = { // update a User object's email address updateUserEmail: function(objectId, data, sessionToken, callback) { - if ( arguments.length !== 4 ) { - throw new Error('Unexpected number of arguments.'); + switch ( arguments.length ) { + case 3: callback = sessionToken; + break; + case 4: break; + default: throw new Error('Unexpected number of arguments.'); } data = { email: data }; parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); @@ -141,8 +158,11 @@ Parse.prototype = { // update a User object's username* updateUserName: function(objectId, data, sessionToken, callback) { - if ( arguments.length !== 4 ) { - throw new Error('Unexpected number of arguments.'); + switch ( arguments.length ) { + case 3: callback = sessionToken; + break; + case 4: break; + default: throw new Error('Unexpected number of arguments.'); } data = { username: data }; parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); @@ -150,8 +170,11 @@ Parse.prototype = { // update any keys of a User object updateUser: function (objectId, data, sessionToken, callback) { - if ( arguments.length !== 4 ) { - throw new Error('Unexpected number of arguments.'); + switch ( arguments.length ) { + case 3: callback = sessionToken; + break; + case 4: break; + default: throw new Error('Unexpected number of arguments.'); } parseRequest.call(this, 'PUT', '/1/users/' + objectId, data, callback, null, sessionToken); }, @@ -169,6 +192,12 @@ Parse.prototype = { // remove an object from the class store deleteUser: function (objectId, sessionToken, callback) { + switch ( arguments.length ) { + case 2: callback = sessionToken; + break; + case 3: break; + default: throw new Error('Unexpected number of arguments'); + } parseRequest.call(this, 'DELETE', '/1/users/' + objectId, null, callback, null, sessionToken); }, diff --git a/package.json b/package.json index 915e6d7..1dcfd03 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "Rafael Galdêncio", "Akhmad Fathonih", "Kody J. Peterson", - "Jo Jordens" + "Jo Jordens", + "Appsaloon" ], "main": "index", "scripts": { diff --git a/test/Parse.test.js b/test/Parse.test.js index e7414ed..342f61c 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -207,7 +207,6 @@ exports.addRelation = function (test) { } }; parse.find(className, query, function (error, response) { - console.log(response); test.ok(!error, 'There shoudn\'t be an error object.'); test.equal(stub1.foo, response.results[0].foo, 'The response object should contain the related object.'); test.done(); From 0b5bc54e1e4bb9fe36f354c051cadb55d24db5ee Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Thu, 23 Apr 2015 15:36:38 +0200 Subject: [PATCH 78/95] Updates readme.md --- readme.md | 622 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 437 insertions(+), 185 deletions(-) diff --git a/readme.md b/readme.md index d670d22..3c8db00 100644 --- a/readme.md +++ b/readme.md @@ -4,274 +4,526 @@ Node Parse API install ------- - npm install node-parse-api - +``` +npm install node-parse-api +``` + examples -------- -### setup with MASTER_KEY (old way) +### setup with MASTER_KEY - var Parse = require('node-parse-api').Parse; +```javascript +var Parse = require('node-parse-api').Parse; - var APP_ID = ...; - var MASTER_KEY = ...; +var APP_ID = ...; +var MASTER_KEY = ...; - var app = new Parse(APP_ID, MASTER_KEY); +var app = new Parse(APP_ID, MASTER_KEY); +``` -### setup with API_KEY (new way) +### setup with API_KEY - var Parse = require('node-parse-api').Parse; +```javascript +var Parse = require('node-parse-api').Parse; - var options = { - app_id:'...', - api_key:'...' // master_key:'...' could be used too - } +var options = { + app_id:'...', + api_key:'...' // master_key:'...' could be used too +} - var app = new Parse(options); +var app = new Parse(options); +``` ### insert an object - // add a Foo object, { foo: 'bar' } - app.insert('Foo', { foo: 'bar' }, function (err, response) { - console.log(response); - }); +* insert(className `string`, data `object`, callback `function`) + +```javascript +// add a Foo object, { foo: 'bar' } +app.insert('Foo', { foo: 'bar' }, function (err, response) { + console.log(response); +}); +``` ### insert a User - app.insertCustom('users', { - username: 'tom@j.com', - password: 'wow' - }, function (err, response) { - console.log(response); - }); +* insertUser(data `object`, callback `function`) + +```javascript +app.insertUser({ + username: 'foo', + password: 'bar' +}, function (err, response) { + console.log(response); +}); +``` + +More properties can be provided, but username and password are required. + +### insert a User with a Pointer + +```javascript +app.insertUser({ + username: 'foo', + password: 'bar', + pointer/*can have any name*/: { + __type: 'Pointer', + className: , + objectId: + } + }, function (err, response) { + console.log(response); +}); +``` ### insert a User with GeoPoints - app.insertCustom('users', { foo: 'bar', location: {__type: 'GeoPoint', latitude: , longitude: } }, function (err, response) { - console.log(response); - }); +```javascript +app.insertUser({ + username: 'foo', + password: 'bar', + location: { + __type: 'GeoPoint', + latitude: , + longitude: + } + }, function (err, response) { + console.log(response); +}); +``` + +### user login + +loginUser(username `string`, password `string`, callback `function`) + +Response contains all of the user fields except password, also includes a sessionToken for this user. + +```javascript +app.loginUser('foo', 'bar', function (error, response) { + // response = {sessionToken: '', createdAt: '', ... } + }); +``` + +### me + +me(sessionToken `string`, callback `function`) + +```javascript +app.me('sessionToken', function (error, response) { + // response is same as getUser response +}); +``` ### insert a file - app.insertFile(fileName, data, fileType, function (err, response) { - fileLink = response.url; - parseName = response.name; - app.insert('Foo', { "foo" : fileLink, "bar" : parseName }, function(erro, res){ - }) - }); +Method parameters: insertFile(fileName `string`, data `string/buffer`, contentType `string`, callback `function`) + +```javascript +// first upload the file to the parse cloud +app.insertFile('foo.txt', 'bar', 'text/plain', function (err, response) { + // then insert a new object with the link to the new file + app.insert('MyFile', {__type: 'File', "name": response.name }, function (error, response) { + }); +}); +``` ### find one - // the Foo with id = 'someId' - app.find('Foo', 'someId', function (err, response) { - console.log(response); - }); +find(className `string`, query `object`, callback `function`) -### find many +```javascript +// the Foo with id = 'someId' +app.find('Foo', {objectId: 'someId'}, function (err, response) { + console.log(response); +}); +``` - // all Foo objects with foo = 'bar' - app.findMany('Foo', { foo: 'bar' }, function (err, response) { - console.log(response); - }); +Returned fields can be restricted with the 'keys' query. +```javascript +var query = { + objectId: 'someId', + keys: 'foo,bar' +}; +app.find('Foo', query, function (error, response) { + //response object will only contain foo and bar fields, as well as the special built-in fields (objectId, createdAt and updatedAt) + }); +``` - // all Foo objects - app.findMany('Foo', '', function (err, response) { - console.log(response); - }): +### find many + +find(className `string`, query `object`, callback `function`) + +```javascript +// all Foo objects with foo = 'bar' +app.find('Foo', {where: {foo: 'bar'}}, function (err, response) { + console.log(response); +}); + +// all Foo objects +// '', null, undefined or any other falsy value will work +app.find('Foo', '', function (err, response) { + console.log(response); +}): +``` + +All types of query constraints Parse provides can be added to the query object as properties. (order, limit, keys, count, include...) + +```javascript +var query = { + where: { + foo: 'bar', + baz: 'qux' + }, + limit: 10, + skip: 5, + order: '-createdAt' +}; +app.find('Foo', query, function (error, response ) { + // the first 5 results will be ignored and the next 10 results will be returned + // response.results will contain up to 10 objects with foo = 'bar' and baz = 'qux', sorted from latest to oldest + }); +``` + +### find one user + +getUser(query `object`, callback `function`) + +```javascript +app.find({objectId: 'someId'}, function (err, response) { + console.log(response); +}); +``` + +### find many users + +getUser(query `object`, callback `function`) + +```javascript +// all users with foo = 'bar' +app.find({where: {foo: 'bar'}}, function (err, response) { + console.log(response); +}); + +// all users +// '', null, undefined or any other falsy value will work +app.find('', function (err, response) { + console.log(response); +}): +``` ### count the number of objects - // just use findMany, and call results.length on the response - app.findMany('Foo', { user: '' }, function (err, response) { - console.log(response.results.length); - }); +```javascript + +var query = { + count: 1, + limit: 0 +}; +app.find('Foo', query, function (error, response) { + // { + // results: [], + // count: 123 + // } +}); +``` + +### edit an object + +update(className `string`, objectId `string`, callback `function`) + +```javascript +app.update('Foo', 'someId', {foo: 'bar'}, function (err, response) { + console.log(response); +}); +``` + +### delete an object + +delete(className `string`, objectId `string`, callback `function`) + +```javascript +app.delete('Foo', 'someId', function (err, response) { + // response = {} +}); +``` + +### delete all objects in a class + +deleteAll(className `string`, callback `function`) + +```javascript +app.deleteAll('Foo', function (err, response) { + // response = [{success: {}, success: {}, ... }] +}); +``` + +### delete user -### update +deleteUser(objectId `string`, [sessionToken `string`], callback `function`) - app.update('Foo', 'someId', { foo: 'fubar' }, function (err, response) { - console.log(response); - }); +If you are using the master key you don't need any session tokens. -### delete +```javascript +app.deleteUser('someId', function (err, response) { + // response = {} +}); +``` - app.delete('Foo', 'someId', function (err) { - // nothing to see here - }); +If you're using the rest api key you will need a session token and will only be able to delete the user object of the matching user. -### deleteAll +```javascript +app.deleteUser('someId', 'sessionToken', function (error, response) { + // response = {} +}); +``` - app.deleteAll('Foo', function (err) { - // nothing to see here - }); +### delete all users + +deleteAll(callback `function`) + +This will only work when using the master key. + +```javascript +app.deleteAllUsers(function (err, response) { + // response = [{success: {}, success: {}, ... }] +}); +``` ### reset a password - //email is built into Parse's special User class - app.passwordReset(email, function(err, response){ - console.log(response); - }); +passwordReset(data `string`, callback `function`) -### update User email +```javascript +//email is built into Parse's special User class +app.passwordReset(email, function(err, response){ + console.log(response); +}); +``` - //email is built into Parse's special User class - app.updateUserEmail(objectId, email, function(err, response){ - if (err) { - console.log(err); - } else { - console.log(response); - } - }); +### edit a user object + +updateUser(objectId `string`, data `object`, [sessionToken `string`], callback `function`) + +With master key + +```javascript +app.updateUser('someId', {email: 'foo@example.com'}, function(err, response){ + console.log(response); +}); +``` + +or with rest api key + +```javascript +app.updateUser('someId', {email: 'foo@example.com'}, 'sesstionToken', function(err, response){ + console.log(response); +}); +``` + +### batch requests + +batch(requests `array`, callback `function`) + +```javascript +var requests = [ + { + method: 'POST', + path: '/1/classes/Foo', + body: { + foo: 'bar1', + baz: 'qux1' + } + }, + { + method: 'POST', + path: '/1/classes/Foo', + body: { + foo: 'bar2', + baz: 'qux2' + } + } +]; +app.batch(requests, function (error, response) { + // response = [{success: {createdAt: '', objectId: ''}, {success: {...}}}] +}); +``` ### insert installation data - //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. - app.insertInstallationData("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", function(err, response){ - if (err) { - console.log(err); - } else { - console.log(response); - } - }); +```javascript +//first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. +app.insertInstallationData("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } +}); +``` ### insert installation data with timeZone - //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. - app.insertInstallationDataWithTimeZone("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", function(err, response){ - if (err) { - console.log(err); - } else { - console.log(response); - } - }); +```javascript +//first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. +app.insertInstallationDataWithTimeZone("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } +}); +``` ### insert installation data with channels - //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the channels array. - arr = ["news", "sports"]; - app.insertInstallationDataWithChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", arr, function(err, response){ - if (err) { - console.log(err); - } else { - console.log(response); - } - }); +```javascript +//first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the channels array. +arr = ["news", "sports"]; +app.insertInstallationDataWithChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", arr, function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } +}); +``` ### insert installation data with timeZone and channels - //first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. 4th is the channels array. - arr = ["news", "sports"]; - app.insertInstallationDataWithTimeZoneAndChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", arr, function(err, response){ - if (err) { - console.log(err); - } else { - console.log(response); - } - }); +```javascript +//first arg is either 'ios' or 'android'. second arg is either the Apple deviceToken or the Android installationId. Third arg is the timezone string. 4th is the channels array. +arr = ["news", "sports"]; +app.insertInstallationDataWithTimeZoneAndChannels("ios", "0123456784abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "EST", arr, function(err, response){ + if (err) { + console.log(err); + } else { + console.log(response); + } +}); +``` ### create a role for a particular user - //create a data object that links the user object's objectId to the role - - var data = { - name: 'Administrator', - ACL: { - "*": { - "read": true - } - }, - roles: { - "__op": "AddRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_Role", - "objectId": "" - } - ] - }, - users: { - "__op": "AddRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_User", - "objectId": "" - } - ] +```javascript +//create a data object that links the user object's objectId to the role + +var data = { + name: 'Administrator', + ACL: { + "*": { + "read": true + } + }, + roles: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_Role", + "objectId": "" } - }; + ] + }, + users: { + "__op": "AddRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" + } + ] + } +}; - app.insertRole(data, function(err, resp){ - console.log(resp); - }); + app.insertRole(data, function(err, resp){ + console.log(resp); + }); +``` ### get a role - //pass the role object's objectId - app.getRole("", function(err, resp){ - console.log(resp); - }); +```javascript +//pass the role object's objectId +app.getRole("", function(err, resp){ + console.log(resp); +}); +``` ### update a role - //pass the objectId of the role, data contains the user's objectId - - var data = { - users: { - "__op": "RemoveRelation", - "objects": [ - { - "__type": "Pointer", - "className": "_User", - "objectId": "" - } - ] + +```javascript +//pass the objectId of the role, data contains the user's objectId + +var data = { + users: { + "__op": "RemoveRelation", + "objects": [ + { + "__type": "Pointer", + "className": "_User", + "objectId": "" } - }; + ] + } +}; - app.updateRole("", data, function(err, resp){ - console.log(resp); - }); + app.updateRole("", data, function(err, resp){ + console.log(resp); + }); +``` ### delete a role - //pass the objectId of the role - app.deleteRole("", function(err, resp){}); +```javascript +//pass the objectId of the role +app.deleteRole("", function(err, resp){}); +``` ### get all the roles - app.getRoles(function(err, resp){}); +```javascript +app.getRoles(function(err, resp){}); +``` ### get a role against a cetain param - var params = { - where: { name: "Administrator" } - }; +```javascript +var params = { + where: { name: "Administrator" } +}; - app.getRoles(params, function(err, resp){ - console.log(resp); - }); + app.getRoles(params, function(err, resp){ + console.log(resp); + }); +``` ### send a push notification - //The data param has to follow the data structure as described in the [Parse REST API](https://www.parse.com/docs/rest#push) - var notification = { - channels: [''], - data: { - alert: "sending too many push notifications is obnoxious" - } - }; - app.sendPush(notification, function(err, resp){ - console.log(resp); - }); +```javascript +//The data param has to follow the data structure as described in the [Parse REST API](https://www.parse.com/docs/rest#push) +var notification = { + channels: [''], + data: { + alert: "sending too many push notifications is obnoxious" + } +}; +app.sendPush(notification, function(err, resp){ + console.log(resp); +}); +``` ### note on sending dates - //when inserting a data, you must use the Parse date object structure, i.e.: - { - "__type": "Date", - "iso": new Date("", "", "").toJSON() - } +```javascript +//when inserting a data, you must use the Parse date object structure, i.e.: +{ + "__type": "Date", + "iso": new Date("", "", "").toJSON() +} +``` # License From 1f16e824992cbe727ae92c3012b5b9499131eae0 Mon Sep 17 00:00:00 2001 From: Jo Jordens Date: Thu, 23 Apr 2015 16:02:51 +0200 Subject: [PATCH 79/95] Corrects some mistakes in readme.md --- readme.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/readme.md b/readme.md index 3c8db00..df2d79f 100644 --- a/readme.md +++ b/readme.md @@ -95,7 +95,7 @@ app.insertUser({ ### user login -loginUser(username `string`, password `string`, callback `function`) +* loginUser(username `string`, password `string`, callback `function`) Response contains all of the user fields except password, also includes a sessionToken for this user. @@ -107,7 +107,7 @@ app.loginUser('foo', 'bar', function (error, response) { ### me -me(sessionToken `string`, callback `function`) +* me(sessionToken `string`, callback `function`) ```javascript app.me('sessionToken', function (error, response) { @@ -117,7 +117,7 @@ app.me('sessionToken', function (error, response) { ### insert a file -Method parameters: insertFile(fileName `string`, data `string/buffer`, contentType `string`, callback `function`) +* insertFile(fileName `string`, data `string/buffer`, contentType `string`, callback `function`) ```javascript // first upload the file to the parse cloud @@ -130,7 +130,7 @@ app.insertFile('foo.txt', 'bar', 'text/plain', function (err, response) { ### find one -find(className `string`, query `object`, callback `function`) +* find(className `string`, query `object`, callback `function`) ```javascript // the Foo with id = 'someId' @@ -153,7 +153,7 @@ app.find('Foo', query, function (error, response) { ### find many -find(className `string`, query `object`, callback `function`) +* find(className `string`, query `object`, callback `function`) ```javascript // all Foo objects with foo = 'bar' @@ -188,7 +188,7 @@ app.find('Foo', query, function (error, response ) { ### find one user -getUser(query `object`, callback `function`) +* getUser(query `object`, callback `function`) ```javascript app.find({objectId: 'someId'}, function (err, response) { @@ -198,7 +198,7 @@ app.find({objectId: 'someId'}, function (err, response) { ### find many users -getUser(query `object`, callback `function`) +* getUser(query `object`, callback `function`) ```javascript // all users with foo = 'bar' @@ -231,7 +231,7 @@ app.find('Foo', query, function (error, response) { ### edit an object -update(className `string`, objectId `string`, callback `function`) +* update(className `string`, objectId `string`, callback `function`) ```javascript app.update('Foo', 'someId', {foo: 'bar'}, function (err, response) { @@ -241,7 +241,7 @@ app.update('Foo', 'someId', {foo: 'bar'}, function (err, response) { ### delete an object -delete(className `string`, objectId `string`, callback `function`) +* delete(className `string`, objectId `string`, callback `function`) ```javascript app.delete('Foo', 'someId', function (err, response) { @@ -251,7 +251,7 @@ app.delete('Foo', 'someId', function (err, response) { ### delete all objects in a class -deleteAll(className `string`, callback `function`) +* deleteAll(className `string`, callback `function`) ```javascript app.deleteAll('Foo', function (err, response) { @@ -261,7 +261,7 @@ app.deleteAll('Foo', function (err, response) { ### delete user -deleteUser(objectId `string`, [sessionToken `string`], callback `function`) +* deleteUser(objectId `string`, [sessionToken `string`], callback `function`) If you are using the master key you don't need any session tokens. @@ -281,7 +281,7 @@ app.deleteUser('someId', 'sessionToken', function (error, response) { ### delete all users -deleteAll(callback `function`) +* deleteAllUsers(callback `function`) This will only work when using the master key. @@ -293,7 +293,7 @@ app.deleteAllUsers(function (err, response) { ### reset a password -passwordReset(data `string`, callback `function`) +* passwordReset(data `string`, callback `function`) ```javascript //email is built into Parse's special User class @@ -304,7 +304,7 @@ app.passwordReset(email, function(err, response){ ### edit a user object -updateUser(objectId `string`, data `object`, [sessionToken `string`], callback `function`) +* updateUser(objectId `string`, data `object`, [sessionToken `string`], callback `function`) With master key @@ -324,7 +324,7 @@ app.updateUser('someId', {email: 'foo@example.com'}, 'sesstionToken', function(e ### batch requests -batch(requests `array`, callback `function`) +* batch(requests `array`, callback `function`) ```javascript var requests = [ @@ -535,4 +535,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 5e428c2778b78835cfd431fc8d58e1024b826ff5 Mon Sep 17 00:00:00 2001 From: Keith Norman Date: Wed, 29 Apr 2015 21:29:12 -0700 Subject: [PATCH 80/95] allow posting arbitrary data to /installations --- lib/Parse.js | 6 ++++++ test/Parse.test.js | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 125d002..1e6fa83 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -272,6 +272,12 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); }, + upsertInstallation: function(deviceType, deviceToken, data, callback) { + data.deviceType = deviceType; + data.deviceToken = deviceToken; + parseRequest.call(this, 'POST', '/1/installations', data, callback); + }, + insertOrUpdateInstallationDataWithChannels: function(deviceType, deviceToken, channels, callback) { var that = this; this.getInstallationDataForDeviceToken(deviceToken, function(err, results) { diff --git a/test/Parse.test.js b/test/Parse.test.js index 342f61c..c4c4600 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -235,6 +235,15 @@ exports.deleteAll = function (test) { }); }; +exports.installationTests = { + upsertInstallation: function(test) { + parse.upsertInstallation('ios', '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', {userID: 'jenny'}, function(error, response) { + test.ok(!error, 'There shouldn\'t be an error object'); + test.done(); + }); + } +} + exports.userTests = { insertUser : function (test) { test.expect(1); From 2dfcfa7eec7a3b681ba842238ee279b9f1c9347a Mon Sep 17 00:00:00 2001 From: Keith Norman Date: Thu, 30 Apr 2015 08:11:53 -0700 Subject: [PATCH 81/95] add deleteInstallation endpoint --- lib/Parse.js | 4 ++++ test/Parse.test.js | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index 1e6fa83..81c2418 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -272,6 +272,10 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/installations?where={"deviceToken":"'+deviceToken+'"}', null, callback); }, + deleteInstallation: function(objectId, callback) { + parseRequest.call(this, 'DELETE', '/1/installations/' + objectId, null, callback); + }, + upsertInstallation: function(deviceType, deviceToken, data, callback) { data.deviceType = deviceType; data.deviceToken = deviceToken; diff --git a/test/Parse.test.js b/test/Parse.test.js index c4c4600..0d53d64 100644 --- a/test/Parse.test.js +++ b/test/Parse.test.js @@ -241,6 +241,16 @@ exports.installationTests = { test.ok(!error, 'There shouldn\'t be an error object'); test.done(); }); + }, + + deleteInstallation: function(test) { + parse.getInstallationDataForDeviceToken('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', function(error, response) { + var id = response.results[0].objectId; + parse.deleteInstallation(id, function(error, response){ + test.ok(!error, 'There shouldn\'t be an error obejct'); + test.done(); + }); + }); } } From a75390dd613ec7531d97144f0abeb2955041ad19 Mon Sep 17 00:00:00 2001 From: Leveton Date: Sun, 14 Jun 2015 22:56:01 -0400 Subject: [PATCH 82/95] updated readme --- npm-debug.log | 556 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 557 insertions(+), 1 deletion(-) create mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..c301034 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,556 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/Users/mleveton/.nvm/v0.10.10/bin/node', +1 verbose cli '/Users/mleveton/.nvm/v0.10.10/bin/npm', +1 verbose cli 'link' ] +2 info using npm@1.2.25 +3 info using node@v0.10.10 +4 verbose linkPkg /Users/mleveton/Documents/node/node-parse-api +5 verbose read json /Users/mleveton/Documents/node/node-parse-api/package.json +6 verbose link build target /Users/mleveton/.nvm/v0.10.10/lib/node_modules/node-parse-api +7 verbose install where,what [ '/Users/mleveton/Documents/node/node-parse-api', [] ] +8 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json +9 verbose readDependencies using package.json deps +10 verbose install where, deps [ '/Users/mleveton/Documents/node/node-parse-api', +10 verbose install [ 'nodeunit' ] ] +11 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json +12 info preinstall node-parse-api@0.3.6 +13 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json +14 verbose readDependencies using package.json deps +15 verbose cache add [ 'nodeunit@~0.9.0', null ] +16 verbose cache add name=undefined spec="nodeunit@~0.9.0" args=["nodeunit@~0.9.0",null] +17 verbose parsed url { protocol: null, +17 verbose parsed url slashes: null, +17 verbose parsed url auth: null, +17 verbose parsed url host: null, +17 verbose parsed url port: null, +17 verbose parsed url hostname: null, +17 verbose parsed url hash: null, +17 verbose parsed url search: null, +17 verbose parsed url query: null, +17 verbose parsed url pathname: 'nodeunit@~0.9.0', +17 verbose parsed url path: 'nodeunit@~0.9.0', +17 verbose parsed url href: 'nodeunit@~0.9.0' } +18 verbose cache add name="nodeunit" spec="~0.9.0" args=["nodeunit","~0.9.0"] +19 verbose parsed url { protocol: null, +19 verbose parsed url slashes: null, +19 verbose parsed url auth: null, +19 verbose parsed url host: null, +19 verbose parsed url port: null, +19 verbose parsed url hostname: null, +19 verbose parsed url hash: null, +19 verbose parsed url search: null, +19 verbose parsed url query: null, +19 verbose parsed url pathname: '~0.9.0', +19 verbose parsed url path: '~0.9.0', +19 verbose parsed url href: '~0.9.0' } +20 verbose addNamed [ 'nodeunit', '~0.9.0' ] +21 verbose addNamed [ null, '>=0.9.0- <0.10.0-' ] +22 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 +23 verbose lock nodeunit@~0.9.0 /Users/mleveton/.npm/98d576fd-nodeunit-0-9-0.lock +24 silly addNameRange { name: 'nodeunit', range: '>=0.9.0- <0.10.0-', hasData: false } +25 verbose url raw nodeunit +26 verbose url resolving [ 'https://registry.npmjs.org/', './nodeunit' ] +27 verbose url resolved https://registry.npmjs.org/nodeunit +28 info trying registry request attempt 1 at 21:39:51 +29 verbose etag "9CSC8MA50OTTQFV9VUZZKPFX4" +30 http GET https://registry.npmjs.org/nodeunit +31 http 200 https://registry.npmjs.org/nodeunit +32 silly registry.get cb [ 200, +32 silly registry.get { date: 'Thu, 19 Mar 2015 01:39:51 GMT', +32 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)', +32 silly registry.get etag: '"7U37RWKY0Z5CK6UIC0H4M97VZ"', +32 silly registry.get 'content-type': 'application/json', +32 silly registry.get 'cache-control': 'max-age=60', +32 silly registry.get 'content-length': '73860', +32 silly registry.get 'accept-ranges': 'bytes', +32 silly registry.get via: '1.1 varnish', +32 silly registry.get 'x-served-by': 'cache-jfk1025-JFK', +32 silly registry.get 'x-cache': 'MISS', +32 silly registry.get 'x-cache-hits': '0', +32 silly registry.get 'x-timer': 'S1426729191.823406,VS0,VE43', +32 silly registry.get vary: 'Accept', +32 silly registry.get 'keep-alive': 'timeout=10, max=50', +32 silly registry.get connection: 'Keep-Alive' } ] +33 silly addNameRange number 2 { name: 'nodeunit', range: '>=0.9.0- <0.10.0-', hasData: true } +34 silly addNameRange versions [ 'nodeunit', +34 silly addNameRange [ '0.1.0', +34 silly addNameRange '0.1.1', +34 silly addNameRange '0.1.2', +34 silly addNameRange '0.2.0', +34 silly addNameRange '0.2.1', +34 silly addNameRange '0.2.2', +34 silly addNameRange '0.2.3', +34 silly addNameRange '0.2.4', +34 silly addNameRange '0.3.1', +34 silly addNameRange '0.4.0', +34 silly addNameRange '0.5.0', +34 silly addNameRange '0.5.1', +34 silly addNameRange '0.5.2', +34 silly addNameRange '0.5.3', +34 silly addNameRange '0.5.4', +34 silly addNameRange '0.5.5', +34 silly addNameRange '0.6.0', +34 silly addNameRange '0.6.1', +34 silly addNameRange '0.6.2', +34 silly addNameRange '0.6.3', +34 silly addNameRange '0.6.4', +34 silly addNameRange '0.7.0', +34 silly addNameRange '0.7.1', +34 silly addNameRange '0.7.2', +34 silly addNameRange '0.7.3', +34 silly addNameRange '0.7.4', +34 silly addNameRange '0.8.0', +34 silly addNameRange '0.8.1', +34 silly addNameRange '0.8.2', +34 silly addNameRange '0.8.3', +34 silly addNameRange '0.8.4', +34 silly addNameRange '0.8.5', +34 silly addNameRange '0.8.6', +34 silly addNameRange '0.8.8', +34 silly addNameRange '0.8.7', +34 silly addNameRange '0.9.0', +34 silly addNameRange '0.9.1' ] ] +35 verbose addNamed [ 'nodeunit', '0.9.1' ] +36 verbose addNamed [ '0.9.1', '0.9.1' ] +37 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 +38 verbose lock nodeunit@0.9.1 /Users/mleveton/.npm/392547d8-nodeunit-0-9-1.lock +39 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz +40 verbose lock https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz /Users/mleveton/.npm/0f972367--org-nodeunit-nodeunit-0-9-1-tgz.lock +41 verbose addRemoteTarball [ 'https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz', +41 verbose addRemoteTarball 'e553dd41d8769402c3b9ab32d0e72e9668405139' ] +42 info retry fetch attempt 1 at 21:39:52 +43 verbose fetch to= /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz +44 http GET https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz +45 http 200 https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz +46 verbose tar unpack /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz +47 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +48 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package /Users/mleveton/.npm/892038b7-92107-0-8900070760864764-package.lock +49 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz +50 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz /Users/mleveton/.npm/a5e887f6-92107-0-8900070760864764-tmp-tgz.lock +51 silly gunzTarPerm modes [ '755', '644' ] +52 silly gunzTarPerm extractEntry package.json +53 silly gunzTarPerm extractEntry .npmignore +54 silly gunzTarPerm extractEntry README.md +55 silly gunzTarPerm extractEntry LICENSE +56 silly gunzTarPerm extractEntry index.js +57 silly gunzTarPerm extractEntry examples/browser/nodeunit.js +58 silly gunzTarPerm extractEntry examples/browser/suite1.js +59 silly gunzTarPerm extractEntry examples/browser/suite2.js +60 silly gunzTarPerm extractEntry examples/browser/suite3.js +61 silly gunzTarPerm extractEntry examples/browser/test.html +62 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js +63 silly gunzTarPerm extractEntry bin/nodeunit +64 silly gunzTarPerm extractEntry bin/nodeunit.json +65 silly gunzTarPerm extractEntry deps/async.js +66 silly gunzTarPerm extractEntry deps/console.log.js +67 silly gunzTarPerm extractEntry deps/json2.js +68 silly gunzTarPerm extractEntry deps/ejs/package.json +69 silly gunzTarPerm extractEntry deps/ejs/benchmark.js +70 silly gunzTarPerm extractEntry deps/ejs/ejs.js +71 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js +72 silly gunzTarPerm extractEntry deps/ejs/index.js +73 silly gunzTarPerm extractEntry deps/ejs/examples/list.js +74 silly gunzTarPerm extractEntry deps/ejs/examples/client.html +75 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs +76 silly gunzTarPerm extractEntry deps/ejs/Makefile +77 silly gunzTarPerm extractEntry deps/ejs/Readme.md +78 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js +79 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js +80 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js +81 silly gunzTarPerm extractEntry deps/ejs/support/compile.js +82 silly gunzTarPerm extractEntry deps/ejs/History.md +83 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js +84 silly gunzTarPerm extractEntry doc/nodeunit.md +85 silly gunzTarPerm extractEntry img/example_fail.png +86 silly gunzTarPerm extractEntry img/example_machineout.png +87 silly gunzTarPerm extractEntry img/example_pass.png +88 silly gunzTarPerm extractEntry Makefile +89 silly gunzTarPerm extractEntry lib/assert.js +90 silly gunzTarPerm extractEntry lib/core.js +91 silly gunzTarPerm extractEntry lib/nodeunit.js +92 silly gunzTarPerm extractEntry lib/track.js +93 silly gunzTarPerm extractEntry lib/types.js +94 silly gunzTarPerm extractEntry lib/utils.js +95 silly gunzTarPerm extractEntry lib/reporters/browser.js +96 silly gunzTarPerm extractEntry lib/reporters/html.js +97 silly gunzTarPerm extractEntry lib/reporters/index.js +98 silly gunzTarPerm extractEntry lib/reporters/junit.js +99 silly gunzTarPerm extractEntry lib/reporters/eclipse.js +100 silly gunzTarPerm extractEntry lib/reporters/machineout.js +101 silly gunzTarPerm extractEntry lib/reporters/minimal.js +102 silly gunzTarPerm extractEntry lib/reporters/nested.js +103 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js +104 silly gunzTarPerm extractEntry lib/reporters/tap.js +105 silly gunzTarPerm extractEntry lib/reporters/default.js +106 silly gunzTarPerm extractEntry lib/reporters/verbose.js +107 silly gunzTarPerm extractEntry lib/reporters/lcov.js +108 silly gunzTarPerm extractEntry man1/nodeunit.1 +109 silly gunzTarPerm extractEntry share/license.js +110 silly gunzTarPerm extractEntry share/junit.xml.ejs +111 silly gunzTarPerm extractEntry share/nodeunit.css +112 silly gunzTarPerm extractEntry nodelint.cfg +113 silly gunzTarPerm extractEntry CONTRIBUTORS.md +114 silly gunzTarPerm extractEntry test/test-runfiles.js +115 silly gunzTarPerm extractEntry test/test-cli.js +116 silly gunzTarPerm extractEntry test/test-failing-callbacks.js +117 silly gunzTarPerm extractEntry test/test-httputil.js +118 silly gunzTarPerm extractEntry test/test-bettererrors.js +119 silly gunzTarPerm extractEntry test/test-runmodule.js +120 silly gunzTarPerm extractEntry test/test-runtest.js +121 silly gunzTarPerm extractEntry test/test-sandbox.js +122 silly gunzTarPerm extractEntry test/test-testcase-legacy.js +123 silly gunzTarPerm extractEntry test/test-testcase.js +124 silly gunzTarPerm extractEntry test/test-base.js +125 silly gunzTarPerm extractEntry test/fixtures/example_test.js +126 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js +127 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js +128 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js +129 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js +130 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js +131 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee +132 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js +133 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js +134 silly gunzTarPerm extractEntry test/test.html +135 verbose read json /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package/package.json +136 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +137 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +138 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz +139 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz +140 verbose from cache /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package/package.json +141 verbose tar pack [ '/Users/mleveton/.npm/nodeunit/0.9.1/package.tgz', +141 verbose tar pack '/var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package' ] +142 verbose tarball /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +143 verbose folder /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +144 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +145 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package /Users/mleveton/.npm/892038b7-92107-0-8900070760864764-package.lock +146 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +147 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock +148 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +149 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package +150 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +151 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +152 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +153 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package /Users/mleveton/.npm/91790b02-veton-npm-nodeunit-0-9-1-package.lock +154 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +155 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +156 verbose tar unpack /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +157 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +158 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package /Users/mleveton/.npm/91790b02-veton-npm-nodeunit-0-9-1-package.lock +159 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +160 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock +161 silly gunzTarPerm modes [ '755', '644' ] +162 silly gunzTarPerm extractEntry package.json +163 silly gunzTarPerm extractEntry .npmignore +164 silly gunzTarPerm extractEntry README.md +165 silly gunzTarPerm extractEntry LICENSE +166 silly gunzTarPerm extractEntry index.js +167 silly gunzTarPerm extractEntry bin/nodeunit +168 silly gunzTarPerm extractEntry bin/nodeunit.json +169 silly gunzTarPerm extractEntry deps/async.js +170 silly gunzTarPerm extractEntry deps/console.log.js +171 silly gunzTarPerm extractEntry deps/json2.js +172 silly gunzTarPerm extractEntry deps/ejs/package.json +173 silly gunzTarPerm extractEntry deps/ejs/benchmark.js +174 silly gunzTarPerm extractEntry deps/ejs/ejs.js +175 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js +176 silly gunzTarPerm extractEntry deps/ejs/index.js +177 silly gunzTarPerm extractEntry deps/ejs/examples/list.js +178 silly gunzTarPerm extractEntry deps/ejs/examples/client.html +179 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs +180 silly gunzTarPerm extractEntry deps/ejs/Makefile +181 silly gunzTarPerm extractEntry deps/ejs/Readme.md +182 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js +183 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js +184 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js +185 silly gunzTarPerm extractEntry deps/ejs/History.md +186 silly gunzTarPerm extractEntry deps/ejs/support/compile.js +187 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js +188 silly gunzTarPerm extractEntry doc/nodeunit.md +189 silly gunzTarPerm extractEntry CONTRIBUTORS.md +190 silly gunzTarPerm extractEntry img/example_fail.png +191 silly gunzTarPerm extractEntry img/example_machineout.png +192 silly gunzTarPerm extractEntry img/example_pass.png +193 silly gunzTarPerm extractEntry Makefile +194 silly gunzTarPerm extractEntry lib/assert.js +195 silly gunzTarPerm extractEntry lib/core.js +196 silly gunzTarPerm extractEntry lib/nodeunit.js +197 silly gunzTarPerm extractEntry lib/track.js +198 silly gunzTarPerm extractEntry lib/types.js +199 silly gunzTarPerm extractEntry lib/utils.js +200 silly gunzTarPerm extractEntry lib/reporters/browser.js +201 silly gunzTarPerm extractEntry lib/reporters/html.js +202 silly gunzTarPerm extractEntry lib/reporters/index.js +203 silly gunzTarPerm extractEntry lib/reporters/junit.js +204 silly gunzTarPerm extractEntry lib/reporters/eclipse.js +205 silly gunzTarPerm extractEntry lib/reporters/machineout.js +206 silly gunzTarPerm extractEntry lib/reporters/minimal.js +207 silly gunzTarPerm extractEntry lib/reporters/nested.js +208 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js +209 silly gunzTarPerm extractEntry lib/reporters/tap.js +210 silly gunzTarPerm extractEntry lib/reporters/default.js +211 silly gunzTarPerm extractEntry lib/reporters/verbose.js +212 silly gunzTarPerm extractEntry lib/reporters/lcov.js +213 silly gunzTarPerm extractEntry man1/nodeunit.1 +214 silly gunzTarPerm extractEntry nodelint.cfg +215 silly gunzTarPerm extractEntry test/test-runfiles.js +216 silly gunzTarPerm extractEntry test/test-cli.js +217 silly gunzTarPerm extractEntry test/test-failing-callbacks.js +218 silly gunzTarPerm extractEntry test/test-httputil.js +219 silly gunzTarPerm extractEntry test/test-bettererrors.js +220 silly gunzTarPerm extractEntry test/test-runmodule.js +221 silly gunzTarPerm extractEntry test/test-runtest.js +222 silly gunzTarPerm extractEntry test/test-sandbox.js +223 silly gunzTarPerm extractEntry test/test-testcase-legacy.js +224 silly gunzTarPerm extractEntry test/test-testcase.js +225 silly gunzTarPerm extractEntry test/test-base.js +226 silly gunzTarPerm extractEntry test/fixtures/example_test.js +227 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js +228 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js +229 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js +230 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js +231 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js +232 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee +233 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js +234 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js +235 silly gunzTarPerm extractEntry test/test.html +236 silly gunzTarPerm extractEntry share/license.js +237 silly gunzTarPerm extractEntry share/junit.xml.ejs +238 silly gunzTarPerm extractEntry share/nodeunit.css +239 silly gunzTarPerm extractEntry examples/browser/nodeunit.js +240 silly gunzTarPerm extractEntry examples/browser/suite1.js +241 silly gunzTarPerm extractEntry examples/browser/suite2.js +242 silly gunzTarPerm extractEntry examples/browser/suite3.js +243 silly gunzTarPerm extractEntry examples/browser/test.html +244 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js +245 verbose read json /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json +246 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +247 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package +248 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +249 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +250 verbose from cache /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json +251 verbose chmod /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz 644 +252 verbose chown /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz [ 501, 20 ] +253 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz +254 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz +255 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 +256 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 +257 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 +258 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 +259 silly resolved [ { name: 'nodeunit', +259 silly resolved version: '0.9.1', +259 silly resolved description: 'Easy unit testing for node.js and the browser.', +259 silly resolved maintainers: [ [Object] ], +259 silly resolved contributors: +259 silly resolved [ [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object], +259 silly resolved [Object] ], +259 silly resolved repository: { type: 'git', url: 'http://github.com/caolan/nodeunit.git' }, +259 silly resolved devDependencies: { 'uglify-js': '>=1.1.0', should: '>=0.4.2' }, +259 silly resolved bugs: { url: 'http://github.com/caolan/nodeunit/issues' }, +259 silly resolved licenses: [ [Object] ], +259 silly resolved directories: { lib: './lib', doc: './doc', man: './man1' }, +259 silly resolved bin: { nodeunit: './bin/nodeunit' }, +259 silly resolved dependencies: { tap: '^0.7.1' }, +259 silly resolved scripts: { test: 'node ./bin/nodeunit' }, +259 silly resolved man: [ '/Users/mleveton/.npm/nodeunit/0.9.1/package/man1/nodeunit.1' ], +259 silly resolved readme: 'Nodeunit\n========\n\nSimple syntax, powerful tools. Nodeunit provides easy async unit testing for\nnode.js and the browser.\n\n* Simple to use\n* Just export the tests from a module\n* Works with node.js and in the browser\n* Helps you avoid common pitfalls when testing asynchronous code\n* Easy to add test cases with setUp and tearDown functions if you wish\n* Flexible reporters for custom output, built-in support for HTML and jUnit XML\n* Allows the use of mocks and stubs\n\n__Contributors__\n\n* [alexgorbatchev](https://github.com/alexgorbatchev)\n* [alexkwolfe](https://github.com/alexkwolfe)\n* [azatoth](https://github.com/azatoth)\n* [kadirpekel](https://github.com/kadirpekel)\n* [lambdalisue](https://github.com/lambdalisue)\n* [luebken](https://github.com/luebken)\n* [orlandov](https://github.com/orlandov)\n* [Sannis](https://github.com/Sannis)\n* [sstephenson](https://github.com/sstephenson)\n* [thegreatape](https://github.com/thegreatape)\n* [mmalecki](https://github.com/mmalecki)\n* and thanks to [cjohansen](https://github.com/cjohansen) for input and advice\n on implementing setUp and tearDown functions. See\n [cjohansen\'s fork](https://github.com/cjohansen/nodeunit).\n\nAlso, check out gerad\'s [nodeunit-dsl](https://github.com/gerad/nodeunit-dsl)\nproject, which implements a \'pretty dsl on top of nodeunit\'.\n\nMore contributor information can be found in the\n[CONTRIBUTORS.md](https://github.com/caolan/nodeunit/blob/master/CONTRIBUTORS.md)\nfile.\n\nUsage\n-----\n\nHere is an example unit test module:\n\n exports.testSomething = function(test){\n test.expect(1);\n test.ok(true, "this assertion should pass");\n test.done();\n };\n\n exports.testSomethingElse = function(test){\n test.ok(false, "this assertion should fail");\n test.done();\n };\n\nWhen run using the included test runner, this will output the following:\n\n\n\nInstallation\n------------\n\nThere are two options for installing nodeunit:\n\n1. Clone / download nodeunit from [github](https://github.com/caolan/nodeunit),\n then:\n\n make && sudo make install\n\n2. Install via npm:\n\n npm install nodeunit -g\n\nAPI Documentation\n-----------------\n\nNodeunit uses the functions available in the node.js\n[assert module](http://nodejs.org/docs/v0.4.2/api/assert.html):\n\n* __ok(value, [message])__ - Tests if value is a true value.\n* __equal(actual, expected, [message])__ - Tests shallow, coercive equality\n with the equal comparison operator ( == ).\n* __notEqual(actual, expected, [message])__ - Tests shallow, coercive\n non-equality with the not equal comparison operator ( != ).\n* __deepEqual(actual, expected, [message])__ - Tests for deep equality.\n* __notDeepEqual(actual, expected, [message])__ - Tests for any deep\n inequality.\n* __strictEqual(actual, expected, [message])__ - Tests strict equality, as\n determined by the strict equality operator ( === )\n* __notStrictEqual(actual, expected, [message])__ - Tests strict non-equality,\n as determined by the strict not equal operator ( !== )\n* __throws(block, [error], [message])__ - Expects block to throw an error.\n* __doesNotThrow(block, [error], [message])__ - Expects block not to throw an\n error.\n* __ifError(value)__ - Tests if value is not a false value, throws if it is a\n true value. Useful when testing the first argument, error in callbacks.\n\nNodeunit also provides the following functions within tests:\n\n* __expect(amount)__ - Specify how many assertions are expected to run within a\n test. Very useful for ensuring that all your callbacks and assertions are\n run.\n* __done()__ - Finish the current test function, and move on to the next. ALL\n tests should call this!\n\nNodeunit aims to be simple and easy to learn. This is achieved through using\nexisting structures (such as node.js modules) to maximum effect, and reducing\nthe API where possible, to make it easier to digest.\n\nTests are simply exported from a module, but they are still run in the order\nthey are defined.\n\n__Note:__ Users of old nodeunit versions may remember using `ok`, `equals` and\n`same` in the style of qunit, instead of the assert functions above. These\nfunctions still exist for backwards compatibility, and are simply aliases to\ntheir assert module counterparts.\n\n\nAsynchronous Testing\n--------------------\n\nWhen testing asynchronous code, there are a number of sharp edges to watch out\nfor. Thankfully, nodeunit is designed to help you avoid as many of these\npitfalls as possible. For the most part, testing asynchronous code in nodeunit\n_just works_.\n\n\n### Tests run in series\n\nWhile running tests in parallel seems like a good idea for speeding up your\ntest suite, in practice I\'ve found it means writing much more complicated\ntests. Because of node\'s module cache, running tests in parallel means mocking\nand stubbing is pretty much impossible. One of the nicest things about testing\nin javascript is the ease of doing stubs:\n\n var _readFile = fs.readFile;\n fs.readFile = function(path, callback){\n // it\'s a stub!\n };\n // test function that uses fs.readFile\n\n // we\'re done\n fs.readFile = _readFile;\n\nYou cannot do this when running tests in parallel. In order to keep testing as\nsimple as possible, nodeunit avoids it. Thankfully, most unit-test suites run\nfast anyway.\n\n\n### Explicit ending of tests\n\nWhen testing async code it\'s important that tests end at the correct point, not\njust after a given number of assertions. Otherwise your tests can run short,\nending before all assertions have completed. It\'s important to detect too\nmany assertions as well as too few. Combining explicit ending of tests with\nan expected number of assertions helps to avoid false test passes, so be sure\nto use the `test.expect()` method at the start of your test functions, and\n`test.done()` when finished.\n\n\nGroups, setUp and tearDown\n--------------------------\n\nNodeunit allows the nesting of test functions:\n\n exports.test1 = function (test) {\n ...\n }\n\n exports.group = {\n test2: function (test) {\n ...\n },\n test3: function (test) {\n ...\n }\n }\n\nThis would be run as:\n\n test1\n group - test2\n group - test3\n\nUsing these groups, Nodeunit allows you to define a `setUp` function, which is\nrun before each test, and a `tearDown` function, which is run after each test\ncalls `test.done()`:\n\n module.exports = {\n setUp: function (callback) {\n this.foo = \'bar\';\n callback();\n },\n tearDown: function (callback) {\n // clean up\n callback();\n },\n test1: function (test) {\n test.equals(this.foo, \'bar\');\n test.done();\n }\n };\n\nIn this way, it\'s possible to have multiple groups of tests in a module, each\ngroup with its own setUp and tearDown functions.\n\n\nRunning Tests\n-------------\n\nNodeunit comes with a basic command-line test runner, which can be installed\nusing `sudo make install`. Example usage:\n\n nodeunit testmodule1.js testfolder [...]\n\nIf no entry file specified, `test` defaults.\n\nThe default test reporter uses color output, because I think that\'s more fun :) I\nintend to add a no-color option in future. To give you a feeling of the fun you\'ll\nbe having writing tests, lets fix the example at the start of the README:\n\n\n\nAhhh, Doesn\'t that feel better?\n\nWhen using the included test runner, it will exit using the failed number of\nassertions as the exit code. This means it exits with 0 when all tests pass.\n\n\n### Command-line Options\n\n* __--reporter FILE__ - you can set the test reporter to a custom module or\non of the modules in nodeunit/lib/reporters, when omitted, the default test runner\nis used.\n* __--list-reporters__ - list available built-in reporters.\n* __--config FILE__ - load config options from a JSON file, allows\nthe customisation of color schemes for the default test reporter etc. See\nbin/nodeunit.json for current available options.\n* __-t testName__ - run specifc test only.\n* __-f fullTestName__ - run specific test only. fullTestName is built so: "outerGroup - .. - innerGroup - testName".\n* __--version__ or __-v__ - report nodeunit version\n* __--help__ - show nodeunit help\n\n\nRunning tests in the browser\n----------------------------\n\nNodeunit tests can also be run inside the browser. For example usage, see\nthe examples/browser folder. The basic syntax is as follows:\n\n__test.html__\n\n \n \n Example Test Suite\n \n \n \n \n \n \n

Example Test Suite

\n \n \n \n\nHere, `suite1` and `suite2` are just object literals containing test functions\nor groups, as would be returned if you did `require(\'test-suite\')` in node.js:\n\n__suite1.js__\n\n this.suite1 = {\n \'example test\': function (test) {\n test.ok(true, \'everything is ok\');\n test.done();\n }\n };\n\nIf you wish to use a commonjs format for your test suites (using exports), it is\nup to you to define the commonjs tools for the browser. There are a number of\nalternatives and it\'s important it fits with your existing code, which is\nwhy nodeunit does not currently provide this out of the box.\n\nIn the example above, the tests will run when the page is loaded.\n\nThe browser-version of nodeunit.js is created in dist/browser when you do, `make\nbrowser`. You\'ll need [UglifyJS](https://github.com/mishoo/UglifyJS) installed in\norder for it to automatically create nodeunit.min.js.\n\n\nAdding nodeunit to Your Projects\n--------------------------------\n\nIf you don\'t want people to have to install the nodeunit command-line tool,\nyou\'ll want to create a script that runs the tests for your project with the\ncorrect require paths set up. Here\'s an example test script, that assumes you\nhave nodeunit in a suitably located node_modules directory.\n\n #!/usr/bin/env node\n var reporter = require(\'nodeunit\').reporters.default;\n reporter.run([\'test\']);\n\nIf you\'re using git, you might find it useful to include nodeunit as a\nsubmodule. Using submodules makes it easy for developers to download nodeunit\nand run your test suite, without cluttering up your repository with\nthe source code. To add nodeunit as a git submodule do the following:\n\n git submodule add git://github.com/caolan/nodeunit.git node_modules/nodeunit\n\nThis will add nodeunit to the node_modules folder of your project. Now, when\ncloning the repository, nodeunit can be downloaded by doing the following:\n\n git submodule init\n git submodule update\n\nLet\'s update the test script above with a helpful hint on how to get nodeunit,\nif it\'s missing:\n\n #!/usr/bin/env node\n try {\n var reporter = require(\'nodeunit\').reporters.default;\n }\n catch(e) {\n console.log("Cannot find nodeunit module.");\n console.log("You can download submodules for this project by doing:");\n console.log("");\n console.log(" git submodule init");\n console.log(" git submodule update");\n console.log("");\n process.exit();\n }\n\n process.chdir(__dirname);\n reporter.run([\'test\']);\n\nNow if someone attempts to run your test suite without nodeunit installed they\nwill be prompted to download the submodules for your project.\n\n\nBuilt-in Test Reporters\n-----------------------\n\n* __default__ - The standard reporter seen in the nodeunit screenshots\n* __minimal__ - Pretty, minimal output, shows errors and progress only\n* __html__ - Outputs a HTML report to stdout\n* __junit__ - Creates jUnit compatible XML reports, which can be used with\n continuous integration tools such as [Hudson](http://hudson-ci.org/).\n* __machineout__ - Simple reporter for machine analysis. There is\n [nodeunit.vim](https://github.com/lambdalisue/nodeunit.vim) which is useful for TDD on VIM.\n\n\nWriting a Test Reporter\n---------------------\n\nNodeunit exports runTest(fn, options), runModule(mod, options) and\nrunFiles(paths, options). You\'ll most likely want to run test suites from\nfiles, which can be done using the latter function. The _options_ argument can\ncontain callbacks which run during testing. Nodeunit provides the following\ncallbacks:\n\n* __moduleStart(name)__ - called before a module is tested\n* __moduleDone(name, assertions)__ - called once all test functions within the\n module have completed (see assertions object reference below)\n ALL tests within the module\n* __testStart(name)__ - called before a test function is run\n* __testReady(test)__ - called before a test function is run with the test object that will be passed to the test function\n* __testDone(name, assertions)__ - called once a test function has completed\n (by calling test.done())\n* __log(assertion)__ - called whenever an assertion is made (see assertion\n object reference below)\n* __done(assertions)__ - called after all tests/modules are complete\n\nThe __assertion__ object:\n\n* __passed()__ - did the assertion pass?\n* __failed()__ - did the assertion fail?\n* __error__ - the AssertionError if the assertion failed\n* __method__ - the nodeunit assertion method used (ok, same, equals...)\n* __message__ - the message the assertion method was called with (optional)\n\nThe __assertionList__ object:\n\n* An array-like object with the following new attributes:\n * __failures()__ - the number of assertions which failed\n * __duration__ - the time taken for the test to complete in msecs\n\nFor a reference implementation of a test reporter, see lib/reporters/default.js in\nthe nodeunit project directory.\n\n\nSandbox utility\n---------------\n\nThis is a function which evaluates JavaScript files in a sandbox and returns the\ncontext. The sandbox function can be used for testing client-side code or private\nun-exported functions within a module.\n\n var sandbox = require(\'nodeunit\').utils.sandbox;\n var example = sandbox(\'example.js\');\n\n__sandbox(files, sandbox)__ - Evaluates JavaScript files in a sandbox, returning\nthe context. The first argument can either be a single filename or an array of\nfilenames. If multiple filenames are given their contents are concatenated before\nevaluation. The second argument is an optional context to use for the sandbox.\n\nNote: When working with the sandbox if your script depends on outside sources\n(i.e. using `require`) then you will want to pass that into the optional\ncontext when setting up the sandbox.\n\n var sandbox = require(\'nodeunit\').utils.sandbox;\n // pass in some node globals\n var box_globals = {\n // Passing module.exports into the sandbox will give your code access to it.\n module: {exports: exports},\n // Passing require into the sandbox will give your code access to use it AND\n // will share the cache with modules already required from outside the sandbox.\n require: require,\n // Passing console into the sandbox will give your code access to it\n console: console\n };\n var example = sandbox(\'example.js\', box_globals);\n\n\nRunning the nodeunit Tests\n--------------------------\n\nThe tests for nodeunit are written using nodeunit itself as the test framework.\nHowever, the module test-base.js first does some basic tests using the assert\nmodule to ensure that test functions are actually run, and a basic level of\nnodeunit functionality is available.\n\nTo run the nodeunit tests do:\n\n make test\n\n__Note:__ There was a bug in node v0.2.0 causing the tests to hang, upgrading\nto v0.2.1 fixes this.\n\n\n__machineout__ reporter\n----------------------------------------------\n\nThe default reporter is readable for human but not for machine analysis.\nWhen you want to analyze the output of nodeunit, use __machineout__ reporter and you will get\n\n\n\n\nnodeunit with vim\n----------------------------------\nThere is [nodeunit.vim](https://github.com/lambdalisue/nodeunit.vim) so you can use\nnodeunit with VIM.\n\nThat compiler uses __machineout__ reporter and it is useful to use\nwith [vim-makegreen](https://github.com/reinh/vim-makegreen).\n\n\n\nContributing\n------------\n\nContributions to the project are most welcome, so feel free to fork and improve.\nWhen submitting a pull request, please run `make lint` first to ensure\nwe\'re following a consistent coding style.\n', +259 silly resolved readmeFilename: 'README.md', +259 silly resolved _id: 'nodeunit@0.9.1', +259 silly resolved dist: { shasum: '37ff34c8fec0edf57ebc0cce5053b8a0810bc354' }, +259 silly resolved _from: 'nodeunit@~0.9.0', +259 silly resolved _resolved: 'https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz' } ] +260 info install nodeunit@0.9.1 into /Users/mleveton/Documents/node/node-parse-api +261 info installOne nodeunit@0.9.1 +262 verbose from cache /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json +263 info /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit unbuild +264 verbose read json /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json +265 verbose tar unpack /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +266 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit +267 verbose lock /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit /Users/mleveton/.npm/b8e3d237--parse-api-node-modules-nodeunit.lock +268 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +269 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock +270 silly gunzTarPerm modes [ '755', '644' ] +271 silly gunzTarPerm extractEntry package.json +272 silly gunzTarPerm extractEntry .npmignore +273 silly gunzTarPerm extractEntry README.md +274 silly gunzTarPerm extractEntry LICENSE +275 silly gunzTarPerm extractEntry index.js +276 silly gunzTarPerm extractEntry bin/nodeunit +277 silly gunzTarPerm extractEntry bin/nodeunit.json +278 silly gunzTarPerm extractEntry deps/async.js +279 silly gunzTarPerm extractEntry deps/console.log.js +280 silly gunzTarPerm extractEntry deps/json2.js +281 silly gunzTarPerm extractEntry deps/ejs/package.json +282 silly gunzTarPerm extractEntry deps/ejs/benchmark.js +283 silly gunzTarPerm extractEntry deps/ejs/ejs.js +284 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js +285 silly gunzTarPerm extractEntry deps/ejs/index.js +286 silly gunzTarPerm extractEntry deps/ejs/examples/list.js +287 silly gunzTarPerm extractEntry deps/ejs/examples/client.html +288 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs +289 silly gunzTarPerm extractEntry deps/ejs/Makefile +290 silly gunzTarPerm extractEntry deps/ejs/Readme.md +291 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js +292 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js +293 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js +294 silly gunzTarPerm extractEntry deps/ejs/History.md +295 silly gunzTarPerm extractEntry deps/ejs/support/compile.js +296 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js +297 silly gunzTarPerm extractEntry doc/nodeunit.md +298 silly gunzTarPerm extractEntry CONTRIBUTORS.md +299 silly gunzTarPerm extractEntry img/example_fail.png +300 silly gunzTarPerm extractEntry img/example_machineout.png +301 silly gunzTarPerm extractEntry img/example_pass.png +302 silly gunzTarPerm extractEntry Makefile +303 silly gunzTarPerm extractEntry lib/assert.js +304 silly gunzTarPerm extractEntry lib/core.js +305 silly gunzTarPerm extractEntry lib/nodeunit.js +306 silly gunzTarPerm extractEntry lib/track.js +307 silly gunzTarPerm extractEntry lib/types.js +308 silly gunzTarPerm extractEntry lib/utils.js +309 silly gunzTarPerm extractEntry lib/reporters/browser.js +310 silly gunzTarPerm extractEntry lib/reporters/html.js +311 silly gunzTarPerm extractEntry lib/reporters/index.js +312 silly gunzTarPerm extractEntry lib/reporters/junit.js +313 silly gunzTarPerm extractEntry lib/reporters/eclipse.js +314 silly gunzTarPerm extractEntry lib/reporters/machineout.js +315 silly gunzTarPerm extractEntry lib/reporters/minimal.js +316 silly gunzTarPerm extractEntry lib/reporters/nested.js +317 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js +318 silly gunzTarPerm extractEntry lib/reporters/tap.js +319 silly gunzTarPerm extractEntry lib/reporters/default.js +320 silly gunzTarPerm extractEntry lib/reporters/verbose.js +321 silly gunzTarPerm extractEntry lib/reporters/lcov.js +322 silly gunzTarPerm extractEntry man1/nodeunit.1 +323 silly gunzTarPerm extractEntry nodelint.cfg +324 silly gunzTarPerm extractEntry test/test-runfiles.js +325 silly gunzTarPerm extractEntry test/test-cli.js +326 silly gunzTarPerm extractEntry test/test-failing-callbacks.js +327 silly gunzTarPerm extractEntry test/test-httputil.js +328 silly gunzTarPerm extractEntry test/test-bettererrors.js +329 silly gunzTarPerm extractEntry test/test-runmodule.js +330 silly gunzTarPerm extractEntry test/test-runtest.js +331 silly gunzTarPerm extractEntry test/test-sandbox.js +332 silly gunzTarPerm extractEntry test/test-testcase-legacy.js +333 silly gunzTarPerm extractEntry test/test-testcase.js +334 silly gunzTarPerm extractEntry test/test-base.js +335 silly gunzTarPerm extractEntry test/fixtures/example_test.js +336 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js +337 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js +338 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js +339 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js +340 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js +341 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee +342 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js +343 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js +344 silly gunzTarPerm extractEntry test/test.html +345 silly gunzTarPerm extractEntry share/license.js +346 silly gunzTarPerm extractEntry share/junit.xml.ejs +347 silly gunzTarPerm extractEntry share/nodeunit.css +348 silly gunzTarPerm extractEntry examples/browser/nodeunit.js +349 silly gunzTarPerm extractEntry examples/browser/suite1.js +350 silly gunzTarPerm extractEntry examples/browser/suite2.js +351 silly gunzTarPerm extractEntry examples/browser/suite3.js +352 silly gunzTarPerm extractEntry examples/browser/test.html +353 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js +354 verbose read json /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json +355 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit +356 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit +357 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +358 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz +359 info preinstall nodeunit@0.9.1 +360 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json +361 verbose readDependencies using package.json deps +362 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json +363 verbose readDependencies using package.json deps +364 verbose cache add [ 'tap@^0.7.1', null ] +365 verbose cache add name=undefined spec="tap@^0.7.1" args=["tap@^0.7.1",null] +366 verbose parsed url { protocol: null, +366 verbose parsed url slashes: null, +366 verbose parsed url auth: null, +366 verbose parsed url host: null, +366 verbose parsed url port: null, +366 verbose parsed url hostname: null, +366 verbose parsed url hash: null, +366 verbose parsed url search: null, +366 verbose parsed url query: null, +366 verbose parsed url pathname: 'tap@^0.7.1', +366 verbose parsed url path: 'tap@^0.7.1', +366 verbose parsed url href: 'tap@^0.7.1' } +367 verbose cache add name="tap" spec="^0.7.1" args=["tap","^0.7.1"] +368 verbose parsed url { protocol: null, +368 verbose parsed url slashes: null, +368 verbose parsed url auth: null, +368 verbose parsed url host: null, +368 verbose parsed url port: null, +368 verbose parsed url hostname: null, +368 verbose parsed url hash: null, +368 verbose parsed url search: null, +368 verbose parsed url query: null, +368 verbose parsed url pathname: '^0.7.1', +368 verbose parsed url path: '^0.7.1', +368 verbose parsed url href: '^0.7.1' } +369 verbose addNamed [ 'tap', '^0.7.1' ] +370 verbose addNamed [ null, null ] +371 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 +372 verbose lock tap@^0.7.1 /Users/mleveton/.npm/50b1620e-tap-0-7-1.lock +373 info addNameTag [ 'tap', '^0.7.1' ] +374 verbose url raw tap +375 verbose url resolving [ 'https://registry.npmjs.org/', './tap' ] +376 verbose url resolved https://registry.npmjs.org/tap +377 info trying registry request attempt 1 at 21:39:58 +378 verbose etag "A52165LP2BJ0ED5UT4KDATU6Y" +379 http GET https://registry.npmjs.org/tap +380 http 200 https://registry.npmjs.org/tap +381 silly registry.get cb [ 200, +381 silly registry.get { date: 'Thu, 19 Mar 2015 01:39:59 GMT', +381 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)', +381 silly registry.get etag: '"84452RW0P649DLKHI249CYPFY"', +381 silly registry.get 'content-type': 'application/json', +381 silly registry.get 'cache-control': 'max-age=60', +381 silly registry.get 'content-length': '64851', +381 silly registry.get 'accept-ranges': 'bytes', +381 silly registry.get via: '1.1 varnish', +381 silly registry.get 'x-served-by': 'cache-jfk1029-JFK', +381 silly registry.get 'x-cache': 'MISS', +381 silly registry.get 'x-cache-hits': '0', +381 silly registry.get 'x-timer': 'S1426729199.152788,VS0,VE185', +381 silly registry.get vary: 'Accept', +381 silly registry.get 'keep-alive': 'timeout=10, max=50', +381 silly registry.get connection: 'Keep-Alive' } ] +382 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 +383 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 +384 verbose about to build /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit +385 info /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit unbuild +386 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json +387 info preuninstall nodeunit@0.9.1 +388 info uninstall nodeunit@0.9.1 +389 verbose true,/Users/mleveton/Documents/node/node-parse-api/node_modules,/Users/mleveton/Documents/node/node-parse-api/node_modules unbuild nodeunit@0.9.1 +390 verbose /Users/mleveton/Documents/node/node-parse-api/node_modules/.bin,[object Object] binRoot +391 info postuninstall nodeunit@0.9.1 +392 error Error: No compatible version found: tap@'^0.7.1' +392 error Valid install targets: +392 error ["0.0.1","0.0.2","0.0.3","0.0.4","0.0.5","0.0.6","0.0.7","0.0.8","0.0.9","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.1.0","0.1.1","0.1.2","0.1.3","0.1.4","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.3.3","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","0.4.11","0.4.12","0.4.13","0.5.0","0.6.0","0.7.0","0.7.1"] +392 error at installTargetsError (/Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/lib/cache.js:709:10) +392 error at /Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/lib/cache.js:631:10 +392 error at saved (/Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:138:7) +392 error at Object.oncomplete (fs.js:107:15) +393 error If you need help, you may report this log at: +393 error +393 error or email it to: +393 error +394 error System Darwin 13.4.0 +395 error command "/Users/mleveton/.nvm/v0.10.10/bin/node" "/Users/mleveton/.nvm/v0.10.10/bin/npm" "link" +396 error cwd /Users/mleveton/Documents/node/node-parse-api +397 error node -v v0.10.10 +398 error npm -v 1.2.25 +399 verbose exit [ 1, true ] diff --git a/package.json b/package.json index f665eb5..f870715 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.5", + "version": "0.3.6", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ "Daniel Gasienica ", From 798e78d41ace0ac37c4f070b71a03d22074f5422 Mon Sep 17 00:00:00 2001 From: Wei Date: Mon, 22 Jun 2015 13:58:19 +0800 Subject: [PATCH 83/95] patch for utf-8 search --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 81c2418..18f6d40 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -52,7 +52,7 @@ Parse.prototype = { // check to see if there is a 'where' object in the query object // the 'where' object need to be stringified by JSON.stringify(), not querystring if ( query.hasOwnProperty('where') ) { - url += '?where=' + JSON.stringify(query.where); + url += '?where=' + encodeURIComponent(JSON.stringify(query.where)); delete query.where; } From 87cbfbaf9ba07921204d92d227e26971920cfae2 Mon Sep 17 00:00:00 2001 From: Leveton Date: Wed, 24 Jun 2015 20:49:57 -0400 Subject: [PATCH 84/95] updated version --- npm-debug.log | 556 -------------------------------------------------- package.json | 2 +- 2 files changed, 1 insertion(+), 557 deletions(-) delete mode 100644 npm-debug.log diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index c301034..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,556 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ '/Users/mleveton/.nvm/v0.10.10/bin/node', -1 verbose cli '/Users/mleveton/.nvm/v0.10.10/bin/npm', -1 verbose cli 'link' ] -2 info using npm@1.2.25 -3 info using node@v0.10.10 -4 verbose linkPkg /Users/mleveton/Documents/node/node-parse-api -5 verbose read json /Users/mleveton/Documents/node/node-parse-api/package.json -6 verbose link build target /Users/mleveton/.nvm/v0.10.10/lib/node_modules/node-parse-api -7 verbose install where,what [ '/Users/mleveton/Documents/node/node-parse-api', [] ] -8 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json -9 verbose readDependencies using package.json deps -10 verbose install where, deps [ '/Users/mleveton/Documents/node/node-parse-api', -10 verbose install [ 'nodeunit' ] ] -11 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json -12 info preinstall node-parse-api@0.3.6 -13 verbose from cache /Users/mleveton/Documents/node/node-parse-api/package.json -14 verbose readDependencies using package.json deps -15 verbose cache add [ 'nodeunit@~0.9.0', null ] -16 verbose cache add name=undefined spec="nodeunit@~0.9.0" args=["nodeunit@~0.9.0",null] -17 verbose parsed url { protocol: null, -17 verbose parsed url slashes: null, -17 verbose parsed url auth: null, -17 verbose parsed url host: null, -17 verbose parsed url port: null, -17 verbose parsed url hostname: null, -17 verbose parsed url hash: null, -17 verbose parsed url search: null, -17 verbose parsed url query: null, -17 verbose parsed url pathname: 'nodeunit@~0.9.0', -17 verbose parsed url path: 'nodeunit@~0.9.0', -17 verbose parsed url href: 'nodeunit@~0.9.0' } -18 verbose cache add name="nodeunit" spec="~0.9.0" args=["nodeunit","~0.9.0"] -19 verbose parsed url { protocol: null, -19 verbose parsed url slashes: null, -19 verbose parsed url auth: null, -19 verbose parsed url host: null, -19 verbose parsed url port: null, -19 verbose parsed url hostname: null, -19 verbose parsed url hash: null, -19 verbose parsed url search: null, -19 verbose parsed url query: null, -19 verbose parsed url pathname: '~0.9.0', -19 verbose parsed url path: '~0.9.0', -19 verbose parsed url href: '~0.9.0' } -20 verbose addNamed [ 'nodeunit', '~0.9.0' ] -21 verbose addNamed [ null, '>=0.9.0- <0.10.0-' ] -22 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 -23 verbose lock nodeunit@~0.9.0 /Users/mleveton/.npm/98d576fd-nodeunit-0-9-0.lock -24 silly addNameRange { name: 'nodeunit', range: '>=0.9.0- <0.10.0-', hasData: false } -25 verbose url raw nodeunit -26 verbose url resolving [ 'https://registry.npmjs.org/', './nodeunit' ] -27 verbose url resolved https://registry.npmjs.org/nodeunit -28 info trying registry request attempt 1 at 21:39:51 -29 verbose etag "9CSC8MA50OTTQFV9VUZZKPFX4" -30 http GET https://registry.npmjs.org/nodeunit -31 http 200 https://registry.npmjs.org/nodeunit -32 silly registry.get cb [ 200, -32 silly registry.get { date: 'Thu, 19 Mar 2015 01:39:51 GMT', -32 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)', -32 silly registry.get etag: '"7U37RWKY0Z5CK6UIC0H4M97VZ"', -32 silly registry.get 'content-type': 'application/json', -32 silly registry.get 'cache-control': 'max-age=60', -32 silly registry.get 'content-length': '73860', -32 silly registry.get 'accept-ranges': 'bytes', -32 silly registry.get via: '1.1 varnish', -32 silly registry.get 'x-served-by': 'cache-jfk1025-JFK', -32 silly registry.get 'x-cache': 'MISS', -32 silly registry.get 'x-cache-hits': '0', -32 silly registry.get 'x-timer': 'S1426729191.823406,VS0,VE43', -32 silly registry.get vary: 'Accept', -32 silly registry.get 'keep-alive': 'timeout=10, max=50', -32 silly registry.get connection: 'Keep-Alive' } ] -33 silly addNameRange number 2 { name: 'nodeunit', range: '>=0.9.0- <0.10.0-', hasData: true } -34 silly addNameRange versions [ 'nodeunit', -34 silly addNameRange [ '0.1.0', -34 silly addNameRange '0.1.1', -34 silly addNameRange '0.1.2', -34 silly addNameRange '0.2.0', -34 silly addNameRange '0.2.1', -34 silly addNameRange '0.2.2', -34 silly addNameRange '0.2.3', -34 silly addNameRange '0.2.4', -34 silly addNameRange '0.3.1', -34 silly addNameRange '0.4.0', -34 silly addNameRange '0.5.0', -34 silly addNameRange '0.5.1', -34 silly addNameRange '0.5.2', -34 silly addNameRange '0.5.3', -34 silly addNameRange '0.5.4', -34 silly addNameRange '0.5.5', -34 silly addNameRange '0.6.0', -34 silly addNameRange '0.6.1', -34 silly addNameRange '0.6.2', -34 silly addNameRange '0.6.3', -34 silly addNameRange '0.6.4', -34 silly addNameRange '0.7.0', -34 silly addNameRange '0.7.1', -34 silly addNameRange '0.7.2', -34 silly addNameRange '0.7.3', -34 silly addNameRange '0.7.4', -34 silly addNameRange '0.8.0', -34 silly addNameRange '0.8.1', -34 silly addNameRange '0.8.2', -34 silly addNameRange '0.8.3', -34 silly addNameRange '0.8.4', -34 silly addNameRange '0.8.5', -34 silly addNameRange '0.8.6', -34 silly addNameRange '0.8.8', -34 silly addNameRange '0.8.7', -34 silly addNameRange '0.9.0', -34 silly addNameRange '0.9.1' ] ] -35 verbose addNamed [ 'nodeunit', '0.9.1' ] -36 verbose addNamed [ '0.9.1', '0.9.1' ] -37 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 -38 verbose lock nodeunit@0.9.1 /Users/mleveton/.npm/392547d8-nodeunit-0-9-1.lock -39 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz -40 verbose lock https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz /Users/mleveton/.npm/0f972367--org-nodeunit-nodeunit-0-9-1-tgz.lock -41 verbose addRemoteTarball [ 'https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz', -41 verbose addRemoteTarball 'e553dd41d8769402c3b9ab32d0e72e9668405139' ] -42 info retry fetch attempt 1 at 21:39:52 -43 verbose fetch to= /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz -44 http GET https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz -45 http 200 https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz -46 verbose tar unpack /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz -47 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -48 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package /Users/mleveton/.npm/892038b7-92107-0-8900070760864764-package.lock -49 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz -50 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz /Users/mleveton/.npm/a5e887f6-92107-0-8900070760864764-tmp-tgz.lock -51 silly gunzTarPerm modes [ '755', '644' ] -52 silly gunzTarPerm extractEntry package.json -53 silly gunzTarPerm extractEntry .npmignore -54 silly gunzTarPerm extractEntry README.md -55 silly gunzTarPerm extractEntry LICENSE -56 silly gunzTarPerm extractEntry index.js -57 silly gunzTarPerm extractEntry examples/browser/nodeunit.js -58 silly gunzTarPerm extractEntry examples/browser/suite1.js -59 silly gunzTarPerm extractEntry examples/browser/suite2.js -60 silly gunzTarPerm extractEntry examples/browser/suite3.js -61 silly gunzTarPerm extractEntry examples/browser/test.html -62 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js -63 silly gunzTarPerm extractEntry bin/nodeunit -64 silly gunzTarPerm extractEntry bin/nodeunit.json -65 silly gunzTarPerm extractEntry deps/async.js -66 silly gunzTarPerm extractEntry deps/console.log.js -67 silly gunzTarPerm extractEntry deps/json2.js -68 silly gunzTarPerm extractEntry deps/ejs/package.json -69 silly gunzTarPerm extractEntry deps/ejs/benchmark.js -70 silly gunzTarPerm extractEntry deps/ejs/ejs.js -71 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js -72 silly gunzTarPerm extractEntry deps/ejs/index.js -73 silly gunzTarPerm extractEntry deps/ejs/examples/list.js -74 silly gunzTarPerm extractEntry deps/ejs/examples/client.html -75 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs -76 silly gunzTarPerm extractEntry deps/ejs/Makefile -77 silly gunzTarPerm extractEntry deps/ejs/Readme.md -78 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js -79 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js -80 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js -81 silly gunzTarPerm extractEntry deps/ejs/support/compile.js -82 silly gunzTarPerm extractEntry deps/ejs/History.md -83 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js -84 silly gunzTarPerm extractEntry doc/nodeunit.md -85 silly gunzTarPerm extractEntry img/example_fail.png -86 silly gunzTarPerm extractEntry img/example_machineout.png -87 silly gunzTarPerm extractEntry img/example_pass.png -88 silly gunzTarPerm extractEntry Makefile -89 silly gunzTarPerm extractEntry lib/assert.js -90 silly gunzTarPerm extractEntry lib/core.js -91 silly gunzTarPerm extractEntry lib/nodeunit.js -92 silly gunzTarPerm extractEntry lib/track.js -93 silly gunzTarPerm extractEntry lib/types.js -94 silly gunzTarPerm extractEntry lib/utils.js -95 silly gunzTarPerm extractEntry lib/reporters/browser.js -96 silly gunzTarPerm extractEntry lib/reporters/html.js -97 silly gunzTarPerm extractEntry lib/reporters/index.js -98 silly gunzTarPerm extractEntry lib/reporters/junit.js -99 silly gunzTarPerm extractEntry lib/reporters/eclipse.js -100 silly gunzTarPerm extractEntry lib/reporters/machineout.js -101 silly gunzTarPerm extractEntry lib/reporters/minimal.js -102 silly gunzTarPerm extractEntry lib/reporters/nested.js -103 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js -104 silly gunzTarPerm extractEntry lib/reporters/tap.js -105 silly gunzTarPerm extractEntry lib/reporters/default.js -106 silly gunzTarPerm extractEntry lib/reporters/verbose.js -107 silly gunzTarPerm extractEntry lib/reporters/lcov.js -108 silly gunzTarPerm extractEntry man1/nodeunit.1 -109 silly gunzTarPerm extractEntry share/license.js -110 silly gunzTarPerm extractEntry share/junit.xml.ejs -111 silly gunzTarPerm extractEntry share/nodeunit.css -112 silly gunzTarPerm extractEntry nodelint.cfg -113 silly gunzTarPerm extractEntry CONTRIBUTORS.md -114 silly gunzTarPerm extractEntry test/test-runfiles.js -115 silly gunzTarPerm extractEntry test/test-cli.js -116 silly gunzTarPerm extractEntry test/test-failing-callbacks.js -117 silly gunzTarPerm extractEntry test/test-httputil.js -118 silly gunzTarPerm extractEntry test/test-bettererrors.js -119 silly gunzTarPerm extractEntry test/test-runmodule.js -120 silly gunzTarPerm extractEntry test/test-runtest.js -121 silly gunzTarPerm extractEntry test/test-sandbox.js -122 silly gunzTarPerm extractEntry test/test-testcase-legacy.js -123 silly gunzTarPerm extractEntry test/test-testcase.js -124 silly gunzTarPerm extractEntry test/test-base.js -125 silly gunzTarPerm extractEntry test/fixtures/example_test.js -126 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js -127 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js -128 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js -129 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js -130 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js -131 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee -132 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js -133 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js -134 silly gunzTarPerm extractEntry test/test.html -135 verbose read json /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package/package.json -136 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -137 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -138 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz -139 silly lockFile a5e887f6-92107-0-8900070760864764-tmp-tgz /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/tmp.tgz -140 verbose from cache /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package/package.json -141 verbose tar pack [ '/Users/mleveton/.npm/nodeunit/0.9.1/package.tgz', -141 verbose tar pack '/var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package' ] -142 verbose tarball /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -143 verbose folder /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -144 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -145 verbose lock /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package /Users/mleveton/.npm/892038b7-92107-0-8900070760864764-package.lock -146 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -147 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock -148 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -149 silly lockFile 892038b7-92107-0-8900070760864764-package /var/folders/hb/b_7grhvj59j7ycy8l42h5cch0000gn/T/npm-89110/1426729192107-0.8900070760864764/package -150 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -151 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -152 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -153 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package /Users/mleveton/.npm/91790b02-veton-npm-nodeunit-0-9-1-package.lock -154 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -155 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -156 verbose tar unpack /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -157 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -158 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package /Users/mleveton/.npm/91790b02-veton-npm-nodeunit-0-9-1-package.lock -159 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -160 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock -161 silly gunzTarPerm modes [ '755', '644' ] -162 silly gunzTarPerm extractEntry package.json -163 silly gunzTarPerm extractEntry .npmignore -164 silly gunzTarPerm extractEntry README.md -165 silly gunzTarPerm extractEntry LICENSE -166 silly gunzTarPerm extractEntry index.js -167 silly gunzTarPerm extractEntry bin/nodeunit -168 silly gunzTarPerm extractEntry bin/nodeunit.json -169 silly gunzTarPerm extractEntry deps/async.js -170 silly gunzTarPerm extractEntry deps/console.log.js -171 silly gunzTarPerm extractEntry deps/json2.js -172 silly gunzTarPerm extractEntry deps/ejs/package.json -173 silly gunzTarPerm extractEntry deps/ejs/benchmark.js -174 silly gunzTarPerm extractEntry deps/ejs/ejs.js -175 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js -176 silly gunzTarPerm extractEntry deps/ejs/index.js -177 silly gunzTarPerm extractEntry deps/ejs/examples/list.js -178 silly gunzTarPerm extractEntry deps/ejs/examples/client.html -179 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs -180 silly gunzTarPerm extractEntry deps/ejs/Makefile -181 silly gunzTarPerm extractEntry deps/ejs/Readme.md -182 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js -183 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js -184 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js -185 silly gunzTarPerm extractEntry deps/ejs/History.md -186 silly gunzTarPerm extractEntry deps/ejs/support/compile.js -187 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js -188 silly gunzTarPerm extractEntry doc/nodeunit.md -189 silly gunzTarPerm extractEntry CONTRIBUTORS.md -190 silly gunzTarPerm extractEntry img/example_fail.png -191 silly gunzTarPerm extractEntry img/example_machineout.png -192 silly gunzTarPerm extractEntry img/example_pass.png -193 silly gunzTarPerm extractEntry Makefile -194 silly gunzTarPerm extractEntry lib/assert.js -195 silly gunzTarPerm extractEntry lib/core.js -196 silly gunzTarPerm extractEntry lib/nodeunit.js -197 silly gunzTarPerm extractEntry lib/track.js -198 silly gunzTarPerm extractEntry lib/types.js -199 silly gunzTarPerm extractEntry lib/utils.js -200 silly gunzTarPerm extractEntry lib/reporters/browser.js -201 silly gunzTarPerm extractEntry lib/reporters/html.js -202 silly gunzTarPerm extractEntry lib/reporters/index.js -203 silly gunzTarPerm extractEntry lib/reporters/junit.js -204 silly gunzTarPerm extractEntry lib/reporters/eclipse.js -205 silly gunzTarPerm extractEntry lib/reporters/machineout.js -206 silly gunzTarPerm extractEntry lib/reporters/minimal.js -207 silly gunzTarPerm extractEntry lib/reporters/nested.js -208 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js -209 silly gunzTarPerm extractEntry lib/reporters/tap.js -210 silly gunzTarPerm extractEntry lib/reporters/default.js -211 silly gunzTarPerm extractEntry lib/reporters/verbose.js -212 silly gunzTarPerm extractEntry lib/reporters/lcov.js -213 silly gunzTarPerm extractEntry man1/nodeunit.1 -214 silly gunzTarPerm extractEntry nodelint.cfg -215 silly gunzTarPerm extractEntry test/test-runfiles.js -216 silly gunzTarPerm extractEntry test/test-cli.js -217 silly gunzTarPerm extractEntry test/test-failing-callbacks.js -218 silly gunzTarPerm extractEntry test/test-httputil.js -219 silly gunzTarPerm extractEntry test/test-bettererrors.js -220 silly gunzTarPerm extractEntry test/test-runmodule.js -221 silly gunzTarPerm extractEntry test/test-runtest.js -222 silly gunzTarPerm extractEntry test/test-sandbox.js -223 silly gunzTarPerm extractEntry test/test-testcase-legacy.js -224 silly gunzTarPerm extractEntry test/test-testcase.js -225 silly gunzTarPerm extractEntry test/test-base.js -226 silly gunzTarPerm extractEntry test/fixtures/example_test.js -227 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js -228 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js -229 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js -230 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js -231 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js -232 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee -233 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js -234 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js -235 silly gunzTarPerm extractEntry test/test.html -236 silly gunzTarPerm extractEntry share/license.js -237 silly gunzTarPerm extractEntry share/junit.xml.ejs -238 silly gunzTarPerm extractEntry share/nodeunit.css -239 silly gunzTarPerm extractEntry examples/browser/nodeunit.js -240 silly gunzTarPerm extractEntry examples/browser/suite1.js -241 silly gunzTarPerm extractEntry examples/browser/suite2.js -242 silly gunzTarPerm extractEntry examples/browser/suite3.js -243 silly gunzTarPerm extractEntry examples/browser/test.html -244 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js -245 verbose read json /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json -246 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -247 silly lockFile 91790b02-veton-npm-nodeunit-0-9-1-package /Users/mleveton/.npm/nodeunit/0.9.1/package -248 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -249 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -250 verbose from cache /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json -251 verbose chmod /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz 644 -252 verbose chown /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz [ 501, 20 ] -253 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz -254 silly lockFile 0f972367--org-nodeunit-nodeunit-0-9-1-tgz https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz -255 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 -256 silly lockFile 392547d8-nodeunit-0-9-1 nodeunit@0.9.1 -257 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 -258 silly lockFile 98d576fd-nodeunit-0-9-0 nodeunit@~0.9.0 -259 silly resolved [ { name: 'nodeunit', -259 silly resolved version: '0.9.1', -259 silly resolved description: 'Easy unit testing for node.js and the browser.', -259 silly resolved maintainers: [ [Object] ], -259 silly resolved contributors: -259 silly resolved [ [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object], -259 silly resolved [Object] ], -259 silly resolved repository: { type: 'git', url: 'http://github.com/caolan/nodeunit.git' }, -259 silly resolved devDependencies: { 'uglify-js': '>=1.1.0', should: '>=0.4.2' }, -259 silly resolved bugs: { url: 'http://github.com/caolan/nodeunit/issues' }, -259 silly resolved licenses: [ [Object] ], -259 silly resolved directories: { lib: './lib', doc: './doc', man: './man1' }, -259 silly resolved bin: { nodeunit: './bin/nodeunit' }, -259 silly resolved dependencies: { tap: '^0.7.1' }, -259 silly resolved scripts: { test: 'node ./bin/nodeunit' }, -259 silly resolved man: [ '/Users/mleveton/.npm/nodeunit/0.9.1/package/man1/nodeunit.1' ], -259 silly resolved readme: 'Nodeunit\n========\n\nSimple syntax, powerful tools. Nodeunit provides easy async unit testing for\nnode.js and the browser.\n\n* Simple to use\n* Just export the tests from a module\n* Works with node.js and in the browser\n* Helps you avoid common pitfalls when testing asynchronous code\n* Easy to add test cases with setUp and tearDown functions if you wish\n* Flexible reporters for custom output, built-in support for HTML and jUnit XML\n* Allows the use of mocks and stubs\n\n__Contributors__\n\n* [alexgorbatchev](https://github.com/alexgorbatchev)\n* [alexkwolfe](https://github.com/alexkwolfe)\n* [azatoth](https://github.com/azatoth)\n* [kadirpekel](https://github.com/kadirpekel)\n* [lambdalisue](https://github.com/lambdalisue)\n* [luebken](https://github.com/luebken)\n* [orlandov](https://github.com/orlandov)\n* [Sannis](https://github.com/Sannis)\n* [sstephenson](https://github.com/sstephenson)\n* [thegreatape](https://github.com/thegreatape)\n* [mmalecki](https://github.com/mmalecki)\n* and thanks to [cjohansen](https://github.com/cjohansen) for input and advice\n on implementing setUp and tearDown functions. See\n [cjohansen\'s fork](https://github.com/cjohansen/nodeunit).\n\nAlso, check out gerad\'s [nodeunit-dsl](https://github.com/gerad/nodeunit-dsl)\nproject, which implements a \'pretty dsl on top of nodeunit\'.\n\nMore contributor information can be found in the\n[CONTRIBUTORS.md](https://github.com/caolan/nodeunit/blob/master/CONTRIBUTORS.md)\nfile.\n\nUsage\n-----\n\nHere is an example unit test module:\n\n exports.testSomething = function(test){\n test.expect(1);\n test.ok(true, "this assertion should pass");\n test.done();\n };\n\n exports.testSomethingElse = function(test){\n test.ok(false, "this assertion should fail");\n test.done();\n };\n\nWhen run using the included test runner, this will output the following:\n\n\n\nInstallation\n------------\n\nThere are two options for installing nodeunit:\n\n1. Clone / download nodeunit from [github](https://github.com/caolan/nodeunit),\n then:\n\n make && sudo make install\n\n2. Install via npm:\n\n npm install nodeunit -g\n\nAPI Documentation\n-----------------\n\nNodeunit uses the functions available in the node.js\n[assert module](http://nodejs.org/docs/v0.4.2/api/assert.html):\n\n* __ok(value, [message])__ - Tests if value is a true value.\n* __equal(actual, expected, [message])__ - Tests shallow, coercive equality\n with the equal comparison operator ( == ).\n* __notEqual(actual, expected, [message])__ - Tests shallow, coercive\n non-equality with the not equal comparison operator ( != ).\n* __deepEqual(actual, expected, [message])__ - Tests for deep equality.\n* __notDeepEqual(actual, expected, [message])__ - Tests for any deep\n inequality.\n* __strictEqual(actual, expected, [message])__ - Tests strict equality, as\n determined by the strict equality operator ( === )\n* __notStrictEqual(actual, expected, [message])__ - Tests strict non-equality,\n as determined by the strict not equal operator ( !== )\n* __throws(block, [error], [message])__ - Expects block to throw an error.\n* __doesNotThrow(block, [error], [message])__ - Expects block not to throw an\n error.\n* __ifError(value)__ - Tests if value is not a false value, throws if it is a\n true value. Useful when testing the first argument, error in callbacks.\n\nNodeunit also provides the following functions within tests:\n\n* __expect(amount)__ - Specify how many assertions are expected to run within a\n test. Very useful for ensuring that all your callbacks and assertions are\n run.\n* __done()__ - Finish the current test function, and move on to the next. ALL\n tests should call this!\n\nNodeunit aims to be simple and easy to learn. This is achieved through using\nexisting structures (such as node.js modules) to maximum effect, and reducing\nthe API where possible, to make it easier to digest.\n\nTests are simply exported from a module, but they are still run in the order\nthey are defined.\n\n__Note:__ Users of old nodeunit versions may remember using `ok`, `equals` and\n`same` in the style of qunit, instead of the assert functions above. These\nfunctions still exist for backwards compatibility, and are simply aliases to\ntheir assert module counterparts.\n\n\nAsynchronous Testing\n--------------------\n\nWhen testing asynchronous code, there are a number of sharp edges to watch out\nfor. Thankfully, nodeunit is designed to help you avoid as many of these\npitfalls as possible. For the most part, testing asynchronous code in nodeunit\n_just works_.\n\n\n### Tests run in series\n\nWhile running tests in parallel seems like a good idea for speeding up your\ntest suite, in practice I\'ve found it means writing much more complicated\ntests. Because of node\'s module cache, running tests in parallel means mocking\nand stubbing is pretty much impossible. One of the nicest things about testing\nin javascript is the ease of doing stubs:\n\n var _readFile = fs.readFile;\n fs.readFile = function(path, callback){\n // it\'s a stub!\n };\n // test function that uses fs.readFile\n\n // we\'re done\n fs.readFile = _readFile;\n\nYou cannot do this when running tests in parallel. In order to keep testing as\nsimple as possible, nodeunit avoids it. Thankfully, most unit-test suites run\nfast anyway.\n\n\n### Explicit ending of tests\n\nWhen testing async code it\'s important that tests end at the correct point, not\njust after a given number of assertions. Otherwise your tests can run short,\nending before all assertions have completed. It\'s important to detect too\nmany assertions as well as too few. Combining explicit ending of tests with\nan expected number of assertions helps to avoid false test passes, so be sure\nto use the `test.expect()` method at the start of your test functions, and\n`test.done()` when finished.\n\n\nGroups, setUp and tearDown\n--------------------------\n\nNodeunit allows the nesting of test functions:\n\n exports.test1 = function (test) {\n ...\n }\n\n exports.group = {\n test2: function (test) {\n ...\n },\n test3: function (test) {\n ...\n }\n }\n\nThis would be run as:\n\n test1\n group - test2\n group - test3\n\nUsing these groups, Nodeunit allows you to define a `setUp` function, which is\nrun before each test, and a `tearDown` function, which is run after each test\ncalls `test.done()`:\n\n module.exports = {\n setUp: function (callback) {\n this.foo = \'bar\';\n callback();\n },\n tearDown: function (callback) {\n // clean up\n callback();\n },\n test1: function (test) {\n test.equals(this.foo, \'bar\');\n test.done();\n }\n };\n\nIn this way, it\'s possible to have multiple groups of tests in a module, each\ngroup with its own setUp and tearDown functions.\n\n\nRunning Tests\n-------------\n\nNodeunit comes with a basic command-line test runner, which can be installed\nusing `sudo make install`. Example usage:\n\n nodeunit testmodule1.js testfolder [...]\n\nIf no entry file specified, `test` defaults.\n\nThe default test reporter uses color output, because I think that\'s more fun :) I\nintend to add a no-color option in future. To give you a feeling of the fun you\'ll\nbe having writing tests, lets fix the example at the start of the README:\n\n\n\nAhhh, Doesn\'t that feel better?\n\nWhen using the included test runner, it will exit using the failed number of\nassertions as the exit code. This means it exits with 0 when all tests pass.\n\n\n### Command-line Options\n\n* __--reporter FILE__ - you can set the test reporter to a custom module or\non of the modules in nodeunit/lib/reporters, when omitted, the default test runner\nis used.\n* __--list-reporters__ - list available built-in reporters.\n* __--config FILE__ - load config options from a JSON file, allows\nthe customisation of color schemes for the default test reporter etc. See\nbin/nodeunit.json for current available options.\n* __-t testName__ - run specifc test only.\n* __-f fullTestName__ - run specific test only. fullTestName is built so: "outerGroup - .. - innerGroup - testName".\n* __--version__ or __-v__ - report nodeunit version\n* __--help__ - show nodeunit help\n\n\nRunning tests in the browser\n----------------------------\n\nNodeunit tests can also be run inside the browser. For example usage, see\nthe examples/browser folder. The basic syntax is as follows:\n\n__test.html__\n\n \n \n Example Test Suite\n \n \n \n \n \n \n

Example Test Suite

\n \n \n \n\nHere, `suite1` and `suite2` are just object literals containing test functions\nor groups, as would be returned if you did `require(\'test-suite\')` in node.js:\n\n__suite1.js__\n\n this.suite1 = {\n \'example test\': function (test) {\n test.ok(true, \'everything is ok\');\n test.done();\n }\n };\n\nIf you wish to use a commonjs format for your test suites (using exports), it is\nup to you to define the commonjs tools for the browser. There are a number of\nalternatives and it\'s important it fits with your existing code, which is\nwhy nodeunit does not currently provide this out of the box.\n\nIn the example above, the tests will run when the page is loaded.\n\nThe browser-version of nodeunit.js is created in dist/browser when you do, `make\nbrowser`. You\'ll need [UglifyJS](https://github.com/mishoo/UglifyJS) installed in\norder for it to automatically create nodeunit.min.js.\n\n\nAdding nodeunit to Your Projects\n--------------------------------\n\nIf you don\'t want people to have to install the nodeunit command-line tool,\nyou\'ll want to create a script that runs the tests for your project with the\ncorrect require paths set up. Here\'s an example test script, that assumes you\nhave nodeunit in a suitably located node_modules directory.\n\n #!/usr/bin/env node\n var reporter = require(\'nodeunit\').reporters.default;\n reporter.run([\'test\']);\n\nIf you\'re using git, you might find it useful to include nodeunit as a\nsubmodule. Using submodules makes it easy for developers to download nodeunit\nand run your test suite, without cluttering up your repository with\nthe source code. To add nodeunit as a git submodule do the following:\n\n git submodule add git://github.com/caolan/nodeunit.git node_modules/nodeunit\n\nThis will add nodeunit to the node_modules folder of your project. Now, when\ncloning the repository, nodeunit can be downloaded by doing the following:\n\n git submodule init\n git submodule update\n\nLet\'s update the test script above with a helpful hint on how to get nodeunit,\nif it\'s missing:\n\n #!/usr/bin/env node\n try {\n var reporter = require(\'nodeunit\').reporters.default;\n }\n catch(e) {\n console.log("Cannot find nodeunit module.");\n console.log("You can download submodules for this project by doing:");\n console.log("");\n console.log(" git submodule init");\n console.log(" git submodule update");\n console.log("");\n process.exit();\n }\n\n process.chdir(__dirname);\n reporter.run([\'test\']);\n\nNow if someone attempts to run your test suite without nodeunit installed they\nwill be prompted to download the submodules for your project.\n\n\nBuilt-in Test Reporters\n-----------------------\n\n* __default__ - The standard reporter seen in the nodeunit screenshots\n* __minimal__ - Pretty, minimal output, shows errors and progress only\n* __html__ - Outputs a HTML report to stdout\n* __junit__ - Creates jUnit compatible XML reports, which can be used with\n continuous integration tools such as [Hudson](http://hudson-ci.org/).\n* __machineout__ - Simple reporter for machine analysis. There is\n [nodeunit.vim](https://github.com/lambdalisue/nodeunit.vim) which is useful for TDD on VIM.\n\n\nWriting a Test Reporter\n---------------------\n\nNodeunit exports runTest(fn, options), runModule(mod, options) and\nrunFiles(paths, options). You\'ll most likely want to run test suites from\nfiles, which can be done using the latter function. The _options_ argument can\ncontain callbacks which run during testing. Nodeunit provides the following\ncallbacks:\n\n* __moduleStart(name)__ - called before a module is tested\n* __moduleDone(name, assertions)__ - called once all test functions within the\n module have completed (see assertions object reference below)\n ALL tests within the module\n* __testStart(name)__ - called before a test function is run\n* __testReady(test)__ - called before a test function is run with the test object that will be passed to the test function\n* __testDone(name, assertions)__ - called once a test function has completed\n (by calling test.done())\n* __log(assertion)__ - called whenever an assertion is made (see assertion\n object reference below)\n* __done(assertions)__ - called after all tests/modules are complete\n\nThe __assertion__ object:\n\n* __passed()__ - did the assertion pass?\n* __failed()__ - did the assertion fail?\n* __error__ - the AssertionError if the assertion failed\n* __method__ - the nodeunit assertion method used (ok, same, equals...)\n* __message__ - the message the assertion method was called with (optional)\n\nThe __assertionList__ object:\n\n* An array-like object with the following new attributes:\n * __failures()__ - the number of assertions which failed\n * __duration__ - the time taken for the test to complete in msecs\n\nFor a reference implementation of a test reporter, see lib/reporters/default.js in\nthe nodeunit project directory.\n\n\nSandbox utility\n---------------\n\nThis is a function which evaluates JavaScript files in a sandbox and returns the\ncontext. The sandbox function can be used for testing client-side code or private\nun-exported functions within a module.\n\n var sandbox = require(\'nodeunit\').utils.sandbox;\n var example = sandbox(\'example.js\');\n\n__sandbox(files, sandbox)__ - Evaluates JavaScript files in a sandbox, returning\nthe context. The first argument can either be a single filename or an array of\nfilenames. If multiple filenames are given their contents are concatenated before\nevaluation. The second argument is an optional context to use for the sandbox.\n\nNote: When working with the sandbox if your script depends on outside sources\n(i.e. using `require`) then you will want to pass that into the optional\ncontext when setting up the sandbox.\n\n var sandbox = require(\'nodeunit\').utils.sandbox;\n // pass in some node globals\n var box_globals = {\n // Passing module.exports into the sandbox will give your code access to it.\n module: {exports: exports},\n // Passing require into the sandbox will give your code access to use it AND\n // will share the cache with modules already required from outside the sandbox.\n require: require,\n // Passing console into the sandbox will give your code access to it\n console: console\n };\n var example = sandbox(\'example.js\', box_globals);\n\n\nRunning the nodeunit Tests\n--------------------------\n\nThe tests for nodeunit are written using nodeunit itself as the test framework.\nHowever, the module test-base.js first does some basic tests using the assert\nmodule to ensure that test functions are actually run, and a basic level of\nnodeunit functionality is available.\n\nTo run the nodeunit tests do:\n\n make test\n\n__Note:__ There was a bug in node v0.2.0 causing the tests to hang, upgrading\nto v0.2.1 fixes this.\n\n\n__machineout__ reporter\n----------------------------------------------\n\nThe default reporter is readable for human but not for machine analysis.\nWhen you want to analyze the output of nodeunit, use __machineout__ reporter and you will get\n\n\n\n\nnodeunit with vim\n----------------------------------\nThere is [nodeunit.vim](https://github.com/lambdalisue/nodeunit.vim) so you can use\nnodeunit with VIM.\n\nThat compiler uses __machineout__ reporter and it is useful to use\nwith [vim-makegreen](https://github.com/reinh/vim-makegreen).\n\n\n\nContributing\n------------\n\nContributions to the project are most welcome, so feel free to fork and improve.\nWhen submitting a pull request, please run `make lint` first to ensure\nwe\'re following a consistent coding style.\n', -259 silly resolved readmeFilename: 'README.md', -259 silly resolved _id: 'nodeunit@0.9.1', -259 silly resolved dist: { shasum: '37ff34c8fec0edf57ebc0cce5053b8a0810bc354' }, -259 silly resolved _from: 'nodeunit@~0.9.0', -259 silly resolved _resolved: 'https://registry.npmjs.org/nodeunit/-/nodeunit-0.9.1.tgz' } ] -260 info install nodeunit@0.9.1 into /Users/mleveton/Documents/node/node-parse-api -261 info installOne nodeunit@0.9.1 -262 verbose from cache /Users/mleveton/.npm/nodeunit/0.9.1/package/package.json -263 info /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit unbuild -264 verbose read json /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json -265 verbose tar unpack /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -266 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit -267 verbose lock /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit /Users/mleveton/.npm/b8e3d237--parse-api-node-modules-nodeunit.lock -268 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -269 verbose lock /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz /Users/mleveton/.npm/f455f5dd-n-npm-nodeunit-0-9-1-package-tgz.lock -270 silly gunzTarPerm modes [ '755', '644' ] -271 silly gunzTarPerm extractEntry package.json -272 silly gunzTarPerm extractEntry .npmignore -273 silly gunzTarPerm extractEntry README.md -274 silly gunzTarPerm extractEntry LICENSE -275 silly gunzTarPerm extractEntry index.js -276 silly gunzTarPerm extractEntry bin/nodeunit -277 silly gunzTarPerm extractEntry bin/nodeunit.json -278 silly gunzTarPerm extractEntry deps/async.js -279 silly gunzTarPerm extractEntry deps/console.log.js -280 silly gunzTarPerm extractEntry deps/json2.js -281 silly gunzTarPerm extractEntry deps/ejs/package.json -282 silly gunzTarPerm extractEntry deps/ejs/benchmark.js -283 silly gunzTarPerm extractEntry deps/ejs/ejs.js -284 silly gunzTarPerm extractEntry deps/ejs/ejs.min.js -285 silly gunzTarPerm extractEntry deps/ejs/index.js -286 silly gunzTarPerm extractEntry deps/ejs/examples/list.js -287 silly gunzTarPerm extractEntry deps/ejs/examples/client.html -288 silly gunzTarPerm extractEntry deps/ejs/examples/list.ejs -289 silly gunzTarPerm extractEntry deps/ejs/Makefile -290 silly gunzTarPerm extractEntry deps/ejs/Readme.md -291 silly gunzTarPerm extractEntry deps/ejs/lib/ejs.js -292 silly gunzTarPerm extractEntry deps/ejs/lib/filters.js -293 silly gunzTarPerm extractEntry deps/ejs/lib/utils.js -294 silly gunzTarPerm extractEntry deps/ejs/History.md -295 silly gunzTarPerm extractEntry deps/ejs/support/compile.js -296 silly gunzTarPerm extractEntry deps/ejs/test/ejs.test.js -297 silly gunzTarPerm extractEntry doc/nodeunit.md -298 silly gunzTarPerm extractEntry CONTRIBUTORS.md -299 silly gunzTarPerm extractEntry img/example_fail.png -300 silly gunzTarPerm extractEntry img/example_machineout.png -301 silly gunzTarPerm extractEntry img/example_pass.png -302 silly gunzTarPerm extractEntry Makefile -303 silly gunzTarPerm extractEntry lib/assert.js -304 silly gunzTarPerm extractEntry lib/core.js -305 silly gunzTarPerm extractEntry lib/nodeunit.js -306 silly gunzTarPerm extractEntry lib/track.js -307 silly gunzTarPerm extractEntry lib/types.js -308 silly gunzTarPerm extractEntry lib/utils.js -309 silly gunzTarPerm extractEntry lib/reporters/browser.js -310 silly gunzTarPerm extractEntry lib/reporters/html.js -311 silly gunzTarPerm extractEntry lib/reporters/index.js -312 silly gunzTarPerm extractEntry lib/reporters/junit.js -313 silly gunzTarPerm extractEntry lib/reporters/eclipse.js -314 silly gunzTarPerm extractEntry lib/reporters/machineout.js -315 silly gunzTarPerm extractEntry lib/reporters/minimal.js -316 silly gunzTarPerm extractEntry lib/reporters/nested.js -317 silly gunzTarPerm extractEntry lib/reporters/skip_passed.js -318 silly gunzTarPerm extractEntry lib/reporters/tap.js -319 silly gunzTarPerm extractEntry lib/reporters/default.js -320 silly gunzTarPerm extractEntry lib/reporters/verbose.js -321 silly gunzTarPerm extractEntry lib/reporters/lcov.js -322 silly gunzTarPerm extractEntry man1/nodeunit.1 -323 silly gunzTarPerm extractEntry nodelint.cfg -324 silly gunzTarPerm extractEntry test/test-runfiles.js -325 silly gunzTarPerm extractEntry test/test-cli.js -326 silly gunzTarPerm extractEntry test/test-failing-callbacks.js -327 silly gunzTarPerm extractEntry test/test-httputil.js -328 silly gunzTarPerm extractEntry test/test-bettererrors.js -329 silly gunzTarPerm extractEntry test/test-runmodule.js -330 silly gunzTarPerm extractEntry test/test-runtest.js -331 silly gunzTarPerm extractEntry test/test-sandbox.js -332 silly gunzTarPerm extractEntry test/test-testcase-legacy.js -333 silly gunzTarPerm extractEntry test/test-testcase.js -334 silly gunzTarPerm extractEntry test/test-base.js -335 silly gunzTarPerm extractEntry test/fixtures/example_test.js -336 silly gunzTarPerm extractEntry test/fixtures/mock_module1.js -337 silly gunzTarPerm extractEntry test/fixtures/mock_module2.js -338 silly gunzTarPerm extractEntry test/fixtures/raw_jscode1.js -339 silly gunzTarPerm extractEntry test/fixtures/raw_jscode2.js -340 silly gunzTarPerm extractEntry test/fixtures/raw_jscode3.js -341 silly gunzTarPerm extractEntry test/fixtures/coffee/mock_coffee_module.coffee -342 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module3.js -343 silly gunzTarPerm extractEntry test/fixtures/dir/mock_module4.js -344 silly gunzTarPerm extractEntry test/test.html -345 silly gunzTarPerm extractEntry share/license.js -346 silly gunzTarPerm extractEntry share/junit.xml.ejs -347 silly gunzTarPerm extractEntry share/nodeunit.css -348 silly gunzTarPerm extractEntry examples/browser/nodeunit.js -349 silly gunzTarPerm extractEntry examples/browser/suite1.js -350 silly gunzTarPerm extractEntry examples/browser/suite2.js -351 silly gunzTarPerm extractEntry examples/browser/suite3.js -352 silly gunzTarPerm extractEntry examples/browser/test.html -353 silly gunzTarPerm extractEntry examples/nested/nested_reporter_test.unit.js -354 verbose read json /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json -355 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit -356 silly lockFile b8e3d237--parse-api-node-modules-nodeunit /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit -357 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -358 silly lockFile f455f5dd-n-npm-nodeunit-0-9-1-package-tgz /Users/mleveton/.npm/nodeunit/0.9.1/package.tgz -359 info preinstall nodeunit@0.9.1 -360 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json -361 verbose readDependencies using package.json deps -362 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json -363 verbose readDependencies using package.json deps -364 verbose cache add [ 'tap@^0.7.1', null ] -365 verbose cache add name=undefined spec="tap@^0.7.1" args=["tap@^0.7.1",null] -366 verbose parsed url { protocol: null, -366 verbose parsed url slashes: null, -366 verbose parsed url auth: null, -366 verbose parsed url host: null, -366 verbose parsed url port: null, -366 verbose parsed url hostname: null, -366 verbose parsed url hash: null, -366 verbose parsed url search: null, -366 verbose parsed url query: null, -366 verbose parsed url pathname: 'tap@^0.7.1', -366 verbose parsed url path: 'tap@^0.7.1', -366 verbose parsed url href: 'tap@^0.7.1' } -367 verbose cache add name="tap" spec="^0.7.1" args=["tap","^0.7.1"] -368 verbose parsed url { protocol: null, -368 verbose parsed url slashes: null, -368 verbose parsed url auth: null, -368 verbose parsed url host: null, -368 verbose parsed url port: null, -368 verbose parsed url hostname: null, -368 verbose parsed url hash: null, -368 verbose parsed url search: null, -368 verbose parsed url query: null, -368 verbose parsed url pathname: '^0.7.1', -368 verbose parsed url path: '^0.7.1', -368 verbose parsed url href: '^0.7.1' } -369 verbose addNamed [ 'tap', '^0.7.1' ] -370 verbose addNamed [ null, null ] -371 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 -372 verbose lock tap@^0.7.1 /Users/mleveton/.npm/50b1620e-tap-0-7-1.lock -373 info addNameTag [ 'tap', '^0.7.1' ] -374 verbose url raw tap -375 verbose url resolving [ 'https://registry.npmjs.org/', './tap' ] -376 verbose url resolved https://registry.npmjs.org/tap -377 info trying registry request attempt 1 at 21:39:58 -378 verbose etag "A52165LP2BJ0ED5UT4KDATU6Y" -379 http GET https://registry.npmjs.org/tap -380 http 200 https://registry.npmjs.org/tap -381 silly registry.get cb [ 200, -381 silly registry.get { date: 'Thu, 19 Mar 2015 01:39:59 GMT', -381 silly registry.get server: 'CouchDB/1.5.0 (Erlang OTP/R16B03)', -381 silly registry.get etag: '"84452RW0P649DLKHI249CYPFY"', -381 silly registry.get 'content-type': 'application/json', -381 silly registry.get 'cache-control': 'max-age=60', -381 silly registry.get 'content-length': '64851', -381 silly registry.get 'accept-ranges': 'bytes', -381 silly registry.get via: '1.1 varnish', -381 silly registry.get 'x-served-by': 'cache-jfk1029-JFK', -381 silly registry.get 'x-cache': 'MISS', -381 silly registry.get 'x-cache-hits': '0', -381 silly registry.get 'x-timer': 'S1426729199.152788,VS0,VE185', -381 silly registry.get vary: 'Accept', -381 silly registry.get 'keep-alive': 'timeout=10, max=50', -381 silly registry.get connection: 'Keep-Alive' } ] -382 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 -383 silly lockFile 50b1620e-tap-0-7-1 tap@^0.7.1 -384 verbose about to build /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit -385 info /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit unbuild -386 verbose from cache /Users/mleveton/Documents/node/node-parse-api/node_modules/nodeunit/package.json -387 info preuninstall nodeunit@0.9.1 -388 info uninstall nodeunit@0.9.1 -389 verbose true,/Users/mleveton/Documents/node/node-parse-api/node_modules,/Users/mleveton/Documents/node/node-parse-api/node_modules unbuild nodeunit@0.9.1 -390 verbose /Users/mleveton/Documents/node/node-parse-api/node_modules/.bin,[object Object] binRoot -391 info postuninstall nodeunit@0.9.1 -392 error Error: No compatible version found: tap@'^0.7.1' -392 error Valid install targets: -392 error ["0.0.1","0.0.2","0.0.3","0.0.4","0.0.5","0.0.6","0.0.7","0.0.8","0.0.9","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.1.0","0.1.1","0.1.2","0.1.3","0.1.4","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.3.3","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","0.4.11","0.4.12","0.4.13","0.5.0","0.6.0","0.7.0","0.7.1"] -392 error at installTargetsError (/Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/lib/cache.js:709:10) -392 error at /Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/lib/cache.js:631:10 -392 error at saved (/Users/mleveton/.nvm/v0.10.10/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:138:7) -392 error at Object.oncomplete (fs.js:107:15) -393 error If you need help, you may report this log at: -393 error -393 error or email it to: -393 error -394 error System Darwin 13.4.0 -395 error command "/Users/mleveton/.nvm/v0.10.10/bin/node" "/Users/mleveton/.nvm/v0.10.10/bin/npm" "link" -396 error cwd /Users/mleveton/Documents/node/node-parse-api -397 error node -v v0.10.10 -398 error npm -v 1.2.25 -399 verbose exit [ 1, true ] diff --git a/package.json b/package.json index 52111f6..2f9c481 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.6", + "version": "0.3.7", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ "Daniel Gasienica ", From a4aceed85d7b301140df13cdc450fdd32f79bc66 Mon Sep 17 00:00:00 2001 From: Victor Akinwande Date: Wed, 22 Jul 2015 16:16:51 +0100 Subject: [PATCH 85/95] Changed the parse options variable "host" field to "hostname" I read somewhere that this is better and it has personally prevented the "[Error: getaddrinfo ENOTFOUND api.parse.com]" error I get occasionally. --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 18f6d40..018448c 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -395,7 +395,7 @@ function parseRequest(method, path, data, callback, contentType, sessionToken) { } var options = { - host: this._api_host, + hostname: this._api_host, port: this._api_port, headers: headers, path: path, From 6d5509b2e1cb88203cc8d2006abc9cab2ede469c Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 27 Jul 2015 18:07:17 +0100 Subject: [PATCH 86/95] added a method that allows for retrival of file by object id easily --- lib/Parse.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 018448c..4449352 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -34,6 +34,13 @@ Parse.prototype = { parseRequest.call(this, 'POST', '/1/users/', data, callback); }, + findWithObjectId: function (className, objectId, callback){ + var url = '/1/' + (className === '_User' ? 'users' : 'classes/' + className + '/' + objectId); + + + parseRequest.call(this, 'GET', url, null, callback); + + }, // get an object from the class store find: function (className, query, callback) { var url = '/1/' + (className === '_User' ? 'users' : 'classes/' + className); @@ -52,7 +59,7 @@ Parse.prototype = { // check to see if there is a 'where' object in the query object // the 'where' object need to be stringified by JSON.stringify(), not querystring if ( query.hasOwnProperty('where') ) { - url += '?where=' + encodeURIComponent(JSON.stringify(query.where)); + url += '?where=' + JSON.stringify(query.where); delete query.where; } @@ -95,6 +102,8 @@ Parse.prototype = { // user login loginUser: function (username, password, callback) { parseRequest.call(this, 'GET', '/1/login/?username=' + username + '&password=' + password, null, callback); + + console.log(callback); }, // retrieve current user @@ -347,7 +356,13 @@ Parse.prototype = { sendPush: function (data, callback) { parseRequest.call(this, 'POST', '/1/push/', data, callback); + }, + + getCurrentSession: function(objectId, callback) + { + parseRequest.call(this, 'GET', '/1/sessions/'+ objectId, callback); } + }; // Parse.com https api request From 2f345845c2290069fccb206f7fef12b4ba267351 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 27 Jul 2015 18:10:27 +0100 Subject: [PATCH 87/95] sorry i taken note of the uriencode --- lib/Parse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Parse.js b/lib/Parse.js index 4449352..9f86e5a 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -59,7 +59,7 @@ Parse.prototype = { // check to see if there is a 'where' object in the query object // the 'where' object need to be stringified by JSON.stringify(), not querystring if ( query.hasOwnProperty('where') ) { - url += '?where=' + JSON.stringify(query.where); + url += '?where=' + encodeURIComponent(JSON.stringify(query.where)); delete query.where; } From d7dd68f423adff93be12789170db94c55bf4a29b Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 27 Jul 2015 18:16:11 +0100 Subject: [PATCH 88/95] left a nasty console.log there, I should have --- lib/Parse.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 9f86e5a..f6dea3d 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -102,8 +102,6 @@ Parse.prototype = { // user login loginUser: function (username, password, callback) { parseRequest.call(this, 'GET', '/1/login/?username=' + username + '&password=' + password, null, callback); - - console.log(callback); }, // retrieve current user From 25c6b3659bc935bcba7858b8612ae701962cb002 Mon Sep 17 00:00:00 2001 From: Julien Crestin Date: Tue, 11 Aug 2015 18:34:50 +0200 Subject: [PATCH 89/95] feat(user): allow user logout --- lib/Parse.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index f6dea3d..4569584 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -104,6 +104,11 @@ Parse.prototype = { parseRequest.call(this, 'GET', '/1/login/?username=' + username + '&password=' + password, null, callback); }, + // user logout + logoutUser: function (sessionToken, callback) { + parseRequest.call(this, 'POST', '/1/logout', null, callback, null, sessionToken); + }, + // retrieve current user me: function (sessionToken, callback) { parseRequest.call(this, 'GET', '/1/users/me', null, callback, null, sessionToken); From fa7e387b81a13dceb31e00a4d01680f7a63c28cb Mon Sep 17 00:00:00 2001 From: Varun Chatterji Date: Thu, 20 Aug 2015 01:57:36 +0800 Subject: [PATCH 90/95] Without a timeout set, the socket can "hang" waiting for a response. --- lib/Parse.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Parse.js b/lib/Parse.js index f6dea3d..d72bf64 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -445,6 +445,10 @@ function parseRequest(method, path, data, callback, contentType, sessionToken) { callback(err); }); }); + + req.setTimeout(5000, function () { + req.connection.destroy(); + }); body && req.write(body, contentType ? 'binary' : 'utf8'); req.end(); From 33deab402af64d07965f75df4f89fcf128b178bd Mon Sep 17 00:00:00 2001 From: Mike Leveton Date: Wed, 19 Aug 2015 21:06:16 -0400 Subject: [PATCH 91/95] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2f9c481..448327c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.7", + "version": "0.3.8", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ "Daniel Gasienica ", From 8ec620d084946be28cb124d7d7228ae2804dbf2d Mon Sep 17 00:00:00 2001 From: achimkoellner Date: Sat, 19 Dec 2015 13:57:16 +0700 Subject: [PATCH 92/95] adds session token as constructor option --- lib/Parse.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Parse.js b/lib/Parse.js index 1bec5dd..22e73e7 100644 --- a/lib/Parse.js +++ b/lib/Parse.js @@ -360,12 +360,12 @@ Parse.prototype = { sendPush: function (data, callback) { parseRequest.call(this, 'POST', '/1/push/', data, callback); }, - + getCurrentSession: function(objectId, callback) { - parseRequest.call(this, 'GET', '/1/sessions/'+ objectId, callback); + parseRequest.call(this, 'GET', '/1/sessions/'+ objectId, callback); } - + }; // Parse.com https api request @@ -388,6 +388,10 @@ function parseRequest(method, path, data, callback, contentType, sessionToken) { } } + if(!sessionToken && this._options && this._options.session_token){ + headers['X-Parse-Session-Token'] = this._options.session_token; + } + var body = null; @@ -450,7 +454,7 @@ function parseRequest(method, path, data, callback, contentType, sessionToken) { callback(err); }); }); - + req.setTimeout(5000, function () { req.connection.destroy(); }); From 3c7e6f1d339d8413026f95a6b7a1c7cca3666d48 Mon Sep 17 00:00:00 2001 From: achimkoellner Date: Sat, 19 Dec 2015 16:11:32 +0700 Subject: [PATCH 93/95] updates readme and package.json --- package.json | 5 +++-- readme.md | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 448327c..1451d9a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "node-parse-api", "description": "A Parse.com REST API client for Node.js", - "version": "0.3.8", + "version": "0.3.8a", "author": "Chris Johnson , Michael Leveton , Seth Gholson", "contributors": [ "Daniel Gasienica ", @@ -20,7 +20,8 @@ "Akhmad Fathonih", "Kody J. Peterson", "Jo Jordens", - "Appsaloon" + "Appsaloon", + "Achim Koellner" ], "main": "index", "scripts": { diff --git a/readme.md b/readme.md index df2d79f..be9eb7e 100644 --- a/readme.md +++ b/readme.md @@ -515,6 +515,33 @@ app.sendPush(notification, function(err, resp){ }); ``` +### usage of a sessionToken for all operations + +If you use node-parse-api with a logged-in user in a node.js server environement a client might send a sessionToken with a request against the server. +You can pass the client sessionToken from the client to performs database operations on behalf of that user session. + +This allows e.g. to find objects of classes that are restricted to be read by only that user (or role). + +```javascript +var Parse = require('node-parse-api').Parse; + +// let's assume this is a sessionToken of an user who is member of the role "moderator" +var sessionToken = '3h3gaa32bdd3h3gaa323h3gaa32bddbdd'; + +var options = { + app_id:'...', + api_key:'...', + session_token: sessionToken // , master_key:'...' could be used too +} + +var app = new Parse(options); + +// let's assume Foo is a class with read permission for "moderator"-users only +app.find('Foo', {objectId: 'someId'}, function (err, response) { + console.log(response); +}); +``` + ### note on sending dates ```javascript From 3d6bc3b0c5af1a8de149d94c6c6e6c8912f6cd3b Mon Sep 17 00:00:00 2001 From: achimkoellner Date: Sat, 19 Dec 2015 16:15:48 +0700 Subject: [PATCH 94/95] removes typos --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index be9eb7e..17b6af3 100644 --- a/readme.md +++ b/readme.md @@ -517,15 +517,15 @@ app.sendPush(notification, function(err, resp){ ### usage of a sessionToken for all operations -If you use node-parse-api with a logged-in user in a node.js server environement a client might send a sessionToken with a request against the server. -You can pass the client sessionToken from the client to performs database operations on behalf of that user session. +If you use node-parse-api in a node.js server environement a client might send a sessionToken with a request to your server. +You can pass that sessionToken as a constructor option to perform database operations on behalf of that user session. This allows e.g. to find objects of classes that are restricted to be read by only that user (or role). ```javascript var Parse = require('node-parse-api').Parse; -// let's assume this is a sessionToken of an user who is member of the role "moderator" +// let's assume this is a sessionToken of a user who is member of the role "moderator" var sessionToken = '3h3gaa32bdd3h3gaa323h3gaa32bddbdd'; var options = { From ddde0459d90499dae041b78df9bf2fcf1bdfbdc6 Mon Sep 17 00:00:00 2001 From: achimkoellner Date: Wed, 23 Dec 2015 12:35:45 +0700 Subject: [PATCH 95/95] corrects readme --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 17b6af3..0bbcdb8 100644 --- a/readme.md +++ b/readme.md @@ -191,7 +191,7 @@ app.find('Foo', query, function (error, response ) { * getUser(query `object`, callback `function`) ```javascript -app.find({objectId: 'someId'}, function (err, response) { +app.getUser({objectId: 'someId'}, function (err, response) { console.log(response); }); ```