Add async functions supports into <Method>.execute

This commit is contained in:
Nikiroy78 2022-11-02 11:36:47 +03:00 committed by GitHub
parent 35799245ed
commit 0f9ba4fc7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1327 additions and 1327 deletions

View File

@ -1,177 +1,177 @@
const njsbacker = require('./index'); const njsbacker = require('./index');
// Создаём класс бэкенда, наследующий класс njsbacker.Main // Создаём класс бэкенда, наследующий класс njsbacker.Main
class Main extends njsbacker.Main { class Main extends njsbacker.Main {
/* errorHandler (error) { return { /* errorHandler (error) { return {
mainbody : JSON.stringify({ error : {}, error }), mainbody : JSON.stringify({ error : {}, error }),
headers : { headers : {
errored : 1 errored : 1
}, },
cookies : { cookies : {
avava : 1 avava : 1
}, },
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 400 code: 400
}};*/ }};*/
session (params, sessionData) { session (params, sessionData) {
sessionData._setValue('example', 1); // Задать значение sessionData._setValue('example', 1); // Задать значение
console.log(sessionData.example); // Получить значение из сессии console.log(sessionData.example); // Получить значение из сессии
sessionData._remove('example'); // Убрать значение sessionData._remove('example'); // Убрать значение
return 1; // Успешно return 1; // Успешно
throw 'Example error' // Пример ошибки throw 'Example error' // Пример ошибки
} }
responseHandler (response) { return ({ responseHandler (response) { return ({
mainbody : { response }, mainbody : { response },
headers : { headers : {
errored: 0 errored: 0
}, },
cookies : {}, cookies : {},
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 200 code: 200
}) }; }) };
/* paramsError (required, additional) { return({ required, additional }) }; */ /* paramsError (required, additional) { return({ required, additional }) }; */
} }
// Создаём экземпляр класса Main // Создаём экземпляр класса Main
var server = new Main( var server = new Main(
false // Отобразить в заголовках информацию о текущем фреймворке false // Отобразить в заголовках информацию о текущем фреймворке
); );
server.setSessionParams( // Зададим необходимые параметры для сессии server.setSessionParams( // Зададим необходимые параметры для сессии
{ {
session_id : { session_id : {
required : false, required : false,
type : njsbacker.types.integer type : njsbacker.types.integer
} }
} }
); );
// Создаём класс группы методов // Создаём класс группы методов
class ExampleMethodGroup extends njsbacker.Group { class ExampleMethodGroup extends njsbacker.Group {
handler (params, session) { // Путевая обработка handler (params, session) { // Путевая обработка
session._setValue('example', 1); // Задать значение session._setValue('example', 1); // Задать значение
console.log(session.example); // Получить значение из сессии console.log(session.example); // Получить значение из сессии
session._remove('example'); // Убрать значение session._remove('example'); // Убрать значение
return 1; // Успешно return 1; // Успешно
throw 'Example error' // Пример ошибки throw 'Example error' // Пример ошибки
} }
} }
// Создаём классы методов // Создаём классы методов
class ExampleAnyMethodsOfHandlingInformation extends njsbacker.Method { class ExampleAnyMethodsOfHandlingInformation extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return { return {
json_data : params.json_name, json_data : params.json_name,
query_data : params.query_name, query_data : params.query_name,
} }
} }
} }
class ExampleMethod extends njsbacker.Method { class ExampleMethod extends njsbacker.Method {
/* /*
var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода
*/ */
// Обработчик параметров // Обработчик параметров
execute (params, session, groups) { execute (params, session, groups) {
return { return {
text : params.text, text : params.text,
result : this.MainObject.call('sum', { result : this.MainObject.call('sum', {
a : 15, a : 15,
b : 17, b : 17,
session_id : params.session_id session_id : params.session_id
}) })
}; };
throw new njsbacker.ApiError('EXAMPLE_ERROR', new Object()); throw new njsbacker.ApiError('EXAMPLE_ERROR', new Object());
} }
} }
class SumMethod extends njsbacker.Method { class SumMethod extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return params.a + params.b; return params.a + params.b;
} }
} }
class FileMethod extends njsbacker.Method { class FileMethod extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return JSON.stringify(params.file); return JSON.stringify(params.file);
} }
} }
// Создаём экземпляры классов // Создаём экземпляры классов
var eamohi = new ExampleAnyMethodsOfHandlingInformation('handler', '/handler', { var eamohi = new ExampleAnyMethodsOfHandlingInformation('handler', '/handler', {
queryName : { queryName : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'name', import_key : 'name',
allow_params : ['query'] allow_params : ['query']
}, },
jsonName : { jsonName : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'name', import_key : 'name',
allow_methods : ['post'], allow_methods : ['post'],
allow_params : ['json'] allow_params : ['json']
} }
}); });
var fileMethod = new FileMethod('file', '/file', { var fileMethod = new FileMethod('file', '/file', {
file : { file : {
required : true, required : true,
type : njsbacker.types.file() type : njsbacker.types.file()
} }
}); });
var sumMethod = new SumMethod('sum', '/sum', { var sumMethod = new SumMethod('sum', '/sum', {
a : { a : {
required : true, required : true,
type : njsbacker.types.integer, type : njsbacker.types.integer,
conversion : false, conversion : false,
// allow_methods : ['post'], // allow_methods : ['post'],
}, },
b : { b : {
required : true, required : true,
type : njsbacker.types.integer, type : njsbacker.types.integer,
conversion : false, conversion : false,
// allow_methods : ['post'], // allow_methods : ['post'],
} }
}); });
var exampleMethod = new ExampleMethod('example', '/example', { var exampleMethod = new ExampleMethod('example', '/example', {
text : { text : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
conversion : false, conversion : false,
values : ['123', 'test'], values : ['123', 'test'],
min_length : 1, min_length : 1,
max_length : 255, max_length : 255,
// allow_methods : ['post'], // allow_methods : ['post'],
// allow_params : ['json'], // allow_params : ['json'],
} }
}); });
// Привяжем метод к группе // Привяжем метод к группе
exampleMethod.group(new ExampleMethodGroup({ exampleMethod.group(new ExampleMethodGroup({
ses : { ses : {
type : njsbacker.types.string type : njsbacker.types.string
} }
})); }));
sumMethod.group(new ExampleMethodGroup({ sumMethod.group(new ExampleMethodGroup({
ses : { ses : {
type : njsbacker.types.string type : njsbacker.types.string
} }
})); }));
// Привяжем метод к основному проекту // Привяжем метод к основному проекту
server.method(exampleMethod); server.method(exampleMethod);
server.method(sumMethod); server.method(sumMethod);
server.method(fileMethod); server.method(fileMethod);
server.method(eamohi); server.method(eamohi);
// Запускаем сервер // Запускаем сервер
server.server('/api/v1').listen(8080, async (err) => { server.server('/api/v1').listen(8080, async (err) => {
if (err) { throw err; } if (err) { throw err; }
else { else {
console.log('SERVER RUNNED'); console.log('SERVER RUNNED');
} }
}); });

View File

@ -1,10 +1,10 @@
class Group { class Group {
constructor (sessionData) { constructor (sessionData) {
this.sessionData = sessionData this.sessionData = sessionData
} }
handler (params, session) { return 1; } handler (params, session) { return 1; }
} }
module.exports = Group; module.exports = Group;

View File

