"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
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());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GadminCrud = void 0;
var axios_1 = __importDefault(require("axios"));
var query_string_1 = require("query-string");
var utils_1 = require("../utils");
var axiosInstance = axios_1.default.create();
axiosInstance.interceptors.response.use(function (response) {
    return response;
}, function (error) {
    var _a, _b, _c;
    var message = (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message;
    if (message) {
        if (message.includes("Unique constraint")) {
            message = "Unique constraint ".concat(message.split("Unique constraint")[1]);
        }
    }
    var customError = __assign(__assign({}, error), { message: message, statusCode: (_c = error.response) === null || _c === void 0 ? void 0 : _c.status });
    return Promise.reject(customError);
});
var mapOperator = function (operator) {
    switch (operator) {
        case 'and':
            return 'AND';
        case 'or':
            return 'OR';
        case 'ne':
            return 'not';
        case 'lt':
            return 'lt';
        case 'gt':
            return 'gt';
        case 'lte':
            return 'lte';
        case 'gte':
            return 'gte';
        case 'in':
            return 'in';
        case 'nin':
            return 'notIn';
        case 'contains':
            return 'contains';
        case 'ncontains':
            return '$exclL';
        case 'containss':
            return 'contains';
        case 'ncontainss':
            return '$excl';
        case 'null':
            return 'none';
        case 'startswith':
            return 'startsWith';
        case 'startswiths':
            return 'startsWith';
        case 'endswith':
            return 'endsWith';
        case 'endswiths':
            return 'endsWith';
    }
    return 'equals';
};
var generateSort = function (sort) {
    if (sort && sort.length > 0) {
        var multipleSort_1 = [];
        sort.map(function (_a) {
            var _b;
            var field = _a.field, order = _a.order;
            if (field && order) {
                multipleSort_1.push((_b = {},
                    _b[field] = order.toLowerCase(),
                    _b));
            }
        });
        return multipleSort_1;
    }
    return;
};
var createSearchQuery = function (filter) {
    var _a, _b, _c, _d, _e;
    if (filter.operator !== 'and' &&
        filter.operator !== 'or' &&
        'field' in filter) {
        // query
        if (filter.field.endsWith('.id')) {
            return _a = {},
                _a[filter.field.split('.')[0]] = {
                    id: (_b = {},
                        _b[mapOperator(filter.operator)] = Array.isArray(filter.value)
                            ? filter.value.map(function (item) { return parseInt(item.toString()); })
                            : parseInt(filter.value.toString()),
                        _b)
                },
                _a;
        }
        return _c = {},
            _c[filter.field] = (_d = {},
                _d[mapOperator(filter.operator)] = filter.value,
                _d),
            _c;
    }
    var operator = filter.operator;
    return _e = {},
        _e[mapOperator(operator)] = filter.value.map(function (filter) {
            return createSearchQuery(filter);
        }),
        _e;
};
var generateSearchFilter = function (filters) {
    return createSearchQuery({
        operator: 'and',
        value: filters
    });
};
var GadminCrud = function (apiUrl, httpClient) {
    if (httpClient === void 0) { httpClient = axiosInstance; }
    return ({
        getList: function (_a) {
            var resource = _a.resource, _b = _a.hasPagination, hasPagination = _b === void 0 ? true : _b, _c = _a.pagination, pagination = _c === void 0 ? { current: 1, pageSize: 10 } : _c, _d = _a.filters, filters = _d === void 0 ? [] : _d, _e = _a.sort, sort = _e === void 0 ? [] : _e, _f = _a.metaData, metaData = _f === void 0 ? {} : _f;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, _g, _h, current, _j, pageSize, query, q, data;
                return __generator(this, function (_k) {
                    switch (_k.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/findMany");
                            _g = pagination !== null && pagination !== void 0 ? pagination : {}, _h = _g.current, current = _h === void 0 ? 1 : _h, _j = _g.pageSize, pageSize = _j === void 0 ? 10 : _j;
                            query = { where: { AND: [] } };
                            q = filters.find(function (f) { return f.field === 'q'; });
                            if (filters) {
                                Object.assign(query, {
                                    where: generateSearchFilter(filters.filter(function (f) { return f.field !== 'q'; }))
                                });
                            }
                            if (q) {
                                if (metaData.transformQFn) {
                                    query.where.AND.push({
                                        OR: generateSearchFilter(metaData.transformQFn(q.value)).AND
                                    });
                                }
                                else {
                                    query.where.AND.push({
                                        q: q.value
                                    });
                                }
                            }
                            if (hasPagination) {
                                Object.assign(query, {
                                    skip: (current - 1) * pageSize,
                                    take: pageSize
                                });
                            }
                            Object.assign(query, {
                                orderBy: generateSort(sort) || [{ id: 'desc' }]
                            }, (0, utils_1.omit)(metaData, ['queryContext', 'transformQFn']));
                            return [4 /*yield*/, httpClient.post(url, query)];
                        case 1:
                            data = (_k.sent()).data;
                            return [2 /*return*/, {
                                    data: data.data,
                                    total: data.meta.itemCount
                                }];
                    }
                });
            });
        },
        getMany: function (_a) {
            var resource = _a.resource, ids = _a.ids, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, query, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/findMany");
                            query = { where: { id: { in: ids } } };
                            return [4 /*yield*/, httpClient.post(url, query)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        create: function (_a) {
            var resource = _a.resource, variables = _a.variables, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/createOne");
                            return [4 /*yield*/, httpClient.post(url, variables)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        update: function (_a) {
            var resource = _a.resource, id = _a.id, variables = _a.variables, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/updateUnique/").concat(id);
                            return [4 /*yield*/, httpClient.patch(url, variables)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        updateMany: function (_a) {
            var resource = _a.resource, ids = _a.ids, variables = _a.variables, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, query, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/updateMany");
                            query = {
                                where: { id: { in: ids } },
                                data: variables
                            };
                            return [4 /*yield*/, httpClient.patch(url, query)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        createMany: function (_a) {
            var resource = _a.resource, variables = _a.variables, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, data, res;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/createMany");
                            return [4 /*yield*/, httpClient.post(url, variables)];
                        case 1:
                            data = (_b.sent()).data;
                            res = {
                                data: new Array(data.count).fill({ id: -1 })
                            };
                            return [2 /*return*/, res];
                    }
                });
            });
        },
        getOne: function (_a) {
            var resource = _a.resource, id = _a.id, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/findUnique/").concat(id);
                            metaData === null || metaData === void 0 ? true : delete metaData.queryContext;
                            return [4 /*yield*/, httpClient.post(url, metaData)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        deleteOne: function (_a) {
            var resource = _a.resource, id = _a.id, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/deleteUnique/").concat(id);
                            return [4 /*yield*/, httpClient.delete(url)];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        deleteMany: function (_a) {
            var resource = _a.resource, ids = _a.ids, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var url, query, data;
                return __generator(this, function (_b) {
                    switch (_b.label) {
                        case 0:
                            url = "".concat(apiUrl, "/").concat(resource, "/deleteMany");
                            query = { where: { id: { in: ids } } };
                            return [4 /*yield*/, httpClient.delete(url, {
                                    data: query
                                })];
                        case 1:
                            data = (_b.sent()).data;
                            return [2 /*return*/, {
                                    data: data
                                }];
                    }
                });
            });
        },
        getApiUrl: function () {
            return apiUrl;
        },
        custom: function (_a) {
            var url = _a.url, method = _a.method, filters = _a.filters, sort = _a.sort, payload = _a.payload, query = _a.query, headers = _a.headers, metaData = _a.metaData;
            return __awaiter(void 0, void 0, void 0, function () {
                var body, requestUrl, axiosResponse, _b, data;
                return __generator(this, function (_c) {
                    switch (_c.label) {
                        case 0:
                            body = {};
                            if (filters) {
                                Object.assign(body, {
                                    where: generateSearchFilter(filters)
                                });
                            }
                            Object.assign(body, {
                                orderBy: generateSort(sort) || [{ id: 'desc' }]
                            });
                            requestUrl = url;
                            if (query) {
                                requestUrl = "".concat(requestUrl, "?").concat((0, query_string_1.stringify)(query));
                            }
                            if (headers) {
                                httpClient.defaults.headers = __assign(__assign({}, httpClient.defaults.headers), headers);
                            }
                            _b = method;
                            switch (_b) {
                                case 'put': return [3 /*break*/, 1];
                                case 'post': return [3 /*break*/, 1];
                                case 'patch': return [3 /*break*/, 1];
                                case 'delete': return [3 /*break*/, 3];
                            }
                            return [3 /*break*/, 5];
                        case 1: return [4 /*yield*/, httpClient[method](url, payload)];
                        case 2:
                            axiosResponse = _c.sent();
                            return [3 /*break*/, 7];
                        case 3: return [4 /*yield*/, httpClient.delete(url, {
                                data: payload
                            })];
                        case 4:
                            axiosResponse = _c.sent();
                            return [3 /*break*/, 7];
                        case 5: return [4 /*yield*/, httpClient.get(requestUrl)];
                        case 6:
                            axiosResponse = _c.sent();
                            return [3 /*break*/, 7];
                        case 7:
                            data = axiosResponse.data;
                            return [2 /*return*/, Promise.resolve({ data: data })];
                    }
                });
            });
        }
    });
};
exports.GadminCrud = GadminCrud;
//# sourceMappingURL=gadmin-data-provider.js.map