Edit with use prettier

This commit is contained in:
Nikiroy78 2023-10-01 22:31:26 +03:00
parent cc51fe6095
commit c4e11381aa
13 changed files with 593 additions and 484 deletions

View File

@ -1,6 +1,4 @@
const router = require('express').Router(); const router = require("express").Router();
// const config = require('../config-handler'); router.use("/v/1.0", require("./v1"));
router.use("/v/1.0", require('./v1'));
module.exports = router; module.exports = router;

View File

@ -1,5 +1,5 @@
module.exports = class ApiError extends Error { module.exports = class ApiError extends Error {
constructor(message, details={}, ...args) { constructor(message, details = {}, ...args) {
super(message, ...args); super(message, ...args);
this.message = message; this.message = message;
this.details = details; this.details = details;

View File

@ -1,46 +1,56 @@
const router = require('express').Router(); const router = require("express").Router();
const response = require('./response-wrapper'); const response = require("./response-wrapper");
// const config = require('../../config-handler'); // const config = require('../../config-handler');
// Парсинг куки // Парсинг куки
//router.use(require('cookie-parser')()); //router.use(require('cookie-parser')());
// Загрузка музыки при помощи спец. метода // Загрузка музыки при помощи спец. метода
function muzicLoad (req, res) { function muzicLoad(req, res) {
res.setHeader('Content-Type', 'audio/mpeg'); res.setHeader("Content-Type", "audio/mpeg");
global.database.muzic.get((err, data) => { global.database.muzic.get(
data = data[0]?.data; (err, data) => {
if (err) { data = data[0]?.data;
res.send(Buffer.from([])); if (err) {
} res.send(Buffer.from([]));
else { } else {
res.send(!data ? Buffer.from([]) : data); res.send(!data ? Buffer.from([]) : data);
} }
}, { where : { id : !Number.isInteger(+req.query.id) ? 0 : +req.query.id } }); },
{ where: { id: !Number.isInteger(+req.query.id) ? 0 : +req.query.id } },
);
} }
// Подгрузка с файла // Подгрузка с файла
router.use('/:method_name', async (req, res, next, ...etc) => { router.use("/:method_name", async (req, res, next, ...etc) => {
if (req.params.method_name === 'muzic') { if (req.params.method_name === "muzic") {
muzicLoad(req, res); muzicLoad(req, res);
return; return;
} }
try { try {
const methodFunct = require(`./methods/${req.params.method_name}`); const methodFunct = require(`./methods/${req.params.method_name}`);
response(methodFunct, req, res); response(methodFunct, req, res);
} } catch (e) {
catch (e) {
if (e.message.includes("Cannot find module")) { if (e.message.includes("Cannot find module")) {
const ApiError = require('./errorClass'); const ApiError = require("./errorClass");
res.status(400).sendModed(await response((req, res) => { res.status(400).sendModed(
throw new ApiError("METHOD_NOT_FOUNDED"); await response(
}, req, res)); (req, res) => {
} throw new ApiError("METHOD_NOT_FOUNDED");
else { },
response(async () => { req,
throw e; res,
}, req, res); ),
);
} else {
response(
async () => {
throw e;
},
req,
res,
);
} }
} }
}); });

View File

@ -1,73 +1,87 @@
const ApiError = require('../errorClass'); const ApiError = require("../errorClass");
const config = require('../../../config-handler'); const config = require("../../../config-handler");
async function isAuthorExists (authorId) { async function isAuthorExists(authorId) {
if (!authorId) return false; if (!authorId) return false;
return (await global.database.authors.promiseMode().get({ where : { id : authorId } })).length !== 0; return (
(
await global.database.authors
.promiseMode()
.get({ where: { id: authorId } })
).length !== 0
);
} }
async function checkSyntaxArgs (req, res) { async function checkSyntaxArgs(req, res) {
return !!( return !!(
( // Проверка поля type. // Проверка поля type.
['author', 'muzic'].indexOf(req.json?.type) !== -1 ["author", "muzic"].indexOf(req.json?.type) !== -1 && // Проверка поля name.
) && typeof req.json.name === "string" &&
( // Проверка поля name. req.json.name.length >= 2 &&
typeof req.json.name === 'string' && req.json.name.length >= 2 && ( (req.json.type === "muzic"
req.json.type === 'muzic' ? true : config().authors_blacklist.filter((blacklisted) => { ? true
return req.json.name.toLowerCase().includes(blacklisted.toLowerCase()); : config().authors_blacklist.filter((blacklisted) => {
}).length === 0 return req.json.name
) .toLowerCase()
) && .includes(blacklisted.toLowerCase());
( // Дополнительные поля для muzic }).length === 0) && // Дополнительные поля для muzic
req.json.type === 'muzic' ? !!( // Для `muzic` (req.json.type === "muzic"
( // Проверка поля author_id. ? !!(
await isAuthorExists(req.json.author_id) // Для `muzic`
) && (
( // Проверка поля data. (Передаётся либо ничего, либо строка с base64) // Проверка поля author_id.
req.json.data === undefined ? true : ( (await isAuthorExists(req.json.author_id)) && // Проверка поля data. (Передаётся либо ничего, либо строка с base64)
typeof req.json.data === 'string' (req.json.data === undefined
? true
: typeof req.json.data === "string")
) )
) )
) : true : true)
) );
)
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (req.json === undefined) { if (req.json === undefined) {
// console.log(req.headers); // console.log(req.headers);
throw new ApiError("METHOD_MUST_BE_POST_JSON", { throw new ApiError("METHOD_MUST_BE_POST_JSON", {
request_method : req.method, request_method: req.method,
'content-type' : !req.headers['content-type'] ? null : req.headers['content-type'] "content-type": !req.headers["content-type"]
? null
: req.headers["content-type"],
}); });
} }
if (!await checkSyntaxArgs(req, res)) { if (!(await checkSyntaxArgs(req, res))) {
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", { throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
request_method : req.method, request_method: req.method,
params : { params: {
type : req.json?.type === undefined ? null : req.json.type, type: req.json?.type === undefined ? null : req.json.type,
name : req.json?.name === undefined ? null : req.json.name, name: req.json?.name === undefined ? null : req.json.name,
...(req.json?.type === 'muzic' ? ({ ...(req.json?.type === "muzic"
author_id : req.json?.author_id === undefined ? null : req.json?.author_id, ? {
data : req.json?.data === undefined ? null : req.json.data, author_id:
}) : ({})) req.json?.author_id === undefined ? null : req.json?.author_id,
} data: req.json?.data === undefined ? null : req.json.data,
}
: {}),
},
}); });
} }
if (req.json.type === 'author') { if (req.json.type === "author") {
let result = await global.database.authors.promiseMode().add({ let result = await global.database.authors.promiseMode().add({
name : req.json.name, name: req.json.name,
time : Math.round(new Date().getTime() / 1000) time: Math.round(new Date().getTime() / 1000),
}); });
return result.dataValues.id; return result.dataValues.id;
} } else {
else {
let result = await global.database.muzic.promiseMode().add({ let result = await global.database.muzic.promiseMode().add({
name : req.json.name, name: req.json.name,
author_id : req.json.author_id, author_id: req.json.author_id,
data : req.json.data === undefined ? undefined : Buffer.from(req.json.data, 'base64'), data:
time : Math.round(new Date().getTime() / 1000) req.json.data === undefined
? undefined
: Buffer.from(req.json.data, "base64"),
time: Math.round(new Date().getTime() / 1000),
}); });
return result.dataValues.id; return result.dataValues.id;
} }
} };

View File

@ -1,84 +1,90 @@
const ApiError = require('../errorClass'); const ApiError = require("../errorClass");
async function isAuthorExists (id) { async function isAuthorExists(id) {
if (!id || !Number.isInteger(id)) return false; if (!id || !Number.isInteger(id)) return false;
return (await global.database.authors.promiseMode().get({ where : { id } })).length !== 0; return (
(await global.database.authors.promiseMode().get({ where: { id } }))
.length !== 0
);
} }
async function isMuzicExists (id) { async function isMuzicExists(id) {
if (!id || !Number.isInteger(id)) return false; if (!id || !Number.isInteger(id)) return false;
let result = (await global.database.muzic.promiseMode().get({ where : { id } })).length !== 0; let result =
console.log('isMuzicExists', result); (await global.database.muzic.promiseMode().get({ where: { id } }))
.length !== 0;
console.log("isMuzicExists", result);
return result; return result;
} }
async function checkSyntaxArgs (req, res) { async function checkSyntaxArgs(req, res) {
return !!( return !!(
( // Проверка поля type // Проверка поля type
['author', 'muzic'].includes(req.json.type) ["author", "muzic"].includes(req.json.type) && // Проверка поля name
) && (req.json.name === undefined
( // Проверка поля name ? true
req.json.name === undefined ? true : (typeof req.json.name === 'string' && req.json.name.length >= 2) : typeof req.json.name === "string" && req.json.name.length >= 2) && // Проверка id
) && (req.json.type === "author"
( // Проверка id ? await isAuthorExists(req.json.id)
req.json.type === 'author' ? await isAuthorExists(req.json.id) : await isMuzicExists(req.json.id) : await isMuzicExists(req.json.id)) && // Проверка при type=muzic
) && (req.json.type === "muzic"
( // Проверка при type=muzic ? // Проверка поля author_id
req.json.type === 'muzic' ? ( (req.json.author_id === undefined
( // Проверка поля author_id ? true
req.json.author_id === undefined ? true : await isAuthorExists(req.json.author_id) : await isAuthorExists(req.json.author_id)) && // Проверка поля data. (Передаётся либо ничего, либо строка с base64)
) && (req.json.data === undefined ? true : typeof req.json.data === "string")
( // Проверка поля data. (Передаётся либо ничего, либо строка с base64) : true)
req.json.data === undefined ? true : ( );
typeof req.json.data === 'string'
)
)
) : true
)
)
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (req.method !== 'POST') { if (req.method !== "POST") {
throw new ApiError("METHOD_MUST_BE_POST_JSON", { throw new ApiError("METHOD_MUST_BE_POST_JSON", {
request_method : req.method request_method: req.method,
}); });
} }
console.log(await checkSyntaxArgs(req, res)); console.log(await checkSyntaxArgs(req, res));
if (!await checkSyntaxArgs(req, res)) { if (!(await checkSyntaxArgs(req, res))) {
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", { throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
request_method : req.method, request_method: req.method,
params : { params: {
id : req.json.id === undefined ? null : req.json.id, id: req.json.id === undefined ? null : req.json.id,
type : req.json.type === undefined ? null : req.json.type, type: req.json.type === undefined ? null : req.json.type,
name : req.json.name === undefined ? null : req.json.name, name: req.json.name === undefined ? null : req.json.name,
...(req.json.type === 'muzic' ? { ...(req.json.type === "muzic"
author_id : req.json.author_id, ? {
data : req.json.data author_id: req.json.author_id,
} : {}) data: req.json.data,
} }
: {}),
},
}); });
} }
if (req.json.type === 'author') { if (req.json.type === "author") {
await global.database.authors.promiseMode().edit({ await global.database.authors.promiseMode().edit(
name : req.json.name {
}, { name: req.json.name,
where : { },
id : req.json.id {
} where: {
}); id: req.json.id,
},
},
);
} else {
await global.database.muzic.promiseMode().edit(
{
name: req.json.name,
author_id: req.json.author_id,
data: !req.json.data ? undefined : Buffer.from(req.json.data, "base64"),
},
{
where: {
id: req.json.id,
},
},
);
} }
else { return "ok";
await global.database.muzic.promiseMode().edit({ };
name : req.json.name,
author_id : req.json.author_id,
data : !req.json.data ? undefined : Buffer.from(req.json.data, "base64")
}, {
where : {
id : req.json.id
}
});
}
return 'ok';
}

