@melchyore/adonis-auto-preload
Version:
Auto-preload multiple relationships when retrieving Lucid models
120 lines (119 loc) • 4.83 kB
JavaScript
"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;