@ -1,182 +1,182 @@
const express = require('express'); const express = require('express');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const version = '1.0.0'; const version = '1.0.0';
class ApiError extends Error { class ApiError extends Error {
constructor (opt, data) { constructor (opt, data) {
super(opt); super(opt);
this.name = 'API Error'; this.name = 'API Error';
this.data = data; this.data = data;
} }
} }
const debug = (text) => {} const debug = (text) => {}
class Main { class Main {
constructor (sendHeaders = true) { constructor (sendHeaders = true) {
this.sendHeaders = sendHeaders; this.sendHeaders = sendHeaders;
this.methods = new Object(); this.methods = new Object();
this.sessionData = new Object(); this.sessionData = new Object();
this.fileUploadConfig = { this.fileUploadConfig = {
limits: { fileSize : 1024 * 1024 * 256 }, // 256 Mb maximum limits: { fileSize : 1024 * 1024 * 256 }, // 256 Mb maximum
abortOnLimit: true, abortOnLimit: true,
responseOnLimit: '{"error":"FILE_SIZE_LIMIT_HAS_BEEN_REACHED"}' responseOnLimit: '{"error":"FILE_SIZE_LIMIT_HAS_BEEN_REACHED"}'
}; };
} }
paramsError (required, additional) { paramsError (required, additional) {
return new ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional }); return new ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional });
} }
errorHadler (error) { errorHadler (error) {
let errorData; let errorData;
if (error.name == "API Error") { if (error.name == "API Error") {
errorData = { errorData = {
code : error.message, code : error.message,
details : error.data details : error.data
}; };
} }
else { else {
errorData = { errorData = {
name : error.name, name : error.name,
stack : error.stack stack : error.stack
}; };
} }
return { return {
mainbody : { error : errorData }, mainbody : { error : errorData },
headers : {}, headers : {},
cookies : {}, cookies : {},
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 400 code: 400
} }
} }
setSessionParams (sessionParams) { setSessionParams (sessionParams) {
this.sessionData = sessionParams; this.sessionData = sessionParams;
} }
session (params, sessionData) { return 1; } session (params, sessionData) { return 1; }
responseHandler (result) { return ({ responseHandler (result) { return ({
mainbody : { result }, mainbody : { result },
headers : {}, headers : {},
cookies : {}, cookies : {},
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 200 code: 200
}) }; }) };
method (methodObj) { method (methodObj) {
methodObj._pinMain(this); methodObj._pinMain(this);
this.methods[methodObj.name] = methodObj; this.methods[methodObj.name] = methodObj;
} }
call (method, params) { call (method, params) {
return this.methods[method].pre_execute(params); return this.methods[method].pre_execute(params);
} }
fileSetting (fileUploadConfig) { fileSetting (fileUploadConfig) {
this.fileUploadConfig = fileUploadConfig; this.fileUploadConfig = fileUploadConfig;
} }
router (returnMiddlewareFunction = false, middlewareFunction = (req, res, next) => next()) { router (returnMiddlewareFunction = false, middlewareFunction = (req, res, next) => next()) {
let router = express.Router(); let router = express.Router();
router.use(require('cookie-parser')()); router.use(require('cookie-parser')());
// parse various different custom JSON types as JSON // parse various different custom JSON types as JSON
router.use(bodyParser.json({ type: 'application/*+json' })) router.use(bodyParser.json({ type: 'application/*+json' }))
router.use(bodyParser.json({ type: 'application/json' })) router.use(bodyParser.json({ type: 'application/json' }))
// parse some custom thing into a Buffer // parse some custom thing into a Buffer
router.use(bodyParser.raw({ type: 'application/vnd.custom-type' })) router.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// parse an HTML body into a string // parse an HTML body into a string
router.use(bodyParser.text({ type: 'text/html' })); router.use(bodyParser.text({ type: 'text/html' }));
// parse application/x-www-form-urlencoded // parse application/x-www-form-urlencoded
router.use(bodyParser.urlencoded({ type: 'application/x-www-form-urlencoded', extended: false })) router.use(bodyParser.urlencoded({ type: 'application/x-www-form-urlencoded', extended: false }))
// parse files // parse files
router.use(require('express-fileupload')(this.fileUploadConfig)); router.use(require('express-fileupload')(this.fileUploadConfig));
for (let name in this.methods) { for (let name in this.methods) {
debug(`CONNECT METHOD : ${name}`); debug(`CONNECT METHOD : ${name}`);
for (let methodId in this.methods[name].allowedMethods) { for (let methodId in this.methods[name].allowedMethods) {
debug(` >> CONNECT METHOD : ${name} [${this.methods[name].allowedMethods[methodId]}] to ${this.methods[name].path}`); debug(` >> CONNECT METHOD : ${name} [${this.methods[name].allowedMethods[methodId]}] to ${this.methods[name].path}`);
router[this.methods[name].allowedMethods[methodId]](this.methods[name].path, async (req, res) => { router[this.methods[name].allowedMethods[methodId]](this.methods[name].path, async (req, res) => {
if (this.sendHeaders) { if (this.sendHeaders) {
res.set('njsbacker-version', version); res.set('njsbacker-version', version);
} }
try { try {
let contentType = req.get('Content-Type'); let contentType = req.get('Content-Type');
if (contentType != undefined) { if (contentType != undefined) {
contentType = contentType.toLowerCase(); contentType = contentType.toLowerCase();
} }
else { else {
contentType = 'unknown'; contentType = 'unknown';
} }
let result = this.methods[name].executeIntoExpressRouter( let result = await this.methods[name].executeIntoExpressRouter(
this.methods[name].allowedMethods[methodId], this.methods[name].allowedMethods[methodId],
req.headers, req.headers,
(contentType.indexOf('json') != -1) ? req.body : new Object(), (contentType.indexOf('json') != -1) ? req.body : new Object(),
req.params, req.params,
req.query, req.query,
(contentType.indexOf('json') == -1) ? req.body : new Object(), (contentType.indexOf('json') == -1) ? req.body : new Object(),
req.files != undefined ? req.files : new Object(), req.files != undefined ? req.files : new Object(),
req.cookies req.cookies
); );
let handledDataResponse = this.responseHandler( let handledDataResponse = this.responseHandler(
result result
); );
if (!handledDataResponse.redirect_uri) { if (!handledDataResponse.redirect_uri) {
for (let header in handledDataResponse.headers) { for (let header in handledDataResponse.headers) {
res.set(header, handledDataResponse.headers[header].toString()); res.set(header, handledDataResponse.headers[header].toString());
} }
for (let cookie in handledDataResponse.cookies) { for (let cookie in handledDataResponse.cookies) {
res.cookie(cookie, handledDataResponse.cookies[cookie].toString()); res.cookie(cookie, handledDataResponse.cookies[cookie].toString());
} }
res.status(handledDataResponse.code).send(handledDataResponse.mainbody); res.status(handledDataResponse.code).send(handledDataResponse.mainbody);
} }
else { else {
res.status(handledDataResponse.code).redirect(handledDataResponse.redirect_uri); res.status(handledDataResponse.code).redirect(handledDataResponse.redirect_uri);
} }
} }
catch (err) { catch (err) {
debug('ERROR RISED:'); debug('ERROR RISED:');
debug(err); debug(err);
let handledDataError = this.errorHadler(err); let handledDataError = this.errorHadler(err);
if (!handledDataError.redirect_uri) { if (!handledDataError.redirect_uri) {
for (let header in handledDataError.headers) { for (let header in handledDataError.headers) {
res.set(header, handledDataError.headers[header].toString()); res.set(header, handledDataError.headers[header].toString());
} }
for (let cookie in handledDataError.cookies) { for (let cookie in handledDataError.cookies) {
res.cookie(cookie, handledDataError.cookies[cookie].toString()); res.cookie(cookie, handledDataError.cookies[cookie].toString());
} }
res.status(handledDataError.code).send(handledDataError.mainbody); res.status(handledDataError.code).send(handledDataError.mainbody);
} }
else { else {
res.status(handledDataError.code).redirect(handledDataError.redirect_uri); res.status(handledDataError.code).redirect(handledDataError.redirect_uri);
} }
} }
}); });
} }
} }
if (returnMiddlewareFunction) { if (returnMiddlewareFunction) {
return middlewareFunction, router; return middlewareFunction, router;
} }
else { else {
return router; return router;
} }
} }
server (mountPath = '/') { server (mountPath = '/') {
let app = express(); let app = express();
app.use(mountPath, this.router(true)); app.use(mountPath, this.router(true));
return app; return app;
} }
} }
module.exports = { Main, ApiError }; module.exports = { Main, ApiError };

View File

