2016-01-28 10:58:12 -08:00
|
|
|
// triggers.js
|
2016-05-19 13:38:16 -07:00
|
|
|
import Parse from 'parse/node';
|
2016-07-23 20:10:06 +02:00
|
|
|
import { logger } from './logger';
|
2016-01-28 10:58:12 -08:00
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export const Types = {
|
2016-01-28 10:58:12 -08:00
|
|
|
beforeSave: 'beforeSave',
|
|
|
|
|
afterSave: 'afterSave',
|
|
|
|
|
beforeDelete: 'beforeDelete',
|
2016-09-17 16:52:35 -04:00
|
|
|
afterDelete: 'afterDelete',
|
2016-11-12 09:35:34 -08:00
|
|
|
beforeFind: 'beforeFind',
|
|
|
|
|
afterFind: 'afterFind'
|
2016-01-28 10:58:12 -08:00
|
|
|
};
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
const baseStore = function() {
|
2016-12-07 15:17:05 -08:00
|
|
|
const Validators = {};
|
|
|
|
|
const Functions = {};
|
|
|
|
|
const Jobs = {};
|
2017-09-15 17:20:51 -04:00
|
|
|
const LiveQuery = [];
|
2016-12-07 15:17:05 -08:00
|
|
|
const Triggers = Object.keys(Types).reduce(function(base, key){
|
2016-02-05 14:38:09 -05:00
|
|
|
base[key] = {};
|
|
|
|
|
return base;
|
|
|
|
|
}, {});
|
2016-04-22 08:20:14 +12:00
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
return Object.freeze({
|
|
|
|
|
Functions,
|
2016-08-30 07:19:21 -04:00
|
|
|
Jobs,
|
2016-02-24 15:55:11 -05:00
|
|
|
Validators,
|
2017-09-15 17:20:51 -04:00
|
|
|
Triggers,
|
|
|
|
|
LiveQuery,
|
2016-02-24 15:55:11 -05:00
|
|
|
});
|
2016-02-25 20:01:52 -08:00
|
|
|
};
|
2016-02-05 14:38:09 -05:00
|
|
|
|
2017-09-18 15:01:07 -04:00
|
|
|
function validateClassNameForTriggers(className, type) {
|
|
|
|
|
const restrictedClassNames = [ '_Session' ];
|
|
|
|
|
if (restrictedClassNames.indexOf(className) != -1) {
|
|
|
|
|
throw `Triggers are not supported for ${className} class.`;
|
|
|
|
|
}
|
|
|
|
|
if (type == Types.beforeSave && className === '_PushStatus') {
|
|
|
|
|
// _PushStatus uses undocumented nested key increment ops
|
|
|
|
|
// allowing beforeSave would mess up the objects big time
|
|
|
|
|
// TODO: Allow proper documented way of using nested increment ops
|
|
|
|
|
throw 'Only afterSave is allowed on _PushStatus';
|
|
|
|
|
}
|
|
|
|
|
return className;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
const _triggerStore = {};
|
2016-02-05 14:38:09 -05:00
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function addFunction(functionName, handler, validationHandler, applicationId) {
|
2016-02-05 14:38:09 -05:00
|
|
|
applicationId = applicationId || Parse.applicationId;
|
2016-02-24 15:55:11 -05:00
|
|
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
2016-02-05 14:38:09 -05:00
|
|
|
_triggerStore[applicationId].Functions[functionName] = handler;
|
|
|
|
|
_triggerStore[applicationId].Validators[functionName] = validationHandler;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 07:19:21 -04:00
|
|
|
export function addJob(jobName, handler, applicationId) {
|
|
|
|
|
applicationId = applicationId || Parse.applicationId;
|
|
|
|
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
|
|
|
|
_triggerStore[applicationId].Jobs[jobName] = handler;
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function addTrigger(type, className, handler, applicationId) {
|
2017-09-18 15:01:07 -04:00
|
|
|
validateClassNameForTriggers(className, type);
|
2016-02-05 14:38:09 -05:00
|
|
|
applicationId = applicationId || Parse.applicationId;
|
2016-02-24 15:55:11 -05:00
|
|
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
2016-02-05 14:38:09 -05:00
|
|
|
_triggerStore[applicationId].Triggers[type][className] = handler;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-15 17:20:51 -04:00
|
|
|
export function addLiveQueryEventHandler(handler, applicationId) {
|
|
|
|
|
applicationId = applicationId || Parse.applicationId;
|
|
|
|
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
|
|
|
|
_triggerStore[applicationId].LiveQuery.push(handler);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function removeFunction(functionName, applicationId) {
|
2016-11-24 15:47:41 -05:00
|
|
|
applicationId = applicationId || Parse.applicationId;
|
|
|
|
|
delete _triggerStore[applicationId].Functions[functionName]
|
2016-02-05 14:38:09 -05:00
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function removeTrigger(type, className, applicationId) {
|
2016-11-24 15:47:41 -05:00
|
|
|
applicationId = applicationId || Parse.applicationId;
|
|
|
|
|
delete _triggerStore[applicationId].Triggers[type][className]
|
2016-02-05 14:38:09 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-19 13:38:16 -07:00
|
|
|
export function _unregisterAll() {
|
|
|
|
|
Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function getTrigger(className, triggerType, applicationId) {
|
2016-02-05 14:38:09 -05:00
|
|
|
if (!applicationId) {
|
|
|
|
|
throw "Missing ApplicationID";
|
|
|
|
|
}
|
|
|
|
|
var manager = _triggerStore[applicationId]
|
2016-04-22 08:20:14 +12:00
|
|
|
if (manager
|
2016-02-05 14:38:09 -05:00
|
|
|
&& manager.Triggers
|
|
|
|
|
&& manager.Triggers[triggerType]
|
|
|
|
|
&& manager.Triggers[triggerType][className]) {
|
|
|
|
|
return manager.Triggers[triggerType][className];
|
2016-01-28 10:58:12 -08:00
|
|
|
}
|
|
|
|
|
return undefined;
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-01-28 10:58:12 -08:00
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function triggerExists(className: string, type: string, applicationId: string): boolean {
|
|
|
|
|
return (getTrigger(className, type, applicationId) != undefined);
|
2016-02-24 00:05:03 -08:00
|
|
|
}
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function getFunction(functionName, applicationId) {
|
2016-02-05 14:38:09 -05:00
|
|
|
var manager = _triggerStore[applicationId];
|
|
|
|
|
if (manager && manager.Functions) {
|
|
|
|
|
return manager.Functions[functionName];
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-02-05 14:38:09 -05:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 07:19:21 -04:00
|
|
|
export function getJob(jobName, applicationId) {
|
|
|
|
|
var manager = _triggerStore[applicationId];
|
|
|
|
|
if (manager && manager.Jobs) {
|
|
|
|
|
return manager.Jobs[jobName];
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-08-30 07:19:21 -04:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getJobs(applicationId) {
|
|
|
|
|
var manager = _triggerStore[applicationId];
|
|
|
|
|
if (manager && manager.Jobs) {
|
|
|
|
|
return manager.Jobs;
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-08-30 07:19:21 -04:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-02-24 15:55:11 -05:00
|
|
|
export function getValidator(functionName, applicationId) {
|
2016-02-05 14:38:09 -05:00
|
|
|
var manager = _triggerStore[applicationId];
|
|
|
|
|
if (manager && manager.Validators) {
|
|
|
|
|
return manager.Validators[functionName];
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-02-05 14:38:09 -05:00
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-22 08:20:14 +12:00
|
|
|
export function getRequestObject(triggerType, auth, parseObject, originalParseObject, config) {
|
2016-01-28 10:58:12 -08:00
|
|
|
var request = {
|
|
|
|
|
triggerName: triggerType,
|
|
|
|
|
object: parseObject,
|
2016-04-22 08:20:14 +12:00
|
|
|
master: false,
|
2017-07-14 19:19:00 +02:00
|
|
|
log: config.loggerController,
|
|
|
|
|
headers: config.headers,
|
2017-10-18 14:13:09 +02:00
|
|
|
ip: config.ip,
|
2016-01-28 10:58:12 -08:00
|
|
|
};
|
2016-04-22 08:20:14 +12:00
|
|
|
|
2016-01-28 10:58:12 -08:00
|
|
|
if (originalParseObject) {
|
|
|
|
|
request.original = originalParseObject;
|
|
|
|
|
}
|
2016-04-22 08:20:14 +12:00
|
|
|
|
2016-01-28 10:58:12 -08:00
|
|
|
if (!auth) {
|
|
|
|
|
return request;
|
|
|
|
|
}
|
|
|
|
|
if (auth.isMaster) {
|
|
|
|
|
request['master'] = true;
|
|
|
|
|
}
|
|
|
|
|
if (auth.user) {
|
|
|
|
|
request['user'] = auth.user;
|
|
|
|
|
}
|
|
|
|
|
if (auth.installationId) {
|
|
|
|
|
request['installationId'] = auth.installationId;
|
|
|
|
|
}
|
|
|
|
|
return request;
|
2016-03-02 20:59:25 -08:00
|
|
|
}
|
2016-01-28 10:58:12 -08:00
|
|
|
|
2017-06-21 09:24:51 -03:00
|
|
|
export function getRequestQueryObject(triggerType, auth, query, count, config, isGet) {
|
|
|
|
|
isGet = !!isGet;
|
|
|
|
|
|
2016-09-17 16:52:35 -04:00
|
|
|
var request = {
|
|
|
|
|
triggerName: triggerType,
|
2017-05-14 21:47:30 -04:00
|
|
|
query,
|
2016-09-17 16:52:35 -04:00
|
|
|
master: false,
|
2017-05-14 21:47:30 -04:00
|
|
|
count,
|
2017-06-21 09:24:51 -03:00
|
|
|
log: config.loggerController,
|
2017-07-14 19:19:00 +02:00
|
|
|
isGet,
|
|
|
|
|
headers: config.headers,
|
2017-10-18 14:13:09 +02:00
|
|
|
ip: config.ip,
|
2016-09-17 16:52:35 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!auth) {
|
|
|
|
|
return request;
|
|
|
|
|
}
|
|
|
|
|
if (auth.isMaster) {
|
|
|
|
|
request['master'] = true;
|
|
|
|
|
}
|
|
|
|
|
if (auth.user) {
|
|
|
|
|
request['user'] = auth.user;
|
|
|
|
|
}
|
|
|
|
|
if (auth.installationId) {
|
|
|
|
|
request['installationId'] = auth.installationId;
|
|
|
|
|
}
|
|
|
|
|
return request;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-28 10:58:12 -08:00
|
|
|
// Creates the response object, and uses the request object to pass data
|
|
|
|
|
// The API will call this with REST API formatted objects, this will
|
|
|
|
|
// transform them to Parse.Object instances expected by Cloud Code.
|
|
|
|
|
// Any changes made to the object in a beforeSave will be included.
|
2016-02-24 15:55:11 -05:00
|
|
|
export function getResponseObject(request, resolve, reject) {
|
2016-01-28 10:58:12 -08:00
|
|
|
return {
|
2016-02-05 14:38:09 -05:00
|
|
|
success: function(response) {
|
2016-11-12 09:35:34 -08:00
|
|
|
if (request.triggerName === Types.afterFind) {
|
|
|
|
|
if(!response){
|
2016-12-01 10:24:46 -08:00
|
|
|
response = request.objects;
|
2016-11-12 09:35:34 -08:00
|
|
|
}
|
|
|
|
|
response = response.map(object => {
|
|
|
|
|
return object.toJSON();
|
|
|
|
|
});
|
|
|
|
|
return resolve(response);
|
|
|
|
|
}
|
2016-02-05 14:38:09 -05:00
|
|
|
// Use the JSON response
|
2016-05-28 21:51:22 +05:30
|
|
|
if (response && !request.object.equals(response)
|
|
|
|
|
&& request.triggerName === Types.beforeSave) {
|
2016-02-05 14:38:09 -05:00
|
|
|
return resolve(response);
|
|
|
|
|
}
|
|
|
|
|
response = {};
|
2016-01-28 10:58:12 -08:00
|
|
|
if (request.triggerName === Types.beforeSave) {
|
2016-02-24 00:00:25 -08:00
|
|
|
response['object'] = request.object._getSaveJSON();
|
2016-01-28 10:58:12 -08:00
|
|
|
}
|
|
|
|
|
return resolve(response);
|
|
|
|
|
},
|
2016-06-01 10:28:06 -04:00
|
|
|
error: function(code, message) {
|
|
|
|
|
if (!message) {
|
|
|
|
|
message = code;
|
|
|
|
|
code = Parse.Error.SCRIPT_FAILED;
|
|
|
|
|
}
|
|
|
|
|
var scriptError = new Parse.Error(code, message);
|
2016-02-03 01:47:05 -08:00
|
|
|
return reject(scriptError);
|
2016-01-28 10:58:12 -08:00
|
|
|
}
|
|
|
|
|
}
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-01-28 10:58:12 -08:00
|
|
|
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
function userIdForLog(auth) {
|
|
|
|
|
return (auth && auth.user) ? auth.user.id : undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function logTriggerAfterHook(triggerType, className, input, auth) {
|
2016-09-22 12:05:54 -07:00
|
|
|
const cleanInput = logger.truncateLogMessage(JSON.stringify(input));
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, {
|
2016-08-17 15:26:42 +02:00
|
|
|
className,
|
2016-07-23 20:10:06 +02:00
|
|
|
triggerType,
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
user: userIdForLog(auth)
|
2016-07-23 20:10:06 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) {
|
2016-09-22 12:05:54 -07:00
|
|
|
const cleanInput = logger.truncateLogMessage(JSON.stringify(input));
|
|
|
|
|
const cleanResult = logger.truncateLogMessage(JSON.stringify(result));
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
|
2016-08-17 15:26:42 +02:00
|
|
|
className,
|
2016-07-23 20:10:06 +02:00
|
|
|
triggerType,
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
user: userIdForLog(auth)
|
2016-07-23 20:10:06 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) {
|
2016-09-22 12:05:54 -07:00
|
|
|
const cleanInput = logger.truncateLogMessage(JSON.stringify(input));
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, {
|
2016-08-17 15:26:42 +02:00
|
|
|
className,
|
2016-07-23 20:10:06 +02:00
|
|
|
triggerType,
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
error,
|
|
|
|
|
user: userIdForLog(auth)
|
2016-07-23 20:10:06 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-12 09:35:34 -08:00
|
|
|
export function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const trigger = getTrigger(className, triggerType, config.applicationId);
|
|
|
|
|
if (!trigger) {
|
|
|
|
|
return resolve();
|
|
|
|
|
}
|
2016-12-01 10:24:46 -08:00
|
|
|
const request = getRequestObject(triggerType, auth, null, null, config);
|
2016-11-12 09:35:34 -08:00
|
|
|
const response = getResponseObject(request,
|
2016-11-24 15:47:41 -05:00
|
|
|
object => {
|
2016-11-12 09:35:34 -08:00
|
|
|
resolve(object);
|
2016-12-01 10:24:46 -08:00
|
|
|
},
|
2016-11-24 15:47:41 -05:00
|
|
|
error => {
|
2016-11-12 09:35:34 -08:00
|
|
|
reject(error);
|
2016-11-24 15:47:41 -05:00
|
|
|
});
|
2016-11-12 09:35:34 -08:00
|
|
|
logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth);
|
|
|
|
|
request.objects = objects.map(object => {
|
|
|
|
|
//setting the class name to transform into parse object
|
2017-01-11 12:31:40 -08:00
|
|
|
object.className = className;
|
2016-11-12 09:35:34 -08:00
|
|
|
return Parse.Object.fromJSON(object);
|
|
|
|
|
});
|
|
|
|
|
const triggerPromise = trigger(request, response);
|
|
|
|
|
if (triggerPromise && typeof triggerPromise.then === "function") {
|
|
|
|
|
return triggerPromise.then(promiseResults => {
|
|
|
|
|
if(promiseResults) {
|
|
|
|
|
resolve(promiseResults);
|
|
|
|
|
}else{
|
|
|
|
|
return reject(new Parse.Error(Parse.Error.SCRIPT_FAILED, "AfterFind expect results to be returned in the promise"));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}).then((results) => {
|
|
|
|
|
logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth);
|
|
|
|
|
return results;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 09:24:51 -03:00
|
|
|
export function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, isGet) {
|
2016-12-07 15:17:05 -08:00
|
|
|
const trigger = getTrigger(className, triggerType, config.applicationId);
|
2016-09-17 16:52:35 -04:00
|
|
|
if (!trigger) {
|
|
|
|
|
return Promise.resolve({
|
|
|
|
|
restWhere,
|
|
|
|
|
restOptions
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-07 15:17:05 -08:00
|
|
|
const parseQuery = new Parse.Query(className);
|
2016-09-17 16:52:35 -04:00
|
|
|
if (restWhere) {
|
2016-11-24 15:47:41 -05:00
|
|
|
parseQuery._where = restWhere;
|
2016-09-17 16:52:35 -04:00
|
|
|
}
|
2017-05-14 21:47:30 -04:00
|
|
|
let count = false;
|
2016-09-17 16:52:35 -04:00
|
|
|
if (restOptions) {
|
|
|
|
|
if (restOptions.include && restOptions.include.length > 0) {
|
|
|
|
|
parseQuery._include = restOptions.include.split(',');
|
|
|
|
|
}
|
|
|
|
|
if (restOptions.skip) {
|
2016-11-24 15:47:41 -05:00
|
|
|
parseQuery._skip = restOptions.skip;
|
2016-09-17 16:52:35 -04:00
|
|
|
}
|
|
|
|
|
if (restOptions.limit) {
|
2016-11-24 15:47:41 -05:00
|
|
|
parseQuery._limit = restOptions.limit;
|
2016-09-17 16:52:35 -04:00
|
|
|
}
|
2017-05-14 21:47:30 -04:00
|
|
|
count = !!restOptions.count;
|
2016-09-17 16:52:35 -04:00
|
|
|
}
|
2017-06-21 09:24:51 -03:00
|
|
|
const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, isGet);
|
2016-11-24 15:47:41 -05:00
|
|
|
return Promise.resolve().then(() => {
|
2016-09-17 16:52:35 -04:00
|
|
|
return trigger(requestObject);
|
2016-11-24 15:47:41 -05:00
|
|
|
}).then((result) => {
|
2016-09-17 16:52:35 -04:00
|
|
|
let queryResult = parseQuery;
|
|
|
|
|
if (result && result instanceof Parse.Query) {
|
|
|
|
|
queryResult = result;
|
|
|
|
|
}
|
2016-12-07 15:17:05 -08:00
|
|
|
const jsonQuery = queryResult.toJSON();
|
2016-09-17 16:52:35 -04:00
|
|
|
if (jsonQuery.where) {
|
|
|
|
|
restWhere = jsonQuery.where;
|
|
|
|
|
}
|
|
|
|
|
if (jsonQuery.limit) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.limit = jsonQuery.limit;
|
|
|
|
|
}
|
|
|
|
|
if (jsonQuery.skip) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.skip = jsonQuery.skip;
|
|
|
|
|
}
|
|
|
|
|
if (jsonQuery.include) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.include = jsonQuery.include;
|
|
|
|
|
}
|
2016-12-01 07:04:47 -08:00
|
|
|
if (jsonQuery.keys) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.keys = jsonQuery.keys;
|
|
|
|
|
}
|
2017-06-21 17:18:10 -03:00
|
|
|
if (requestObject.readPreference) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.readPreference = requestObject.readPreference;
|
|
|
|
|
}
|
|
|
|
|
if (requestObject.includeReadPreference) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.includeReadPreference = requestObject.includeReadPreference;
|
|
|
|
|
}
|
|
|
|
|
if (requestObject.subqueryReadPreference) {
|
|
|
|
|
restOptions = restOptions || {};
|
|
|
|
|
restOptions.subqueryReadPreference = requestObject.subqueryReadPreference;
|
|
|
|
|
}
|
2016-09-17 16:52:35 -04:00
|
|
|
return {
|
|
|
|
|
restWhere,
|
|
|
|
|
restOptions
|
|
|
|
|
};
|
2016-11-24 15:47:41 -05:00
|
|
|
}, (err) => {
|
2016-09-17 16:52:35 -04:00
|
|
|
if (typeof err === 'string') {
|
|
|
|
|
throw new Parse.Error(1, err);
|
|
|
|
|
} else {
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2016-07-23 20:10:06 +02:00
|
|
|
|
2016-01-28 10:58:12 -08:00
|
|
|
// To be used as part of the promise chain when saving/deleting an object
|
|
|
|
|
// Will resolve successfully if no trigger is configured
|
|
|
|
|
// Resolves to an object, empty or containing an object key. A beforeSave
|
|
|
|
|
// trigger will set the object key to the rest format object to save.
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
// originalParseObject is optional, we only need that for before/afterSave functions
|
2016-04-22 08:20:14 +12:00
|
|
|
export function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config) {
|
2016-01-28 10:58:12 -08:00
|
|
|
if (!parseObject) {
|
|
|
|
|
return Promise.resolve({});
|
|
|
|
|
}
|
|
|
|
|
return new Promise(function (resolve, reject) {
|
2016-04-22 08:20:14 +12:00
|
|
|
var trigger = getTrigger(parseObject.className, triggerType, config.applicationId);
|
2016-02-05 14:38:09 -05:00
|
|
|
if (!trigger) return resolve();
|
2016-04-22 08:20:14 +12:00
|
|
|
var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config);
|
2016-11-24 15:47:41 -05:00
|
|
|
var response = getResponseObject(request, (object) => {
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
logTriggerSuccessBeforeHook(
|
2017-06-20 09:15:26 -07:00
|
|
|
triggerType, parseObject.className, parseObject.toJSON(), object, auth);
|
2016-07-23 20:10:06 +02:00
|
|
|
resolve(object);
|
2016-11-24 15:47:41 -05:00
|
|
|
}, (error) => {
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
logTriggerErrorBeforeHook(
|
2017-06-20 09:15:26 -07:00
|
|
|
triggerType, parseObject.className, parseObject.toJSON(), auth, error);
|
2016-07-23 20:10:06 +02:00
|
|
|
reject(error);
|
|
|
|
|
});
|
2016-02-05 14:38:09 -05:00
|
|
|
// Force the current Parse app before the trigger
|
2016-04-22 08:20:14 +12:00
|
|
|
Parse.applicationId = config.applicationId;
|
|
|
|
|
Parse.javascriptKey = config.javascriptKey || '';
|
|
|
|
|
Parse.masterKey = config.masterKey;
|
2016-08-17 15:26:42 +02:00
|
|
|
|
Make parse-server cloud code logging closer parse.com legacy (#2550)
* Make parse-server cloud code logging much to parse.com legacy. (fixes #2501)
1. More closely mimic the wording. Include the user id.
2. Truncate input and result at 1k char.
3. Use more sensible metadata that would makes sense to index. The guideline I used was: if it makes sense to filter on, put it in metadata. If it makes sense to "free text" search on, then put it in the message.
- file and console output, logging an object does not do what on might expect. For example, logging a function's "params":
```
expected:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, params= { foo: "bar", "bar": baz }, user=qWHLVEsbEe
what you actually get:
info: Ran cloud function aFunction for user qWHLVEsbEe with:
Input: {"foo":"bar","bar":"baz"}
Result: "it worked!" functionName=aFunction, foo=bar, bar=baz, user=qWHLVEsbEe
```
- logging highly variable metadata is pretty useless for indexing when logs are sent to a logging repository like elastic search. In that use case, you want to index stuff you expect to filter on like user, hook type.
- finally, putting the same input and result data in both the metadata and the message makes each message much larger with no additional value (that I know of anyway :).
4. Change some of the naming of functions in trigger.js to make future work easier. I was confused about why there were three logging functions in trigger and it took me awhile to get that before hooks and after hooks are logged differently. I just changed the names to make it obvious at first glance.
5. Add some try/catches to help any future futzers see syntax errors, etc instead of just hanging.
Some log examples from unit test output:
```
info: Ran cloud function loggerTest for user YUD2os1i5B with:
Input: {}
Result: {} functionName=loggerTest, user=YUD2os1i5B
info: beforeSave triggered for MyObject for user nssehQ3wtz:
Input: {}
Result: {} className=MyObject, triggerType=beforeSave, user=nssehQ3wtz
info: afterSave triggered for MyObject for user XdznQgTD0p:
Input: {"createdAt":"2016-08-19T01:11:31.249Z","updatedAt":"2016-08-19T01:11:31.249Z","objectId":"POoOOLL89U"} className=MyObject, triggerType=afterSave, user=XdznQgTD0p
error: beforeSave failed for MyObject for user 7JHqCZgnhf:
Input: {}
Error: {"code":141,"message":"uh oh!"} className=MyObject, triggerType=beforeSave, code=141, message=uh oh!, user=7JHqCZgnhf
info: Ran cloud function aFunction for user YR3nOoT3r9 with:
Input: {"foo":"bar"}
Result: "it worked!" functionName=aFunction, user=YR3nOoT3r9
error: Failed running cloud function aFunction for user Xm6NpOyuMC with:
Input: {"foo":"bar"}
Error: {"code":141,"message":"it failed!"} functionName=aFunction, code=141, message=it failed!, user=Xm6NpOyuMC
info: Ran cloud function aFunction for user CK1lvkmaLg with:
Input: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated)
Result: {"longString":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lobortis semper diam, ac euismod diam pharetra sed. Etiam eget efficitur neque. Proin nec diam mi. Sed ut purus dolor. Nulla nulla nibh, ornare vitae ornare et, scelerisque rutrum eros. Mauris venenatis tincidunt turpis a mollis. Donec gravida eget enim in luctus.\n\nSed porttitor commodo orci, ut pretium eros convallis eget. Curabitur pretium velit in odio dictum luctus. Vivamus ac tristique arcu, a semper tellus. Morbi euismod purus dapibus vestibulum sagittis. Nunc dapibus vehicula leo at scelerisque. Donec porta mauris quis nulla imperdiet consectetur. Curabitur sagittis eleifend arcu eget elementum. Aenean interdum tincidunt ornare. Pellentesque sit amet interdum tortor. Pellentesque blandit nisl eget euismod consequat. Etiam feugiat felis sit amet porta pulvinar. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n\nNulla faucibus sem ipsum, at rhoncus diam pulvinar at. Vivamus consectetur, diam... (truncated) functionName=aFunction, user=CK1lvkmaLg
```
* Implement PR comments:
- add back params to metadata and add back to the test
- use screaming snake case for conts
* fix typo
2016-08-19 13:39:51 -07:00
|
|
|
// AfterSave and afterDelete triggers can return a promise, which if they
|
|
|
|
|
// do, needs to be resolved before this promise is resolved,
|
|
|
|
|
// so trigger execution is synced with RestWrite.execute() call.
|
|
|
|
|
// If triggers do not return a promise, they can run async code parallel
|
|
|
|
|
// to the RestWrite.execute() call.
|
2016-08-17 15:26:42 +02:00
|
|
|
var triggerPromise = trigger(request, response);
|
|
|
|
|
if(triggerType === Types.afterSave || triggerType === Types.afterDelete)
|
|
|
|
|
{
|
2016-11-24 15:47:41 -05:00
|
|
|
logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth);
|
|
|
|
|
if(triggerPromise && typeof triggerPromise.then === "function") {
|
|
|
|
|
return triggerPromise.then(resolve, resolve);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return resolve();
|
|
|
|
|
}
|
2016-08-17 15:26:42 +02:00
|
|
|
}
|
2016-01-28 10:58:12 -08:00
|
|
|
});
|
2016-11-24 15:47:41 -05:00
|
|
|
}
|
2016-01-28 10:58:12 -08:00
|
|
|
|
|
|
|
|
// Converts a REST-format object to a Parse.Object
|
|
|
|
|
// data is either className or an object
|
2016-02-24 15:55:11 -05:00
|
|
|
export function inflate(data, restObject) {
|
2016-01-28 10:58:12 -08:00
|
|
|
var copy = typeof data == 'object' ? data : {className: data};
|
|
|
|
|
for (var key in restObject) {
|
|
|
|
|
copy[key] = restObject[key];
|
|
|
|
|
}
|
|
|
|
|
return Parse.Object.fromJSON(copy);
|
|
|
|
|
}
|
2017-09-15 17:20:51 -04:00
|
|
|
|
|
|
|
|
export function runLiveQueryEventHandlers(data, applicationId = Parse.applicationId) {
|
|
|
|
|
if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) { return; }
|
|
|
|
|
_triggerStore[applicationId].LiveQuery.forEach((handler) => handler(data));
|
|
|
|
|
}
|