UNPKG

@melchyore/adonis-auto-preload

Version:

Auto-preload multiple relationships when retrieving Lucid models

120 lines (119 loc) 4.83 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutoPreload = void 0; const WrongRelationshipTypeException_1 = __importDefault(require("../Exceptions/WrongRelationshipTypeException")); const WrongArgumentTypeException_1 = __importDefault(require("../Exceptions/WrongArgumentTypeException")); const AutoPreload = (superclass) => { class AutoPreloadModel extends superclass { static boot() { if (this.booted) { return; } if (this.$with.length > 0) { const isWrongType = this.$with.every((relationship) => { return !['function', 'string'].includes(typeof relationship); }); if (isWrongType) { throw WrongRelationshipTypeException_1.default.invoke(this.name); } } super.boot(); this.$originalWith = [...this.$with]; for (const hook of ['fetch', 'find']) { this.before(hook, (query) => { this.handleAutoPreload(query); }); } this.before('paginate', ([_, query]) => { this.handleAutoPreload(query, false); }); } static without(relationships) { this.checkArrayOfRelationships('without', relationships); this.$with = this.$with.filter((relationship) => { if (typeof relationship === 'string') { return !relationships.includes(relationship); } else if (typeof relationship === 'function') { return relationship; } else { throw WrongArgumentTypeException_1.default.invoke(relationship); } }); return this; } static withOnly(relationships) { this.checkArrayOfRelationships('withOnly', relationships); this.$with = this.$with.filter((relationship) => { if (typeof relationship === 'string') { return relationships.includes(relationship); } else if (typeof relationship === 'function') { return relationship; } else { throw WrongArgumentTypeException_1.default.invoke(relationship); } }); return this; } static withoutAny() { this.$with = []; return this; } static handleAutoPreload(query, restorePreloads = true) { const preloads = this.$with; if (preloads.length > 0) { for (const preload of preloads) { if (typeof preload === 'string') { if (preload.includes('.')) { this.handleNestedRelationships(query, preload.split('.')); } else { query.preload(preload); } } else if (typeof preload === 'function') { preload(query); } } } if (restorePreloads) { this.$with = [...this.$originalWith]; } } /** * Recursive function to handle nested relationships. */ static handleNestedRelationships(query, relationships) { if (relationships.length > 0) { const nextRelation = relationships.shift(); if (nextRelation) { query.preload(nextRelation, (qb) => { if (relationships.length > 0) { this.handleNestedRelationships(qb, relationships); } }); } } } static checkArrayOfRelationships(method, relationships) { if (relationships.length > 0) { const isWrongType = relationships.every((relationship) => { return !['function', 'string'].includes(typeof relationship); }); if (isWrongType) { throw WrongArgumentTypeException_1.default.invoke(method); } } } } AutoPreloadModel.$with = []; AutoPreloadModel.$originalWith = []; return AutoPreloadModel; }; exports.AutoPreload = AutoPreload;