Skip to content

Commit 8f2b20d

Browse files
Lucian MateescuLucian Mateescu
Lucian Mateescu
authored and
Lucian Mateescu
committed
Merge remote-tracking branch 'upstream/master'
2 parents 9078372 + 72fa1f2 commit 8f2b20d

File tree

5 files changed

+196
-34
lines changed

5 files changed

+196
-34
lines changed

README.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ There is a development wiki here on GitHub: https://github.com/ParsePlatform/par
2222
* cloud - The absolute path to your cloud code main.js file
2323
* fileKey - For migrated apps, this is necessary to provide access to files already hosted on Parse.
2424
* facebookAppIds - An array of valid Facebook application IDs.
25+
* serverURL - URL which will be used by Cloud Code functions to make requests against.
2526

2627
#### Client key options:
2728

@@ -49,14 +50,17 @@ var ParseServer = require('parse-server').ParseServer;
4950

5051
var app = express();
5152

53+
var port = process.env.PORT || 1337;
54+
5255
// Specify the connection string for your mongodb database
5356
// and the location to your Parse cloud code
5457
var api = new ParseServer({
5558
databaseURI: 'mongodb://localhost:27017/dev',
5659
cloud: '/home/myApp/cloud/main.js', // Provide an absolute path
5760
appId: 'myAppId',
5861
masterKey: 'mySecretMasterKey',
59-
fileKey: 'optionalFileKey'
62+
fileKey: 'optionalFileKey',
63+
serverURL: 'http://localhost:' + port + '/parse' // Don't forget to change to https if needed
6064
});
6165

6266
// Serve the Parse API on the /parse URL prefix
@@ -67,13 +71,48 @@ app.get('/', function(req, res) {
6771
res.status(200).send('Express is running here.');
6872
});
6973

70-
var port = process.env.PORT || 1337;
7174
app.listen(port, function() {
7275
console.log('parse-server-example running on port ' + port + '.');
7376
});
7477

