UNPKG

adonis-forge

Version:

Bundle utils for AdonisJS

121 lines (120 loc) 3.55 kB
// src/crud/utils/query_handler.ts var QueryHandler = class { model; qs; constructor(model, qs) { this.model = model; this.qs = qs; } handle(query) { this.handleSearch(query); this.handleIncludes(query); return query; } handleSearch(query) { const modelKeys = Object.keys(this.model.$keys.columnsToSerialized.all()); const validKeys = Object.keys(this.qs).filter((key) => { if (key === "keywords" && Array.isArray(this.qs[key])) { query.where((q) => { const keywords = this.qs[key]; for (const val of keywords) { Object.entries(val).forEach(([k, value]) => { q.orWhere(k, "like", `%${value}%`); }); } }); return false; } const match = key.match(/^\$(\w+)\$/); if (match) { this.handleMagicQuery(query, { operator: match[1], field: key.replace(match[0], ""), value: this.qs[key] }); return false; } if (!modelKeys.includes(key) || ["created_at", "updated_at"].includes(key)) { return false; } return true; }); for (const key of validKeys) { query.where(key, this.qs[key]); } } handleMagicQuery(query, options) { switch (options.operator) { case "gt": query.where(options.field, ">", options.value); break; case "lt": query.where(options.field, "<", options.value); break; case "like": query.where(options.field, "like", `%${options.value}%`); break; case "in": query.whereIn( options.field, options.value.split(",").map((e) => Number(e)) ); break; case "notIn": query.whereNotIn( options.field, options.value.split(",").map((e) => Number(e)) ); break; case "between": const [left, right] = options.value.split(","); query.whereBetween(options.field, [Number(left), Number(right)]); break; default: throw new Error(`invalid operator ${options.operator}`); } } /** * @example * &includes=user,address */ handleIncludes(query) { if (!this.qs["includes"]) return; const includes = Array.isArray(this.qs["includes"]) ? this.qs["includes"] : this.qs["includes"].split(",").filter((item) => item !== "").map((item) => item.trim()) || []; const arrayOptions = []; for (const include of includes) { const [firstRelation, secondRelation] = include.split("."); if (!arrayOptions[firstRelation]) { arrayOptions[firstRelation] = { firstRelation, subs: [] }; } if (secondRelation) { arrayOptions[firstRelation].subs.push({ secondRelation }); } if (firstRelation && !secondRelation) { this.hasInclude(includes); } if (arrayOptions) { for (const relationOption of Object.keys(arrayOptions)) { query.preload(`${arrayOptions[relationOption].firstRelation}`, () => { }); } } } } hasInclude(includes) { let includesNotAvailables = []; for (const include of includes) { const [first] = include.split("."); if (!this.model.$hasRelation(first)) { includesNotAvailables.push(include); } } if (includesNotAvailables.length) { throw new Error(`invalid relations includes ${includesNotAvailables.map((e) => e)}`); } } }; export { QueryHandler }; //# sourceMappingURL=chunk-5AVUSAWG.js.map