@ -1,268 +1,268 @@
const typesApi = require('./types'); const typesApi = require('./types');
const Session = require('./Session'); const Session = require('./Session');
var errHandlers = new Object(); var errHandlers = new Object();
const formatMessage = (message, errorType, scheme, value, param) => { const formatMessage = (message, errorType, scheme, value, param) => {
value = String(value); value = String(value);
switch (errorType) { switch (errorType) {
case 'typeError' : case 'typeError' :
return message.split('{param}').join(param).split('{long_type}').join(scheme.type.long_name).split('{short_type}').join(scheme.type.short_name); return message.split('{param}').join(param).split('{long_type}').join(scheme.type.long_name).split('{short_type}').join(scheme.type.short_name);
case 'valuesError' : case 'valuesError' :
return message.split('{param}').join(param).split('{value}').join(value).split('{values}').join(scheme.values.join(', ')); return message.split('{param}').join(param).split('{value}').join(value).split('{values}').join(scheme.values.join(', '));
case 'minLengthError' : case 'minLengthError' :
return message.split('{value}').join(scheme.min_length); return message.split('{value}').join(scheme.min_length);
case 'maxLengthError' : case 'maxLengthError' :
return message.split('{value}').join(scheme.max_length); return message.split('{value}').join(scheme.max_length);
case 'httpMethodError' : case 'httpMethodError' :
return message.split('{method}').join(value).split('{methods}').join(scheme.allow_methods.join(', ')); return message.split('{method}').join(value).split('{methods}').join(scheme.allow_methods.join(', '));
default : default :
return errHandlers[errorType](message, errorType, scheme, value, param); return errHandlers[errorType](message, errorType, scheme, value, param);
} }
}; };
const compileParams = (params) => { const compileParams = (params) => {
let compiled = new Object(); let compiled = new Object();
for (let objKey in params) { for (let objKey in params) {
compiled = Object.assign(compiled, params[objKey]); compiled = Object.assign(compiled, params[objKey]);
} }
return compiled; return compiled;
} }
class Method { class Method {
constructor (name, path, params) { constructor (name, path, params) {
this.name = name; this.name = name;
this.path = path; this.path = path;
this.paramsCompiles = params; this.paramsCompiles = params;
this.groupsConnected = new Array(); this.groupsConnected = new Array();
this.allowedMethods = new Array(); this.allowedMethods = new Array();
// Errors // Errors
this.error = new Object(); this.error = new Object();
this.error.typeError = 'param {param} must be only {long_type} ({short_type})'; this.error.typeError = 'param {param} must be only {long_type} ({short_type})';
this.error.valuesError = 'value "{value}" not finded into {values}'; this.error.valuesError = 'value "{value}" not finded into {values}';
this.error.minLengthError = 'value must be more or equal {value}'; this.error.minLengthError = 'value must be more or equal {value}';
this.error.maxLengthError = 'value must be less or equal {value}'; this.error.maxLengthError = 'value must be less or equal {value}';
this.error.httpMethodError = 'Method {method} does not supported. Methods supports: {methods}'; this.error.httpMethodError = 'Method {method} does not supported. Methods supports: {methods}';
this.isDynamic = false; this.isDynamic = false;
// Setting allow methods // Setting allow methods
let allowedMethods; let allowedMethods;
for (let param in params) { for (let param in params) {
if (!params[param].allow_methods) allowedMethods = ['get', 'post', 'put', 'delete']; if (!params[param].allow_methods) allowedMethods = ['get', 'post', 'put', 'delete'];
else { else {
allowedMethods = params[param].allow_methods; allowedMethods = params[param].allow_methods;
} }
for (let allowMethod in allowedMethods) { for (let allowMethod in allowedMethods) {
if (this.allowedMethods.indexOf(allowedMethods[allowMethod]) == -1) { if (this.allowedMethods.indexOf(allowedMethods[allowMethod]) == -1) {
this.allowedMethods.push(allowedMethods[allowMethod]); this.allowedMethods.push(allowedMethods[allowMethod]);
} }
} }
} }
} }
setError (errorCode, message, handler=null) { setError (errorCode, message, handler=null) {
this.error[errorCode] = message; this.error[errorCode] = message;
if (!!handler) { if (!!handler) {
errHandlers[errorCode] = handler; errHandlers[errorCode] = handler;
} }
} }
useDynamicType (condition) { useDynamicType (condition) {
this.isDynamic = !!condition; this.isDynamic = !!condition;
} }
_pinMain (mainObject) { _pinMain (mainObject) {
this.MainObject = mainObject; this.MainObject = mainObject;
} }
executeIntoExpressRouter ( async executeIntoExpressRouter (
currentMethod, currentMethod,
headers, headers,
json, json,
params, params,
query, query,
body, body,
files, files,
cookies cookies
) { ) {
let paramsEndless = new Object(); let paramsEndless = new Object();
let paramScheme; let paramScheme;
let required = { missed : [], unsyntax : [] }; let required = { missed : [], unsyntax : [] };
let additional = { missed : [], unsyntax : [] }; let additional = { missed : [], unsyntax : [] };
let checkKeys; let checkKeys;
let paramsCompiles = Object.assign({}, this.paramsCompiles, this.MainObject.sessionData); let paramsCompiles = Object.assign({}, this.paramsCompiles, this.MainObject.sessionData);
for (let groupId in this.groupsConnected) { for (let groupId in this.groupsConnected) {
paramsCompiles = Object.assign({}, paramsCompiles, this.groupsConnected[groupId].sessionData); paramsCompiles = Object.assign({}, paramsCompiles, this.groupsConnected[groupId].sessionData);
} }
for (let param in paramsCompiles) { for (let param in paramsCompiles) {
checkKeys = new Array(); checkKeys = new Array();
paramScheme = { paramScheme = {
required : false, required : false,
import_key : param, import_key : param,
save_key : param, save_key : param,
type : this.isDynamic ? typesApi.dynamic : typesApi.unknown, type : this.isDynamic ? typesApi.dynamic : typesApi.unknown,
allow_methods : ['get', 'post', 'put', 'delete'], allow_methods : ['get', 'post', 'put', 'delete'],
conversion : false, conversion : false,
allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies'] allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies']
}; };
// Configure paramScheme // Configure paramScheme
for (let key in paramsCompiles[param]) { paramScheme[key] = paramsCompiles[param][key]; } for (let key in paramsCompiles[param]) { paramScheme[key] = paramsCompiles[param][key]; }
// check missible // check missible
if (headers[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('headers') != -1) { checkKeys.push('headers'); } if (headers[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('headers') != -1) { checkKeys.push('headers'); }
if (json[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('json') != -1) { checkKeys.push('json'); } if (json[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('json') != -1) { checkKeys.push('json'); }
if (query[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('query') != -1) { checkKeys.push('query'); } if (query[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('query') != -1) { checkKeys.push('query'); }
if (body[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('body') != -1) { checkKeys.push('body'); } if (body[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('body') != -1) { checkKeys.push('body'); }
if (files[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('files') != -1) { checkKeys.push('files'); } if (files[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('files') != -1) { checkKeys.push('files'); }
if (cookies[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('cookies') != -1) { checkKeys.push('cookies'); } if (cookies[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('cookies') != -1) { checkKeys.push('cookies'); }
if (params[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('params') != -1) { checkKeys.push('params'); } if (params[paramScheme.import_key] != undefined & paramScheme.allow_params.indexOf('params') != -1) { checkKeys.push('params'); }
if (checkKeys.length == 0) { if (checkKeys.length == 0) {
if (paramScheme.required) { required.missed.push(paramScheme.import_key); } if (paramScheme.required) { required.missed.push(paramScheme.import_key); }
else { additional.missed.push(paramScheme.import_key); } else { additional.missed.push(paramScheme.import_key); }
} }
else if (paramScheme.allow_methods.indexOf(currentMethod) == -1) { else if (paramScheme.allow_methods.indexOf(currentMethod) == -1) {
if (paramScheme.required) { required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, paramScheme.import_key) }); } if (paramScheme.required) { required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, paramScheme.import_key) }); }
else { additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, paramScheme.import_key)}); } else { additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, paramScheme.import_key)}); }
} }
else { else {
checkKeys = checkKeys.sort((a, b) => Number(b == 'query' || b == 'cookies') - Number(a == 'query' || a == 'cookies')); checkKeys = checkKeys.sort((a, b) => Number(b == 'query' || b == 'cookies') - Number(a == 'query' || a == 'cookies'));
let isSyntax; let isSyntax;
let convertedValue; let convertedValue;
let selectedSyntaxError = 'typeError'; let selectedSyntaxError = 'typeError';
for (let key in checkKeys) { for (let key in checkKeys) {
switch (checkKeys[key]) { switch (checkKeys[key]) {
case 'query' : case 'query' :
[isSyntax, convertedValue] = paramScheme.type.syntax(query[paramScheme.import_key], true); [isSyntax, convertedValue] = paramScheme.type.syntax(query[paramScheme.import_key], true);
break; break;
case 'cookies' : case 'cookies' :
[isSyntax, convertedValue] = paramScheme.type.syntax(cookies[paramScheme.import_key], true); [isSyntax, convertedValue] = paramScheme.type.syntax(cookies[paramScheme.import_key], true);
break; break;
case 'headers' : case 'headers' :
[isSyntax, convertedValue] = paramScheme.type.syntax(headers[paramScheme.import_key], true); [isSyntax, convertedValue] = paramScheme.type.syntax(headers[paramScheme.import_key], true);
break; break;
case 'body' : case 'body' :
[isSyntax, convertedValue] = paramScheme.type.syntax(body[paramScheme.import_key], true); [isSyntax, convertedValue] = paramScheme.type.syntax(body[paramScheme.import_key], true);
break; break;
case 'json' : case 'json' :
[isSyntax, convertedValue] = paramScheme.type.syntax(json[paramScheme.import_key], paramScheme.conversion); [isSyntax, convertedValue] = paramScheme.type.syntax(json[paramScheme.import_key], paramScheme.conversion);
break; break;
case 'params' : case 'params' :
[isSyntax, convertedValue] = paramScheme.type.syntax(params[paramScheme.import_key], paramScheme.conversion); [isSyntax, convertedValue] = paramScheme.type.syntax(params[paramScheme.import_key], paramScheme.conversion);
break; break;
case 'files' : case 'files' :
[isSyntax, convertedValue] = paramScheme.type.syntax(files[paramScheme.import_key], paramScheme.conversion); [isSyntax, convertedValue] = paramScheme.type.syntax(files[paramScheme.import_key], paramScheme.conversion);
break; break;
} }
if (isSyntax) { if (isSyntax) {
[isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(convertedValue, paramScheme); [isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(convertedValue, paramScheme);
if (isSyntax) break; if (isSyntax) break;
} }
} }
if (isSyntax) { if (isSyntax) {
paramsEndless[paramScheme.save_key] = convertedValue; paramsEndless[paramScheme.save_key] = convertedValue;
} }
else { else {
if (paramScheme.required) { required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, paramScheme.import_key) }); } if (paramScheme.required) { required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, paramScheme.import_key) }); }
else { additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, paramScheme.import_key)}); } else { additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, paramScheme.import_key)}); }
} }
} }
} }
if (required.missed.length > 0 || required.unsyntax.length > 0 || additional.unsyntax.length > 0) { if (required.missed.length > 0 || required.unsyntax.length > 0 || additional.unsyntax.length > 0) {
throw this.MainObject.paramsError(required, additional); throw this.MainObject.paramsError(required, additional);
} }
else { else {
return this.pre_execute(paramsEndless, false); return await this.pre_execute(paramsEndless, false);
} }
} }
pre_execute (params, needsChecking = true) { async pre_execute (params, needsChecking = true) {
if (needsChecking) { if (needsChecking) {
let required = { missed : [], unsyntax : [] }; let required = { missed : [], unsyntax : [] };
let additional = { missed : [], unsyntax : [] }; let additional = { missed : [], unsyntax : [] };
let isSyntax; let isSyntax;
let value; let value;
let paramScheme; let paramScheme;
let paramsCompiles = Object.assign(this.paramsCompiles, this.MainObject.sessionData); let paramsCompiles = Object.assign(this.paramsCompiles, this.MainObject.sessionData);
for (let param in paramsCompiles) { for (let param in paramsCompiles) {
paramScheme = { paramScheme = {
required : false, required : false,
type : this.isDynamic ? typesApi.dynamic : typesApi.unknown, type : this.isDynamic ? typesApi.dynamic : typesApi.unknown,
import_key : param, import_key : param,
save_key : param, save_key : param,
allow_methods : ['get', 'post', 'put', 'delete'], allow_methods : ['get', 'post', 'put', 'delete'],
conversion : false, conversion : false,
allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies'] allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies']
}; };
for (let key in paramsCompiles[param]) { paramScheme[key] = paramsCompiles[param][key]; } for (let key in paramsCompiles[param]) { paramScheme[key] = paramsCompiles[param][key]; }
if (params[paramScheme.import_key] === undefined) { if (params[paramScheme.import_key] === undefined) {
if (paramScheme.required) { if (paramScheme.required) {
required.missed.push(paramScheme.import_key); required.missed.push(paramScheme.import_key);
} }
else { else {
additional.missed.push(paramScheme.import_key); additional.missed.push(paramScheme.import_key);
} }
} }
else { else {
let selectedSyntaxError = 'typeError'; let selectedSyntaxError = 'typeError';
[isSyntax, value] = paramScheme.type.syntax(params[paramScheme.import_key], paramScheme.conversion); [isSyntax, value] = paramScheme.type.syntax(params[paramScheme.import_key], paramScheme.conversion);
if (!isSyntax) { if (!isSyntax) {
if (paramScheme.required) { if (paramScheme.required) {
required.unsyntax.push({param : paramScheme.import_key, description : this.error.typeError.split('{param}').join(paramScheme.import_key).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); required.unsyntax.push({param : paramScheme.import_key, description : this.error.typeError.split('{param}').join(paramScheme.import_key).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)});
} }
else { else {
additional.unsyntax.push({param : paramScheme.import_key, description : this.error.typeError.split('{param}').join(paramScheme.import_key).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); additional.unsyntax.push({param : paramScheme.import_key, description : this.error.typeError.split('{param}').join(paramScheme.import_key).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)});
} }
} }
else { else {
[isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(value, paramScheme); [isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(value, paramScheme);
if (!isSyntax) { if (!isSyntax) {
if (paramScheme.required) { if (paramScheme.required) {
required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, paramScheme.import_key)}); required.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, paramScheme.import_key)});
} }
else { else {
additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, paramScheme.import_key)}); additional.unsyntax.push({param : paramScheme.import_key, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, paramScheme.import_key)});
} }
} }
else { else {
params[paramScheme.save_key] = value; params[paramScheme.save_key] = value;
} }
} }
} }
} }
if (required.missed.length > 0 || required.unsyntax.length > 0 || additional.unsyntax.length > 0) { if (required.missed.length > 0 || required.unsyntax.length > 0 || additional.unsyntax.length > 0) {
throw this.MainObject.paramsError(required, additional); throw this.MainObject.paramsError(required, additional);
} }
} }
// Исполнение сессии // Исполнение сессии
let sessionData = new Session(); let sessionData = new Session();
let groupData = new Session(); let groupData = new Session();
this.MainObject.session(params, sessionData); this.MainObject.session(params, sessionData);
sessionData = sessionData._getValues(); sessionData = sessionData._getValues();
for (let groupId in this.groupsConnected) { for (let groupId in this.groupsConnected) {
this.groupsConnected[groupId].handler(params, groupData); this.groupsConnected[groupId].handler(params, groupData);
} }
// for (let key in sessionData) { params[key] = sessionData[key]; } // for (let key in sessionData) { params[key] = sessionData[key]; }
// Исполнение группы // Исполнение группы
return this.execute(params, sessionData, groupData._getValues()); return await this.execute(params, sessionData, groupData._getValues());
} }
group (group) { group (group) {
this.groupsConnected.push(group); this.groupsConnected.push(group);
} }
execute (params, sessionData, groupData) {} execute (params, sessionData, groupData) {}
} }
module.exports = Method; module.exports = Method;

