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