add files into repos

This commit is contained in:
Nikiroy78 2022-10-11 08:16:40 +03:00
parent 81fa21fbff
commit 67f7ab075a
5 changed files with 282 additions and 95 deletions

View File

@ -2,7 +2,7 @@ const backend = require('./index');
// Создаём класс бэкенда, наследующий класс backend.Main // Создаём класс бэкенда, наследующий класс backend.Main
class Main extends backend.Main { class Main extends backend.Main {
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'); // Убрать значение
@ -42,7 +42,7 @@ server.typeError = 'param {param} must be only {long_type} ({short_type})';
// Создаём класс группы методов // Создаём класс группы методов
class ExampleMethodGroup extends backend.Group { class ExampleMethodGroup extends backend.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'); // Убрать значение
@ -50,7 +50,7 @@ class ExampleMethodGroup extends backend.Group {
return 'Example error' // Пример ошибки return 'Example error' // Пример ошибки
} }
} }
// Создаём класс метода // Создаём классы методов
class ExampleMethod extends backend.Method { class ExampleMethod extends backend.Method {
/* /*
var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода var result = this.MainObject.call(method : string, params : object) // Вызов подключённого метода
@ -58,18 +58,46 @@ class ExampleMethod extends backend.Method {
// Обработчик параметров // Обработчик параметров
execute (params) { execute (params) {
console.log(params); return {
return params.text; text : params.text,
throw { code: 'EXAMPLE_ERROR', details: new Object() }; result : this.MainObject.call('sum', {
a : 15,
b : 17
})
};
throw new backend.ApiError('EXAMPLE_ERROR', new Object());
} }
} }
class SumMethod extends backend.Method {
execute (params) {
return params.a + params.b;
}
}
// Создаём экземпляры классов
var sumMethod = new SumMethod('sum', '/sum', {
a : {
required : true,
type : backend.types.integer,
conversion : false,
// allow_methods : ['post'],
},
b : {
required : true,
type : backend.types.integer,
conversion : false,
// allow_methods : ['post'],
}
});
var exampleMethod = new ExampleMethod('example', '/example', { var exampleMethod = new ExampleMethod('example', '/example', {
text: { text: {
required : true, required : true,
type : backend.types.string, type : backend.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'],
@ -78,8 +106,10 @@ var exampleMethod = new ExampleMethod('example', '/example', {
}); });
// Привяжем метод к группе // Привяжем метод к группе
exampleMethod.group(ExampleMethodGroup); exampleMethod.group(ExampleMethodGroup);
sumMethod.group(ExampleMethodGroup);
// Привяжем метод к основному проекту // Привяжем метод к основному проекту
server.method(exampleMethod); server.method(exampleMethod);
server.method(sumMethod);
// Запускаем сервер // Запускаем сервер
server.server('/api/v1'/*, { Информация о SSL }*/).listen(8080, async (err) => { server.server('/api/v1'/*, { Информация о SSL }*/).listen(8080, async (err) => {

View File

@ -17,54 +17,55 @@ class Main {
constructor (sendHeaders = true) { constructor (sendHeaders = true) {
this.sendHeaders = sendHeaders; this.sendHeaders = sendHeaders;
this.methods = new Object(); this.methods = new Object();
this.errorHadler = (error) => {
let errorData;
if (error.name == "API Error") {
errorData = {
code : error.message,
details : error.data
};
}
else {
errorData = {
name : error.name,
stack : error.stack
};
}
return {
mainbody : { error : errorData },
headers : {},
cookies : {},
// redirect_uri: ''; // if want redirect to another url
code: 400
}
};
this.responseHandler = (response) => ({
mainbody : { response },
headers : {},
cookies : {},
// redirect_uri: ''; // if want redirect to another url
code: 200
});
this.paramsError = (required, additional) => {
return new ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional });
};
this.typeError = 'param {param} must be only {long_type} ({short_type})';
} }
paramsError (required, additional) {
return new ApiError('UNSYNTAX_OR_MISSED_REQUIRED_PARAMS', { required, additional });
}
errorHadler (error) {
let errorData;
if (error.name == "API Error") {
errorData = {
code : error.message,
details : error.data
};
}
else {
errorData = {
name : error.name,
stack : error.stack
};
}
return {
mainbody : { error : errorData },
headers : {},
cookies : {},
// redirect_uri: ''; // if want redirect to another url
code: 400
}
}
session (params, sessionData) { return 1; }
responseHandler (result) { return ({
mainbody : { result },
headers : {},
cookies : {},
// redirect_uri: ''; // if want redirect to another url
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.name].pre_execute(params); return this.methods[method].pre_execute(params);
} }
router (returnMiddlewareFunction = false, middlewareFunction = (req, res, next) => next(), debug = (text) => {}) { router (returnMiddlewareFunction = false, middlewareFunction = (req, res, next) => next(), debug = (text) => console.log(text)) {
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
@ -84,7 +85,7 @@ class Main {
} }
try { try {
let contentType = req.get('Content-Type'); let contentType = req.get('Content-Type');
if (!!contentType) { if (contentType != undefined) {
contentType = contentType.toLowerCase(); contentType = contentType.toLowerCase();
} }
else { else {
@ -92,6 +93,7 @@ class Main {
} }
let result = this.methods[name].executeIntoExpressRouter( let result = this.methods[name].executeIntoExpressRouter(
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,
@ -105,6 +107,7 @@ class Main {
); );
if (!handledDataResponse.redirect_uri) { if (!handledDataResponse.redirect_uri) {
for (let header in handledDataResponse.headers) { for (let header in handledDataResponse.headers) {
console.log('>>header', header);
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) {

View File

@ -1,4 +1,31 @@
const typesApi = require('./types'); const typesApi = require('./types');
const Session = require('./Session');
const formatMessage = (message, errorType, scheme, value, param) => {
value = String(value);
switch (errorType) {
case 'typeError' :
return message.split('{param}').join(param).split('{long_type}').join(scheme.type.long_name).split('{short_type}').join(scheme.type.short_name);
case 'valuesError' :
return message.split('{param}').join(param).split('{value}').join(value).split('{values}').join(scheme.values.join(', '));
case 'minLengthError' :
return message.split('{value}').join(scheme.min_length);
case 'maxLengthError' :
return message.split('{value}').join(scheme.max_length);
case 'httpMethodError' :
return message.split('{method}').join(value).split('{methods}').join(scheme.allow_methods.join(', '));
}
};
const compileParams = (params) => {
let compiled = new Object();
for (let objKey in params) {
compiled = Object.assign(compiled, params[objKey]);
}
return compiled;
}
class Method { class Method {
@ -8,8 +35,15 @@ class Method {
this.paramsCompiles = params; this.paramsCompiles = params;
this.groupsConnected = new Array(); this.groupsConnected = new Array();
this.allowedMethods = new Array(); this.allowedMethods = new Array();
this.typeError = 'param {param} must be only {long_type} ({short_type})'; // Errors
this.valuesError = 'value (({value})) not finded into {values}'; this.error = new Object();
this.error.typeError = 'param {param} must be only {long_type} ({short_type})';
this.error.valuesError = 'value "{value}" not finded into {values}';
this.error.minLengthError = 'value must be more 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.isDynamic = false;
// Setting allow methods // Setting allow methods
let allowedMethods; let allowedMethods;
@ -26,11 +60,16 @@ class Method {
} }
} }
useDynamicType (condition) {
this.isDynamic = !!condition;
}
_pinMain (mainObject) { _pinMain (mainObject) {
this.MainObject = mainObject; this.MainObject = mainObject;
} }
executeIntoExpressRouter ( executeIntoExpressRouter (
currentMethod,
headers, headers,
json, json,
params, params,
@ -39,37 +78,58 @@ class Method {
files, files,
cookies cookies
) { ) {
// Execute session
let sessionObject = new Session();
this.MainObject.session(compileParams({
headers,
json,
params,
query,
body,
files,
cookies
}), sessionObject);
let values = sessionObject._getValues();
for (let key in values) { paramsEndless[key] = values[key]; }
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 = new Array(); let checkKeys;
for (let param in this.paramsCompiles) { for (let param in this.paramsCompiles) {
checkKeys = new Array();
paramScheme = { paramScheme = {
required : false, required : false,
type : typesApi.unknown, type : this.isDynamic ? typesApi.dynamic : typesApi.unknown,
allow_methods : ['get', 'post', 'put', 'delete'], allow_methods : ['get', 'post', 'put', 'delete'],
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 this.paramsCompiles[param]) { paramScheme[key] = this.paramsCompiles[param][key]; } for (let key in this.paramsCompiles[param]) { paramScheme[key] = this.paramsCompiles[param][key]; }
// check missible // check missible
if (headers[param] !== undefined & paramScheme.allow_params.indexOf('headers') != -1) { checkKeys.push('headers'); } if (headers[param] != undefined & paramScheme.allow_params.indexOf('headers') != -1) { checkKeys.push('headers'); }
if (json[param] !== undefined & paramScheme.allow_params.indexOf('json') != -1) { checkKeys.push('json'); } if (json[param] != undefined & paramScheme.allow_params.indexOf('json') != -1) { checkKeys.push('json'); }
if (query[param] !== undefined & paramScheme.allow_params.indexOf('query') != -1) { checkKeys.push('query'); } if (query[param] != undefined & paramScheme.allow_params.indexOf('query') != -1) { checkKeys.push('query'); }
if (body[param] !== undefined & paramScheme.allow_params.indexOf('body') != -1) { checkKeys.push('body'); } if (body[param] != undefined & paramScheme.allow_params.indexOf('body') != -1) { checkKeys.push('body'); }
if (files[param] !== undefined & paramScheme.allow_params.indexOf('files') != -1) { checkKeys.push('files'); } if (files[param] != undefined & paramScheme.allow_params.indexOf('files') != -1) { checkKeys.push('files'); }
if (cookies[param] !== undefined & paramScheme.allow_params.indexOf('cookies') != -1) { checkKeys.push('cookies'); } if (cookies[param] != undefined & paramScheme.allow_params.indexOf('cookies') != -1) { checkKeys.push('cookies'); }
if (params[param] !== undefined & paramScheme.allow_params.indexOf('params') != -1) { checkKeys.push('params'); } if (params[param] != undefined & paramScheme.allow_params.indexOf('params') != -1) { checkKeys.push('params'); }
if (checkKeys.length == 0) { if (checkKeys.length == 0) {
if (paramScheme.required) { required.missed.push(param); } if (paramScheme.required) { required.missed.push(param); }
else { additional.missed.push(param); } else { additional.missed.push(param); }
} }
else if (paramScheme.allow_methods.indexOf(currentMethod) == -1) {
if (paramScheme.required) { required.unsyntax.push({param : param, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, param) }); }
else { additional.unsyntax.push({param : param, description : formatMessage(this.error.httpMethodError, 'httpMethodError', paramScheme, currentMethod, param)}); }
}
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';
for (let key in checkKeys) { for (let key in checkKeys) {
switch (checkKeys[key]) { switch (checkKeys[key]) {
case 'query' : case 'query' :
@ -82,20 +142,20 @@ class Method {
[isSyntax, convertedValue] = paramScheme.type.syntax(headers[param], true); [isSyntax, convertedValue] = paramScheme.type.syntax(headers[param], true);
break; break;
case 'json' : case 'json' :
[isSyntax, convertedValue] = paramScheme.type.syntax(json[param], false); [isSyntax, convertedValue] = paramScheme.type.syntax(json[param], paramScheme.conversion);
break; break;
case 'params' : case 'params' :
[isSyntax, convertedValue] = paramScheme.type.syntax(params[param], false); [isSyntax, convertedValue] = paramScheme.type.syntax(params[param], paramScheme.conversion);
break; break;
case 'body' : case 'body' :
[isSyntax, convertedValue] = paramScheme.type.syntax(body[param], false); [isSyntax, convertedValue] = paramScheme.type.syntax(body[param], paramScheme.conversion);
break; break;
case 'files' : case 'files' :
[isSyntax, convertedValue] = paramScheme.type.syntax(files[param], false); [isSyntax, convertedValue] = paramScheme.type.syntax(files[param], paramScheme.conversion);
break; break;
} }
if (isSyntax) { if (isSyntax) {
isSyntax = paramScheme.type.checkSchema(convertedValue, paramScheme); [isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(convertedValue, paramScheme);
if (isSyntax) break; if (isSyntax) break;
} }
} }
@ -103,8 +163,8 @@ class Method {
paramsEndless[param] = convertedValue; paramsEndless[param] = convertedValue;
} }
else { else {
if (paramScheme.required) { required.unsyntax.push({param : param, description : this.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); } if (paramScheme.required) { required.unsyntax.push({param : param, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, param) }); }
else { additional.unsyntax.push({param : param, description : this.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); } else { additional.unsyntax.push({param : param, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, convertedValue, param)}); }
} }
} }
} }
@ -121,14 +181,15 @@ class Method {
let required = { missed : [], unsyntax : [] }; let required = { missed : [], unsyntax : [] };
let additional = { missed : [], unsyntax : [] }; let additional = { missed : [], unsyntax : [] };
let isSyntax; let isSyntax;
let _; let value;
let paramScheme; let paramScheme;
for (let param in this.paramsCompiles) { for (let param in this.paramsCompiles) {
paramScheme = { paramScheme = {
required : false, required : false,
type : typesApi.unknown, type : this.isDynamic ? typesApi.dynamic : typesApi.unknown,
allow_methods : ['get', 'post', 'put', 'delete'], allow_methods : ['get', 'post', 'put', 'delete'],
conversion : false,
allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies'] allow_params : ['headers', 'json', 'params', 'query', 'body', 'files', 'cookies']
}; };
for (let key in this.paramsCompiles[param]) { paramScheme[key] = this.paramsCompiles[param][key]; } for (let key in this.paramsCompiles[param]) { paramScheme[key] = this.paramsCompiles[param][key]; }
@ -141,31 +202,28 @@ class Method {
} }
} }
else { else {
[isSyntax, _] = paramScheme.type(params[param], false); let selectedSyntaxError = 'typeError';
[isSyntax, value] = paramScheme.type.syntax(params[param], paramScheme.conversion);
if (!isSyntax) { if (!isSyntax) {
if (paramScheme.required) { if (paramScheme.required) {
required.unsyntax.push({param : param, description : this.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); required.unsyntax.push({param : param, description : this.error.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)});
} }
else { else {
additional.unsyntax.push({param : param, description : this.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)}); additional.unsyntax.push({param : param, description : this.error.typeError.split('{param}').join(param).split('{long_type}').join(paramScheme.type.long_name).split('{short_type}').join(paramScheme.type.short_name)});
} }
} }
else { else {
if (paramScheme.values != undefined) { [isSyntax, selectedSyntaxError] = paramScheme.type.checkSchema(value, paramScheme);
if (paramScheme.values.indexOf(params[param]) == -1) { if (!isSyntax) {
if (paramScheme.required) { if (paramScheme.required) {
required.unsyntax.push({ required.unsyntax.push({param : param, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, param)});
param : param,
description : this.valuesError.split('{value}').join(convertedValue.toString()).split('{values}').join(paramScheme.values.join(', '))
});
}
else {
additional.unsyntax.push({
param : param,
description : this.valuesError.split('{value}').join(convertedValue.toString()).split('{values}').join(paramScheme.values.join(', '))
});
}
} }
else {
additional.unsyntax.push({param : param, description : formatMessage(this.error[selectedSyntaxError], selectedSyntaxError, paramScheme, value, param)});
}
}
else {
params[param] = value;
} }
} }
} }
@ -174,13 +232,9 @@ class Method {
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 {
return this.execute(params);
}
}
else {
return this.execute(params);
} }
return this.execute(params);
} }
group (groupClass) { group (groupClass) {

View File

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

View File

@ -1,22 +1,92 @@
module.exports = { module.exports = {
dynamic : {
long_name : 'dynamic',
short_name : 'dyn',
checkSchema : (value, schema) => {
if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError'];
}
}
return [true, 'ok'];
},
syntax : (value, needs_convert = true) => [true, value]
},
unknown : { unknown : {
long_name : 'unknown', long_name : 'unknown',
short_name : 'unk', short_name : 'unk',
syntax : (value, needs_convert = true) => { checkSchema : (value, schema) => { throw new Error('Undefined datatype'); },
syntax : (value, needs_convert = true) => {
throw new Error('Undefined datatype'); throw new Error('Undefined datatype');
} }
}, },
integer : {
long_name : 'integer',
short_name : 'int',
checkSchema : (value, schema) => {
if (schema.values != undefined) { // values
if (schema.values.indexOf(value) == -1) {
return [false, 'valuesError'];
}
}
if (schema.min_length != undefined) { // min_length
if (value < schema.min_length) {
return [false, 'minLengthError'];
}
}
if (schema.max_length != undefined) { // max_length
if (value > schema.max_length) {
return [false, 'maxLengthError'];
}
}
return [true, 'ok'];
},
syntax : (value, needs_convert = false) => {
function isInt (value) {
if (String(parseInt(value)) == 'NaN') return false;
return String(parseInt(value)) == String(Number(value));
}
if (typeof(value) == 'number' & isInt(value)) {
return [true, value];
}
else if (needs_convert & isInt(value)) {
return [true, parseInt(value)];
}
else {
return [false, 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) { 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 (value.length < schema.min_length) {
return [false, 'minLengthError'];
}
}
if (schema.max_length != undefined) { // max_length
if (value.length > schema.max_length) {
return [false, 'maxLengthError'];
}
}
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];
} }