View File

@ -1,31 +1,31 @@
class Session { class Session {
constructor () { constructor () {
this._namesReserved = ['_getValues', '_namesReserved', '_setValue', '_remove']; this._namesReserved = ['_getValues', '_namesReserved', '_setValue', '_remove'];
} }
_setValue (key, value) { _setValue (key, value) {
if (this._namesReserved.indexOf(key) == -1) { if (this._namesReserved.indexOf(key) == -1) {
this[key] = value; this[key] = value;
} }
} }
_remove (key, value) { _remove (key, value) {
if (this._namesReserved.indexOf(key) == -1) { if (this._namesReserved.indexOf(key) == -1) {
delete this[key]; delete this[key];
} }
} }
_getValues () { _getValues () {
let values = new Object(); let values = new Object();
for (let value in this) { for (let value in this) {
if (this._namesReserved.indexOf(value) == -1) { if (this._namesReserved.indexOf(value) == -1) {
values[value] = this[value]; values[value] = this[value];
} }
} }
return values; return values;
} }
} }
module.exports = Session; module.exports = Session;

View File

@ -1,217 +1,217 @@
const types = { const types = {
dynamic : { dynamic : {
long_name : 'dynamic', long_name : 'dynamic',
short_name : 'dyn', short_name : 'dyn',
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.values != undefined) { // values if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) { if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError']; return [false, 'valuesError'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = true) => [true, value] syntax : (value, needs_convert = true) => [true, value]
}, },
unknown : { unknown : {
long_name : 'unknown', long_name : 'unknown',
short_name : 'unk', short_name : 'unk',
checkSchema : (value, schema) => { throw new Error('Undefined datatype'); }, checkSchema : (value, schema) => { throw new Error('Undefined datatype'); },
syntax : (value, needs_convert = true) => { syntax : (value, needs_convert = true) => {
throw new Error('Undefined datatype'); throw new Error('Undefined datatype');
} }
}, },
float : { float : {
long_name : 'float', long_name : 'float',
short_name : 'float', short_name : 'float',
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.values != undefined) { // values if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) { if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError']; return [false, 'valuesError'];
} }
} }
if (schema.min_length != undefined) { // min_length if (schema.min_length != undefined) { // min_length
if (value < schema.min_length) { if (value < schema.min_length) {
return [false, 'minLengthError']; return [false, 'minLengthError'];
} }
} }
if (schema.max_length != undefined) { // max_length if (schema.max_length != undefined) { // max_length
if (value > schema.max_length) { if (value > schema.max_length) {
return [false, 'maxLengthError']; return [false, 'maxLengthError'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = true) => { syntax : (value, needs_convert = true) => {
function isFloat (value) { function isFloat (value) {
if (String(parseFloat(value)) == 'NaN') return false; if (String(parseFloat(value)) == 'NaN') return false;
return String(parseFloat(value)) == String(Number(value)); return String(parseFloat(value)) == String(Number(value));
} }
if (typeof(value) == 'number' & isFloat(value)) { if (typeof(value) == 'number' & isFloat(value)) {
return [true, value]; return [true, value];
} }
else if (needs_convert & isFloat(value)) { else if (needs_convert & isFloat(value)) {
return [true, parseFloat(value)]; return [true, parseFloat(value)];
} }
else { else {
return [false, undefined]; return [false, undefined];
} }
} }
}, },
array : (splitter, type=types.dynamic) => ({ array : (splitter, type=types.dynamic) => ({
long_name : `array (${type.long_name})`, long_name : `array (${type.long_name})`,
short_name : `arr (${type.short_name})`, short_name : `arr (${type.short_name})`,
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.min_length != undefined) { // min_length if (schema.min_length != undefined) { // min_length
if (value.length < schema.min_length) { if (value.length < schema.min_length) {
return [false, 'minLengthError']; return [false, 'minLengthError'];
} }
} }
if (schema.max_length != undefined) { // max_length if (schema.max_length != undefined) { // max_length
if (value.length > schema.max_length) { if (value.length > schema.max_length) {
return [false, 'maxLengthError']; return [false, 'maxLengthError'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = false) => { syntax : (value, needs_convert = false) => {
if (typeof(value) == 'string' & !!needs_convert) { if (typeof(value) == 'string' & !!needs_convert) {
value = value.split(splitter); value = value.split(splitter);
} }
else if (typeof(value) != 'object') { else if (typeof(value) != 'object') {
return [false, undefined]; return [false, undefined];
} }
// checking type of array // checking type of array
let isSyntax = Object.assign({}, value).filter(item => type.syntax(item, needs_convert)[0]).length == value.length; let isSyntax = Object.assign({}, value).filter(item => type.syntax(item, needs_convert)[0]).length == value.length;
return [isSyntax, isSyntax ? value : undefined] return [isSyntax, isSyntax ? value : undefined]
} }
}), }),
integer : { integer : {
long_name : 'integer', long_name : 'integer',
short_name : 'int', short_name : 'int',
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.values != undefined) { // values if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) { if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError']; return [false, 'valuesError'];
} }
} }
if (schema.min_length != undefined) { // min_length if (schema.min_length != undefined) { // min_length
if (value < schema.min_length) { if (value < schema.min_length) {
return [false, 'minLengthError']; return [false, 'minLengthError'];
} }
} }
if (schema.max_length != undefined) { // max_length if (schema.max_length != undefined) { // max_length
if (value > schema.max_length) { if (value > schema.max_length) {
return [false, 'maxLengthError']; return [false, 'maxLengthError'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = false) => { syntax : (value, needs_convert = false) => {
function isInt (value) { function isInt (value) {
if (String(parseInt(value)) == 'NaN') return false; if (String(parseInt(value)) == 'NaN') return false;
return String(parseInt(value)) == String(Number(value)); return String(parseInt(value)) == String(Number(value));
} }
if (typeof(value) == 'number' & isInt(value)) { if (typeof(value) == 'number' & isInt(value)) {
return [true, value]; return [true, value];
} }
else if (needs_convert & isInt(value)) { else if (needs_convert & isInt(value)) {
return [true, parseInt(value)]; return [true, parseInt(value)];
} }
else { else {
return [false, undefined]; return [false, undefined];
} }
} }
}, },
file : (allowed_types=null) => ({ file : (allowed_types=null) => ({
long_name : 'file', long_name : 'file',
short_name : 'file', short_name : 'file',
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.min_length != undefined) { // min_length if (schema.min_length != undefined) { // min_length
if (value.size < schema.min_length) { if (value.size < schema.min_length) {
return [false, 'minLengthError']; return [false, 'minLengthError'];
} }
} }
if (schema.max_length != undefined) { // max_length if (schema.max_length != undefined) { // max_length
if (value.size > schema.max_length) { if (value.size > schema.max_length) {
return [false, 'maxLengthError']; return [false, 'maxLengthError'];
} }
} }
if (allowed_types != null) { if (allowed_types != null) {
let file_extension = value.name.split(".")[value.name.split(".").length - 1]; let file_extension = value.name.split(".")[value.name.split(".").length - 1];
if (allowed_types.indexOf(file_extension.toLowerCase()) == -1) { if (allowed_types.indexOf(file_extension.toLowerCase()) == -1) {
return [false, 'unAllowExtension']; return [false, 'unAllowExtension'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = false) => { syntax : (value, needs_convert = false) => {
if (typeof(value) != 'object') { if (typeof(value) != 'object') {
return [false, undefined]; return [false, undefined];
} }
else { else {
let syntaxed = value.name != undefined & let syntaxed = value.name != undefined &
value.mv != undefined & value.mv != undefined &
value.mimetype != undefined & value.mimetype != undefined &
value.data != undefined & value.data != undefined &
value.tempFilePath != undefined & value.tempFilePath != undefined &
value.truncated != undefined & value.truncated != undefined &
value.size != undefined & value.size != undefined &
value.md5 != undefined; value.md5 != undefined;
return [syntaxed, syntaxed ? value : undefined]; return [syntaxed, syntaxed ? value : undefined];
} }
} }
}), }),
string : { string : {
long_name : 'string', long_name : 'string',
short_name : 'str', short_name : 'str',
checkSchema : (value, schema) => { checkSchema : (value, schema) => {
if (schema.values != undefined) { // values if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) { if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError']; return [false, 'valuesError'];
} }
} }
if (schema.min_length != undefined) { // min_length if (schema.min_length != undefined) { // min_length
if (value.length < schema.min_length) { if (value.length < schema.min_length) {
return [false, 'minLengthError']; return [false, 'minLengthError'];
} }
} }
if (schema.max_length != undefined) { // max_length if (schema.max_length != undefined) { // max_length
if (value.length > schema.max_length) { if (value.length > schema.max_length) {
return [false, 'maxLengthError']; return [false, 'maxLengthError'];
} }
} }
return [true, 'ok']; return [true, 'ok'];
}, },
syntax : (value, needs_convert = false) => { syntax : (value, needs_convert = false) => {
if (typeof(value) == 'string') { if (typeof(value) == 'string') {
return [true, value]; return [true, value];
} }
else if (needs_convert) { else if (needs_convert) {
return [true, value.toString()]; return [true, value.toString()];
} }
else { else {
return [false, undefined]; return [false, undefined];
} }
} }
} }
}; };
module.exports = types; module.exports = types;

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
Main : require('./components/Main').Main, Main : require('./components/Main').Main,
ApiError : require('./components/Main').ApiError, ApiError : require('./components/Main').ApiError,
Method : require('./components/Method'), Method : require('./components/Method'),
types : require('./components/types'), types : require('./components/types'),
Group : require('./components/Group') Group : require('./components/Group')
}; };