View File

@ -1,79 +1,81 @@
const ApiError = require('../errorClass'); const ApiError = require("../errorClass");
async function checkSyntaxArgs (req, res) { async function checkSyntaxArgs(req, res) {
return !!( return !!(
( // Проверка поля offset // Проверка поля offset
req.query.id === undefined ? true : Number.isInteger(+req.query.offset) (req.query.id === undefined ? true : Number.isInteger(+req.query.offset)) && // Проверка поля offset
) && (req.query.offset === undefined
( // Проверка поля offset ? true
req.query.offset === undefined ? true : Number.isInteger(+req.query.offset) : Number.isInteger(+req.query.offset)) && // Проверка поля count
) && (req.query.count === undefined
( // Проверка поля count ? true
req.query.count === undefined ? true : Number.isInteger(+req.query.count) : Number.isInteger(+req.query.count)) && // Проверка поля min_date
) && (req.query.min_date === undefined
( // Проверка поля min_date ? true
req.query.min_date === undefined ? true : Number.isInteger(+req.query.min_date) : Number.isInteger(+req.query.min_date)) && // Проверка поля max_date
) && (req.query.max_date === undefined
( // Проверка поля max_date ? true
req.query.max_date === undefined ? true : Number.isInteger(+req.query.max_date) : Number.isInteger(+req.query.max_date)) && // Проверка поля q. (Ключевые слова для поиска)
) && true // (Проверки нет, query всегда строка, необязательный параметр)
( // Проверка поля q. (Ключевые слова для поиска) );
true // (Проверки нет, query всегда строка, необязательный параметр)
)
)
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (req.method !== 'GET') { if (req.method !== "GET") {
throw new ApiError("METHOD_MUST_BE_GET", { throw new ApiError("METHOD_MUST_BE_GET", {
request_method : req.method request_method: req.method,
}); });
} }
if (!await checkSyntaxArgs(req, res)) { if (!(await checkSyntaxArgs(req, res))) {
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", { throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
request_method : req.method, request_method: req.method,
params : { params: {
id : req.query?.id === undefined ? null : req.query.id, id: req.query?.id === undefined ? null : req.query.id,
q : req.query?.q === undefined ? null : req.query.q, q: req.query?.q === undefined ? null : req.query.q,
offset : req.query?.offset === undefined ? null : req.query.offset, offset: req.query?.offset === undefined ? null : req.query.offset,
count : req.query?.count === undefined ? null : req.query.count, count: req.query?.count === undefined ? null : req.query.count,
min_date : req.query?.min_date === undefined ? null : req.query.min_date, min_date: req.query?.min_date === undefined ? null : req.query.min_date,
max_date : req.query?.max_date === undefined ? null : req.query.max_date max_date: req.query?.max_date === undefined ? null : req.query.max_date,
} },
}); });
} }
const offset = req.query.offset === undefined ? 0 : +req.query.offset; const offset = req.query.offset === undefined ? 0 : +req.query.offset;
const countFromNull = req.query.count === undefined ? undefined : offset + (+req.query.count); const countFromNull =
req.query.count === undefined ? undefined : offset + +req.query.count;
let result = (await global.database.authors.promiseMode().get(
req.query.id === undefined ? {} : { let result = (
id : +req.query.id await global.database.authors.promiseMode().get(
} req.query.id === undefined
)).map(i => ({ ? {}
id : i.id, : {
name : i.name, id: +req.query.id,
date : i.time },
)
).map((i) => ({
id: i.id,
name: i.name,
date: i.time,
})); }));
// Если просят выборку по времени // Если просят выборку по времени
if (req.query.min_date || req.query.max_date) { if (req.query.min_date || req.query.max_date) {
const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date; const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date;
const maxDate = req.query.max_date === undefined ? 1e+32 : +req.query.max_date; const maxDate =
req.query.max_date === undefined ? 1e32 : +req.query.max_date;
result = result.filter((res) => minDate <= res.date && res.date <= maxDate); result = result.filter((res) => minDate <= res.date && res.date <= maxDate);
} }
if (req.query?.q !== undefined) { if (req.query?.q !== undefined) {
result = result.filter(i => { result = result.filter((i) => {
const search = req.query.q.toLowerCase(); const search = req.query.q.toLowerCase();
return i.name.toLowerCase().includes(search); return i.name.toLowerCase().includes(search);
}); });
} }
result = result.slice(offset, countFromNull); result = result.slice(offset, countFromNull);
return { return {
count : result.length, count: result.length,
items : result items: result,
}; };
} };

