kinvey-flex-sdk
Version:
SDK for creating Kinvey Flex Services
198 lines (177 loc) • 6.24 kB
JavaScript
/**
* Copyright (c) 2018 Kinvey Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
const logger = require('./logger');
function isFunctionHandler(taskType) {
return taskType === 'businessLogic' || taskType === 'functions';
}
function logAlreadyResponded(task) {
let message = 'Invoked done() or next() more than once to the same Flex ';
if (isFunctionHandler(task.taskType)) {
message += `Functions request to "${task.taskName}"`;
} else {
message += `Data handler ${task.request.method} for ${task.request.serviceObjectName}`;
}
logger.error(message);
}
function normalizeError(error) {
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack
};
}
return error;
}
function createCompletionHandler(task, modules, cb) {
const updateRequestBody = task.hookType === 'pre';
let responseCallback = cb;
function completionHandler(body) {
const result = {};
result.body = body;
const api = {
setBody(body) {
if (body != null) {
result.body = body;
}
return this;
},
setQuery(query) {
if (query) {
result.query = query;
if (result.query.query && typeof result.query.query === 'object') {
result.query.query = JSON.stringify(result.query.query);
}
if (result.query.sort && typeof result.query.sort === 'object') {
result.query.sort = JSON.stringify(result.query.sort);
}
}
return this;
},
created() {
result.statusCode = 201;
return this;
},
accepted() {
result.statusCode = 202;
return this;
},
ok() {
result.statusCode = 200;
return this;
},
notFound(debug) {
result.statusCode = 404;
result.body = {
error: 'NotFound',
description: 'The requested entity or entities were not found in the serviceObject',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
badRequest(debug) {
result.statusCode = 400;
result.body = {
error: 'BadRequest',
description: 'Unable to understand request',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
unauthorized(debug) {
result.statusCode = 401;
result.body = {
error: 'InvalidCredentials',
description: 'Invalid credentials. Please retry your request with correct credentials',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
forbidden(debug) {
result.statusCode = 403;
result.body = {
error: 'Forbidden',
description: 'The request is forbidden',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
notAllowed(debug) {
result.statusCode = 405;
result.body = {
error: 'NotAllowed',
description: 'The request is not allowed',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
notImplemented(debug) {
result.statusCode = 501;
result.body = {
error: 'NotImplemented',
description: 'The request invoked a method that is not implemented',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
runtimeError(debug) {
result.statusCode = 550;
result.body = {
error: 'FlexRuntimeError',
description: 'The Flex Service had a runtime error. See debug message for details',
debug: normalizeError(debug) || normalizeError(result.body) || {}
};
return this;
},
done() {
if (!result.statusCode) {
result.statusCode = 200;
}
task.response.body = result.body || task.response.body;
task.response.statusCode = result.statusCode;
// TODO: Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object
//
// if result.statusCode < 400 and entityParser.isKinveyEntity(entity) is false
// if entity.constructor isnt Array
// entity = entityParser.entity entity
task.response.continue = false;
responseCallback(null, task);
responseCallback = logAlreadyResponded.bind(null, task);
},
next() {
if (!result.statusCode) {
result.statusCode = 200;
}
if (updateRequestBody) {
task.request.body = result.body || task.request.body;
task.request.query = result.query || task.request.query;
task.request.params = result.query || task.request.query;
} else {
task.response.body = result.body || task.response.body;
}
if (modules.requestContext && modules.requestContext.getCustomRequestProperties()) {
task.request.headers['x-kinvey-custom-request-properties'] = JSON.stringify(modules.requestContext.getCustomRequestProperties());
}
task.response.statusCode = result.statusCode;
// TODO: Ensure that the result is a kinveyEntity or array of kinveyEntities or {count} object
task.response.continue = true;
responseCallback(null, task);
responseCallback = logAlreadyResponded.bind(null, task);
}
};
return api;
}
return completionHandler;
}
module.exports = createCompletionHandler;