Files
kami-parse-server/src/index.js

225 lines
7.2 KiB
JavaScript
Raw Normal View History

2016-01-28 10:58:12 -08:00
// ParseServer - open-source compatible API Server for Parse apps
var batch = require('./batch'),
bodyParser = require('body-parser'),
cache = require('./cache'),
DatabaseAdapter = require('./DatabaseAdapter'),
express = require('express'),
middlewares = require('./middlewares'),
multer = require('multer'),
Parse = require('parse/node').Parse,
PromiseRouter = require('./PromiseRouter'),
httpRequest = require('./httpRequest');
2016-01-28 10:58:12 -08:00
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
import { S3Adapter } from './Adapters/Files/S3Adapter';
import { FilesController } from './Controllers/FilesController';
2016-02-08 22:51:58 -08:00
import ParsePushAdapter from './Adapters/Push/ParsePushAdapter';
import { PushController } from './Controllers/PushController';
import { ClassesRouter } from './Routers/ClassesRouter';
import { InstallationsRouter } from './Routers/InstallationsRouter';
import { UsersRouter } from './Routers/UsersRouter';
import { SessionsRouter } from './Routers/SessionsRouter';
import { RolesRouter } from './Routers/RolesRouter';
import { FileLoggerAdapter } from './Adapters/Logger/FileLoggerAdapter';
import { LoggerController } from './Controllers/LoggerController';
2016-01-28 10:58:12 -08:00
// Mutate the Parse object to add the Cloud Code handlers
addParseCloud();
// ParseServer works like a constructor of an express app.
// The args that we understand are:
// "databaseAdapter": a class like ExportAdapter providing create, find,
// update, and delete
// "filesAdapter": a class like GridStoreAdapter providing create, get,
// and delete
// "databaseURI": a uri like mongodb://localhost:27017/dbname to tell us
// what database this Parse API connects to.
// "cloud": relative location to cloud code to require, or a function
// that is given an instance of Parse as a parameter. Use this instance of Parse
// to register your cloud code hooks and functions.
2016-01-28 10:58:12 -08:00
// "appId": the application id to host
// "masterKey": the master key for requests to this app
2016-01-30 15:20:44 -08:00
// "facebookAppIds": an array of valid Facebook Application IDs, required
// if using Facebook login
2016-01-28 10:58:12 -08:00
// "collectionPrefix": optional prefix for database collection names
// "fileKey": optional key from Parse dashboard for supporting older files
// hosted by Parse
// "clientKey": optional key from Parse dashboard
// "dotNetKey": optional key from Parse dashboard
// "restAPIKey": optional key from Parse dashboard
// "javascriptKey": optional key from Parse dashboard
// "push": optional key from configure push
function ParseServer({
appId,
masterKey,
databaseAdapter,
filesAdapter = new GridStoreAdapter(),
push,
loggerAdapter = new FileLoggerAdapter(),
databaseURI,
cloud,
collectionPrefix = '',
clientKey = '',
javascriptKey = '',
dotNetKey = '',
restAPIKey = '',
fileKey = 'invalid-file-key',
facebookAppIds = [],
enableAnonymousUsers = true,
oauth = {},
serverURL = '',
}) {
if (!appId || !masterKey) {
2016-01-28 10:58:12 -08:00
throw 'You must provide an appId and masterKey!';
}
if (databaseAdapter) {
DatabaseAdapter.setAdapter(databaseAdapter);
2016-01-28 10:58:12 -08:00
}
// Make push adapter
let pushConfig = push;
let pushAdapter;
if (pushConfig && pushConfig.adapter) {
pushAdapter = pushConfig.adapter;
} else if (pushConfig) {
pushAdapter = new ParsePushAdapter(pushConfig)
}
if (databaseURI) {
DatabaseAdapter.setAppDatabaseURI(appId, databaseURI);
2016-01-28 10:58:12 -08:00
}
if (cloud) {
2016-01-28 10:58:12 -08:00
addParseCloud();
if (typeof cloud === 'function') {
cloud(Parse)
} else if (typeof cloud === 'string') {
require(cloud);
2016-02-01 15:41:22 -05:00
} else {
throw "argument 'cloud' must either be a string or a function";
}
2016-01-28 10:58:12 -08:00
}
let filesController = new FilesController(filesAdapter);
cache.apps[appId] = {
masterKey: masterKey,
collectionPrefix: collectionPrefix,
clientKey: clientKey,
javascriptKey: javascriptKey,
dotNetKey: dotNetKey,
restAPIKey: restAPIKey,
fileKey: fileKey,
facebookAppIds: facebookAppIds,
filesController: filesController,
enableAnonymousUsers: enableAnonymousUsers,
oauth: oauth,
2016-01-28 10:58:12 -08:00
};
2016-01-30 15:20:44 -08:00
// To maintain compatibility. TODO: Remove in v2.1
if (process.env.FACEBOOK_APP_ID) {
cache.apps[appId]['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
2016-01-30 15:20:44 -08:00
}
2016-01-28 10:58:12 -08:00
// Initialize the node client SDK automatically
Parse.initialize(appId, javascriptKey, masterKey);
Parse.serverURL = serverURL;
2016-01-28 10:58:12 -08:00
// This app serves the Parse API directly.
// It's the equivalent of https://api.parse.com/1 in the hosted Parse API.
var api = express();
// File handling needs to be before default middlewares are applied
api.use('/', filesController.getExpressRouter());
2016-01-28 10:58:12 -08:00
// TODO: separate this from the regular ParseServer object
if (process.env.TESTING == 1) {
api.use('/', require('./testing-routes').router);
}
api.use(bodyParser.json({ 'type': '*/*' }));
api.use(middlewares.allowCrossDomain);
api.use(middlewares.allowMethodOverride);
api.use(middlewares.handleParseHeaders);
2016-02-09 20:45:02 -08:00
let routers = [
new ClassesRouter().getExpressRouter(),
new UsersRouter().getExpressRouter(),
new SessionsRouter().getExpressRouter(),
new RolesRouter().getExpressRouter(),
2016-02-09 20:45:02 -08:00
require('./analytics'),
new InstallationsRouter().getExpressRouter(),
2016-02-09 20:45:02 -08:00
require('./functions'),
require('./schemas'),
new PushController(pushAdapter).getExpressRouter(),
2016-02-19 13:06:02 -05:00
new LoggerController(loggerAdapter).getExpressRouter(),
require('./validate_purchase')
2016-02-09 20:45:02 -08:00
];
if (process.env.PARSE_EXPERIMENTAL_CONFIG_ENABLED || process.env.TESTING) {
2016-02-09 20:45:02 -08:00
routers.push(require('./global_config'));
}
2016-01-28 10:58:12 -08:00
2016-02-09 20:45:02 -08:00
let appRouter = new PromiseRouter();
routers.forEach((router) => {
appRouter.merge(router);
});
batch.mountOnto(appRouter);
2016-01-28 10:58:12 -08:00
2016-02-09 20:45:02 -08:00
appRouter.mountOnto(api);
2016-01-28 10:58:12 -08:00
api.use(middlewares.handleParseErrors);
return api;
}
function addParseCloud() {
Parse.Cloud.Functions = {};
Parse.Cloud.Validators = {};
2016-01-28 10:58:12 -08:00
Parse.Cloud.Triggers = {
beforeSave: {},
beforeDelete: {},
afterSave: {},
afterDelete: {}
};
2016-02-03 21:51:40 +00:00
Parse.Cloud.define = function(functionName, handler, validationHandler) {
2016-01-28 10:58:12 -08:00
Parse.Cloud.Functions[functionName] = handler;
Parse.Cloud.Validators[functionName] = validationHandler;
2016-01-28 10:58:12 -08:00
};
Parse.Cloud.beforeSave = function(parseClass, handler) {
var className = getClassName(parseClass);
Parse.Cloud.Triggers.beforeSave[className] = handler;
};
Parse.Cloud.beforeDelete = function(parseClass, handler) {
var className = getClassName(parseClass);
Parse.Cloud.Triggers.beforeDelete[className] = handler;
};
Parse.Cloud.afterSave = function(parseClass, handler) {
var className = getClassName(parseClass);
Parse.Cloud.Triggers.afterSave[className] = handler;
};
Parse.Cloud.afterDelete = function(parseClass, handler) {
var className = getClassName(parseClass);
Parse.Cloud.Triggers.afterDelete[className] = handler;
};
Parse.Cloud.httpRequest = httpRequest;
2016-01-28 10:58:12 -08:00
global.Parse = Parse;
}
function getClassName(parseClass) {
if (parseClass && parseClass.className) {
return parseClass.className;
}
return parseClass;
}
module.exports = {
ParseServer: ParseServer,
S3Adapter: S3Adapter
2016-01-28 10:58:12 -08:00
};