View File

@ -1,110 +1,142 @@
const ApiError = require('../errorClass'); const ApiError = require("../errorClass");
async function isAuthorExists (authorId) { async function isAuthorExists(authorId) {
if (!authorId) return false; if (!authorId) return false;
return (await global.database.authors.promiseMode().get({ where : { id : authorId } })).length !== 0; return (
(
await global.database.authors
.promiseMode()
.get({ where: { id: authorId } })
).length !== 0
);
} }
async function isAuthorsExists (authorsId) { async function isAuthorsExists(authorsId) {
if (!Array.isArray(authorsId)) return false; if (!Array.isArray(authorsId)) return false;
const authors = (await global.database.authors.promiseMode().get()).map(i => i.id); const authors = (await global.database.authors.promiseMode().get()).map(
return authorsId.map(authorId => authors.includes(authorId)); (i) => i.id,
);
return authorsId.map((authorId) => authors.includes(authorId));
} }
async function checkSyntaxArgs (req, res) { async function checkSyntaxArgs(req, res) {
return !!( return !!(
( // Проверка поля author. // Проверка поля author.
req.query.author === undefined ? true : await isAuthorExists(+req.query.author) (req.query.author === undefined
) && ? true
( // Проверка поля authors. : await isAuthorExists(+req.query.author)) && // Проверка поля authors.
req.query.authors === undefined ? true : await isAuthorsExists(req.query.authors.split(',').map(i => +i)) (req.query.authors === undefined
) && ? true
( // Проверка поля offset : await isAuthorsExists(req.query.authors.split(",").map((i) => +i))) && // Проверка поля offset
req.query.offset === undefined ? true : Number.isInteger(+req.query.offset) (req.query.offset === undefined
) && ? true
( // Проверка поля count : Number.isInteger(+req.query.offset)) && // Проверка поля count
req.query.count === undefined ? true : Number.isInteger(+req.query.count) (req.query.count === undefined
) && ? true
( // Проверка поля min_date : Number.isInteger(+req.query.count)) && // Проверка поля min_date
req.query.min_date === undefined ? true : Number.isInteger(+req.query.min_date) (req.query.min_date === undefined
) && ? true
( // Проверка поля max_date : Number.isInteger(+req.query.min_date)) && // Проверка поля max_date
req.query.max_date === undefined ? true : Number.isInteger(+req.query.max_date) (req.query.max_date === undefined
) && ? true
( // Проверка поля q. (Ключевые слова для поиска) : Number.isInteger(+req.query.max_date)) && // Проверка поля q. (Ключевые слова для поиска)
true // (Проверки нет, query всегда строка, необязательный параметр) true && // (Проверки нет, query всегда строка, необязательный параметр) // Проверка поля searchByAuthor (Флаг для 'q'. 0 - отключить)
) && true && // (Проверки нет, query всегда строка, необязательный параметр) // Проверка поля searchByName (Флаг для 'q'. 0 - отключить)
( // Проверка поля searchByAuthor (Флаг для 'q'. 0 - отключить) true // (Проверки нет, query всегда строка, необязательный параметр)
true // (Проверки нет, query всегда строка, необязательный параметр) );
) &&
( // Проверка поля searchByName (Флаг для 'q'. 0 - отключить)
true // (Проверки нет, query всегда строка, необязательный параметр)
)
)
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (req.method !== 'GET') { if (req.method !== "GET") {
throw new ApiError("METHOD_MUST_BE_GET", { throw new ApiError("METHOD_MUST_BE_GET", {
request_method : req.method request_method: req.method,
}); });
} }
if (!await checkSyntaxArgs(req, res)) { if (!(await checkSyntaxArgs(req, res))) {
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", { throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
request_method : req.method, request_method: req.method,
params : { params: {
author : req.query?.author === undefined ? null : req.query.author, author: req.query?.author === undefined ? null : req.query.author,
authors : req.query?.authors === undefined ? null : req.query.authors, authors: req.query?.authors === undefined ? null : req.query.authors,
q : req.query?.q === undefined ? null : req.query.q, q: req.query?.q === undefined ? null : req.query.q,
offset : req.query?.offset === undefined ? null : req.query.offset, offset: req.query?.offset === undefined ? null : req.query.offset,
count : req.query?.count === undefined ? null : req.query.count, count: req.query?.count === undefined ? null : req.query.count,
searchByAuthor : req.query?.searchByAuthor === undefined ? null : req.query.searchByAuthor, searchByAuthor:
searchByName : req.query?.searchByName === undefined ? null : req.query.searchByName, req.query?.searchByAuthor === undefined
min_date : req.query?.min_date === undefined ? null : req.query.min_date, ? null
max_date : req.query?.max_date === undefined ? null : req.query.max_date : req.query.searchByAuthor,
} searchByName:
req.query?.searchByName === undefined ? null : req.query.searchByName,
min_date: req.query?.min_date === undefined ? null : req.query.min_date,
max_date: req.query?.max_date === undefined ? null : req.query.max_date,
},
}); });
} }
// Оптимизация: флаг searchByAuthor выставится на 0, если была запрошена выборка по музыке определённого автора // Оптимизация: флаг searchByAuthor выставится на 0, если была запрошена выборка по музыке определённого автора
// Тем самым, мы ускоряем время ответа, поскольку мы не перебираем массив searchedAuthors с целью поиска совпадений // Тем самым, мы ускоряем время ответа, поскольку мы не перебираем массив searchedAuthors с целью поиска совпадений
let searchByAuthor = req.query.author === undefined ? req.query.searchByAuthor : '0'; let searchByAuthor =
req.query.author === undefined ? req.query.searchByAuthor : "0";
const offset = req.query.offset === undefined ? 0 : +req.query.offset; const offset = req.query.offset === undefined ? 0 : +req.query.offset;
const countFromNull = req.query.count === undefined ? undefined : offset + (+req.query.count); const countFromNull =
req.query.count === undefined ? undefined : offset + +req.query.count;
let result = (await global.database.muzic.promiseMode().get(req.query?.author === undefined
? {} : { where: { let result = (
author_id : +req.query.author await global.database.muzic.promiseMode().get(
}})).map(i => ({ id : i.id, name : i.name, author_id : i.author_id, is_data_exists : i.data !== null, date : i.time })); req.query?.author === undefined
? {}
: {
where: {
author_id: +req.query.author,
},
},
)
).map((i) => ({
id: i.id,
name: i.name,
author_id: i.author_id,
is_data_exists: i.data !== null,
date: i.time,
}));
// Если просят выборку по authors // Если просят выборку по authors
if (req.query.authors) { if (req.query.authors) {
let authors = req.query.authors.split(',').map(author => +author); let authors = req.query.authors.split(",").map((author) => +author);
result = result.filter(res => authors.includes(res.author_id)); result = result.filter((res) => authors.includes(res.author_id));
} }
// Если просят выборку по времени // Если просят выборку по времени
if (req.query.min_date || req.query.max_date) { if (req.query.min_date || req.query.max_date) {
const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date; const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date;
const maxDate = req.query.max_date === undefined ? 1e+32 : +req.query.max_date; const maxDate =
req.query.max_date === undefined ? 1e32 : +req.query.max_date;
result = result.filter((res) => minDate <= res.date && res.date <= maxDate); result = result.filter((res) => minDate <= res.date && res.date <= maxDate);
} }
if (req.query?.q !== undefined) { if (req.query?.q !== undefined) {
let authors = await global.database.authors.promiseMode().get(); let authors = await global.database.authors.promiseMode().get();
let searchedAuthors = result.map(i => { let searchedAuthors = result.map((i) => {
let author_id = i.author_id; let author_id = i.author_id;
return authors.filter(a => a.id === author_id)[0]; return authors.filter((a) => a.id === author_id)[0];
}); });
result = result.filter(i => { result = result.filter((i) => {
const search = req.query.q.toLowerCase(); const search = req.query.q.toLowerCase();
return (req.query.searchByName !== '0' && i.name.toLowerCase().includes(search)) || return (
!!(searchByAuthor !== '0' && searchedAuthors.filter(a => a.id === i.author_id)[0]?.name.toLowerCase().includes(search)); (req.query.searchByName !== "0" &&
i.name.toLowerCase().includes(search)) ||
!!(
searchByAuthor !== "0" &&
searchedAuthors
.filter((a) => a.id === i.author_id)[0]
?.name.toLowerCase()
.includes(search)
)
);
}); });
} }
result = result.slice(offset, countFromNull); result = result.slice(offset, countFromNull);
return { return {
count : result.length, count: result.length,
items : result items: result,
}; };
} };

View File

@ -1,63 +1,72 @@
const ApiError = require('../errorClass'); const ApiError = require("../errorClass");
const config = require('../../../config-handler'); const config = require("../../../config-handler");
async function isAuthorExists (authorId) { async function isAuthorExists(authorId) {
if (!authorId) return false; if (!authorId) return false;
return (await global.database.authors.promiseMode().get({ where : { id : authorId } })).length !== 0; return (
(
await global.database.authors
.promiseMode()
.get({ where: { id: authorId } })
).length !== 0
);
} }
async function checkSyntaxArgs (req, res) { async function checkSyntaxArgs(req, res) {
return !!( return !!(
( // Проверка поля type. // Проверка поля type.
['author', 'muzic'].indexOf(req.json?.type) !== -1 ["author", "muzic"].indexOf(req.json?.type) !== -1 && // Проверка поля id.
) && (Number.isInteger(req.json.id) && req.json.type === "author"
( // Проверка поля id. ? await isAuthorExists(req.json.id)
Number.isInteger(req.json.id) && req.json.type === 'author' ? await isAuthorExists(req.json.id) : true : true)
) );
)
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (req.json === undefined) { if (req.json === undefined) {
// console.log(req.headers); // console.log(req.headers);
throw new ApiError("METHOD_MUST_BE_POST_JSON", { throw new ApiError("METHOD_MUST_BE_POST_JSON", {
request_method : req.method, request_method: req.method,
'content-type' : !req.headers['content-type'] ? null : req.headers['content-type'] "content-type": !req.headers["content-type"]
? null
: req.headers["content-type"],
}); });
} }
if (!await checkSyntaxArgs(req, res)) { if (!(await checkSyntaxArgs(req, res))) {
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", { throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
request_method : req.method, request_method: req.method,
params : { params: {
type : req.json?.type === undefined ? null : req.json.type, type: req.json?.type === undefined ? null : req.json.type,
name : req.json?.name === undefined ? null : req.json.name, name: req.json?.name === undefined ? null : req.json.name,
...(req.json?.type === 'muzic' ? ({ ...(req.json?.type === "muzic"
author_id : req.json?.author_id === undefined ? null : req.json?.author_id, ? {
data : req.json?.data === undefined ? null : req.json.data, author_id:
}) : ({})) req.json?.author_id === undefined ? null : req.json?.author_id,
} data: req.json?.data === undefined ? null : req.json.data,
}
: {}),
},
}); });
} }
if (req.json.type === 'author') { if (req.json.type === "author") {
// Удаляем всю музыку этого исполнителя // Удаляем всю музыку этого исполнителя
await global.database.muzic.promiseMode().remove({ await global.database.muzic.promiseMode().remove({
where: { where: {
author_id: req.json.id author_id: req.json.id,
} },
}); });
// Удаляем исполнителя // Удаляем исполнителя
await global.database.authors.promiseMode().remove({ await global.database.authors.promiseMode().remove({
where: { where: {
id: req.json.id id: req.json.id,
} },
}); });
} } else {
else {
await global.database.muzic.promiseMode().remove({ await global.database.muzic.promiseMode().remove({
where: { where: {
id: req.json.id id: req.json.id,
} },
}); });
} }
return 'ok'; return "ok";
} };

