diff --git a/packages/server/services/search/collectors/extensions.js b/packages/server/services/search/collectors/extensions.js new file mode 100644 index 00000000..3d9a509d --- /dev/null +++ b/packages/server/services/search/collectors/extensions.js @@ -0,0 +1,19 @@ +import { Extension } from "@db_models" + +export default { + key: "extensions", + model: Extension, + query: (keywords) => { + const [name, version] = keywords.split("@") + + const build = { + name: { $regex: name, $options: "i" }, + } + + if (version) { + build.version = { $regex: version, $options: "i" } + } + + return build + }, +} diff --git a/packages/server/services/search/collectors/tracks.js b/packages/server/services/search/collectors/tracks.js new file mode 100644 index 00000000..daa0a55d --- /dev/null +++ b/packages/server/services/search/collectors/tracks.js @@ -0,0 +1,11 @@ +import { Track } from "@db_models" + +export default { + key: "tracks", + model: Track, + query: (keywords) => { + return { + $or: [{ title: new RegExp(keywords, "i") }], + } + }, +} diff --git a/packages/server/services/search/collectors/users.js b/packages/server/services/search/collectors/users.js new file mode 100644 index 00000000..cf91d61d --- /dev/null +++ b/packages/server/services/search/collectors/users.js @@ -0,0 +1,14 @@ +import { User } from "@db_models" + +export default { + key: "users", + model: User, + query: (keywords) => { + return { + $or: [ + { username: new RegExp(keywords, "i") }, + { public_name: new RegExp(keywords, "i") }, + ], + } + }, +} diff --git a/packages/server/services/search/routes/search/get.js b/packages/server/services/search/routes/search/get.js index 656a5f97..3d20ef6f 100644 --- a/packages/server/services/search/routes/search/get.js +++ b/packages/server/services/search/routes/search/get.js @@ -1,46 +1,46 @@ -import { Track, User } from "@db_models" import pMap from "p-map" +import UsersCollector from "../../collectors/users" +import TracksCollector from "../../collectors/tracks" +import ExtensionsCollector from "../../collectors/extensions" + const escapeRegex = (str) => { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // Escapa caracteres especiales } +const collectors = { + users: UsersCollector, + tracks: TracksCollector, + extensions: ExtensionsCollector, +} + export default { useMiddlewares: ["withOptionalAuthentication"], fn: async (req, res) => { - let { keywords, limit = 50, offset = 0 } = req.query + let { + keywords = "", + limit = 50, + offset = 0, + fields = "users,tracks", + } = req.query if (typeof keywords === "undefined") { throw new OperationError(400, "Keywords are required") } + fields = fields.split(",").map((field) => field.trim()) + let results = {} keywords = escapeRegex(keywords) - const collections = [ - { - key: "users", - model: User, - query: () => { - return { - $or: [ - { username: new RegExp(keywords, "i") }, - { public_name: new RegExp(keywords, "i") }, - ], - } - }, - }, - { - key: "tracks", - model: Track, - query: () => { - return { - $or: [{ title: new RegExp(keywords, "i") }], - } - }, - }, - ] + const collections = [] + + fields.forEach((field) => { + if (collectors[field]) { + collections.push(collectors[field]) + } + }) let searchers = collections.map((collection) => { return async () => { @@ -52,7 +52,7 @@ export default { items: [], } - const query = collection.query() + const query = collection.query(keywords) const totalItems = await collection.model.countDocuments(query)