7578
```
7679

80+
81+
#### Standalone usage
82+
83+
You can configure the Parse Server with environment variables:
84+
85+
```js
86+
PARSE_SERVER_DATABASE_URI
87+
PARSE_SERVER_CLOUD_CODE_MAIN
88+
PARSE_SERVER_COLLECTION_PREFIX
89+
PARSE_SERVER_APPLICATION_ID // required
90+
PARSE_SERVER_CLIENT_KEY
91+
PARSE_SERVER_REST_API_KEY
92+
PARSE_SERVER_DOTNET_KEY
93+
PARSE_SERVER_JAVASCRIPT_KEY
94+
PARSE_SERVER_DOTNET_KEY
95+
PARSE_SERVER_MASTER_KEY // required
96+
PARSE_SERVER_FILE_KEY
97+
PARSE_SERVER_FACEBOOK_APP_IDS // string of comma separated list
98+
99+
```
100+
101+
102+
103+
Alernatively, you can use the `PARSE_SERVER_OPTIONS` environment variable set to the JSON of your configuration (see Usage).
104+
105+
To start the server, just run `npm start`.
106+
107+
##### Global installation
108+
109+
You can install parse-server globally
110+
111+
`$ npm install -g parse-server`
112+
113+
Now you can just run `$ parse-server` from your command line.
114+
115+
77116
### Supported
78117

79118
* CRUD operations

bin/parse-server

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env node
2+
var express = require('express');
3+
var ParseServer = require("../index").ParseServer;
4+
5+
var app = express();
6+
7+
var options = {};
8+
if (process.env.PARSE_SERVER_OPTIONS) {
9+
10+
options = JSON.parse(process.env.PARSE_SERVER_OPTIONS);
11+
12+
} else {
13+
14+
options.databaseURI = process.env.PARSE_SERVER_DATABASE_URI;
15+
options.cloud = process.env.PARSE_SERVER_CLOUD_CODE_MAIN;
16+
options.collectionPrefix = process.env.PARSE_SERVER_COLLECTION_PREFIX;
17+
18+
// Keys and App ID
19+
options.appId = process.env.PARSE_SERVER_APPLICATION_ID;
20+
options.clientKey = process.env.PARSE_SERVER_CLIENT_KEY;
21+
options.restAPIKey = process.env.PARSE_SERVER_REST_API_KEY;
22+
options.dotNetKey = process.env.PARSE_SERVER_DOTNET_KEY;
23+
options.javascriptKey = process.env.PARSE_SERVER_JAVASCRIPT_KEY;
24+
options.dotNetKey = process.env.PARSE_SERVER_DOTNET_KEY;
25+
options.masterKey = process.env.PARSE_SERVER_MASTER_KEY;
26+
options.fileKey = process.env.PARSE_SERVER_FILE_KEY;
27+
// Comma separated list of facebook app ids
28+
var facebookAppIds = process.env.PARSE_SERVER_FACEBOOK_APP_IDS;
29+
30+
if (facebookAppIds) {
31+
facebookAppIds = facebookAppIds.split(",");
32+
options.facebookAppIds = facebookAppIds;
33+
}
34+
}
35+
36+
var mountPath = process.env.PARSE_SERVER_MOUNT_PATH || "/";
37+
var api = new ParseServer(options);
38+
app.use('/', api);
39+
40+
var port = process.env.PORT || 1337;
41+
app.listen(port, function() {
42+
console.log('parse-server-example running on http://localhost:'+ port + mountPath);
43+
});

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ function ParseServer(args) {
8282

8383
// Initialize the node client SDK automatically
8484
Parse.initialize(args.appId, args.javascriptKey || '', args.masterKey);
85+
if(args.serverURL) {
86+
Parse.serverURL = args.serverURL;
87+
}
8588

8689
// This app serves the Parse API directly.
8790
// It's the equivalent of https://api.parse.com/1 in the hosted Parse API.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@
3131
"scripts": {
3232
"pretest": "MONGODB_VERSION=${MONGODB_VERSION:=3.0.8} mongodb-runner start",
3333
"test": "TESTING=1 ./node_modules/.bin/istanbul cover --include-all-sources -x **/spec/** ./node_modules/.bin/jasmine",
34-
"posttest": "mongodb-runner stop"
34+
"posttest": "mongodb-runner stop",
35+
"start": "./bin/parse-server"
3536
},
3637
"engines": {
3738
"node": ">=4.1"
39+
},
40+
"bin": {
41+
"parse-server": "./bin/parse-server"
3842
}
3943
}

transform.js

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -363,23 +363,17 @@ function transformAtom(atom, force, options) {
363363
objectId: atom.objectId
364364
};
365365
}
366-
if (atom.__type == 'Date') {
367-
return new Date(atom.iso);
366+
if (DateCoder.isValidJSON(atom)) {
367+
return DateCoder.JSONToDatabase(atom);
368368
}
369-
if (atom.__type == 'GeoPoint') {
370-
if (!inArray && !inObject) {
371-
return [atom.longitude, atom.latitude];
372-
}
373-
return atom;
369+
if (BytesCoder.isValidJSON(atom)) {
370+
return BytesCoder.JSONToDatabase(atom);
374371
}
375-
if (atom.__type == 'Bytes') {
376-
return new mongodb.Binary(new Buffer(atom.base64, 'base64'));
372+
if (GeoPointCoder.isValidJSON(atom)) {
373+
return (inArray || inObject ? atom : GeoPointCoder.JSONToDatabase(atom));
377374
}
378-
if (atom.__type == 'File') {
379-
if (!inArray && !inObject) {
380-
return atom.name;
381-
}
382-
return atom;
375+
if (FileCoder.isValidJSON(atom)) {
376+
return (inArray || inObject ? atom : FileCoder.JSONToDatabase(atom));
383377
}
384378

385379
if (force) {
@@ -620,11 +614,8 @@ function untransformObject(schema, className, mongoObject) {
620614
return Parse._encode(mongoObject);
621615
}
622616

623-
if (mongoObject instanceof mongodb.Binary) {
624-
return {
625-
__type: 'Bytes',
626-
base64: mongoObject.buffer.toString('base64')
627-
};
617+
if (BytesCoder.isValidDatabaseObject(mongoObject)) {
618+
return BytesCoder.databaseToJSON(mongoObject);
628619
}
629620

630621
var restObject = untransformACL(mongoObject);
@@ -699,20 +690,14 @@ function untransformObject(schema, className, mongoObject) {
699690
//} else if (mongoObject[key] === null) {
700691
//break;
701692
} else {
702-
var expected = schema.getExpectedType(className, key);
703-
if (expected == 'file' && mongoObject[key]) {
704-
restObject[key] = {
705-
__type: 'File',
706-
name: mongoObject[key]
707-
};
693+
var expectedType = schema.getExpectedType(className, key);
694+
var value = mongoObject[key];
695+
if (expectedType === 'file' && FileCoder.isValidDatabaseObject(value)) {
696+
restObject[key] = FileCoder.databaseToJSON(value);
708697
break;
709698
}
710-
if (expected == 'geopoint') {
711-
restObject[key] = {
712-
__type: 'GeoPoint',
713-
latitude: mongoObject[key][1],
714-
longitude: mongoObject[key][0]
715-
};
699+
if (expectedType === 'geopoint' && GeoPointCoder.isValidDatabaseObject(value)) {
700+
restObject[key] = GeoPointCoder.databaseToJSON(value);
716701
break;
717702
}
718703
}
@@ -726,6 +711,94 @@ function untransformObject(schema, className, mongoObject) {
726711
}
727712
}
728713

714+
var DateCoder = {
715+
JSONToDatabase(json) {
716+
return new Date(json.iso);
717+
},
718+
719+
isValidJSON(value) {
720+
return (typeof value === 'object' &&
721+
value !== null &&
722+
value.__type === 'Date'
723+
);
724+
}
725+
};
726+
727+
var BytesCoder = {
728+
databaseToJSON(object) {
729+
return {
730+
__type: 'Bytes',
731+
base64: object.buffer.toString('base64')
732+
};
733+
},
734+
735+
isValidDatabaseObject(object) {
736+
return (object instanceof mongodb.Binary);
737+
},
738+
739+
JSONToDatabase(json) {
740+
return new mongodb.Binary(new Buffer(json.base64, 'base64'));
741+
},
742+
743+
isValidJSON(value) {
744+
return (typeof value === 'object' &&
745+
value !== null &&
746+
value.__type === 'Bytes'
747+
);
748+
}
749+
};
750+
751+
var GeoPointCoder = {
752+
databaseToJSON(object) {
753+
return {
754+
__type: 'GeoPoint',
755+
latitude: object[1],
756+
longitude: object[0]
757+
}
758+
},
759+
760+
isValidDatabaseObject(object) {
761+
return (object instanceof Array &&
762+
object.length == 2
763+
);
764+
},
765+
766+
JSONToDatabase(json) {
767+
return [ json.longitude, json.latitude ];
768+
},
769+
770+
isValidJSON(value) {
771+
return (typeof value === 'object' &&
772+
value !== null &&
773+
value.__type === 'GeoPoint'
774+
);
775+
}
776+
};
777+
778+
var FileCoder = {
779+
databaseToJSON(object) {
780+
return {
781+
__type: 'File',
782+
name: object
783+
}
784+
},
785+
786+
isValidDatabaseObject(object) {
787+
return (typeof object === 'string');
788+
},
789+
790+
JSONToDatabase(json) {
791+
return json.name;
792+
},
793+
794+
isValidJSON(value) {
795+
return (typeof value === 'object' &&
796+
value !== null &&
797+
value.__type === 'File'
798+
);
799+
}
800+
};
801+
729802
module.exports = {
730803
transformKey: transformKey,
731804
transformCreate: transformCreate,

0 commit comments

Comments
 (0)