View File

@ -1,54 +1,61 @@
const fs = require('fs'); const fs = require("fs");
const config = require('../../config-handler'); const config = require("../../config-handler");
const unknownError = (err) => { const unknownError = (err) => {
const stackId = (new Date()).getTime(); const stackId = new Date().getTime();
let errorLoggingFolder = config().error_logs_folder; let errorLoggingFolder = config().error_logs_folder;
errorLoggingFolder = !['/', '\\'].includes(errorLoggingFolder.at(-1)) ? errorLoggingFolder + '/' : errorLoggingFolder; errorLoggingFolder = !["/", "\\"].includes(errorLoggingFolder.at(-1))
fs.writeFileSync(`${errorLoggingFolder}error_${stackId}.log`, `ERROR: ? errorLoggingFolder + "/"
: errorLoggingFolder;
fs.writeFileSync(
`${errorLoggingFolder}error_${stackId}.log`,
`ERROR:
Date: ${new Date()} Date: ${new Date()}
Name: ${err.name} Name: ${err.name}
Message: ${err.message} Message: ${err.message}
Stack: Stack:
${err.stack}`); ${err.stack}`,
);
return { return {
error : 'UNKNOWN_ERROR', error: "UNKNOWN_ERROR",
details : { details: {
trace_id : stackId trace_id: stackId,
} },
}; };
} };
const unknownResponseFormat = 'UNKNOWN_RESPONSE_FORMAT'; const unknownResponseFormat = "UNKNOWN_RESPONSE_FORMAT";
async function handlingError (funct, success, error) { async function handlingError(funct, success, error) {
try { try {
success(await funct()); success(await funct());
} } catch (e) {
catch (e) {
// console.log('error', e); // console.log('error', e);
error(e.name === 'ApiError' ? { error(
error : e.message, e.name === "ApiError"
details : e.details ? {
} : unknownError(e)); error: e.message,
details: e.details,
}
: unknownError(e),
);
} }
} }
module.exports = async (method, req, res) => { module.exports = async (method, req, res) => {
if (req.query.response_format === 'json') { if (req.query.response_format === "json") {
handlingError( handlingError(
async () => ({ response : await method(req, res) }), async () => ({ response: await method(req, res) }),
async (data) => { async (data) => {
res.sendModed(data); res.sendModed(data);
}, },
async (errBody) => { async (errBody) => {
res.errorModeOn(); res.errorModeOn();
res.status(400).sendModed(errBody); res.status(400).sendModed(errBody);
} },
); );
} } else {
else {
res.status(400).sendModed(unknownResponseFormat); res.status(400).sendModed(unknownResponseFormat);
} }
} };

