slonik-trpc
Version:
Slonik tRPC loader
113 lines (112 loc) • 6.19 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeFilter = exports.mergeFilters = exports.createFilters = void 0;
const slonik_1 = require("slonik");
const zod_1 = require("../helpers/zod");
/**
* Specify context type first
*/
const createFilters = () => (filters, interpreters, options) => {
return {
filters,
interpreters,
options,
};
};
exports.createFilters = createFilters;
/**
* Merges two or more filter declarations to allow easy composability.
* If options is specified, it overwrites the pre and post-processing, and the original functions are NOT called.
* Otherwise the original postprocessing and preprocessing of filters is kept, and the functions are called sequentially.
*/
const mergeFilters = (filters, options) => {
return {
filters: filters.reduce((acc, filter) => {
return Object.assign(Object.assign({}, acc), filter.filters);
}, {}),
interpreters: filters.reduce((acc, filter) => {
return Object.assign(Object.assign({}, acc), filter.interpreters);
}, {}),
options: options ? options : {
postprocess(conditions, allFilters, context) {
return filters.reduce((acc, filter) => {
var _a, _b;
return ((_b = (_a = filter.options) === null || _a === void 0 ? void 0 : _a.postprocess) === null || _b === void 0 ? void 0 : _b.call(_a, acc, allFilters, context)) || acc;
}, conditions);
},
preprocess(allFilters, context) {
return filters.reduce((acc, filter) => {
var _a, _b;
return ((_b = (_a = filter.options) === null || _a === void 0 ? void 0 : _a.preprocess) === null || _b === void 0 ? void 0 : _b.call(_a, acc, context)) || acc;
}, allFilters);
}
},
};
};
exports.mergeFilters = mergeFilters;
function makeFilter(interpreters, options) {
const interpretFilter = (filter, context) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const conditions = [];
const addCondition = (item) => item && conditions.push(item);
for (const key of Object.keys(filter)) {
const interpreter = interpreters[key];
const condition = yield (interpreter === null || interpreter === void 0 ? void 0 : interpreter(filter[key], filter, context));
if (condition) {
addCondition(condition);
}
}
if ((_a = filter.OR) === null || _a === void 0 ? void 0 : _a.length) {
const orConditions = yield Promise.all(filter.OR.map((or) => __awaiter(this, void 0, void 0, function* () {
const orFilter = yield interpretFilter(or, context);
return orFilter.length
? slonik_1.sql.fragment `(${slonik_1.sql.join(orFilter, slonik_1.sql.fragment `) AND (`)})`
: null;
}))).then(filters => filters.filter(zod_1.notEmpty));
if (orConditions === null || orConditions === void 0 ? void 0 : orConditions.length) {
addCondition(slonik_1.sql.fragment `(${slonik_1.sql.join(orConditions, slonik_1.sql.fragment `) OR (`)})`);
}
}
if ((_b = filter.AND) === null || _b === void 0 ? void 0 : _b.length) {
const andConditions = yield Promise.all(filter.AND.map((and) => __awaiter(this, void 0, void 0, function* () {
const andFilter = yield interpretFilter(and, context);
return andFilter.length
? slonik_1.sql.fragment `(${slonik_1.sql.join(andFilter, slonik_1.sql.fragment `) AND (`)})`
: null;
}))).then(filters => filters.filter(zod_1.notEmpty));
if (andConditions === null || andConditions === void 0 ? void 0 : andConditions.length) {
addCondition(slonik_1.sql.fragment `(${slonik_1.sql.join(andConditions, slonik_1.sql.fragment `) AND (`)})`);
}
}
if (filter.NOT) {
const notFilter = yield interpretFilter(filter.NOT, context);
if (notFilter.length) {
addCondition(slonik_1.sql.fragment `NOT (${slonik_1.sql.join(notFilter, slonik_1.sql.fragment `) AND (`)})`);
}
}
// return sql.fragment`(${sql.join(conditions, sql.fragment`) AND (`)})`;
return conditions;
});
const getConditions = (filters, context) => __awaiter(this, void 0, void 0, function* () {
var _c, _d;
const conditions = yield interpretFilter(((_c = options === null || options === void 0 ? void 0 : options.preprocess) === null || _c === void 0 ? void 0 : _c.call(options, filters, context)) || filters, context);
return (((_d = options === null || options === void 0 ? void 0 : options.postprocess) === null || _d === void 0 ? void 0 : _d.call(options, conditions, filters, context)) || conditions);
});
const getWhereFragment = (filter, context) => __awaiter(this, void 0, void 0, function* () {
const conditions = yield getConditions(filter, context);
return (conditions === null || conditions === void 0 ? void 0 : conditions.length)
? slonik_1.sql.fragment `(${slonik_1.sql.join(conditions, slonik_1.sql.fragment `)\n AND (`)})\n`
: slonik_1.sql.fragment `TRUE`;
});
return getWhereFragment;
}
exports.makeFilter = makeFilter;