Skip to content

Commit 65ad4b3

Browse files
authored
Merge pull request #384 from dblythy/master
Add QOL changes to Parse Server Example
2 parents 7147755 + 61f24a9 commit 65ad4b3

File tree

11 files changed

+292
-30
lines changed

11 files changed

+292
-30
lines changed

.eslintrc.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"extends": "eslint:recommended",
3+
"env": {
4+
"node": true,
5+
"es6": true
6+
},
7+
"parserOptions": {
8+
"ecmaVersion": 6,
9+
"sourceType": "module"
10+
},
11+
"parser": "babel-eslint",
12+
"rules": {
13+
"indent": ["error", 2, { "SwitchCase": 1 }],
14+
"linebreak-style": ["error", "unix"],
15+
"no-trailing-spaces": 2,
16+
"eol-last": 2,
17+
"space-in-parens": ["error", "never"],
18+
"no-multiple-empty-lines": 1,
19+
"prefer-const": "error",
20+
"space-infix-ops": "error",
21+
"no-useless-escape": "off",
22+
"require-atomic-updates": "off",
23+
"no-var": 1,
24+
"no-await-in-loop" : 1
25+
},
26+
"globals" : {
27+
"Parse" : true
28+
}
29+
}

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Node.js
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- '**'
9+
workflow_dispatch:
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node-version: [12.x]
16+
name: ${{ matrix.name }}
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: Use Node.js ${{ matrix.node-version }}
20+
uses: actions/setup-node@v1
21+
with:
22+
node-version: ${{ matrix.node-version }}
23+
- name: Install Dependancies
24+
run: npm install
25+
- name: Check Linting
26+
run: npm run lint
27+
- name: Run Tests
28+
run: npm run test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ node_modules
2828

2929
# Emacs
3030
*~
31+
.eslintcache

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,14 @@ Example using it via JavaScript:
133133
Parse.initialize('myAppId','unused');
134134
Parse.serverURL = 'https://whatever.herokuapp.com';
135135