View File

@ -1,6 +1,8 @@
const fs = require('fs'); const fs = require("fs");
module.exports = () => { module.exports = () => {
const config = JSON.parse(fs.readFileSync("./config.json", { encoding : 'utf-8' })); const config = JSON.parse(
fs.readFileSync("./config.json", { encoding: "utf-8" }),
);
// Проверить конфиг на целостность // Проверить конфиг на целостность
return config; return config;
} };

View File

@ -1,118 +1,136 @@
const { Sequelize, DataTypes } = require('sequelize'); const { Sequelize, DataTypes } = require("sequelize");
class Table { class Table {
constructor (model) { constructor(model) {
this.model = model; this.model = model;
} }
promiseMode () { promiseMode() {
return new TablePromise(this.model); return new TablePromise(this.model);
} }
get (cb, condition = null) { get(cb, condition = null) {
this.model.findAll({...(!condition ? {} : condition), raw: true }) this.model
.then(data => cb(null, data)).catch(err => cb(err, null)); .findAll({ ...(!condition ? {} : condition), raw: true })
.then((data) => cb(null, data))
.catch((err) => cb(err, null));
} }
add (item, cb) { add(item, cb) {
this.model.create(item).then(i => cb(null, i)) this.model
.catch(err => cb(err, null)); .create(item)
.then((i) => cb(null, i))
.catch((err) => cb(err, null));
} }
remove (condition, cb) { remove(condition, cb) {
this.model.destroy(condition).then(i => cb(null, i)) this.model
.catch(err => cb(err, null)); .destroy(condition)
.then((i) => cb(null, i))
.catch((err) => cb(err, null));
} }
edit (data, condition, cb) { edit(data, condition, cb) {
this.model.update(data, condition).then(i => cb(null, i)) this.model
.catch(err => cb(err, null)); .update(data, condition)
.then((i) => cb(null, i))
.catch((err) => cb(err, null));
} }
} }
class TablePromise extends Table { class TablePromise extends Table {
async get (condition) { async get(condition) {
return await this.model.findAll({...(!condition ? {} : condition), raw: true }); return await this.model.findAll({
...(!condition ? {} : condition),
raw: true,
});
} }
async add (item) { async add(item) {
//setTimeout(() => this.model.findAll(), 0); //setTimeout(() => this.model.findAll(), 0);
return await this.model.create(item); return await this.model.create(item);
} }
async remove (condition) { async remove(condition) {
return await this.model.destroy(condition); return await this.model.destroy(condition);
} }
async edit (data, condition) { async edit(data, condition) {
return await this.model.update(data, condition); return await this.model.update(data, condition);
} }
} }
class Database { class Database {
constructor ( constructor(address, port, username, password, database) {
address, this.sequelize = new Sequelize(
port, `postgres://${username}:${password}@${address}:${port}/${database}`,
username, );
password, this.sequelize.authenticate().then(
database () => {
) { this.authors = new Table(
this.sequelize = new Sequelize(`postgres://${username}:${password}@${address}:${port}/${database}`); this.sequelize.define(
this.sequelize.authenticate().then(() => { "authors",
this.authors = new Table( {
this.sequelize.define('authors', { id: {
id: { type: DataTypes.INTEGER,
type: DataTypes.INTEGER, primaryKey: true,
primaryKey: true, autoIncrement: true,
autoIncrement: true, allowNull: false,
allowNull: false },
}, name: {
name: { type: DataTypes.TEXT,
type: DataTypes.TEXT, allowNull: false,
allowNull: false },
}, time: {
time : { type: DataTypes.INTEGER,
type: DataTypes.INTEGER, allowNull: false,
allowNull: false },
} },
}, { {
freezeTableName: true, freezeTableName: true,
timestamps: false timestamps: false,
}) },
); ),
this.muzic = new Table( );
this.sequelize.define('muzic', { this.muzic = new Table(
id: { this.sequelize.define(
type: DataTypes.INTEGER, "muzic",
primaryKey: true, {
autoIncrement: true, id: {
allowNull: false type: DataTypes.INTEGER,
}, primaryKey: true,
name: { autoIncrement: true,
type: DataTypes.TEXT, allowNull: false,
allowNull: false },
}, name: {
author_id: { type: DataTypes.TEXT,
type: DataTypes.INTEGER, allowNull: false,
allowNull: false },
}, author_id: {
data: { type: DataTypes.INTEGER,
type: DataTypes.BLOB('long') allowNull: false,
}, },
time : { data: {
type: DataTypes.INTEGER, type: DataTypes.BLOB("long"),
allowNull: false },
} time: {
}, { type: DataTypes.INTEGER,
freezeTableName: true, allowNull: false,
timestamps: false },
}) },
); {
console.log('Database successful connected!') freezeTableName: true,
}, (err) => { timestamps: false,
throw err; },
}) ),
);
console.log("Database successful connected!");
},
(err) => {
throw err;
},
);
} }
} }
module.exports = { Database } module.exports = { Database };