View File

@ -6,7 +6,7 @@
"express-fileupload": "^1.4.0" "express-fileupload": "^1.4.0"
}, },
"name": "njsbacker", "name": "njsbacker",
"version": "0.9.1", "version": "0.9.2",
"description": "Module for easy developing back-end projects at express.js", "description": "Module for easy developing back-end projects at express.js",
"main": "index.js", "main": "index.js",
"devDependencies": {}, "devDependencies": {},

882
readme.md
View File

@ -1,441 +1,441 @@
# Njsbacker # Njsbacker
Njsbacker is framework for backend developing at node.js/express.js *(in future versions can be supports any frameworks)* Njsbacker is framework for backend developing at node.js/express.js *(in future versions can be supports any frameworks)*
## How it works? ## How it works?
Below you can see simple scheme as framework works: from **session** response get into **Main class** where or getting at **Group** and next into **Method**, or at **Method Class** where response data from http-params, **Group** and **Session** hadling at execution method. Below you can see simple scheme as framework works: from **session** response get into **Main class** where or getting at **Group** and next into **Method**, or at **Method Class** where response data from http-params, **Group** and **Session** hadling at execution method.
![simple scheme of njsbacker work](https://sun9-71.userapi.com/impg/VjRpi90eSMsV05NPRU3GVNxwEbem8ITGjErioQ/lyD9S-F_qI4.jpg?size=726x341&quality=96&sign=d48f6eff6f6da9747675287096eb24b3&type=album) ![simple scheme of njsbacker work](https://sun9-71.userapi.com/impg/VjRpi90eSMsV05NPRU3GVNxwEbem8ITGjErioQ/lyD9S-F_qI4.jpg?size=726x341&quality=96&sign=d48f6eff6f6da9747675287096eb24b3&type=album)
After init main logic, logic can be converted at **express.js router** or **express.js server (app)**. Below you can see example code: After init main logic, logic can be converted at **express.js router** or **express.js server (app)**. Below you can see example code:
```javascript ```javascript
// ... another code // ... another code
mainserverObject.server( mainserverObject.server(
'/api' // mount path of api '/api' // mount path of api
).listen(8080, '127.0.0.1', async (err) => { ).listen(8080, '127.0.0.1', async (err) => {
if (err) { if (err) {
throw err; throw err;
} }
else { else {
console.log('SERVER RUNNED'); console.log('SERVER RUNNED');
} }
}); });
``` ```
Below you can see how responses from http/call-function hadless into reponse at scheme: Below you can see how responses from http/call-function hadless into reponse at scheme:
![simple scheme of njsbacker handling data an executing](https://sun9-78.userapi.com/impg/etOt-TcZ1KVxUnIm3laKJgAveXaMEOGfbGY0Wg/dIekdeOOKeo.jpg?size=649x353&quality=96&sign=958f40b23ab188ea03612bc98def05fe&type=album) ![simple scheme of njsbacker handling data an executing](https://sun9-78.userapi.com/impg/etOt-TcZ1KVxUnIm3laKJgAveXaMEOGfbGY0Wg/dIekdeOOKeo.jpg?size=649x353&quality=96&sign=958f40b23ab188ea03612bc98def05fe&type=album)
Http data or Data from call method gets into pre_execution binary function where checks data: syntax/missed or no: if all successfuly data get into Session/Group/Method execute method else throwing error. Http data or Data from call method gets into pre_execution binary function where checks data: syntax/missed or no: if all successfuly data get into Session/Group/Method execute method else throwing error.
### Before work. ### Before work.
Before work you must install this package: Before work you must install this package:
```bash ```bash
# for npm # for npm
npm install njsbacker npm install njsbacker
# for yarn # for yarn
yarn add njsbacker yarn add njsbacker
``` ```
And import at yoy project And import at yoy project
```javascript ```javascript
// from nodejs // from nodejs
const njsbacker = require('njsbacker'); const njsbacker = require('njsbacker');
``` ```
```typescript ```typescript
// from typescript // from typescript
import njsbacker from 'njsbacker'; import njsbacker from 'njsbacker';
``` ```
*(We will be use node.js)* *(We will be use node.js)*
## General clases and objects ## General clases and objects
### Main ### Main
Main class is main backend-application, mainbased skelet of project. Mainclass object containts methods, groups, sessionHandler, etc. For all works you must create your class from njsbacker.Main Main class is main backend-application, mainbased skelet of project. Mainclass object containts methods, groups, sessionHandler, etc. For all works you must create your class from njsbacker.Main
```javascript ```javascript
const njsbacker = require('njsbacker'); const njsbacker = require('njsbacker');
class App extends njsbacker.Main { class App extends njsbacker.Main {
// ... // ...
} }
``` ```
If you want handling your format errors, responses *(default JSON)* you must add methods into your body of class: If you want handling your format errors, responses *(default JSON)* you must add methods into your body of class:
```javascript ```javascript
const njsbacker = require('njsbacker'); const njsbacker = require('njsbacker');
class App extends njsbacker.Main { class App extends njsbacker.Main {
errorHadler (error) { // Handling and show errors at backend application. errorHadler (error) { // Handling and show errors at backend application.
let errorData; let errorData;
let codeStatus = 400; let codeStatus = 400;
if (error.name == "API Error") { if (error.name == "API Error") {
errorData = { errorData = {
code : error.message, code : error.message,
details : error.data details : error.data
}; };
} }
else { else {
errorData = { errorData = {
name : error.name, name : error.name,
stack : error.stack stack : error.stack
}; };
codeStatus = 502; codeStatus = 502;
} }
return { return {
mainbody : { error : errorData }, mainbody : { error : errorData },
headers : { headers : {
error : error.name error : error.name
}, },
cookies : { cookies : {
error_rised_at : Math.round(new Date().getTime() / 1000) error_rised_at : Math.round(new Date().getTime() / 1000)
}, },
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: codeStatus code: codeStatus
} }
} }
responseHandler (response) { return ({ // Handling responses at backend application responseHandler (response) { return ({ // Handling responses at backend application
mainbody : { response }, mainbody : { response },
headers : { headers : {
errored: 0 errored: 0
}, },
cookies : {}, cookies : {},
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 200 code: 200
}) }; }) };
session (params, sessionData) { // Session function session (params, sessionData) { // Session function
sessionData._setValue('example', 1); // Set value of sessionData object sessionData._setValue('example', 1); // Set value of sessionData object
console.log(sessionData.example); // Get value from sessionData object console.log(sessionData.example); // Get value from sessionData object
sessionData._remove('example'); // Remove value sessionData._remove('example'); // Remove value
return; // Successful return; // Successful
throw 'Example error'; // Example of error throw 'Example error'; // Example of error
} }
paramsError (required, additional) { // Handling missed/unsyntax params paramsError (required, additional) { // Handling missed/unsyntax params
return new njsbacker.ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional }); return new njsbacker.ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional });
} }
} }
``` ```
#### Method: errorHadler #### Method: errorHadler
Hadling and format errors. First argument is error object when may be hadled by this method. Returns handled error schema when must be containts next params: Hadling and format errors. First argument is error object when may be hadled by this method. Returns handled error schema when must be containts next params:
```typescript ```typescript
mainbody : < buffer / object / string > // content when will be returns mainbody : < buffer / object / string > // content when will be returns
headers : object // headers into http-response headers : object // headers into http-response
cookies : object // cookies when will be applyed cookies : object // cookies when will be applyed
code : number // http-code code : number // http-code
redirect_uri : string // redirect url (non-required, undefined if not redirect) redirect_uri : string // redirect url (non-required, undefined if not redirect)
``` ```
#### Method: responseHandler #### Method: responseHandler
Handling responses at backend application. First argument is reponse from .execute method at **Method** object. Must be containts next params: Handling responses at backend application. First argument is reponse from .execute method at **Method** object. Must be containts next params:
```typescript ```typescript
mainbody : < buffer / object / string > // content when will be returns mainbody : < buffer / object / string > // content when will be returns
headers : object // headers into http-response headers : object // headers into http-response
cookies : object // cookies when will be applyed cookies : object // cookies when will be applyed
code : number // http-code code : number // http-code
redirect_uri : string // redirect url (non-required, undefined if not redirect) redirect_uri : string // redirect url (non-required, undefined if not redirect)
``` ```
#### Method: session #### Method: session
Method that call before executing method or groups of method. First argument - params from http/call method, second argument - **Session** object. This method setting **Session** object params and return error at http-response if error throws. Method that call before executing method or groups of method. First argument - params from http/call method, second argument - **Session** object. This method setting **Session** object params and return error at http-response if error throws.
#### Method: paramsError #### Method: paramsError
Method that return error when missing or unsyntax params. Method that return error when missing or unsyntax params.
#### Create object of njsbacker.Main and configuration #### Create object of njsbacker.Main and configuration
Before work you must create object of njsbacker.Main: Before work you must create object of njsbacker.Main:
```javascript ```javascript
var app = new App( var app = new App(
false // Returns information about njsbacker in headers. false // Returns information about njsbacker in headers.
); );
``` ```
If you're planning use session you can configure him: If you're planning use session you can configure him:
```javascript ```javascript
app.setSessionParams( app.setSessionParams(
{ {
example_session_param : { example_session_param : {
required : false, required : false,
type : njsbacker.types.string type : njsbacker.types.string
} }
} }
); );
``` ```
**First param** - information about inputed params [(Params inforamtion)](#params-information) **First param** - information about inputed params [(Params inforamtion)](#params-information)
### Method ### Method
After you create **njsbacker.Main** object you must create class that extends from **njsbacker.Method**: After you create **njsbacker.Main** object you must create class that extends from **njsbacker.Method**:
```javascript ```javascript
class ExampleMethod extends njsbacker.Method { class ExampleMethod extends njsbacker.Method {
// Params handler // Params handler
execute (params, session, groups) { execute (params, session, groups) {
// Any code... // Any code...
return anotherResult; return anotherResult;
// If you needs raising error: // If you needs raising error:
throw new njsbacker.ApiError( throw new njsbacker.ApiError(
'EXAMPLE_ERROR', // Error code 'EXAMPLE_ERROR', // Error code
new Object() // Error details new Object() // Error details
); );
} }
} }
``` ```
#### Method: execute #### Method: execute
Method of executing current method. Return data when will be sended to njsbacker.Main.responseHandler method. Method of executing current method. Return data when will be sended to njsbacker.Main.responseHandler method.
#### Connection and configure njsbacker.Method #### Connection and configure njsbacker.Method
After creating class you must create object of njsbacker.Method: After creating class you must create object of njsbacker.Method:
```javascript ```javascript
var exampleMethod = new ExampleMethod('example', '/example', { var exampleMethod = new ExampleMethod('example', '/example', {
text : { text : {
required : true, required : true,
type : njsbacker.types.string, type : backend.types.string,
min_length : 1, min_length : 1,
max_length : 255 max_length : 255
} }
}); });
``` ```
**First param** - name of method into system. **First param** - name of method into system.
**Second param** - path to method into http-server **Second param** - path to method into http-server
**Third param** - information about inputed params [(Params inforamtion)](#params-information) **Third param** - information about inputed params [(Params inforamtion)](#params-information)
If you create object of **njsbacker.Group** you can pin it with use next method: If you create object of **njsbacker.Group** you can pin it with use next method:
```javascript ```javascript
exampleMethod.group(groupObject); exampleMethod.group(groupObject);
``` ```
And that this method work you must pin this method to object of **njsbacker.Main** with use next method: And that this method work you must pin this method to object of **njsbacker.Main** with use next method:
```javascript ```javascript
app.method(exampleMethod); app.method(exampleMethod);
``` ```
#### Additional tool into njsbacker.Method: this.MainObject.call #### Additional tool into njsbacker.Method: this.MainObject.call
Inside execute method you can refer to existing methods into API. Inside execute method you can refer to existing methods into API.
**Annotation**: this.MainObject is object of **njsbacker.Main** there was been included to **njsbacker.Method** **Annotation**: this.MainObject is object of **njsbacker.Main** there was been included to **njsbacker.Method**
```javascript ```javascript
class ExampleMethod extends njsbacker.Method { class ExampleMethod extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
// Another code here... // Another code here...
this.MainObject.call('SecondExampleMethodName', { this.MainObject.call('SecondExampleMethodName', {
param : "value" param : "value"
}); });
// Another code here... // Another code here...
return result; return result;
} }
} }
``` ```
**First param** - name of method. **First param** - name of method.
**Second param** - params there sends into method. **Second param** - params there sends into method.
## Additional clases and objects ## Additional clases and objects
### Params Information ### Params Information
Before reading this part we tolds about inputed params into http. Before reading this part we tolds about inputed params into http.
**Example:** **Example:**
```javascript ```javascript
var paramsInfo = { var paramsInfo = {
paramNameCookie : { paramNameCookie : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'param', import_key : 'param',
allow_params : ['cookies'] allow_params : ['cookies']
}, },
paramNameQuery : { paramNameQuery : {
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'param', import_key : 'param',
allow_params : ['query'] allow_params : ['query']
} }
} }
var exampleMethod = new ExampleMethod('example', '/example', paramsInfo); var exampleMethod = new ExampleMethod('example', '/example', paramsInfo);
``` ```
**Objects keys and default values**: **Objects keys and default values**:
```typescript ```typescript
required : boolean = false // Required param or no. required : boolean = false // Required param or no.
import_key : string = param // Key when using as param int http headers/string (etc.) import_key : string = param // Key when using as param int http headers/string (etc.)
save_key : string = param // Key when will be saved at param object save_key : string = param // Key when will be saved at param object
type : object = njsbacker.types.unknown // Param's datatype type : object = njsbacker.types.unknown // Param's datatype
allow_methods : array = ['get', 'post', 'put', 'delete'] // Methods when method will be listen. allow_methods : array = ['get', 'post', 'put', 'delete'] // Methods when method will be listen.
conversion : boolean = false // Covert datatype if inputed datatype not equal "type" param. conversion : boolean = false // Covert datatype if inputed datatype not equal "type" param.
allow_params : array = ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies'] // Http-params where will be reads into method. allow_params : array = ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies'] // Http-params where will be reads into method.
``` ```
### Group ### Group
This is njbacker object where executing before **njsbacker.Method** if was been pinned to **njsbacker.Method**. This is njbacker object where executing before **njsbacker.Method** if was been pinned to **njsbacker.Method**.
Before work you must create class when extends from **njsbacker.Method** and create into class method **handler**: Before work you must create class when extends from **njsbacker.Method** and create into class method **handler**:
```javascript ```javascript
class ExampleGroup extends njsbacker.Method { class ExampleGroup extends njsbacker.Method {
handler (params, session) { // Path handling handler (params, session) { // Path handling
session._setValue('example', 1); // Set value session._setValue('example', 1); // Set value
console.log(session.example); // Get value from session console.log(session.example); // Get value from session
session._remove('example'); // Remove value session._remove('example'); // Remove value
return 1; // Successful return 1; // Successful
throw 'Example error' // Error example throw 'Example error' // Error example
} }
} }
``` ```
### types ### types
**dynamic** - Dynamic datatype **dynamic** - Dynamic datatype
**unknown** - Unknown datatype *(Raising error)* **unknown** - Unknown datatype *(Raising error)*
**float** - Float *(real)* datatype **float** - Float *(real)* datatype
**array** *(function)* - array of data. **array** *(function)* - array of data.
```javascript ```javascript
// Example of array // Example of array
var datatype = njsbacker.types.array( var datatype = njsbacker.types.array(
splitSymbol, // symbol where will be used for splits queries, cookies and other string params. (required) splitSymbol, // symbol where will be used for splits queries, cookies and other string params. (required)
typeOfArray, // type of array data. (default: dynamic) typeOfArray, // type of array data. (default: dynamic)
); );
``` ```
**integer** - Integer datatype. **integer** - Integer datatype.
**file** *(function)* - file object [read more in express-fileupload module](https://www.npmjs.com/package/express-fileupload) **file** *(function)* - file object [read more in express-fileupload module](https://www.npmjs.com/package/express-fileupload)
```javascript ```javascript
// Example of file // Example of file
var datatype = njsbacker.types.file( var datatype = njsbacker.types.file(
allowedExtensions, // allowed extensions (default: null (all extensions allowed)) allowedExtensions, // allowed extensions (default: null (all extensions allowed))
); );
``` ```
**string** - String datatype. **string** - String datatype.
## Example code ## Example code
```javascript ```javascript
const njsbacker = require('./index'); const njsbacker = require('./index');
// Create backend mainclass then extends from njsbacker.Main: // Create backend mainclass then extends from njsbacker.Main:
class Main extends njsbacker.Main { class Main extends njsbacker.Main {
session (params, sessionData) { session (params, sessionData) {
sessionData._setValue('example', 1); // Set value sessionData._setValue('example', 1); // Set value
console.log(sessionData.example); // Get value from session console.log(sessionData.example); // Get value from session
sessionData._remove('example'); // Remove value sessionData._remove('example'); // Remove value
return 1; // Successful return 1; // Successful
throw 'Example error' // Example of error throw 'Example error' // Example of error
} }
responseHandler (response) { return ({ responseHandler (response) { return ({
mainbody : { response }, mainbody : { response },
headers : { headers : {
errored: 0 errored: 0
}, },
cookies : {}, cookies : {},
// redirect_uri: ''; // if want redirect to another url // redirect_uri: ''; // if want redirect to another url
code: 200 code: 200
}) }; }) };
/* paramsError (required, additional) { return({ required, additional }) }; */ /* paramsError (required, additional) { return({ required, additional }) }; */
} }
// Create object of Main class. // Create object of Main class.
var server = new Main( var server = new Main(
false // Show information about this library into headers. false // Show information about this library into headers.
); );
server.setSessionParams( // Set required params for session. server.setSessionParams( // Set required params for session.
{ {
session_id : { session_id : {
required : false, required : false,
type : njsbacker.types.integer type : njsbacker.types.integer
} }
} }
); );
// Create class from method's group. // Create class from method's group.
class ExampleMethodGroup extends njsbacker.Group { class ExampleMethodGroup extends njsbacker.Group {
handler (params, session) { // Path handling handler (params, session) { // Path handling
session._setValue('example', 1); // Set value session._setValue('example', 1); // Set value
console.log(session.example); // Get value from session console.log(session.example); // Get value from session
session._remove('example'); // Remove value session._remove('example'); // Remove value
return 1; // Successful return 1; // Successful
throw 'Example error' // Example of error throw 'Example error' // Example of error
} }
} }
// Create classes of method // Create classes of method
class ExampleAnyMethodsOfHandlingInformation extends njsbacker.Method { class ExampleAnyMethodsOfHandlingInformation extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return { return {
json_data : params.json_name, json_data : params.json_name,
query_data : params.query_name, query_data : params.query_name,
} }
} }
} }
class ExampleMethod extends njsbacker.Method { class ExampleMethod extends njsbacker.Method {
/* /*
var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода
*/ */
// Params handler // Params handler
execute (params, session, groups) { execute (params, session, groups) {
return { return {
text : params.text, text : params.text,
result : this.MainObject.call('sum', { result : this.MainObject.call('sum', {
a : 15, a : 15,
b : 17, b : 17,
session_id : params.session_id session_id : params.session_id
}) })
}; };
throw new njsbacker.ApiError('EXAMPLE_ERROR', new Object()); throw new njsbacker.ApiError('EXAMPLE_ERROR', new Object());
} }
} }
class SumMethod extends njsbacker.Method { class SumMethod extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return params.a + params.b; return params.a + params.b;
} }
} }
class FileMethod extends njsbacker.Method { class FileMethod extends njsbacker.Method {
execute (params, session, groups) { execute (params, session, groups) {
return JSON.stringify(params.file); return JSON.stringify(params.file);
} }
} }
// Create class objects // Create class objects
var eamohi = new ExampleAnyMethodsOfHandlingInformation('handler', '/handler', { var eamohi = new ExampleAnyMethodsOfHandlingInformation('handler', '/handler', {
queryName : { queryName : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'name', import_key : 'name',
allow_params : ['query'] allow_params : ['query']
}, },
jsonName : { jsonName : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
import_key : 'name', import_key : 'name',
allow_methods : ['post'], allow_methods : ['post'],
allow_params : ['json'] allow_params : ['json']
} }
}); });
var fileMethod = new FileMethod('file', '/file', { var fileMethod = new FileMethod('file', '/file', {
file : { file : {
required : true, required : true,
type : njsbacker.types.file() type : njsbacker.types.file()
} }
}); });
var sumMethod = new SumMethod('sum', '/sum', { var sumMethod = new SumMethod('sum', '/sum', {
a : { a : {
required : true, required : true,
type : njsbacker.types.integer, type : njsbacker.types.integer,
conversion : false, conversion : false,
// allow_methods : ['post'], // allow_methods : ['post'],
}, },
b : { b : {
required : true, required : true,
type : njsbacker.types.integer, type : njsbacker.types.integer,
conversion : false, conversion : false,
// allow_methods : ['post'], // allow_methods : ['post'],
} }
}); });
var exampleMethod = new ExampleMethod('example', '/example', { var exampleMethod = new ExampleMethod('example', '/example', {
text : { text : {
required : true, required : true,
type : njsbacker.types.string, type : njsbacker.types.string,
conversion : false, conversion : false,
values : ['123', 'test'], values : ['123', 'test'],
min_length : 1, min_length : 1,
max_length : 255, max_length : 255,
// allow_methods : ['post'], // allow_methods : ['post'],
// allow_params : ['json'], // allow_params : ['json'],
} }
}); });
// Pins methods to group // Pins methods to group
exampleMethod.group(new ExampleMethodGroup({ exampleMethod.group(new ExampleMethodGroup({
ses : { ses : {
type : njsbacker.types.string type : njsbacker.types.string
} }
})); }));
sumMethod.group(new ExampleMethodGroup({ sumMethod.group(new ExampleMethodGroup({
ses : { ses : {
type : njsbacker.types.string type : njsbacker.types.string
} }
})); }));
// Pin methods to mein project // Pin methods to mein project
server.method(exampleMethod); server.method(exampleMethod);
server.method(sumMethod); server.method(sumMethod);
server.method(fileMethod); server.method(fileMethod);
server.method(eamohi); server.method(eamohi);
// Run server // Run server
server.server('/api/v1').listen(8080, async (err) => { server.server('/api/v1').listen(8080, async (err) => {
if (err) { throw err; } if (err) { throw err; }
else { else {
console.log('SERVER RUNNED'); console.log('SERVER RUNNED');
} }
}); });
``` ```
You can show example code in file **codeExample.js** You can show example code in file **codeExample.js**