136-
var obj = new Parse.Object('GameScore');
136+
const obj = new Parse.Object('GameScore');
137137
obj.set('score',1337);
138-
obj.save().then(function(obj) {
139-
console.log(obj.toJSON());
140-
var query = new Parse.Query('GameScore');
141-
query.get(obj.id).then(function(objAgain) {
142-
console.log(objAgain.toJSON());
143-
}, function(err) {console.log(err); });
144-
}, function(err) { console.log(err); });
138+
await obj.save();
139+
console.log(obj.toJSON());
140+
141+
const query = new Parse.Query('GameScore');
142+
const objAgain = await query.get(obj.id);
143+
console.log(objAgain.toJSON());
145144
```
146145

147146
Example using it on Android:

cloud/main.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1-
Parse.Cloud.define('hello', function(req, res) {
1+
Parse.Cloud.define('hello', (req) => {
2+
console.log(req)
23
return 'Hi';
34
});
5+
6+
Parse.Cloud.define('asyncFunction', async (req) => {
7+
await new Promise((resolve) => setTimeout(resolve,1000));
8+
console.log(req)
9+
return 'Hi async';
10+
});
11+
12+
Parse.Cloud.beforeSave('Test', () => {
13+
throw new Parse.Error(211,'Saving test objects is not available.')
14+
});

index.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
// Example express application adding the parse-server module to expose Parse
22
// compatible API routes.
33

4-
var express = require('express');
5-
var ParseServer = require('parse-server').ParseServer;
6-
var path = require('path');
4+
const express = require('express');
5+
const ParseServer = require('parse-server').ParseServer;
6+
const path = require('path');
7+
const args = process.argv || [];
8+
const test = args.some(arg => arg.includes('jasmine'));
79

8-
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
10+
const databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
911

1012
if (!databaseUri) {
1113
console.log('DATABASE_URI not specified, falling back to localhost.');
1214
}
13-
14-
var api = new ParseServer({
15+
const config = {
1516
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
1617
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
1718
appId: process.env.APP_ID || 'myAppId',
@@ -20,19 +21,22 @@ var api = new ParseServer({
2021
liveQuery: {
2122
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
2223
}
23-
});
24+
};
2425
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
2526
// If you wish you require them, you can set them as options in the initialization above:
2627
// javascriptKey, restAPIKey, dotNetKey, clientKey
2728

28-
var app = express();
29+
const app = express();
2930

3031
// Serve static assets from the /public folder
3132
app.use('/public', express.static(path.join(__dirname, '/public')));
3233

3334
// Serve the Parse API on the /parse URL prefix
34-
var mountPath = process.env.PARSE_MOUNT || '/parse';
35-
app.use(mountPath, api);
35+
const mountPath = process.env.PARSE_MOUNT || '/parse';
36+
if (!test) {
37+
const api = new ParseServer(config);
38+
app.use(mountPath, api);
39+
}
3640

3741
// Parse Server plays nicely with the rest of your web routes
3842
app.get('/', function(req, res) {
@@ -45,11 +49,17 @@ app.get('/test', function(req, res) {
4549
res.sendFile(path.join(__dirname, '/public/test.html'));
4650
});
4751

48-
var port = process.env.PORT || 1337;
49-
var httpServer = require('http').createServer(app);
50-
httpServer.listen(port, function() {
52+
const port = process.env.PORT || 1337;
53+
if (!test) {
54+
const httpServer = require('http').createServer(app);
55+
httpServer.listen(port, function() {
5156
console.log('parse-server-example running on port ' + port + '.');
52-
});
57+
});
58+
// This will enable the Live Query real-time server
59+
ParseServer.createLiveQueryServer(httpServer);
60+
}
5361

54-
// This will enable the Live Query real-time server
55-
ParseServer.createLiveQueryServer(httpServer);
62+
module.exports = {
63+
app,
64+
config
65+
};

package.json

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,29 @@
99
},
1010
"license": "MIT",
1111
"dependencies": {
12-
"express": "~4.11.x",
13-
"kerberos": "~0.0.x",
14-
"parse": "~1.8.0",
15-
"parse-server": "*"
12+
"express": "4.17.1",
13+
"kerberos": "1.1.4",
14+
"parse": "2.19.0",
15+
"parse-server": "4.5.0"
1616
},
1717
"scripts": {
18-
"start": "node index.js"
18+
"start": "node index.js",
19+
"lint": "eslint --cache ./cloud && eslint --cache index.js",
20+
"lint-fix": "eslint --cache --fix ./cloud && eslint --cache --fix index.js",
21+
"test": "jasmine"
1922
},
2023
"engines": {
2124
"node": ">=4.3"
25+
},
26+
"devDependencies": {
27+
"eslint": "^7.17.0",
28+
"eslint-config-standard": "^16.0.2",
29+
"eslint-plugin-import": "^2.22.1",
30+
"eslint-plugin-node": "^11.1.0",
31+
"eslint-plugin-promise": "^4.2.1",
32+
"babel-eslint": "^10.1.0",
33+
"jasmine": "^3.6.3",
34+
"mongodb-runner": "^4.8.0",
35+
"bluebird": "^3.7.2"
2236
}
2337
}

spec/Tests.spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
describe("Parse Server example", () => {
2+
Parse.User.enableUnsafeCurrentUser();
3+
it('call function', async () => {
4+
const result = await Parse.Cloud.run('hello');
5+
expect(result).toBe('Hi');
6+
});
7+
it('call async function', async () => {
8+
const result = await Parse.Cloud.run('asyncFunction');
9+
expect(result).toBe('Hi async');
10+
})
11+
it('failing test', async () => {
12+
const obj = new Parse.Object('Test');
13+
try {
14+
await obj.save();
15+
fail('should not have been able to save test object.');
16+
} catch (e) {
17+
expect(e).toBeDefined();
18+
expect(e.code).toBe(212);
19+
expect(e.message).toBe('Saving test objects is not available.');
20+
}
21+
})
22+
});

spec/helper.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const Parse = require("parse/node");
2+
Parse.initialize("test");
3+
Parse.serverURL = "http://localhost:30001/test";
4+
Parse.masterKey = "test";
5+
const {
6+
startParseServer,
7+
stopParseServer,
8+
dropDB,
9+
} = require("./utils/test-runner.js");
10+
beforeAll(async () => {
11+
await startParseServer();
12+
}, 100 * 60 * 2);
13+
14+
afterAll(async () => {
15+
await dropDB();
16+
await stopParseServer();
17+
});

spec/support/jasmine.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"spec_dir": "spec",
3+
"spec_files": [
4+
"**/*[sS]pec.js"
5+
],
6+
"helpers": ["helper.js"],
7+
"stopSpecOnExpectationFailure": false,
8+
"random": false
9+
}

spec/utils/test-runner.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
const Promise = require("bluebird");
2+
const http = require("http");
3+
const { MongoClient } = require("mongodb");
4+
const { ParseServer } = require("parse-server");
5+
const { config, app } = require("../../index.js");
6+
const Config = require("../../node_modules/parse-server/lib/Config");
7+
8+
const mongoDBRunnerStart = require("mongodb-runner/mocha/before").bind({
9+
timeout() {},
10+
slow() {},
11+
});
12+
const mongoDBRunnerStop = require("mongodb-runner/mocha/after");
13+
14+
const startDB = () =>
15+
new Promise((done, reject) => {
16+
done.fail = reject;
17+
mongoDBRunnerStart(done);
18+
});
19+
20+
const stopDB = () =>
21+
new Promise((done, reject) => {
22+
done.fail = reject;
23+
mongoDBRunnerStop(done);
24+
});
25+
26+
const connectDB = (databaseURI) =>
27+
new Promise((resolve, reject) => {
28+
MongoClient.connect(databaseURI, (err, db) => {
29+
if (err) {
30+
reject(err);
31+
} else {
32+
resolve(db);
33+
}
34+
});
35+
});
36+
37+
let parseServerState = {};
38+
39+
const dropDB = async () => {
40+
await Parse.User.logOut();
41+
const app = Config.get("test");
42+
return await app.database.deleteEverything(true);
43+
};
44+
45+
/**
46+
* Starts the ParseServer instance
47+
* @param {Object} parseServerOptions Used for creating the `ParseServer`
48+
* @return {Promise} Runner state
49+
*/
50+
async function startParseServer() {
51+
const mongodbPort = process.env.MONGODB_PORT || 27017;
52+
let parseServerOptions = Object.assign(config, {
53+
databaseName: "parse-test",
54+
databaseURI: `mongodb://localhost:${mongodbPort}/parse-test`,
55+
masterKey: "test",
56+
javascriptKey: "test",
57+
appId: "test",
58+
port: 30001,
59+
mountPath: "/test",
60+
serverURL: `http://localhost:30001/test`,
61+
logLevel: "error",
62+
silent: true,
63+
});
64+
const {
65+
databaseURI,
66+
masterKey,
67+
javascriptKey,
68+
appId,
69+
port,
70+
serverURL,
71+
mountPath,
72+
} = parseServerOptions;
73+
await startDB();
74+
const mongoConnection = await connectDB(databaseURI);
75+
parseServerOptions = Object.assign(
76+
{
77+
masterKey,
78+
javascriptKey,
79+
appId,
80+
serverURL,
81+
databaseURI,
82+
silent: process.env.VERBOSE !== "1",
83+
},
84+
parseServerOptions
85+
);
86+
const parseServer = new ParseServer(parseServerOptions);
87+
app.use(mountPath, parseServer);
88+
89+
const httpServer = http.createServer(app);
90+
91+
Promise.promisifyAll(httpServer);
92+
Promise.promisifyAll(mongoConnection);
93+
await httpServer.listenAsync(port);
94+
95+
Object.assign(parseServerState, {
96+
parseServer,
97+
httpServer,
98+
mongoConnection,
99+
expressApp: app,
100+
parseServerOptions,
101+
});
102+
return parseServerOptions;
103+
}
104+
105+
/**
106+
* Stops the ParseServer instance
107+
* @return {Promise}
108+
*/
109+
function stopParseServer() {
110+
const { httpServer } = parseServerState;
111+
return httpServer
112+
.closeAsync()
113+
.then(stopDB)
114+
.then(() => (parseServerState = {}));
115+
}
116+
117+
module.exports = {
118+
dropDB,
119+
startParseServer,
120+
stopParseServer,
121+
parseServerState,
122+
};

0 commit comments

Comments
 (0)