View File

@ -1,35 +1,40 @@
const config = require('./config-handler'); const config = require("./config-handler");
const fs = require('fs'); const fs = require("fs");
function log (date, req, ip, res) { function log(date, req, ip, res) {
const requestBody = !req.byteBody.toString('utf-8') ? '' : ` const requestBody = !req.byteBody.toString("utf-8")
? ""
: `
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
[REQUEST BODY] [REQUEST BODY]
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
${req.byteBody.toString('utf-8')}`; ${req.byteBody.toString("utf-8")}`;
let action = `HTTP ${req.httpVersion} ${req.method} ${req.originalUrl} let action = `HTTP ${req.httpVersion} ${req.method} ${req.originalUrl}
~~~~~~~~~ ~~~~~~~~~
[HEADERS] [HEADERS]
~~~~~~~~~ ~~~~~~~~~
${Object.entries(req.headers).map(([header, value]) => header + ": " + value).join('\n')}${requestBody}`; ${Object.entries(req.headers)
let response = !res.isError ? '' : `\n----------------\nError raised:\n----------------\n${JSON.stringify(res.responseData)}`; .map(([header, value]) => header + ": " + value)
.join("\n")}${requestBody}`;
let response = !res.isError
? ""
: `\n----------------\nError raised:\n----------------\n${JSON.stringify(
res.responseData,
)}`;
//console.log(`================================\nREPORT\n================================\n\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}${response}`); //console.log(`================================\nREPORT\n================================\n\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}${response}`);
let loggerFolder = config().logger_folder; let loggerFolder = config().logger_folder;
loggerFolder = !['/', '\\'].includes(loggerFolder.at(-1)) ? loggerFolder + '/' : loggerFolder; loggerFolder = !["/", "\\"].includes(loggerFolder.at(-1))
? loggerFolder + "/"
: loggerFolder;
fs.writeFileSync( fs.writeFileSync(
`${loggerFolder}${date.getTime()}.log`, `${loggerFolder}${date.getTime()}.log`,
`================================\nREPORT\n================================\n\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}${response}` `================================\nREPORT\n================================\n\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}${response}`,
); );
} }
module.exports = async (req, res, next) => { module.exports = async (req, res, next) => {
// console.log('ip', req.ip); // console.log('ip', req.ip);
log( log(new Date(), req, req.ip, res);
new Date(),
req,
req.ip,
res
);
next(); next();
}; };

View File

@ -1,10 +1,10 @@
"use strict"; "use strict";
const express = require('express'); const express = require("express");
const bodyHand = require('body'); const bodyHand = require("body");
const config = require('./config-handler'); const config = require("./config-handler");
const http = require('http'); const http = require("http");
const { Database } = require('./database'); const { Database } = require("./database");
const app = express(); const app = express();
@ -13,74 +13,80 @@ global.database = new Database(
config().database.port, config().database.port,
config().database.username, config().database.username,
config().database.password, config().database.password,
config().database.database config().database.database,
); );
http.ServerResponse.prototype.errorModeOn = function () { http.ServerResponse.prototype.errorModeOn = function () {
this.isError = true; this.isError = true;
} };
http.ServerResponse.prototype.bindNext = function (next) { http.ServerResponse.prototype.bindNext = function (next) {
this.next = next; this.next = next;
} };
http.ServerResponse.prototype.sendModed = function (sendData) { // Модифицируем res.send http.ServerResponse.prototype.sendModed = function (sendData) {
// Модифицируем res.send
if (sendData !== undefined && config().logger_mode) { if (sendData !== undefined && config().logger_mode) {
this.responseData = sendData; this.responseData = sendData;
require('./logger')(this.req, this, this.next); require("./logger")(this.req, this, this.next);
} }
this.send(sendData); this.send(sendData);
} };
app.use((req, res, next) => { app.use((req, res, next) => {
res.bindNext(next); res.bindNext(next);
next(); next();
}); });
app.use((req, res, next) => { // Для добавления оригинального тела запроса app.use((req, res, next) => {
const body = bodyHand(req, res, { // Для добавления оригинального тела запроса
limit: 9999999999, const body = bodyHand(
cache: false, req,
encoding: 'base64' res,
}, (err, body) => { {
if (!err) { limit: 9999999999,
req.byteBody = Buffer.from(body, 'base64'); cache: false,
encoding: "base64",
// Запись в req.json при json },
if ( (err, body) => {
!!req.headers && if (!err) {
req.headers['content-type']?.includes('json') req.byteBody = Buffer.from(body, "base64");
) {
try { // Запись в req.json при json
req.json = JSON.parse(req.byteBody.toString('utf8')); if (!!req.headers && req.headers["content-type"]?.includes("json")) {
try {
req.json = JSON.parse(req.byteBody.toString("utf8"));
} catch (_e) {}
} }
catch (_e) {}
} }
} next();
next(); },
}); );
}); });
app.use("/api", async (rq, rs, next) => next(), require('./api')); app.use("/api", async (rq, rs, next) => next(), require("./api"));
// Подключение через HTTPS // Подключение через HTTPS
let server; let server;
if (!config().ssl.enabled) { if (!config().ssl.enabled) {
server = app; server = app;
} } else {
else { const https = require("https");
const https = require('https'); server = https.createServer(
server = https.createServer({ {
cert : fs.readFileSync(config().ssl['public'], 'utf-8'), cert: fs.readFileSync(config().ssl["public"], "utf-8"),
key : fs.readFileSync(config().ssl['private'], 'utf-8') key: fs.readFileSync(config().ssl["private"], "utf-8"),
}, app); },
app,
);
} }
server.listen(config().port, config().address, async (err) => { server.listen(config().port, config().address, async (err) => {
if (err) { if (err) {
throw err; throw err;
} else {
console.log(
`Kodex Muzic catalog runned at ${config().address}:${config().port}`,
);
} }
else { });
console.log(`Kodex Muzic catalog runned at ${config().address}:${config().port}`);
}
});