"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __glob = (map) => (path) => { var fn = map[path]; if (fn) return fn(); throw new Error("Module not found in bundle: " + path); }; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/utils/is-promise.js function isPromise(value) { if (!value) return false; if (typeof value !== "object") return false; return typeof value.then === "function"; } var init_is_promise = __esm({ "src/utils/is-promise.js"() { "use strict"; __name(isPromise, "isPromise"); } }); // src/utils/capitalize.js function capitalize(string) { if (!string || typeof string !== "string") return string; return string.charAt(0).toUpperCase() + string.slice(1); } var init_capitalize = __esm({ "src/utils/capitalize.js"() { "use strict"; __name(capitalize, "capitalize"); } }); // src/utils/clone-deep.js function cloneDeep(value) { if (!value) return value; const types = [Number, String, Boolean]; let result; types.forEach((type) => { if (value instanceof type) result = type(value); }); if (result === void 0) { if (Array.isArray(value)) { result = []; value.forEach((child, index) => { result[index] = cloneDeep(child); }); } else if (typeof value === "object") { if ("nodeType" in value && value.nodeType && "cloneNode" in value && typeof value.cloneNode === "function") { result = value.cloneNode(true); } else if (!("prototype" in value) || !value.prototype) { if (value instanceof Date) { result = new Date(value); } else if (value.constructor && value.constructor.name === "Object") { result = {}; for (const key in value) { result[key] = cloneDeep(value[key]); } } else { result = value; } } else { result = value; } } else { result = value; } } return result; } var init_clone_deep = __esm({ "src/utils/clone-deep.js"() { "use strict"; __name(cloneDeep, "cloneDeep"); } }); // src/utils/singularize.js function singularize(noun) { if (!noun || typeof noun !== "string") return noun; const endings = { ves: "fe", ies: "y", i: "us", zes: "ze", ses: "s", es: "e", s: "" }; return noun.replace( new RegExp(`(${Object.keys(endings).join("|")})$`), (r) => endings[r] ); } var init_singularize = __esm({ "src/utils/singularize.js"() { "use strict"; __name(singularize, "singularize"); } }); // src/utils/is-deep-equal.js function isDeepEqual(firstValue, secondValue) { const cached = /* @__PURE__ */ new WeakMap(); const compare = /* @__PURE__ */ __name((a, b) => { if (a === null || b === null) return a === b; if (typeof a !== "object" || typeof b !== "object") return a === b; const dataTypeA = Array.isArray(a) ? "array" : "object"; const dataTypeB = Array.isArray(b) ? "array" : "object"; if (dataTypeA !== dataTypeB) return false; const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; const symbolsA = Object.getOwnPropertySymbols(a); const symbolsB = Object.getOwnPropertySymbols(b); if (symbolsA.length !== symbolsB.length) return false; let setForA = cached.get(a); if (setForA == null) { setForA = /* @__PURE__ */ new Set(); cached.set(a, setForA); } else if (setForA.has(b)) { return true; } setForA.add(b); let setForB = cached.get(b); if (setForB == null) { setForB = /* @__PURE__ */ new Set(); cached.set(b, setForB); } else if (setForB.has(a)) { return true; } setForB.add(a); const propertyNamesA = [...keysA, ...symbolsA]; for (const propertyNameA of propertyNamesA) { if (!Object.prototype.hasOwnProperty.call(b, propertyNameA)) return false; const propertyValueA = a[propertyNameA]; const propertyValueB = b[propertyNameA]; if (!compare(propertyValueA, propertyValueB)) return false; } return true; }, "compare"); return compare(firstValue, secondValue); } var init_is_deep_equal = __esm({ "src/utils/is-deep-equal.js"() { "use strict"; __name(isDeepEqual, "isDeepEqual"); } }); // src/errors/not-implemented-error.js var import_js_format, _NotImplementedError, NotImplementedError; var init_not_implemented_error = __esm({ "src/errors/not-implemented-error.js"() { "use strict"; import_js_format = require("@e22m4u/js-format"); _NotImplementedError = class _NotImplementedError extends import_js_format.Errorf { }; __name(_NotImplementedError, "NotImplementedError"); NotImplementedError = _NotImplementedError; } }); // src/errors/invalid-argument-error.js var import_js_format2, _InvalidArgumentError, InvalidArgumentError; var init_invalid_argument_error = __esm({ "src/errors/invalid-argument-error.js"() { "use strict"; import_js_format2 = require("@e22m4u/js-format"); _InvalidArgumentError = class _InvalidArgumentError extends import_js_format2.Errorf { }; __name(_InvalidArgumentError, "InvalidArgumentError"); InvalidArgumentError = _InvalidArgumentError; } }); // src/errors/invalid-operator-value-error.js var import_js_format3, _InvalidOperatorValueError, InvalidOperatorValueError; var init_invalid_operator_value_error = __esm({ "src/errors/invalid-operator-value-error.js"() { "use strict"; import_js_format3 = require("@e22m4u/js-format"); _InvalidOperatorValueError = class _InvalidOperatorValueError extends Error { /** * Constructor. * * @param {string} operator * @param {string} expected * @param {*} value */ constructor(operator, expected, value) { super( (0, import_js_format3.format)( "Condition of {%s: ...} should have %s, but %v was given.", operator, expected, value ) ); } }; __name(_InvalidOperatorValueError, "InvalidOperatorValueError"); InvalidOperatorValueError = _InvalidOperatorValueError; } }); // src/errors/index.js var init_errors = __esm({ "src/errors/index.js"() { "use strict"; init_not_implemented_error(); init_invalid_argument_error(); init_invalid_operator_value_error(); } }); // src/utils/like-to-regexp.js function likeToRegexp(pattern, isCaseInsensitive = false) { if (typeof pattern !== "string") { throw new InvalidArgumentError( "The first argument of `likeToRegexp` should be a String, but %v was given.", pattern ); } const regexSpecials = "-[]{}()*+?.\\^$|"; let regexString = ""; let isEscaping = false; for (const char of pattern) { if (isEscaping) { regexString += regexSpecials.includes(char) ? `\\${char}` : char; isEscaping = false; } else if (char === "\\") { isEscaping = true; } else if (char === "%") { regexString += ".*"; } else if (char === "_") { regexString += "."; } else if (regexSpecials.includes(char)) { regexString += `\\${char}`; } else { regexString += char; } } if (isEscaping) { regexString += "\\\\"; } const flags = isCaseInsensitive ? "i" : ""; return new RegExp(`^${regexString}$`, flags); } var init_like_to_regexp = __esm({ "src/utils/like-to-regexp.js"() { "use strict"; init_errors(); __name(likeToRegexp, "likeToRegexp"); } }); // src/utils/is-plain-object.js function isPlainObject(value) { return Boolean( typeof value === "object" && value && !Array.isArray(value) && (!value.constructor || value.constructor && value.constructor.name === "Object") ); } var init_is_plain_object = __esm({ "src/utils/is-plain-object.js"() { "use strict"; __name(isPlainObject, "isPlainObject"); } }); // src/utils/string-to-regexp.js function stringToRegexp(pattern, flags = void 0) { if (pattern instanceof RegExp) { return new RegExp(pattern, flags); } return new RegExp(pattern, flags); } var init_string_to_regexp = __esm({ "src/utils/string-to-regexp.js"() { "use strict"; __name(stringToRegexp, "stringToRegexp"); } }); // src/utils/get-value-by-path.js function getValueByPath(obj, path, orElse = void 0) { if (!obj || typeof obj !== "object") return orElse; if (!path || typeof path !== "string") return orElse; const keys = path.split("."); let value = obj; for (const key of keys) { if (typeof value === "object" && value !== null && key in value) { value = value[key]; } else { value = orElse; break; } } return value; } var init_get_value_by_path = __esm({ "src/utils/get-value-by-path.js"() { "use strict"; __name(getValueByPath, "getValueByPath"); } }); // src/utils/select-object-keys.js function selectObjectKeys(obj, keys) { if (!obj || typeof obj !== "object" || Array.isArray(obj)) throw new InvalidArgumentError( "The first argument of selectObjectKeys should be an Object, but %v was given.", obj ); if (!Array.isArray(keys)) throw new InvalidArgumentError( "The second argument of selectObjectKeys should be an Array of String, but %v was given.", keys ); keys.forEach((key) => { if (typeof key !== "string") throw new InvalidArgumentError( "The second argument of selectObjectKeys should be an Array of String, but %v was given.", key ); }); const result = {}; const allKeys = Object.keys(obj); allKeys.forEach((key) => { if (keys.includes(key)) result[key] = obj[key]; }); return result; } var init_select_object_keys = __esm({ "src/utils/select-object-keys.js"() { "use strict"; init_errors(); __name(selectObjectKeys, "selectObjectKeys"); } }); // src/utils/exclude-object-keys.js function excludeObjectKeys(obj, keys) { if (typeof obj !== "object" || !obj || Array.isArray(obj)) throw new InvalidArgumentError( "Cannot exclude keys from a non-Object value, %v was given.", obj ); const result = { ...obj }; keys = Array.isArray(keys) ? keys : [keys]; keys.forEach((key) => delete result[key]); return result; } var init_exclude_object_keys = __esm({ "src/utils/exclude-object-keys.js"() { "use strict"; init_errors(); __name(excludeObjectKeys, "excludeObjectKeys"); } }); // src/utils/model-name-to-model-key.js function modelNameToModelKey(modelName) { if (!modelName || typeof modelName !== "string" || /\s/.test(modelName)) throw new InvalidArgumentError( "The model name should be a non-empty String without spaces, but %v was given.", modelName ); if (modelName.toLowerCase() !== "model") modelName = modelName.replace(/[-_]?Model$/, "").replace(/[-_](MODEL|model)$/, ""); return modelName.toLowerCase().replace(/[-_]/g, ""); } var init_model_name_to_model_key = __esm({ "src/utils/model-name-to-model-key.js"() { "use strict"; init_errors(); __name(modelNameToModelKey, "modelNameToModelKey"); } }); // src/utils/index.js var init_utils = __esm({ "src/utils/index.js"() { "use strict"; init_is_promise(); init_capitalize(); init_clone_deep(); init_singularize(); init_is_deep_equal(); init_like_to_regexp(); init_is_plain_object(); init_string_to_regexp(); init_get_value_by_path(); init_select_object_keys(); init_exclude_object_keys(); init_model_name_to_model_key(); } }); // src/filter/slice-clause-tool.js var import_js_service, _SliceClauseTool, SliceClauseTool; var init_slice_clause_tool = __esm({ "src/filter/slice-clause-tool.js"() { "use strict"; import_js_service = require("@e22m4u/js-service"); init_errors(); _SliceClauseTool = class _SliceClauseTool extends import_js_service.Service { /** * Slice. * * @param {object[]} entities * @param {number|undefined} skip * @param {number|undefined} limit * @returns {object[]} */ slice(entities, skip = void 0, limit = void 0) { if (!Array.isArray(entities)) throw new InvalidArgumentError( "The first argument of SliceClauseTool.slice should be an Array, but %v was given.", entities ); if (skip != null && typeof skip !== "number") throw new InvalidArgumentError( 'The provided option "skip" should be a Number, but %v was given.', skip ); if (limit != null && typeof limit !== "number") throw new InvalidArgumentError( 'The provided option "limit" should be a Number, but %v was given.', limit ); skip = skip || 0; limit = limit || entities.length; return entities.slice(skip, skip + limit); } /** * Validate skip clause. * * @param {number|undefined} skip */ static validateSkipClause(skip) { if (skip == null) return; if (typeof skip !== "number") throw new InvalidArgumentError( 'The provided option "skip" should be a Number, but %v was given.', skip ); } /** * Validate limit clause. * * @param {number|undefined} limit */ static validateLimitClause(limit) { if (limit == null) return; if (typeof limit !== "number") throw new InvalidArgumentError( 'The provided option "limit" should be a Number, but %v was given.', limit ); } }; __name(_SliceClauseTool, "SliceClauseTool"); SliceClauseTool = _SliceClauseTool; } }); // src/filter/order-clause-tool.js function compareFn(a, b) { let undefinedA, undefinedB; for (let i = 0, l = this.length; i < l; i++) { const aVal = getValueByPath(a, this[i].key); const bVal = getValueByPath(b, this[i].key); undefinedB = bVal === void 0 && aVal !== void 0; undefinedA = aVal === void 0 && bVal !== void 0; if (undefinedB || aVal > bVal) { return this[i].reverse; } else if (undefinedA || aVal < bVal) { return -1 * this[i].reverse; } } return 0; } var import_js_service2, _OrderClauseTool, OrderClauseTool; var init_order_clause_tool = __esm({ "src/filter/order-clause-tool.js"() { "use strict"; import_js_service2 = require("@e22m4u/js-service"); init_utils(); init_errors(); _OrderClauseTool = class _OrderClauseTool extends import_js_service2.Service { /** * Sort. * * @param {object[]} entities * @param {string|string[]|undefined} clause */ sort(entities, clause) { if (clause == null) return; if (Array.isArray(clause) === false) clause = [clause]; if (!clause.length) return; const mapping = []; clause.forEach((key, index) => { if (!key || typeof key !== "string") throw new InvalidArgumentError( 'The provided option "order" should be a non-empty String or an Array of non-empty String, but %v was given.', key ); let reverse = 1; const matches = key.match(/\s+(A|DE)SC$/i); if (matches) { key = key.replace(/\s+(A|DE)SC/i, ""); if (matches[1].toLowerCase() === "de") reverse = -1; } mapping[index] = { key, reverse }; }); entities.sort(compareFn.bind(mapping)); } /** * Validate order clause. * * @param {string|string[]|undefined} clause */ static validateOrderClause(clause) { if (clause == null) return; if (Array.isArray(clause) === false) clause = [clause]; if (!clause.length) return; clause.forEach((field) => { if (!field || typeof field !== "string") throw new InvalidArgumentError( 'The provided option "order" should be a non-empty String or an Array of non-empty String, but %v was given.', field ); }); } /** * Normalize order clause. * * @param {string|string[]|undefined} clause * @returns {string[]|undefined} */ static normalizeOrderClause(clause) { if (clause == null) return; if (Array.isArray(clause) === false) clause = [clause]; if (!clause.length) return; clause.forEach((field) => { if (!field || typeof field !== "string") throw new InvalidArgumentError( 'The provided option "order" should be a non-empty String or an Array of non-empty String, but %v was given.', field ); }); return clause; } }; __name(_OrderClauseTool, "OrderClauseTool"); OrderClauseTool = _OrderClauseTool; __name(compareFn, "compareFn"); } }); // src/filter/operator-clause-tool.js var import_js_service3, _OperatorClauseTool, OperatorClauseTool; var init_operator_clause_tool = __esm({ "src/filter/operator-clause-tool.js"() { "use strict"; import_js_service3 = require("@e22m4u/js-service"); init_utils(); init_errors(); _OperatorClauseTool = class _OperatorClauseTool extends import_js_service3.Service { /** * Compare. * * @param {*} val1 The 1st value * @param {*} val2 The 2nd value * @param {*} noTypeConversion * @returns {number} 0: =, positive: >, negative < */ compare(val1, val2, noTypeConversion = false) { if (val1 === val2) { return 0; } if (val1 == null || val2 == null) { return val1 == val2 ? 0 : NaN; } const type1 = typeof val1; const type2 = typeof val2; if (type1 === "object" || type2 === "object") { return isDeepEqual(val1, val2) ? 0 : NaN; } if ((type1 === "number" || type1 === "string" || type1 === "boolean") && (type2 === "number" || type2 === "string" || type2 === "boolean")) { if (noTypeConversion && type1 !== type2) { return NaN; } const num1 = Number(val1); const num2 = Number(val2); if (!isNaN(num1) && !isNaN(num2)) { return num1 - num2; } } if (type1 === "string" && type2 === "string") { if (val1 > val2) return 1; if (val1 < val2) return -1; return 0; } return NaN; } /** * Test all operators. * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testAll(clause, value) { if (!clause || typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( "The first argument of OperatorUtils.testAll should be an Object, but %v was given.", clause ); const operatorMap = { eq: this.testEqNeq, neq: this.testEqNeq, gt: this.testGtLt, gte: this.testGtLt, lt: this.testGtLt, lte: this.testGtLt, inq: this.testInq, nin: this.testNin, between: this.testBetween, exists: this.testExists, like: this.testLike, nlike: this.testNlike, ilike: this.testIlike, nilike: this.testNilike, regexp: this.testRegexp }; const clauseKeys = Object.keys(clause); const knownOperators = clauseKeys.filter((key) => operatorMap[key]); if (knownOperators.length === 0) { return void 0; } return knownOperators.every((op) => { const singleOpClause = { [op]: clause[op] }; if (op === "regexp" && "flags" in clause) { singleOpClause.flags = clause.flags; } const testFn = operatorMap[op]; const result = testFn.call(this, singleOpClause, value); return result; }); } /** * Test eq/neq operator. * * @example * ```ts * { * eq: 'foo', * } * ``` * * @example * ```ts * { * neq: 'foo', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testEqNeq(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testEqNeq should be an Object, but %v was given.", clause ); if ("eq" in clause) return this.compare(clause.eq, value, true) === 0; if ("neq" in clause) return this.compare(clause.neq, value, true) !== 0; } /** * Test lt/gt/lte/gte operator. * * @example * ```ts * { * lt: 10, * } * ``` * * @example * ```ts * { * lte: 10, * } * ``` * * @example * ```ts * { * gt: 10, * } * ``` * * @example * ```ts * { * gte: 10, * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testGtLt(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testGtLt should be an Object, but %v was given.", clause ); if ("gt" in clause) return this.compare(value, clause.gt) > 0; if ("gte" in clause) return this.compare(value, clause.gte) >= 0; if ("lt" in clause) return this.compare(value, clause.lt) < 0; if ("lte" in clause) return this.compare(value, clause.lte) <= 0; } /** * Test inc operator. * * @example * ```ts * { * inc: ['foo', 'bar'], * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testInq(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testInq should be an Object, but %v was given.", clause ); if ("inq" in clause && clause.inq !== void 0) { if (!clause.inq || !Array.isArray(clause.inq)) { throw new InvalidOperatorValueError( "inq", "an Array of possible values", clause.inq ); } for (let i = 0; i < clause.inq.length; i++) { if (this.compare(clause.inq[i], value, true) === 0) { return true; } } return false; } } /** * Test nin operator. * * @example * ```ts * { * nin: ['foo', 'bar'], * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testNin(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testNin should be an Object, but %v was given.", clause ); if ("nin" in clause && clause.nin !== void 0) { if (!clause.nin || !Array.isArray(clause.nin)) { throw new InvalidOperatorValueError( "nin", "an Array of possible values", clause.nin ); } return clause.nin.every((element) => { return this.compare(element, value, true) !== 0; }); } } /** * Test between operator. * * @example * ```ts * { * between: [10, 20], * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testBetween(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testBetween should be an Object, but %v was given.", clause ); if ("between" in clause && clause.between !== void 0) { if (!Array.isArray(clause.between) || clause.between.length !== 2) { throw new InvalidOperatorValueError( "between", "an Array of 2 elements", clause.between ); } return this.testGtLt({ gte: clause.between[0] }, value) && this.testGtLt({ lte: clause.between[1] }, value); } } /** * Test exists operator. * * @example * ```ts * { * exists: true, * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testExists(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testExists should be an Object, but %v was given.", clause ); if ("exists" in clause && clause.exists !== void 0) { if (typeof clause.exists !== "boolean") { throw new InvalidOperatorValueError( "exists", "a Boolean", clause.exists ); } return clause.exists ? value !== void 0 : value === void 0; } } /** * Test like operator. * * @example * ```ts * { * like: 'foo', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testLike(clause, value) { if (!clause || typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( "The first argument of OperatorUtils.testLike should be an Object, but %v was given.", clause ); if ("like" in clause && clause.like !== void 0) { if (typeof clause.like !== "string") throw new InvalidOperatorValueError("like", "a String", clause.like); return likeToRegexp(clause.like).test(value); } } /** * Test nlike operator. * * @example * ```ts * { * nlike: 'foo', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testNlike(clause, value) { if (!clause || typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( "The first argument of OperatorUtils.testNlike should be an Object, but %v was given.", clause ); if ("nlike" in clause && clause.nlike !== void 0) { if (typeof clause.nlike !== "string") { throw new InvalidOperatorValueError("nlike", "a String", clause.nlike); } return !likeToRegexp(clause.nlike).test(value); } } /** * Test ilike operator. * * @example * ```ts * { * ilike: 'foo', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testIlike(clause, value) { if (!clause || typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( "The first argument of OperatorUtils.testIlike should be an Object, but %v was given.", clause ); if ("ilike" in clause && clause.ilike !== void 0) { if (typeof clause.ilike !== "string") { throw new InvalidOperatorValueError("ilike", "a String", clause.ilike); } return likeToRegexp(clause.ilike, true).test(value); } } /** * Test nilike operator. * * @example * ```ts * { * nilike: 'foo', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testNilike(clause, value) { if (!clause || typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( "The first argument of OperatorUtils.testNilike should be an Object, but %v was given.", clause ); if ("nilike" in clause && clause.nilike !== void 0) { if (typeof clause.nilike !== "string") { throw new InvalidOperatorValueError( "nilike", "a String", clause.nilike ); } return !likeToRegexp(clause.nilike, true).test(value); } } /** * Test regexp. * * @example * ```ts * { * regexp: 'foo.*', * } * ``` * * @example * ```ts * { * regexp: 'foo.*', * flags: 'i', * } * ``` * * @param {object} clause * @param {*} value * @returns {boolean|undefined} */ testRegexp(clause, value) { if (!clause || typeof clause !== "object") throw new InvalidArgumentError( "The first argument of OperatorUtils.testRegexp should be an Object, but %v was given.", clause ); if ("regexp" in clause && clause.regexp !== void 0) { if (typeof clause.regexp !== "string" && !(clause.regexp instanceof RegExp)) { throw new InvalidOperatorValueError( "regexp", "a String", clause.regexp ); } const flags = clause.flags || void 0; if (flags && typeof flags !== "string") throw new InvalidArgumentError( "RegExp flags should be a String, but %v was given.", clause.flags ); if (!value || typeof value !== "string") return false; const regExp = stringToRegexp(clause.regexp, flags); return !!value.match(regExp); } } }; __name(_OperatorClauseTool, "OperatorClauseTool"); OperatorClauseTool = _OperatorClauseTool; } }); // src/filter/where-clause-tool.js var import_js_service4, _WhereClauseTool, WhereClauseTool; var init_where_clause_tool = __esm({ "src/filter/where-clause-tool.js"() { "use strict"; import_js_service4 = require("@e22m4u/js-service"); init_errors(); init_operator_clause_tool(); init_utils(); _WhereClauseTool = class _WhereClauseTool extends import_js_service4.Service { /** * Filter by where clause. * * @example * ``` * const entities = [ * {foo: 1, bar: 'a'}, * {foo: 2, bar: 'b'}, * {foo: 3, bar: 'b'}, * {foo: 4, bar: 'b'}, * ]; * * const result = filterByWhereClause(entities, { * foo: {gt: 2}, * bar: 'b', * }); * * console.log(result); * // [ * // {foo: 3, bar: 'b'}, * // {foo: 4, bar: 'b'}, * // ]; * * ``` * * @param {object[]} entities * @param {WhereClause|undefined} where * @returns {object[]} */ filter(entities, where = void 0) { if (!Array.isArray(entities)) throw new InvalidArgumentError( "The first argument of WhereClauseTool.filter should be an Array of Object, but %v was given.", entities ); if (where == null) return entities; return entities.filter(this._createFilter(where)); } /** * Create where filter. * * @param {WhereClause} whereClause * @returns {Function} */ _createFilter(whereClause) { if (typeof whereClause !== "object" || Array.isArray(whereClause)) throw new InvalidArgumentError( 'The provided option "where" should be an Object, but %v was given.', whereClause ); const keys = Object.keys(whereClause); return (data) => { if (typeof data !== "object") throw new InvalidArgumentError( "The first argument of WhereClauseTool.filter should be an Array of Object, but %v was given.", data ); return keys.every((key) => { if (key === "and" && key in whereClause) { const andClause = whereClause[key]; if (Array.isArray(andClause)) return andClause.every((clause) => this._createFilter(clause)(data)); } else if (key === "or" && key in whereClause) { const orClause = whereClause[key]; if (Array.isArray(orClause)) return orClause.some((clause) => this._createFilter(clause)(data)); } const value = getValueByPath(data, key); const matcher = whereClause[key]; if (this._test(matcher, value)) return true; }); }; } /** * Value testing. * * @param {*} example * @param {*} value * @returns {boolean} */ _test(example, value) { if (example === value) { return true; } if (example === null) { return value === null; } if (example === void 0) { return value === void 0; } if (example instanceof RegExp) { if (typeof value === "string") { return example.test(value); } if (Array.isArray(value)) { return value.some((el) => typeof el === "string" && example.test(el)); } return false; } if (isPlainObject(example)) { const operatorsTest = this.getService(OperatorClauseTool).testAll( example, value ); if (operatorsTest !== void 0) { if ("neq" in example && Array.isArray(value)) { return !value.some((el) => isDeepEqual(el, example.neq)); } return operatorsTest; } } if (Array.isArray(value)) { const isElementMatched = value.some((el) => isDeepEqual(el, example)); if (isElementMatched) return true; } return isDeepEqual(example, value); } /** * Validate where clause. * * @param {WhereClause|undefined} clause */ static validateWhereClause(clause) { if (clause == null || typeof clause === "function") return; if (typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( 'The provided option "where" should be an Object, but %v was given.', clause ); } }; __name(_WhereClauseTool, "WhereClauseTool"); WhereClauseTool = _WhereClauseTool; } }); // src/definition/model/relations/relation-type.js var RelationType; var init_relation_type = __esm({ "src/definition/model/relations/relation-type.js"() { "use strict"; RelationType = { BELONGS_TO: "belongsTo", HAS_ONE: "hasOne", HAS_MANY: "hasMany", REFERENCES_MANY: "referencesMany" }; } }); // src/definition/model/relations/relation-definition.js var init_relation_definition = __esm({ "src/definition/model/relations/relation-definition.js"() { "use strict"; } }); // src/definition/model/relations/relations-definition-validator.js var import_js_service5, _RelationsDefinitionValidator, RelationsDefinitionValidator; var init_relations_definition_validator = __esm({ "src/definition/model/relations/relations-definition-validator.js"() { "use strict"; import_js_service5 = require("@e22m4u/js-service"); init_relation_type(); init_relation_type(); init_errors(); _RelationsDefinitionValidator = class _RelationsDefinitionValidator extends import_js_service5.Service { /** * Validate. * * @param {string} modelName * @param {object} relDefs */ validate(modelName, relDefs) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The first argument of RelationsDefinitionValidator.validate should be a non-empty String, but %v was given.", modelName ); if (!relDefs || typeof relDefs !== "object" || Array.isArray(relDefs)) throw new InvalidArgumentError( 'The provided option "relations" of the model %v should be an Object, but %v was given.', modelName, relDefs ); const relNames = Object.keys(relDefs); relNames.forEach((relName) => { const relDef = relDefs[relName]; this._validateRelation(modelName, relName, relDef); }); } /** * Validate relation. * * @param {string} modelName * @param {string} relName * @param {object} relDef */ _validateRelation(modelName, relName, relDef) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The first argument of RelationsDefinitionValidator._validateRelation should be a non-empty String, but %v was given.", modelName ); if (!relName || typeof relName !== "string") throw new InvalidArgumentError( "The relation name of the model %v should be a non-empty String, but %v was given.", modelName, relName ); if (!relDef || typeof relDef !== "object" || Array.isArray(relDef)) throw new InvalidArgumentError( "The relation %v of the model %v should be an Object, but %v was given.", relName, modelName, relDef ); if (!relDef.type || !Object.values(RelationType).includes(relDef.type)) throw new InvalidArgumentError( 'The relation %v of the model %v requires the option "type" to have one of relation types: %l, but %v was given.', relName, modelName, Object.values(RelationType), relDef.type ); this._validateBelongsTo(modelName, relName, relDef); this._validateHasOne(modelName, relName, relDef); this._validateHasMany(modelName, relName, relDef); this._validateReferencesMany(modelName, relName, relDef); } /** * Validate "belongsTo". * * @example The regular "belongsTo" relation. * ``` * { * type: RelationType.BELONGS_TO, * model: 'model', * foreignKey: 'modelId', // optional * } * ``` * * @example The polymorphic "belongsTo" relation. * ``` * { * type: RelationType.BELONGS_TO, * polymorphic: true, * foreignKey: 'referenceId', // optional * discriminator: 'referenceType', // optional * } * ``` * * @param {string} modelName * @param {string} relName * @param {object} relDef * @private */ _validateBelongsTo(modelName, relName, relDef) { if (relDef.type !== RelationType.BELONGS_TO) return; if (relDef.polymorphic) { if (typeof relDef.polymorphic !== "boolean") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "belongsTo", so it expects the option "polymorphic" to be a Boolean, but %v was given.', relName, modelName, relDef.polymorphic ); if (relDef.foreignKey && typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "belongsTo" relation, so it expects the provided option "foreignKey" to be a String, but %v was given.', relName, modelName, relDef.foreignKey ); if (relDef.discriminator && typeof relDef.discriminator !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "belongsTo" relation, so it expects the provided option "discriminator" to be a String, but %v was given.', relName, modelName, relDef.discriminator ); } else { if (!relDef.model || typeof relDef.model !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "belongsTo", so it requires the option "model" to be a non-empty String, but %v was given.', relName, modelName, relDef.model ); if (relDef.foreignKey && typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "belongsTo", so it expects the provided option "foreignKey" to be a String, but %v was given.', relName, modelName, relDef.foreignKey ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v is a non-polymorphic "belongsTo" relation, so it should not have the option "discriminator" to be provided.', relName, modelName ); } } /** * Validate "hasOne". * * @example The regular "hasOne" relation. * ``` * { * type: RelationType.HAS_ONE, * model: 'model', * foreignKey: 'modelId', * } * ``` * * @example The polymorphic "hasOne" relation with a target relation name. * ``` * { * type: RelationType.HAS_ONE, * model: 'model', * polymorphic: 'reference', * } * ``` * * @example The polymorphic "hasOne" relation with target relation keys. * ``` * { * type: RelationType.HAS_ONE, * model: 'model', * polymorphic: true, * foreignKey: 'referenceId', * discriminator: 'referenceType', * } * ``` * * @param {string} modelName * @param {string} relName * @param {object} relDef * @private */ _validateHasOne(modelName, relName, relDef) { if (relDef.type !== RelationType.HAS_ONE) return; if (!relDef.model || typeof relDef.model !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasOne", so it requires the option "model" to be a non-empty String, but %v was given.', relName, modelName, relDef.model ); if (relDef.polymorphic) { if (typeof relDef.polymorphic === "string") { if (relDef.foreignKey) throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with a String value, so it should not have the option "foreignKey" to be provided.', relName, modelName ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with a String value, so it should not have the option "discriminator" to be provided.', relName, modelName ); } else if (typeof relDef.polymorphic === "boolean") { if (!relDef.foreignKey || typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with "true" value, so it requires the option "foreignKey" to be a non-empty String, but %v was given.', relName, modelName, relDef.foreignKey ); if (!relDef.discriminator || typeof relDef.discriminator !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with "true" value, so it requires the option "discriminator" to be a non-empty String, but %v was given.', relName, modelName, relDef.discriminator ); } else { throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasOne", so it expects the provided option "polymorphic" to be a String or a Boolean, but %v was given.', relName, modelName, relDef.polymorphic ); } } else { if (!relDef.foreignKey || typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasOne", so it requires the option "foreignKey" to be a non-empty String, but %v was given.', relName, modelName, relDef.foreignKey ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v is a non-polymorphic "hasOne" relation, so it should not have the option "discriminator" to be provided.', relName, modelName ); } } /** * Validate "hasMany". * * @example The regular "hasMany" relation. * ``` * { * type: RelationType.HAS_MANY, * model: 'model', * foreignKey: 'modelId', * } * ``` * * @example The polymorphic "hasMany" relation with a target relation name. * ``` * { * type: RelationType.HAS_MANY, * model: 'model', * polymorphic: 'reference', * } * ``` * * @example The polymorphic "hasMany" relation with target relation keys. * ``` * { * type: RelationType.HAS_MANY, * model: 'model', * polymorphic: true, * foreignKey: 'referenceId', * discriminator: 'referenceType', * } * ``` * * @param {string} modelName * @param {string} relName * @param {object} relDef * @private */ _validateHasMany(modelName, relName, relDef) { if (relDef.type !== RelationType.HAS_MANY) return; if (!relDef.model || typeof relDef.model !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasMany", so it requires the option "model" to be a non-empty String, but %v was given.', relName, modelName, relDef.model ); if (relDef.polymorphic) { if (typeof relDef.polymorphic === "string") { if (relDef.foreignKey) throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with a String value, so it should not have the option "foreignKey" to be provided.', relName, modelName ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with a String value, so it should not have the option "discriminator" to be provided.', relName, modelName ); } else if (typeof relDef.polymorphic === "boolean") { if (!relDef.foreignKey || typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with "true" value, so it requires the option "foreignKey" to be a non-empty String, but %v was given.', relName, modelName, relDef.foreignKey ); if (!relDef.discriminator || typeof relDef.discriminator !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the option "polymorphic" with "true" value, so it requires the option "discriminator" to be a non-empty String, but %v was given.', relName, modelName, relDef.discriminator ); } else { throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasMany", so it expects the provided option "polymorphic" to be a String or a Boolean, but %v was given.', relName, modelName, relDef.polymorphic ); } } else { if (!relDef.foreignKey || typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "hasMany", so it requires the option "foreignKey" to be a non-empty String, but %v was given.', relName, modelName, relDef.foreignKey ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v is a non-polymorphic "hasMany" relation, so it should not have the option "discriminator" to be provided.', relName, modelName ); } } /** * Validate "referencesMany". * * @example * ``` * { * type: RelationType.REFERENCES_MANY, * model: 'model', * foreignKey: 'modelIds', // optional * } * ``` * * @param {string} modelName * @param {string} relName * @param {object} relDef * @private */ _validateReferencesMany(modelName, relName, relDef) { if (relDef.type !== RelationType.REFERENCES_MANY) return; if (!relDef.model || typeof relDef.model !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "referencesMany", so it requires the option "model" to be a non-empty String, but %v was given.', relName, modelName, relDef.model ); if (relDef.foreignKey && typeof relDef.foreignKey !== "string") throw new InvalidArgumentError( 'The relation %v of the model %v has the type "referencesMany", so it expects the provided option "foreignKey" to be a String, but %v was given.', relName, modelName, relDef.foreignKey ); if (relDef.discriminator) throw new InvalidArgumentError( 'The relation %v of the model %v has the type "referencesMany", so it should not have the option "discriminator" to be provided.', relName, modelName ); } }; __name(_RelationsDefinitionValidator, "RelationsDefinitionValidator"); RelationsDefinitionValidator = _RelationsDefinitionValidator; } }); // src/definition/model/relations/index.js var init_relations = __esm({ "src/definition/model/relations/index.js"() { "use strict"; init_relation_type(); init_relation_definition(); init_relations_definition_validator(); } }); // src/definition/model/properties/data-type.js var DataType; var init_data_type = __esm({ "src/definition/model/properties/data-type.js"() { "use strict"; DataType = { ANY: "any", STRING: "string", NUMBER: "number", BOOLEAN: "boolean", ARRAY: "array", OBJECT: "object" }; } }); // src/definition/model/properties/property-definition.js var init_property_definition = __esm({ "src/definition/model/properties/property-definition.js"() { "use strict"; } }); // src/definition/model/properties/property-uniqueness.js var PropertyUniqueness; var init_property_uniqueness = __esm({ "src/definition/model/properties/property-uniqueness.js"() { "use strict"; PropertyUniqueness = { STRICT: "strict", SPARSE: "sparse", NON_UNIQUE: "nonUnique" }; } }); // src/definition/definition-registry.js var import_js_service6, _DefinitionRegistry, DefinitionRegistry; var init_definition_registry = __esm({ "src/definition/definition-registry.js"() { "use strict"; import_js_service6 = require("@e22m4u/js-service"); init_utils(); init_errors(); init_model(); init_definition(); _DefinitionRegistry = class _DefinitionRegistry extends import_js_service6.Service { /** * Datasources. * * @type {object} */ _datasources = {}; /** * Models. * * @type {object} */ _models = {}; /** * Add datasource. * * @param {object} datasourceDef */ addDatasource(datasourceDef) { this.getService(DatasourceDefinitionValidator).validate(datasourceDef); const name = datasourceDef.name; if (name in this._datasources) throw new InvalidArgumentError( "The datasource %v is already defined.", name ); this._datasources[name] = datasourceDef; } /** * Has datasource. * * @param {string} name * @returns {boolean} */ hasDatasource(name) { return Boolean(this._datasources[name]); } /** * Get datasource. * * @param {string} name * @returns {object} */ getDatasource(name) { const datasourceDef = this._datasources[name]; if (!datasourceDef) throw new InvalidArgumentError("The datasource %v is not defined.", name); return datasourceDef; } /** * Add model. * * @param {object} modelDef */ addModel(modelDef) { this.getService(ModelDefinitionValidator).validate(modelDef); const modelKey = modelNameToModelKey(modelDef.name); if (modelKey in this._models) throw new InvalidArgumentError( "The model %v is already defined.", modelDef.name ); this._models[modelKey] = modelDef; } /** * Has model. * * @param {string} name * @returns {boolean} */ hasModel(name) { const modelKey = modelNameToModelKey(name); return Boolean(this._models[modelKey]); } /** * Get model. * * @param {string} name * @returns {object} */ getModel(name) { const modelKey = modelNameToModelKey(name); const modelDef = this._models[modelKey]; if (!modelDef) throw new InvalidArgumentError("The model %v is not defined.", name); return modelDef; } }; __name(_DefinitionRegistry, "DefinitionRegistry"); DefinitionRegistry = _DefinitionRegistry; } }); // src/definition/model/model-definition-utils.js var import_js_service7, import_js_empty_values, DEFAULT_PRIMARY_KEY_PROPERTY_NAME, _ModelDefinitionUtils, ModelDefinitionUtils; var init_model_definition_utils = __esm({ "src/definition/model/model-definition-utils.js"() { "use strict"; import_js_service7 = require("@e22m4u/js-service"); init_properties(); init_utils(); init_utils(); import_js_empty_values = require("@e22m4u/js-empty-values"); init_errors(); init_definition_registry(); DEFAULT_PRIMARY_KEY_PROPERTY_NAME = "id"; _ModelDefinitionUtils = class _ModelDefinitionUtils extends import_js_service7.Service { /** * Get primary key as property name. * * @param {string} modelName * @returns {string} */ getPrimaryKeyAsPropertyName(modelName) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propNames = Object.keys(propDefs).filter((propName) => { const propDef = propDefs[propName]; return propDef && typeof propDef === "object" && propDef.primaryKey; }); if (propNames.length < 1) { const isDefaultPrimaryKeyAlreadyInUse = Object.keys(propDefs).includes( DEFAULT_PRIMARY_KEY_PROPERTY_NAME ); if (isDefaultPrimaryKeyAlreadyInUse) throw new InvalidArgumentError( 'The property name %v of the model %v is defined as a regular property. In this case, a primary key should be defined explicitly. Do use the option "primaryKey" to specify the primary key.', DEFAULT_PRIMARY_KEY_PROPERTY_NAME, modelName ); return DEFAULT_PRIMARY_KEY_PROPERTY_NAME; } return propNames[0]; } /** * Get primary key as column name. * * @param {string} modelName * @returns {string} */ getPrimaryKeyAsColumnName(modelName) { const pkPropName = this.getPrimaryKeyAsPropertyName(modelName); let pkColName; try { pkColName = this.getColumnNameByPropertyName(modelName, pkPropName); } catch (error) { if (!(error instanceof InvalidArgumentError)) throw error; } if (pkColName === void 0) return pkPropName; return pkColName; } /** * Get table name by model name. * * @param {string} modelName * @returns {string} */ getTableNameByModelName(modelName) { var _a; const modelDef = this.getService(DefinitionRegistry).getModel(modelName); return (_a = modelDef.tableName) != null ? _a : modelName; } /** * Get column name by property name. * * @param {string} modelName * @param {string} propertyName * @returns {string} */ getColumnNameByPropertyName(modelName, propertyName) { var _a; const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propDef = propDefs[propertyName]; if (!propDef) throw new InvalidArgumentError( "The model %v does not have the property %v.", modelName, propertyName ); if (propDef && typeof propDef === "object") return (_a = propDef.columnName) != null ? _a : propertyName; return propertyName; } /** * Get default property value. * * @param {string} modelName * @param {string} propertyName * @returns {*} */ getDefaultPropertyValue(modelName, propertyName) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propDef = propDefs[propertyName]; if (!propDef) throw new InvalidArgumentError( "The model %v does not have the property %v.", modelName, propertyName ); if (propDef && typeof propDef === "object") return propDef.default instanceof Function ? propDef.default() : propDef.default; } /** * Set default values for empty properties. * * @param {string} modelName * @param {object} modelData * @param {boolean|undefined} onlyProvidedProperties * @returns {object} */ setDefaultValuesToEmptyProperties(modelName, modelData, onlyProvidedProperties = false) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propNames = onlyProvidedProperties ? Object.keys(modelData) : Object.keys(propDefs); const extendedData = cloneDeep(modelData); const emptyValuesService = this.getService(import_js_empty_values.EmptyValuesService); propNames.forEach((propName) => { const propDef = propDefs[propName]; const propValue = extendedData[propName]; const propType = propDef != null ? this.getDataTypeFromPropertyDefinition(propDef) : DataType.ANY; const isEmpty = emptyValuesService.isEmptyByType(propType, propValue); if (!isEmpty) return; if (propDef && typeof propDef === "object" && propDef.default !== void 0) { extendedData[propName] = this.getDefaultPropertyValue( modelName, propName ); } }); return extendedData; } /** * Convert property names to column names. * * @param {string} modelName * @param {object} modelData * @returns {object} */ convertPropertyNamesToColumnNames(modelName, modelData) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propNames = Object.keys(propDefs); const convertedData = cloneDeep(modelData); propNames.forEach((propName) => { if (!(propName in convertedData)) return; const colName = this.getColumnNameByPropertyName(modelName, propName); let propValue = convertedData[propName]; const propDef = propDefs[propName]; if (propValue !== null && typeof propValue === "object" && !Array.isArray(propValue) && propDef !== null && typeof propDef === "object" && propDef.type === DataType.OBJECT && propDef.model) { propValue = this.convertPropertyNamesToColumnNames( propDef.model, propValue ); } if (Array.isArray(propValue) && propDef !== null && typeof propDef === "object" && propDef.type === DataType.ARRAY && propDef.itemModel) { propValue = propValue.map((el) => { return el !== null && typeof el === "object" && !Array.isArray(el) ? this.convertPropertyNamesToColumnNames(propDef.itemModel, el) : el; }); } delete convertedData[propName]; convertedData[colName] = propValue; }); return convertedData; } /** * Convert column names to property names. * * @param {string} modelName * @param {object} tableData * @returns {object} */ convertColumnNamesToPropertyNames(modelName, tableData) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propNames = Object.keys(propDefs); const convertedData = cloneDeep(tableData); propNames.forEach((propName) => { const colName = this.getColumnNameByPropertyName(modelName, propName); if (!(colName in convertedData)) return; let colValue = convertedData[colName]; const propDef = propDefs[propName]; if (colValue !== null && typeof colValue === "object" && !Array.isArray(colValue) && propDef !== null && typeof propDef === "object" && propDef.type === DataType.OBJECT && propDef.model) { colValue = this.convertColumnNamesToPropertyNames( propDef.model, colValue ); } if (Array.isArray(colValue) && propDef !== null && typeof propDef === "object" && propDef.type === DataType.ARRAY && propDef.itemModel) { colValue = colValue.map((el) => { return el !== null && typeof el === "object" && !Array.isArray(el) ? this.convertColumnNamesToPropertyNames(propDef.itemModel, el) : el; }); } delete convertedData[colName]; convertedData[propName] = colValue; }); return convertedData; } /** * Get data type by property name. * * @param {string} modelName * @param {string} propertyName * @returns {string} */ getDataTypeByPropertyName(modelName, propertyName) { const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propDef = propDefs[propertyName]; if (!propDef) { const pkPropName = this.getPrimaryKeyAsPropertyName(modelName); if (pkPropName === propertyName) return DataType.ANY; throw new InvalidArgumentError( "The model %v does not have the property %v.", modelName, propertyName ); } if (typeof propDef === "string") return propDef; return propDef.type; } /** * Get data type from property definition. * * @param {object} propDef * @returns {string} */ getDataTypeFromPropertyDefinition(propDef) { if ((!propDef || typeof propDef !== "object") && !Object.values(DataType).includes(propDef)) { throw new InvalidArgumentError( 'The argument "propDef" of the ModelDefinitionUtils.getDataTypeFromPropertyDefinition should be an Object or the DataType enum, but %v was given.', propDef ); } if (typeof propDef === "string") return propDef; const dataType = propDef.type; if (!Object.values(DataType).includes(dataType)) throw new InvalidArgumentError( 'The given Object to the ModelDefinitionUtils.getDataTypeFromPropertyDefinition should have the "type" property with one of values: %l, but %v was given.', Object.values(DataType), propDef.type ); return dataType; } /** * Get own properties definition of primary keys. * * @param {string} modelName * @returns {object} */ getOwnPropertiesDefinitionOfPrimaryKeys(modelName) { var _a; const modelDef = this.getService(DefinitionRegistry).getModel(modelName); const propDefs = (_a = modelDef.properties) != null ? _a : {}; const pkPropNames = Object.keys(propDefs).filter((propName) => { const propDef = propDefs[propName]; return typeof propDef === "object" && propDef.primaryKey; }); return pkPropNames.reduce((a, k) => ({ ...a, [k]: propDefs[k] }), {}); } /** * Get own properties definition without primary keys. * * @param {string} modelName * @returns {object} */ getOwnPropertiesDefinitionWithoutPrimaryKeys(modelName) { var _a; const modelDef = this.getService(DefinitionRegistry).getModel(modelName); const propDefs = (_a = modelDef.properties) != null ? _a : {}; return Object.keys(propDefs).reduce((result, propName) => { const propDef = propDefs[propName]; if (typeof propDef === "object" && propDef.primaryKey) return result; return { ...result, [propName]: propDef }; }, {}); } /** * Get properties definition in base model hierarchy. * * @param {string} modelName * @returns {object} */ getPropertiesDefinitionInBaseModelHierarchy(modelName) { let pkPropDefs = {}; let regularPropDefs = {}; const recursion = /* @__PURE__ */ __name((currModelName, prevModelName = void 0) => { if (currModelName === prevModelName) throw new InvalidArgumentError( "The model %v has a circular inheritance.", currModelName ); if (Object.keys(pkPropDefs).length === 0) pkPropDefs = this.getOwnPropertiesDefinitionOfPrimaryKeys(currModelName); regularPropDefs = { ...this.getOwnPropertiesDefinitionWithoutPrimaryKeys(currModelName), ...regularPropDefs }; const modelDef = this.getService(DefinitionRegistry).getModel(currModelName); if (modelDef.base) recursion(modelDef.base, currModelName); }, "recursion"); recursion(modelName); return { ...pkPropDefs, ...regularPropDefs }; } /** * Get own relations definition. * * @param {string} modelName * @returns {object} */ getOwnRelationsDefinition(modelName) { var _a; const modelDef = this.getService(DefinitionRegistry).getModel(modelName); return (_a = modelDef.relations) != null ? _a : {}; } /** * Get relations definition in base model hierarchy. * * @param {string} modelName * @returns {object} */ getRelationsDefinitionInBaseModelHierarchy(modelName) { let result = {}; const recursion = /* @__PURE__ */ __name((currModelName, prevModelName = void 0) => { var _a; if (currModelName === prevModelName) throw new InvalidArgumentError( "The model %v has a circular inheritance.", currModelName ); const modelDef = this.getService(DefinitionRegistry).getModel(currModelName); const ownRelDefs = (_a = modelDef.relations) != null ? _a : {}; result = { ...ownRelDefs, ...result }; if (modelDef.base) recursion(modelDef.base, currModelName); }, "recursion"); recursion(modelName); return result; } /** * Get relation definition by name. * * @param {string} modelName * @param {string} relationName * @returns {object} */ getRelationDefinitionByName(modelName, relationName) { const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName); const relNames = Object.keys(relDefs); let foundDef; for (const relName of relNames) { if (relName === relationName) { foundDef = relDefs[relName]; break; } } if (!foundDef) throw new InvalidArgumentError( "The model %v does not have relation name %v.", modelName, relationName ); return foundDef; } /** * Exclude object keys by relation names. * * @param {string} modelName * @param {object} modelData * @returns {object} */ excludeObjectKeysByRelationNames(modelName, modelData) { if (!modelData || typeof modelData !== "object" || Array.isArray(modelData)) throw new InvalidArgumentError( "The second argument of ModelDefinitionUtils.excludeObjectKeysByRelationNames should be an Object, but %v was given.", modelData ); const relDefs = this.getRelationsDefinitionInBaseModelHierarchy(modelName); const relNames = Object.keys(relDefs); return excludeObjectKeys(modelData, relNames); } /** * Get model name of property value if defined. * * @param {string} modelName * @param {string} propertyName * @returns {string|undefined} */ getModelNameOfPropertyValueIfDefined(modelName, propertyName) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( 'Parameter "modelName" of ModelDefinitionUtils.getModelNameOfPropertyValueIfDefined requires a non-empty String, but %v was given.', modelName ); if (!propertyName || typeof propertyName !== "string") throw new InvalidArgumentError( 'Parameter "propertyName" of ModelDefinitionUtils.getModelNameOfPropertyValueIfDefined requires a non-empty String, but %v was given.', propertyName ); const propDefs = this.getPropertiesDefinitionInBaseModelHierarchy(modelName); const propDef = propDefs[propertyName]; if (!propDef) return void 0; if (propDef && typeof propDef === "object") { if (propDef.type === DataType.OBJECT) return propDef.model || void 0; if (propDef.type === DataType.ARRAY) return propDef.itemModel || void 0; } return void 0; } }; __name(_ModelDefinitionUtils, "ModelDefinitionUtils"); ModelDefinitionUtils = _ModelDefinitionUtils; } }); // src/definition/model/properties/property-uniqueness-validator.js var import_js_service8, import_js_empty_values2, _PropertyUniquenessValidator, PropertyUniquenessValidator; var init_property_uniqueness_validator = __esm({ "src/definition/model/properties/property-uniqueness-validator.js"() { "use strict"; init_data_type(); import_js_service8 = require("@e22m4u/js-service"); init_utils(); import_js_empty_values2 = require("@e22m4u/js-empty-values"); init_property_uniqueness(); init_errors(); init_model_definition_utils(); _PropertyUniquenessValidator = class _PropertyUniquenessValidator extends import_js_service8.Service { /** * Validate. * * @param {Function} countMethod * @param {string} methodName * @param {string} modelName * @param {object} modelData * @param {*} modelId * @returns {Promise} */ async validate(countMethod, methodName, modelName, modelData, modelId = void 0) { if (typeof countMethod !== "function") throw new InvalidArgumentError( 'The parameter "countMethod" of the PropertyUniquenessValidator must be a Function, but %v was given.', countMethod ); if (!methodName || typeof methodName !== "string") throw new InvalidArgumentError( 'The parameter "methodName" of the PropertyUniquenessValidator must be a non-empty String, but %v was given.', methodName ); if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( 'The parameter "modelName" of the PropertyUniquenessValidator must be a non-empty String, but %v was given.', modelName ); if (!isPlainObject(modelData)) throw new InvalidArgumentError( "The data of the model %v should be an Object, but %v was given.", modelName, modelData ); const propDefs = this.getService( ModelDefinitionUtils ).getPropertiesDefinitionInBaseModelHierarchy(modelName); const isPartial = methodName === "patch" || methodName === "patchById"; const propNames = Object.keys(isPartial ? modelData : propDefs); const idProp = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); const createError = /* @__PURE__ */ __name((propName, propValue) => new InvalidArgumentError( "An existing document of the model %v already has the property %v with the value %v and should be unique.", modelName, propName, propValue ), "createError"); let willBeReplaced = void 0; const emptyValuesService = this.getService(import_js_empty_values2.EmptyValuesService); for (const propName of propNames) { const propDef = propDefs[propName]; if (!propDef || typeof propDef === "string" || !propDef.unique || propDef.unique === PropertyUniqueness.NON_UNIQUE) { continue; } const propValue = modelData[propName]; if (propDef.unique === PropertyUniqueness.SPARSE) { const propType = propDef.type || DataType.ANY; const isEmpty = emptyValuesService.isEmptyByType(propType, propValue); if (isEmpty) continue; } if (methodName === "create") { const count = await countMethod({ [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } else if (methodName === "replaceById") { const count = await countMethod({ [idProp]: { neq: modelId }, [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } else if (methodName === "replaceOrCreate") { const idFromData = modelData[idProp]; if (willBeReplaced == null && idFromData != null) { const count = await countMethod({ [idProp]: idFromData }); willBeReplaced = count > 0; } if (willBeReplaced) { const count = await countMethod({ [idProp]: { neq: idFromData }, [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } else { const count = await countMethod({ [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } } else if (methodName === "patch") { const count = await countMethod({ [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } else if (methodName === "patchById") { const count = await countMethod({ [idProp]: { neq: modelId }, [propName]: propValue }); if (count > 0) throw createError(propName, propValue); } else { throw new InvalidArgumentError( "The PropertyUniquenessValidator does not support the adapter method %v.", methodName ); } } } }; __name(_PropertyUniquenessValidator, "PropertyUniquenessValidator"); PropertyUniquenessValidator = _PropertyUniquenessValidator; } }); // src/definition/model/properties/primary-keys-definition-validator.js var import_js_service9, _PrimaryKeysDefinitionValidator, PrimaryKeysDefinitionValidator; var init_primary_keys_definition_validator = __esm({ "src/definition/model/properties/primary-keys-definition-validator.js"() { "use strict"; import_js_service9 = require("@e22m4u/js-service"); init_errors(); init_model_definition_utils(); _PrimaryKeysDefinitionValidator = class _PrimaryKeysDefinitionValidator extends import_js_service9.Service { /** * Validate. * * @param {string} modelName * @param {object} propDefs */ validate(modelName, propDefs) { const propNames = Object.keys(propDefs).filter((propName) => { const propDef = propDefs[propName]; return propDef && typeof propDef === "object" && propDef.primaryKey; }); if (propNames.length < 1) { const isDefaultPrimaryKeyAlreadyInUse = Object.keys(propDefs).includes(DEFAULT_PRIMARY_KEY_PROPERTY_NAME); if (isDefaultPrimaryKeyAlreadyInUse) throw new InvalidArgumentError( 'The property name %v of the model %v is defined as a regular property. In this case, a primary key should be defined explicitly. Do use the option "primaryKey" to specify the primary key.', DEFAULT_PRIMARY_KEY_PROPERTY_NAME, modelName ); return; } if (propNames.length > 1) throw new InvalidArgumentError( "The model definition %v should not have multiple primary keys, but %v keys given.", modelName, propNames.length ); const pkPropName = propNames[0]; const pkPropDef = propDefs[pkPropName]; if (pkPropDef && typeof pkPropDef === "object" && pkPropDef.default !== void 0) { throw new InvalidArgumentError( "Do not specify a default value for the primary key %v of the model %v.", pkPropName, modelName ); } } }; __name(_PrimaryKeysDefinitionValidator, "PrimaryKeysDefinitionValidator"); PrimaryKeysDefinitionValidator = _PrimaryKeysDefinitionValidator; } }); // src/definition/model/properties/properties-definition-validator.js var import_js_service10, _PropertiesDefinitionValidator, PropertiesDefinitionValidator; var init_properties_definition_validator = __esm({ "src/definition/model/properties/properties-definition-validator.js"() { "use strict"; import_js_service10 = require("@e22m4u/js-service"); init_data_type(); init_utils(); init_property_uniqueness(); init_errors(); init_primary_keys_definition_validator(); _PropertiesDefinitionValidator = class _PropertiesDefinitionValidator extends import_js_service10.Service { /** * Validate. * * @param {string} modelName * @param {object} propDefs */ validate(modelName, propDefs) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The first argument of PropertiesDefinitionValidator.validate should be a non-empty String, but %v was given.", modelName ); if (!propDefs || typeof propDefs !== "object" || Array.isArray(propDefs)) { throw new InvalidArgumentError( 'The provided option "properties" of the model %v should be an Object, but %v was given.', modelName, propDefs ); } const propNames = Object.keys(propDefs); propNames.forEach((propName) => { const propDef = propDefs[propName]; this._validateProperty(modelName, propName, propDef); }); this.getService(PrimaryKeysDefinitionValidator).validate( modelName, propDefs ); } /** * Validate property. * * @param {string} modelName * @param {string} propName * @param {object} propDef */ _validateProperty(modelName, propName, propDef) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The first argument of PropertiesDefinitionValidator._validateProperty should be a non-empty String, but %v was given.", modelName ); if (!propName || typeof propName !== "string") throw new InvalidArgumentError( "The property name of the model %v should be a non-empty String, but %v was given.", modelName, propName ); if (!propDef) throw new InvalidArgumentError( "The property %v of the model %v should have a property definition, but %v was given.", propName, modelName, propDef ); if (typeof propDef === "string") { if (!Object.values(DataType).includes(propDef)) throw new InvalidArgumentError( "In case of a short property definition, the property %v of the model %v should have one of data types: %l, but %v was given.", propName, modelName, Object.values(DataType), propDef ); return; } if (!propDef || typeof propDef !== "object" || Array.isArray(propDef)) { throw new InvalidArgumentError( "In case of a full property definition, the property %v of the model %v should be an Object, but %v was given.", propName, modelName, propDef ); } if (!propDef.type || !Object.values(DataType).includes(propDef.type)) throw new InvalidArgumentError( 'The property %v of the model %v requires the option "type" to have one of data types: %l, but %v was given.', propName, modelName, Object.values(DataType), propDef.type ); if (propDef.itemType && !Object.values(DataType).includes(propDef.itemType)) { throw new InvalidArgumentError( 'The provided option "itemType" of the property %v in the model %v should have one of data types: %l, but %v was given.', propName, modelName, Object.values(DataType), propDef.itemType ); } if (propDef.itemModel && typeof propDef.itemModel !== "string") { throw new InvalidArgumentError( 'The provided option "itemModel" of the property %v in the model %v should be a String, but %v was given.', propName, modelName, propDef.itemModel ); } if (propDef.model && typeof propDef.model !== "string") throw new InvalidArgumentError( 'The provided option "model" of the property %v in the model %v should be a String, but %v was given.', propName, modelName, propDef.model ); if (propDef.primaryKey && typeof propDef.primaryKey !== "boolean") throw new InvalidArgumentError( 'The provided option "primaryKey" of the property %v in the model %v should be a Boolean, but %v was given.', propName, modelName, propDef.primaryKey ); if (propDef.columnName && typeof propDef.columnName !== "string") throw new InvalidArgumentError( 'The provided option "columnName" of the property %v in the model %v should be a String, but %v was given.', propName, modelName, propDef.columnName ); if (propDef.columnType && typeof propDef.columnType !== "string") throw new InvalidArgumentError( 'The provided option "columnType" of the property %v in the model %v should be a String, but %v was given.', propName, modelName, propDef.columnType ); if (propDef.required && typeof propDef.required !== "boolean") throw new InvalidArgumentError( 'The provided option "required" of the property %v in the model %v should be a Boolean, but %v was given.', propName, modelName, propDef.required ); if (propDef.required && propDef.default !== void 0) throw new InvalidArgumentError( 'The property %v of the model %v is a required property, so it should not have the option "default" to be provided.', propName, modelName ); if (propDef.primaryKey && propDef.required) throw new InvalidArgumentError( 'The property %v of the model %v is a primary key, so it should not have the option "required" to be provided.', propName, modelName ); if (propDef.primaryKey && propDef.default !== void 0) throw new InvalidArgumentError( 'The property %v of the model %v is a primary key, so it should not have the option "default" to be provided.', propName, modelName ); if (propDef.itemType && propDef.type !== DataType.ARRAY) throw new InvalidArgumentError( 'The property %v of the model %v has a non-array type, so it should not have the option "itemType" to be provided.', propName, modelName, propDef.type ); if (propDef.itemModel && propDef.type !== DataType.ARRAY) throw new InvalidArgumentError( 'The option "itemModel" is not supported for %s property type, so the property %v of the model %v should not have the option "itemModel" to be provided.', capitalize(propDef.type), propName, modelName ); if (propDef.itemModel && propDef.itemType !== DataType.OBJECT) { if (propDef.itemType) { throw new InvalidArgumentError( 'The provided option "itemModel" requires the option "itemType" to be explicitly set to Object, but the property %v of the model %v has specified item type as %s.', propName, modelName, capitalize(propDef.itemType) ); } else { throw new InvalidArgumentError( 'The provided option "itemModel" requires the option "itemType" to be explicitly set to Object, but the property %v of the model %v does not have specified item type.', propName, modelName ); } } if (propDef.model && propDef.type !== DataType.OBJECT) throw new InvalidArgumentError( 'The option "model" is not supported for %s property type, so the property %v of the model %v should not have the option "model" to be provided.', capitalize(propDef.type), propName, modelName ); if (propDef.unique) { if (typeof propDef.unique !== "boolean" && !Object.values(PropertyUniqueness).includes(propDef.unique)) { throw new InvalidArgumentError( 'The provided option "unique" of the property %v in the model %v should be a Boolean or one of values: %l, but %v was given.', propName, modelName, Object.values(PropertyUniqueness), propDef.unique ); } } if (propDef.unique && propDef.primaryKey) throw new InvalidArgumentError( 'The property %v of the model %v is a primary key, so it should not have the option "unique" to be provided.', propName, modelName ); } }; __name(_PropertiesDefinitionValidator, "PropertiesDefinitionValidator"); PropertiesDefinitionValidator = _PropertiesDefinitionValidator; } }); // src/definition/model/properties/index.js var init_properties = __esm({ "src/definition/model/properties/index.js"() { "use strict"; init_data_type(); init_property_definition(); init_property_uniqueness(); init_property_uniqueness_validator(); init_properties_definition_validator(); init_primary_keys_definition_validator(); } }); // src/definition/model/model-definition.js var init_model_definition = __esm({ "src/definition/model/model-definition.js"() { "use strict"; } }); // src/definition/model/model-data-sanitizer.js var import_js_service11, _ModelDataSanitizer, ModelDataSanitizer; var init_model_data_sanitizer = __esm({ "src/definition/model/model-data-sanitizer.js"() { "use strict"; import_js_service11 = require("@e22m4u/js-service"); init_errors(); init_model_definition_utils(); _ModelDataSanitizer = class _ModelDataSanitizer extends import_js_service11.Service { /** * Validate. * * @param {string} modelName * @param {object} modelData * @returns {object} */ sanitize(modelName, modelData) { if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The first argument of ModelDataSanitizer.sanitize should be a string, but %v was given.", modelName ); if (!modelData || typeof modelData !== "object") throw new InvalidArgumentError( "The second argument of ModelDataSanitizer.sanitize should be an Object, but %v was given.", modelData ); return this.getService( ModelDefinitionUtils ).excludeObjectKeysByRelationNames(modelName, modelData); } }; __name(_ModelDataSanitizer, "ModelDataSanitizer"); ModelDataSanitizer = _ModelDataSanitizer; } }); // src/definition/model/model-definition-validator.js var import_js_service12, _ModelDefinitionValidator, ModelDefinitionValidator; var init_model_definition_validator = __esm({ "src/definition/model/model-definition-validator.js"() { "use strict"; import_js_service12 = require("@e22m4u/js-service"); init_errors(); init_relations(); init_properties(); _ModelDefinitionValidator = class _ModelDefinitionValidator extends import_js_service12.Service { /** * Validate. * * @param {object} modelDef */ validate(modelDef) { if (!modelDef || typeof modelDef !== "object" || Array.isArray(modelDef)) throw new InvalidArgumentError( "The model definition should be an Object, but %v was given.", modelDef ); if (!modelDef.name || typeof modelDef.name !== "string") throw new InvalidArgumentError( 'The model definition requires the option "name" as a non-empty String, but %v was given.', modelDef.name ); if (modelDef.datasource && typeof modelDef.datasource !== "string") throw new InvalidArgumentError( 'The provided option "datasource" of the model %v should be a String, but %v was given.', modelDef.name, modelDef.datasource ); if (modelDef.base && typeof modelDef.base !== "string") throw new InvalidArgumentError( 'The provided option "base" of the model %v should be a String, but %v was given.', modelDef.name, modelDef.base ); if (modelDef.tableName && typeof modelDef.tableName !== "string") throw new InvalidArgumentError( 'The provided option "tableName" of the model %v should be a String, but %v was given.', modelDef.name, modelDef.tableName ); if (modelDef.properties) { if (typeof modelDef.properties !== "object" || Array.isArray(modelDef.properties)) { throw new InvalidArgumentError( 'The provided option "properties" of the model %v should be an Object, but %v was given.', modelDef.name, modelDef.properties ); } this.getService(PropertiesDefinitionValidator).validate( modelDef.name, modelDef.properties ); } if (modelDef.relations) { if (typeof modelDef.relations !== "object" || Array.isArray(modelDef.relations)) { throw new InvalidArgumentError( 'The provided option "relations" of the model %v should be an Object, but %v was given.', modelDef.name, modelDef.relations ); } this.getService(RelationsDefinitionValidator).validate( modelDef.name, modelDef.relations ); } } }; __name(_ModelDefinitionValidator, "ModelDefinitionValidator"); ModelDefinitionValidator = _ModelDefinitionValidator; } }); // src/definition/model/index.js var init_model = __esm({ "src/definition/model/index.js"() { "use strict"; init_relations(); init_properties(); init_model_definition(); init_model_data_sanitizer(); init_model_definition_utils(); init_model_definition_validator(); } }); // src/definition/datasource/datasource-definition-validator.js var import_js_service13, _DatasourceDefinitionValidator, DatasourceDefinitionValidator; var init_datasource_definition_validator = __esm({ "src/definition/datasource/datasource-definition-validator.js"() { "use strict"; import_js_service13 = require("@e22m4u/js-service"); init_errors(); _DatasourceDefinitionValidator = class _DatasourceDefinitionValidator extends import_js_service13.Service { /** * Validate. * * @param {object} datasourceDef */ validate(datasourceDef) { if (!datasourceDef || typeof datasourceDef !== "object") throw new InvalidArgumentError( "The datasource definition should be an Object, but %v was given.", datasourceDef ); if (!datasourceDef.name || typeof datasourceDef.name !== "string") throw new InvalidArgumentError( 'The datasource definition requires the option "name" as a non-empty String, but %v was given.', datasourceDef.name ); if (!datasourceDef.adapter || typeof datasourceDef.adapter !== "string") throw new InvalidArgumentError( 'The datasource %v requires the option "adapter" as a non-empty String, but %v was given.', datasourceDef.name, datasourceDef.adapter ); } }; __name(_DatasourceDefinitionValidator, "DatasourceDefinitionValidator"); DatasourceDefinitionValidator = _DatasourceDefinitionValidator; } }); // src/definition/datasource/index.js var init_datasource = __esm({ "src/definition/datasource/index.js"() { "use strict"; init_datasource_definition_validator(); } }); // src/definition/index.js var init_definition = __esm({ "src/definition/index.js"() { "use strict"; init_model(); init_datasource(); init_definition_registry(); } }); // src/filter/fields-clause-tool.js var import_js_service14, _FieldsClauseTool, FieldsClauseTool; var init_fields_clause_tool = __esm({ "src/filter/fields-clause-tool.js"() { "use strict"; import_js_service14 = require("@e22m4u/js-service"); init_utils(); init_errors(); init_definition(); _FieldsClauseTool = class _FieldsClauseTool extends import_js_service14.Service { /** * Filter. * * @param {object|object[]} input * @param {string} modelName * @param {string|string[]|undefined} clause * @returns {object|object[]} */ filter(input, modelName, clause) { const isArray = Array.isArray(input); let entities = isArray ? input : [input]; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( "The first argument of FieldsClauseTool.filter should be an Object or an Array of Object, but %v was given.", entity ); }); if (!modelName || typeof modelName !== "string") throw new InvalidArgumentError( "The second argument of FieldsClauseTool.filter should be a non-empty String, but %v was given.", modelName ); if (clause == null) return input; const fields = Array.isArray(clause) ? clause.slice() : [clause]; if (!fields.length) return input; fields.forEach((field) => { if (!field || typeof field !== "string") throw new InvalidArgumentError( 'The provided option "fields" should be a non-empty String or an Array of non-empty String, but %v was given.', field ); }); const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); if (fields.indexOf(pkPropName) === -1) fields.push(pkPropName); entities = entities.map((entity) => selectObjectKeys(entity, fields)); return isArray ? entities : entities[0]; } /** * Validate fields clause. * * @param {string|string[]|undefined} clause */ static validateFieldsClause(clause) { if (clause == null) return; const fields = Array.isArray(clause) ? clause : [clause]; if (!fields.length) return; fields.forEach((field) => { if (!field || typeof field !== "string") throw new InvalidArgumentError( 'The provided option "fields" should be a non-empty String or an Array of non-empty String, but %v was given.', field ); }); } /** * Normalize fields clause. * * @param {string|string[]|undefined} clause * @returns {string[]|undefined} */ static normalizeFieldsClause(clause) { if (clause == null) return; const fields = Array.isArray(clause) ? clause : [clause]; if (!fields.length) return; fields.forEach((field) => { if (!field || typeof field !== "string") throw new InvalidArgumentError( 'The provided option "fields" should be a non-empty String or an Array of non-empty String, but %v was given.', field ); }); return fields; } }; __name(_FieldsClauseTool, "FieldsClauseTool"); FieldsClauseTool = _FieldsClauseTool; } }); // src/adapter/decorator/inclusion-decorator.js var import_js_service15, _InclusionDecorator, InclusionDecorator; var init_inclusion_decorator = __esm({ "src/adapter/decorator/inclusion-decorator.js"() { "use strict"; init_adapter(); import_js_service15 = require("@e22m4u/js-service"); init_filter(); init_errors(); _InclusionDecorator = class _InclusionDecorator extends import_js_service15.Service { /** * Decorate. * * @param {Adapter} adapter */ decorate(adapter) { if (!adapter || !(adapter instanceof Adapter)) throw new InvalidArgumentError( "The first argument of InclusionDecorator.decorate should be an Adapter instance, but %v was given.", adapter ); const tool = adapter.getService(IncludeClauseTool); const includeTo = /* @__PURE__ */ __name((...args) => tool.includeTo(...args), "includeTo"); const create = adapter.create; adapter.create = async function(modelName, modelData, filter) { const retvalData = await create.call(this, modelName, modelData, filter); if (filter && typeof filter === "object" && filter.include) await includeTo([retvalData], modelName, filter.include); return retvalData; }; const replaceById = adapter.replaceById; adapter.replaceById = async function(modelName, id, modelData, filter) { const retvalData = await replaceById.call( this, modelName, id, modelData, filter ); if (filter && typeof filter === "object" && filter.include) await includeTo([retvalData], modelName, filter.include); return retvalData; }; const replaceOrCreate = adapter.replaceOrCreate; adapter.replaceOrCreate = async function(modelName, modelData, filter) { const retvalData = await replaceOrCreate.call( this, modelName, modelData, filter ); if (filter && typeof filter === "object" && filter.include) await includeTo([retvalData], modelName, filter.include); return retvalData; }; const patchById = adapter.patchById; adapter.patchById = async function(modelName, id, modelData, filter) { const retvalData = await patchById.call( this, modelName, id, modelData, filter ); if (filter && typeof filter === "object" && filter.include) await includeTo([retvalData], modelName, filter.include); return retvalData; }; const find = adapter.find; adapter.find = async function(modelName, filter) { const modelItems = await find.call(this, modelName, filter); if (filter && typeof filter === "object" && filter.include) await includeTo(modelItems, modelName, filter.include); return modelItems; }; const findById = adapter.findById; adapter.findById = async function(modelName, id, filter) { const retvalData = await findById.call(this, modelName, id, filter); if (filter && typeof filter === "object" && filter.include) await includeTo([retvalData], modelName, filter.include); return retvalData; }; } }; __name(_InclusionDecorator, "InclusionDecorator"); InclusionDecorator = _InclusionDecorator; } }); // src/adapter/decorator/default-values-decorator.js var import_js_service16, _DefaultValuesDecorator, DefaultValuesDecorator; var init_default_values_decorator = __esm({ "src/adapter/decorator/default-values-decorator.js"() { "use strict"; init_adapter(); import_js_service16 = require("@e22m4u/js-service"); init_errors(); init_definition(); _DefaultValuesDecorator = class _DefaultValuesDecorator extends import_js_service16.Service { /** * Decorate. * * @param {Adapter} adapter */ decorate(adapter) { if (!adapter || !(adapter instanceof Adapter)) throw new InvalidArgumentError( "The first argument of DefaultValuesDecorator.decorate should be an Adapter instance, but %v was given.", adapter ); const utils = adapter.getService(ModelDefinitionUtils); const setDefaults = /* @__PURE__ */ __name((...args) => utils.setDefaultValuesToEmptyProperties(...args), "setDefaults"); const create = adapter.create; adapter.create = function(modelName, modelData, filter) { modelData = setDefaults(modelName, modelData); return create.call(this, modelName, modelData, filter); }; const replaceById = adapter.replaceById; adapter.replaceById = function(modelName, id, modelData, filter) { modelData = setDefaults(modelName, modelData); return replaceById.call(this, modelName, id, modelData, filter); }; const replaceOrCreate = adapter.replaceOrCreate; adapter.replaceOrCreate = function(modelName, modelData, filter) { modelData = setDefaults(modelName, modelData); return replaceOrCreate.call(this, modelName, modelData, filter); }; const patch = adapter.patch; adapter.patch = function(modelName, modelData, where) { modelData = setDefaults(modelName, modelData, true); return patch.call(this, modelName, modelData, where); }; const patchById = adapter.patchById; adapter.patchById = function(modelName, id, modelData, filter) { modelData = setDefaults(modelName, modelData, true); return patchById.call(this, modelName, id, modelData, filter); }; const find = adapter.find; adapter.find = async function(modelName, filter) { const modelItems = await find.call(this, modelName, filter); return modelItems.map((modelItem) => setDefaults(modelName, modelItem)); }; const findById = adapter.findById; adapter.findById = async function(modelName, id, filter) { const retvalData = await findById.call(this, modelName, id, filter); return setDefaults(modelName, retvalData); }; } }; __name(_DefaultValuesDecorator, "DefaultValuesDecorator"); DefaultValuesDecorator = _DefaultValuesDecorator; } }); // src/adapter/decorator/data-sanitizing-decorator.js var import_js_service17, _DataSanitizingDecorator, DataSanitizingDecorator; var init_data_sanitizing_decorator = __esm({ "src/adapter/decorator/data-sanitizing-decorator.js"() { "use strict"; init_adapter(); import_js_service17 = require("@e22m4u/js-service"); init_errors(); init_definition(); _DataSanitizingDecorator = class _DataSanitizingDecorator extends import_js_service17.Service { /** * Decorate. * * @param {Adapter} adapter */ decorate(adapter) { if (!adapter || !(adapter instanceof Adapter)) throw new InvalidArgumentError( "The first argument of DataSanitizingDecorator.decorate should be an Adapter instance, but %v was given.", adapter ); const sanitizer = adapter.getService(ModelDataSanitizer); const sanitize = /* @__PURE__ */ __name((...args) => sanitizer.sanitize(...args), "sanitize"); const create = adapter.create; adapter.create = async function(modelName, modelData, filter) { modelData = sanitize(modelName, modelData); return create.call(this, modelName, modelData, filter); }; const replaceById = adapter.replaceById; adapter.replaceById = async function(modelName, id, modelData, filter) { modelData = sanitize(modelName, modelData); return replaceById.call(this, modelName, id, modelData, filter); }; const replaceOrCreate = adapter.replaceOrCreate; adapter.replaceOrCreate = async function(modelName, modelData, filter) { modelData = sanitize(modelName, modelData); return replaceOrCreate.call(this, modelName, modelData, filter); }; const patch = adapter.patch; adapter.patch = async function(modelName, modelData, where) { modelData = sanitize(modelName, modelData); return patch.call(this, modelName, modelData, where); }; const patchById = adapter.patchById; adapter.patchById = async function(modelName, id, modelData, filter) { modelData = sanitize(modelName, modelData); return patchById.call(this, modelName, id, modelData, filter); }; } }; __name(_DataSanitizingDecorator, "DataSanitizingDecorator"); DataSanitizingDecorator = _DataSanitizingDecorator; } }); // src/adapter/decorator/fields-filtering-decorator.js var import_js_service18, _FieldsFilteringDecorator, FieldsFilteringDecorator; var init_fields_filtering_decorator = __esm({ "src/adapter/decorator/fields-filtering-decorator.js"() { "use strict"; init_adapter(); import_js_service18 = require("@e22m4u/js-service"); init_filter(); init_errors(); _FieldsFilteringDecorator = class _FieldsFilteringDecorator extends import_js_service18.Service { /** * Decorate. * * @param {Adapter} adapter */ decorate(adapter) { if (!adapter || !(adapter instanceof Adapter)) throw new InvalidArgumentError( "The first argument of FieldsFilteringDecorator.decorate should be an Adapter instance, but %v was given.", adapter ); const tool = adapter.getService(FieldsClauseTool); const selectFields = /* @__PURE__ */ __name((...args) => tool.filter(...args), "selectFields"); const create = adapter.create; adapter.create = async function(modelName, modelData, filter) { let result = await create.call(this, modelName, modelData, filter); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; const replaceById = adapter.replaceById; adapter.replaceById = async function(modelName, id, modelData, filter) { let result = await replaceById.call( this, modelName, id, modelData, filter ); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; const replaceOrCreate = adapter.replaceOrCreate; adapter.replaceOrCreate = async function(modelName, modelData, filter) { let result = await replaceOrCreate.call( this, modelName, modelData, filter ); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; const patchById = adapter.patchById; adapter.patchById = async function(modelName, id, modelData, filter) { let result = await patchById.call(this, modelName, id, modelData, filter); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; const find = adapter.find; adapter.find = async function(modelName, filter) { let result = await find.call(this, modelName, filter); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; const findById = adapter.findById; adapter.findById = async function(modelName, id, filter) { let result = await findById.call(this, modelName, id, filter); if (filter && typeof filter === "object" && filter.fields) result = selectFields(result, modelName, filter.fields); return result; }; } }; __name(_FieldsFilteringDecorator, "FieldsFilteringDecorator"); FieldsFilteringDecorator = _FieldsFilteringDecorator; } }); // src/adapter/decorator/property-uniqueness-decorator.js var import_js_service19, _PropertyUniquenessDecorator, PropertyUniquenessDecorator; var init_property_uniqueness_decorator = __esm({ "src/adapter/decorator/property-uniqueness-decorator.js"() { "use strict"; init_adapter(); import_js_service19 = require("@e22m4u/js-service"); init_errors(); init_definition(); _PropertyUniquenessDecorator = class _PropertyUniquenessDecorator extends import_js_service19.Service { /** * Decorate. * * @param {Adapter} adapter */ decorate(adapter) { if (!adapter || !(adapter instanceof Adapter)) throw new InvalidArgumentError( "The first argument of PropertyUniquenessDecorator.decorate should be an Adapter instance, but %v was given.", adapter ); const validator = this.getService(PropertyUniquenessValidator); const create = adapter.create; adapter.create = async function(modelName, modelData, filter) { const countMethod = adapter.count.bind(adapter, modelName); await validator.validate(countMethod, "create", modelName, modelData); return create.call(this, modelName, modelData, filter); }; const replaceById = adapter.replaceById; adapter.replaceById = async function(modelName, id, modelData, filter) { const countMethod = adapter.count.bind(adapter, modelName); await validator.validate( countMethod, "replaceById", modelName, modelData, id ); return replaceById.call(this, modelName, id, modelData, filter); }; const replaceOrCreate = adapter.replaceOrCreate; adapter.replaceOrCreate = async function(modelName, modelData, filter) { const countMethod = adapter.count.bind(adapter, modelName); await validator.validate( countMethod, "replaceOrCreate", modelName, modelData ); return replaceOrCreate.call(this, modelName, modelData, filter); }; const patch = adapter.patch; adapter.patch = async function(modelName, modelData, where) { const countMethod = adapter.count.bind(adapter, modelName); await validator.validate(countMethod, "patch", modelName, modelData); return patch.call(this, modelName, modelData, where); }; const patchById = adapter.patchById; adapter.patchById = async function(modelName, id, modelData, filter) { const countMethod = adapter.count.bind(adapter, modelName); await validator.validate( countMethod, "patchById", modelName, modelData, id ); return patchById.call(this, modelName, id, modelData, filter); }; } }; __name(_PropertyUniquenessDecorator, "PropertyUniquenessDecorator"); PropertyUniquenessDecorator = _PropertyUniquenessDecorator; } }); // src/adapter/decorator/index.js var init_decorator = __esm({ "src/adapter/decorator/index.js"() { "use strict"; init_inclusion_decorator(); init_default_values_decorator(); init_data_sanitizing_decorator(); init_fields_filtering_decorator(); init_property_uniqueness_decorator(); } }); // src/adapter/adapter.js var import_js_service20, ADAPTER_CLASS_NAME, _Adapter, Adapter; var init_adapter = __esm({ "src/adapter/adapter.js"() { "use strict"; import_js_service20 = require("@e22m4u/js-service"); init_errors(); init_decorator(); init_decorator(); init_decorator(); init_decorator(); init_decorator(); ADAPTER_CLASS_NAME = "Adapter"; _Adapter = class _Adapter extends import_js_service20.Service { /** * Settings. * * @type {object|undefined} */ _settings; /** * Settings. * * @returns {object|undefined} */ get settings() { return this._settings; } /** * Constructor. * * @param {object|undefined} container * @param {object|undefined} settings */ constructor(container = void 0, settings = void 0) { super(container); this._settings = settings; if (this.constructor !== _Adapter) { this.getService(DataSanitizingDecorator).decorate(this); this.getService(DefaultValuesDecorator).decorate(this); this.getService(PropertyUniquenessDecorator).decorate(this); this.getService(FieldsFilteringDecorator).decorate(this); this.getService(InclusionDecorator).decorate(this); } } /** * Create. * * @param {string} modelName * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ create(modelName, modelData, filter = void 0) { throw new NotImplementedError( "%s.create is not implemented.", this.constructor.name ); } /** * Replace by id. * * @param {string} modelName * @param {number|string} id * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ replaceById(modelName, id, modelData, filter = void 0) { throw new NotImplementedError( "%s.replaceById is not implemented.", this.constructor.name ); } /** * Replace or create. * * @param {string} modelName * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ replaceOrCreate(modelName, modelData, filter = void 0) { throw new NotImplementedError( "%s.replaceOrCreate is not implemented.", this.constructor.name ); } /** * Patch. * * @param {string} modelName * @param {object} modelData * @param {object|undefined} where * @returns {Promise} */ patch(modelName, modelData, where = void 0) { throw new NotImplementedError( "%s.patch is not implemented.", this.constructor.name ); } /** * Patch by id. * * @param {string} modelName * @param {number|string} id * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ patchById(modelName, id, modelData, filter = void 0) { throw new NotImplementedError( "%s.patchById is not implemented.", this.constructor.name ); } /** * Find. * * @param {string} modelName * @param {object|undefined} filter * @returns {Promise} */ find(modelName, filter = void 0) { throw new NotImplementedError( "%s.find is not implemented.", this.constructor.name ); } /** * Find by id. * * @param {string} modelName * @param {number|string} id * @param {object|undefined} filter * @returns {Promise} */ findById(modelName, id, filter = void 0) { throw new NotImplementedError( "%s.findById is not implemented.", this.constructor.name ); } /** * Delete. * * @param {string} modelName * @param {object|undefined} where * @returns {Promise} */ delete(modelName, where = void 0) { throw new NotImplementedError( "%s.delete is not implemented.", this.constructor.name ); } /** * Delete by id. * * @param {string} modelName * @param {number|string} id * @returns {Promise} */ deleteById(modelName, id) { throw new NotImplementedError( "%s.deleteById is not implemented.", this.constructor.name ); } /** * Exists. * * @param {string} modelName * @param {number|string} id * @returns {Promise} */ exists(modelName, id) { throw new NotImplementedError( "%s.exists is not implemented.", this.constructor.name ); } /** * Count. * * @param {string} modelName * @param {object|undefined} where * @returns {Promise} */ count(modelName, where = void 0) { throw new NotImplementedError( "%s.count is not implemented.", this.constructor.name ); } }; __name(_Adapter, "Adapter"); /** * Kind. * * @type {string} */ __publicField(_Adapter, "kinds", [...import_js_service20.Service.kinds, ADAPTER_CLASS_NAME]); Adapter = _Adapter; } }); // src/adapter/builtin/memory-adapter.js var memory_adapter_exports = {}; __export(memory_adapter_exports, { MemoryAdapter: () => MemoryAdapter }); var _MemoryAdapter, MemoryAdapter; var init_memory_adapter = __esm({ "src/adapter/builtin/memory-adapter.js"() { "use strict"; init_adapter(); init_utils(); init_utils(); init_definition(); init_filter(); init_filter(); init_filter(); init_errors(); init_definition(); _MemoryAdapter = class _MemoryAdapter extends Adapter { /** * Tables. * * @type {Map>>} */ _tables = /* @__PURE__ */ new Map(); /** * Last ids. * * @type {Map} */ _lastIds = /* @__PURE__ */ new Map(); /** * Get table or create. * * @param {string} modelName * @returns {Map} */ _getTableOrCreate(modelName) { const tableName = this.getService(ModelDefinitionUtils).getTableNameByModelName(modelName); let table = this._tables.get(tableName); if (table) return table; table = /* @__PURE__ */ new Map(); this._tables.set(tableName, table); return table; } /** * Gen next id value. * * @param {string} modelName * @param {string} propName * @returns {number} */ _genNextIdValue(modelName, propName) { var _a; const propType = this.getService( ModelDefinitionUtils ).getDataTypeByPropertyName(modelName, propName); if (propType !== DataType.ANY && propType !== DataType.NUMBER) throw new InvalidArgumentError( "The memory adapter able to generate only Number identifiers, but the primary key %v of the model %v is defined as %s. Do provide your own value for the %v property, or change the type in the primary key definition to a Number that will be generated automatically.", propName, modelName, capitalize(propType), propName ); const tableName = this.getService(ModelDefinitionUtils).getTableNameByModelName(modelName); const lastId = (_a = this._lastIds.get(tableName)) != null ? _a : 0; const nextId = lastId + 1; this._lastIds.set(tableName, nextId); const table = this._getTableOrCreate(modelName); const existedIds = Array.from(table.keys()); if (existedIds.includes(nextId)) return this._genNextIdValue(modelName, propName); return nextId; } /** * Create * * @param {string} modelName * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ // eslint-disable-next-line no-unused-vars async create(modelName, modelData, filter = void 0) { const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); let idValue = modelData[pkPropName]; if (idValue == null || idValue === "" || idValue === 0) { idValue = this._genNextIdValue(modelName, pkPropName); } const table = this._getTableOrCreate(modelName); if (table.has(idValue)) throw new InvalidArgumentError( "The value %v of the primary key %v already exists in the model %v.", idValue, pkPropName, modelName ); modelData = cloneDeep(modelData); modelData[pkPropName] = idValue; const tableData = this.getService( ModelDefinitionUtils ).convertPropertyNamesToColumnNames(modelName, modelData); table.set(idValue, tableData); return this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, tableData); } /** * Replace by id. * * @param {string} modelName * @param {string|number} id * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ // eslint-disable-next-line no-unused-vars async replaceById(modelName, id, modelData, filter = void 0) { const table = this._getTableOrCreate(modelName); const isExists = table.has(id); const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); if (!isExists) throw new InvalidArgumentError( "The value %v of the primary key %v does not exist in the model %v.", id, pkPropName, modelName ); modelData = cloneDeep(modelData); modelData[pkPropName] = id; const tableData = this.getService( ModelDefinitionUtils ).convertPropertyNamesToColumnNames(modelName, modelData); table.set(id, tableData); return this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, tableData); } /** * Replace or create. * * @param {string} modelName * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ // eslint-disable-next-line no-unused-vars async replaceOrCreate(modelName, modelData, filter = void 0) { const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); let idValue = modelData[pkPropName]; if (idValue == null || idValue === "" || idValue === 0) { idValue = this._genNextIdValue(modelName, pkPropName); } const table = this._getTableOrCreate(modelName); modelData = cloneDeep(modelData); modelData[pkPropName] = idValue; const tableData = this.getService( ModelDefinitionUtils ).convertPropertyNamesToColumnNames(modelName, modelData); table.set(idValue, tableData); return this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, tableData); } /** * Patch. * * @param {string} modelName * @param {object} modelData * @param {object|undefined} where * @returns {Promise} */ async patch(modelName, modelData, where = void 0) { const table = this._getTableOrCreate(modelName); const tableItems = Array.from(table.values()); if (!tableItems.length) return 0; let modelItems = tableItems.map( (tableItem) => this.getService(ModelDefinitionUtils).convertColumnNamesToPropertyNames( modelName, tableItem ) ); if (where && typeof where === "object") modelItems = this.getService(WhereClauseTool).filter(modelItems, where); const size = modelItems.length; const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); modelData = cloneDeep(modelData); delete modelData[pkPropName]; modelItems.forEach((existingModelData) => { const mergedModelData = Object.assign({}, existingModelData, modelData); const mergedTableData = this.getService( ModelDefinitionUtils ).convertPropertyNamesToColumnNames(modelName, mergedModelData); const idValue = existingModelData[pkPropName]; table.set(idValue, mergedTableData); }); return size; } /** * Patch by id. * * @param {string} modelName * @param {string|number} id * @param {object} modelData * @param {object|undefined} filter * @returns {Promise} */ // eslint-disable-next-line no-unused-vars async patchById(modelName, id, modelData, filter = void 0) { const table = this._getTableOrCreate(modelName); const existingTableData = table.get(id); const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); if (existingTableData == null) throw new InvalidArgumentError( "The value %v of the primary key %v does not exist in the model %v.", id, pkPropName, modelName ); modelData = cloneDeep(modelData); delete modelData[pkPropName]; const existingModelData = this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, existingTableData); const mergedModelData = Object.assign({}, existingModelData, modelData); const mergedTableData = this.getService( ModelDefinitionUtils ).convertPropertyNamesToColumnNames(modelName, mergedModelData); table.set(id, mergedTableData); return this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, mergedTableData); } /** * Find. * * @param {string} modelName * @param {object|undefined} filter * @returns {Promise} */ async find(modelName, filter = void 0) { const table = this._getTableOrCreate(modelName); const tableItems = Array.from(table.values()); let modelItems = tableItems.map( (tableItem) => this.getService(ModelDefinitionUtils).convertColumnNamesToPropertyNames( modelName, tableItem ) ); if (filter && typeof filter === "object") { if (filter.where) modelItems = this.getService(WhereClauseTool).filter( modelItems, filter.where ); if (filter.skip || filter.limit) modelItems = this.getService(SliceClauseTool).slice( modelItems, filter.skip, filter.limit ); if (filter.order) this.getService(OrderClauseTool).sort(modelItems, filter.order); } return modelItems; } /** * Find by id. * * @param {string} modelName * @param {string|number} id * @param {object|undefined} filter * @returns {Promise} */ // eslint-disable-next-line no-unused-vars async findById(modelName, id, filter = void 0) { const table = this._getTableOrCreate(modelName); const tableData = table.get(id); const pkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); if (!tableData) throw new InvalidArgumentError( "The value %v of the primary key %v does not exist in the model %v.", id, pkPropName, modelName ); return this.getService( ModelDefinitionUtils ).convertColumnNamesToPropertyNames(modelName, tableData); } /** * Delete. * * @param {string} modelName * @param {object|undefined} where * @returns {Promise} */ async delete(modelName, where = void 0) { const table = this._getTableOrCreate(modelName); const tableItems = Array.from(table.values()); if (!tableItems.length) return 0; let modelItems = tableItems.map( (tableItem) => this.getService(ModelDefinitionUtils).convertColumnNamesToPropertyNames( modelName, tableItem ) ); if (where && typeof where === "object") modelItems = this.getService(WhereClauseTool).filter(modelItems, where); const size = modelItems.length; const idPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( modelName ); modelItems.forEach((modelData) => { const idValue = modelData[idPropName]; table.delete(idValue); }); return size; } /** * Delete by id. * * @param {string} modelName * @param {string|number} id * @returns {Promise} */ async deleteById(modelName, id) { const table = this._getTableOrCreate(modelName); const isExists = table.has(id); table.delete(id); return isExists; } /** * Exists. * * @param {string} modelName * @param {string|number} id * @returns {Promise} */ async exists(modelName, id) { const table = this._getTableOrCreate(modelName); return table.has(id); } /** * Count. * * @param {string} modelName * @param {object|undefined} where * @returns {Promise} */ async count(modelName, where = void 0) { const table = this._getTableOrCreate(modelName); const tableItems = Array.from(table.values()); let modelItems = tableItems.map( (tableItem) => this.getService(ModelDefinitionUtils).convertColumnNamesToPropertyNames( modelName, tableItem ) ); if (where && typeof where === "object") modelItems = this.getService(WhereClauseTool).filter(modelItems, where); return modelItems.length; } }; __name(_MemoryAdapter, "MemoryAdapter"); MemoryAdapter = _MemoryAdapter; } }); // import("./builtin/**/*-adapter.js") in src/adapter/adapter-loader.js var globImport_builtin_adapter_js; var init_ = __esm({ 'import("./builtin/**/*-adapter.js") in src/adapter/adapter-loader.js'() { globImport_builtin_adapter_js = __glob({ "./builtin/memory-adapter.js": () => Promise.resolve().then(() => (init_memory_adapter(), memory_adapter_exports)) }); } }); // src/adapter/adapter-loader.js function findAdapterCtorInModule(module2) { let adapterCtor; if (!module2 || typeof module2 !== "object" || Array.isArray(module2)) return; for (const ctor of Object.values(module2)) { if (typeof ctor === "function" && Array.isArray(ctor.kinds) && Adapter.kinds.includes(ADAPTER_CLASS_NAME)) { adapterCtor = ctor; break; } } return adapterCtor; } var import_js_service21, _AdapterLoader, AdapterLoader; var init_adapter_loader = __esm({ "src/adapter/adapter-loader.js"() { "use strict"; init_adapter(); import_js_service21 = require("@e22m4u/js-service"); init_adapter(); init_errors(); init_(); _AdapterLoader = class _AdapterLoader extends import_js_service21.Service { /** * Load by name. * * @param {string} adapterName * @param {object|undefined} settings * @returns {Promise} */ async loadByName(adapterName, settings = void 0) { if (!adapterName || typeof adapterName !== "string") throw new InvalidArgumentError( "The adapter name should be a non-empty String, but %v was given.", adapterName ); let adapterCtor; try { const module2 = await globImport_builtin_adapter_js(`./builtin/${adapterName}-adapter.js`); adapterCtor = findAdapterCtorInModule(module2); } catch (e) { } if (!adapterCtor) try { const module2 = await Promise.resolve().then(() => __toESM(require(`@e22m4u/js-repository-${adapterName}-adapter`))); adapterCtor = findAdapterCtorInModule(module2); } catch (e) { } if (!adapterCtor) throw new InvalidArgumentError( "The adapter %v is not found.", adapterName ); return new adapterCtor(this.container, settings); } }; __name(_AdapterLoader, "AdapterLoader"); AdapterLoader = _AdapterLoader; __name(findAdapterCtorInModule, "findAdapterCtorInModule"); } }); // src/adapter/adapter-registry.js var import_js_service22, _AdapterRegistry, AdapterRegistry; var init_adapter_registry = __esm({ "src/adapter/adapter-registry.js"() { "use strict"; init_adapter(); import_js_service22 = require("@e22m4u/js-service"); init_adapter_loader(); init_definition(); _AdapterRegistry = class _AdapterRegistry extends import_js_service22.Service { /** * Adapters. * * @type {object} */ _adapters = {}; /** * Get adapter. * * @param {string} datasourceName * @returns {Promise} */ async getAdapter(datasourceName) { let adapter = this._adapters[datasourceName]; if (adapter) return adapter; const datasource = this.getService(DefinitionRegistry).getDatasource(datasourceName); const adapterName = datasource.adapter; adapter = await this.getService(AdapterLoader).loadByName( adapterName, datasource ); this._adapters[datasourceName] = adapter; return adapter; } }; __name(_AdapterRegistry, "AdapterRegistry"); AdapterRegistry = _AdapterRegistry; } }); // src/adapter/index.js var init_adapter2 = __esm({ "src/adapter/index.js"() { "use strict"; init_adapter(); init_adapter_loader(); init_adapter_registry(); } }); // src/repository/repository.js var import_js_service23, _Repository, Repository; var init_repository = __esm({ "src/repository/repository.js"() { "use strict"; import_js_service23 = require("@e22m4u/js-service"); init_adapter2(); init_adapter2(); init_errors(); init_definition(); _Repository = class _Repository extends import_js_service23.Service { /** * Model name. * * @type {string} */ _modelName; /** * Model name. * * @returns {string} */ get modelName() { return this._modelName; } /** * Datasource name. * * @type {string} */ _datasourceName; /** * Datasource name. * * @returns {string} */ get datasourceName() { return this._datasourceName; } /** * Constructor. * * @typedef {import('@e22m4u/js-service').ServiceContainer} ServiceContainer * @param {ServiceContainer} container * @param {string} modelName */ constructor(container, modelName) { super(container); this._modelName = modelName; const modelDef = this.getService(DefinitionRegistry).getModel(modelName); const datasourceName = modelDef.datasource; if (!datasourceName) throw new InvalidArgumentError( "The model %v does not have a specified datasource.", modelName ); this._datasourceName = datasourceName; } /** * Get adapter. * * @returns {Adapter} */ async getAdapter() { return this.getService(AdapterRegistry).getAdapter(this.datasourceName); } /** * Create. * * @param {object} data * @param {object|undefined} filter * @returns {Promise} */ async create(data, filter = void 0) { const adapter = await this.getAdapter(); return adapter.create(this.modelName, data, filter); } /** * Replace by id. * * @param {number|string} id * @param {object} data * @param {object|undefined} filter * @returns {Promise} */ async replaceById(id, data, filter = void 0) { const adapter = await this.getAdapter(); return adapter.replaceById(this.modelName, id, data, filter); } /** * Replace or create. * * @param {object} data * @param {object|undefined} filter * @returns {Promise} */ async replaceOrCreate(data, filter = void 0) { const adapter = await this.getAdapter(); return adapter.replaceOrCreate(this.modelName, data, filter); } /** * Patch. * * @param {object} data * @param {object|undefined} where * @returns {Promise} */ async patch(data, where = void 0) { const adapter = await this.getAdapter(); return adapter.patch(this.modelName, data, where); } /** * Patch by id. * * @param {number|string} id * @param {object} data * @param {object|undefined} filter * @returns {Promise} */ async patchById(id, data, filter = void 0) { const adapter = await this.getAdapter(); return adapter.patchById(this.modelName, id, data, filter); } /** * Find. * * @param {object|undefined} filter * @returns {Promise} */ async find(filter = void 0) { const adapter = await this.getAdapter(); return adapter.find(this.modelName, filter); } /** * Find one. * * @param {object|undefined} filter * @returns {Promise} */ async findOne(filter = void 0) { const adapter = await this.getAdapter(); filter = filter != null ? filter : {}; filter.limit = 1; const result = await adapter.find(this.modelName, filter); return result.length ? result[0] : void 0; } /** * Find by id. * * @param {number|string} id * @param {object|undefined} filter * @returns {Promise} */ async findById(id, filter = void 0) { const adapter = await this.getAdapter(); return adapter.findById(this.modelName, id, filter); } /** * Delete. * * @param {object|undefined} where * @returns {Promise} */ async delete(where = void 0) { const adapter = await this.getAdapter(); return adapter.delete(this.modelName, where); } /** * Delete by id. * * @param {number|string} id * @returns {Promise} */ async deleteById(id) { const adapter = await this.getAdapter(); return adapter.deleteById(this.modelName, id); } /** * Exists. * * @param {number|string} id * @returns {Promise} */ async exists(id) { const adapter = await this.getAdapter(); return adapter.exists(this.modelName, id); } /** * Count. * * @param {object|undefined} where * @returns {Promise} */ async count(where = void 0) { const adapter = await this.getAdapter(); return adapter.count(this.modelName, where); } }; __name(_Repository, "Repository"); Repository = _Repository; } }); // src/repository/repository-registry.js var import_js_service24, _RepositoryRegistry, RepositoryRegistry; var init_repository_registry = __esm({ "src/repository/repository-registry.js"() { "use strict"; import_js_service24 = require("@e22m4u/js-service"); init_repository(); init_utils(); init_errors(); _RepositoryRegistry = class _RepositoryRegistry extends import_js_service24.Service { /** * Repositories. * * @type {object} */ _repositories = {}; /** * Repository ctor. * * @type {typeof Repository} * @private */ _repositoryCtor = Repository; /** * Set repository ctor. * * @param {typeof Repository} ctor */ setRepositoryCtor(ctor) { if (!ctor || typeof ctor !== "function" || !(ctor.prototype instanceof Repository)) { throw new InvalidArgumentError( "The first argument of RepositoryRegistry.setRepositoryCtor must inherit from Repository class, but %v was given.", ctor ); } this._repositoryCtor = ctor; } /** * Get repository. * * @param {string} modelName * @returns {Repository} */ getRepository(modelName) { const modelKey = modelNameToModelKey(modelName); let repository = this._repositories[modelKey]; if (repository) return repository; repository = new this._repositoryCtor(this.container, modelName); this._repositories[modelKey] = repository; return repository; } }; __name(_RepositoryRegistry, "RepositoryRegistry"); RepositoryRegistry = _RepositoryRegistry; } }); // src/repository/index.js var init_repository2 = __esm({ "src/repository/index.js"() { "use strict"; init_repository(); init_repository_registry(); } }); // src/relations/has-one-resolver.js var import_js_service25, _HasOneResolver, HasOneResolver; var init_has_one_resolver = __esm({ "src/relations/has-one-resolver.js"() { "use strict"; import_js_service25 = require("@e22m4u/js-service"); init_utils(); init_definition(); init_errors(); init_repository2(); init_definition(); _HasOneResolver = class _HasOneResolver extends import_js_service25.Service { /** * Include to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} foreignKey * @param {object|undefined} scope * @returns {Promise} */ async includeTo(entities, sourceName, targetName, relationName, foreignKey, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasOneResolver.includeTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasOneResolver.includeTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasOneResolver.includeTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasOneResolver.includeTo requires a non-empty String, but %v was given.', relationName ); if (!foreignKey || typeof foreignKey !== "string") throw new InvalidArgumentError( 'The parameter "foreignKey" of HasOneResolver.includeTo requires a non-empty String, but %v was given.', foreignKey ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasOneResolver.includeTo should be an Object, but %v was given.', scope ); const sourcePkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( sourceName ); const sourceIds = []; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of HasOneResolver.includeTo requires an Array of Object, but %v was given.', entity ); const sourceId = entity[sourcePkPropName]; if (sourceIds.includes(sourceId)) return; sourceIds.push(sourceId); }); const promises = []; const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); scope = scope ? cloneDeep(scope) : {}; const targetBySourceId = /* @__PURE__ */ new Map(); sourceIds.forEach((sourceId) => { const filter = cloneDeep(scope); filter.where = { and: [{ [foreignKey]: sourceId }, ...scope.where ? [scope.where] : []] }; filter.limit = 1; promises.push( targetRepository.find(filter).then((result) => { if (result.length) targetBySourceId.set(sourceId, result[0]); }) ); }); await Promise.all(promises); Array.from(targetBySourceId.keys()).forEach((sourceId) => { const sources = entities.filter((v) => v[sourcePkPropName] === sourceId); sources.forEach((v) => v[relationName] = targetBySourceId.get(sourceId)); }); } /** * Include polymorphic to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} foreignKey * @param {string} discriminator * @param {object|undefined} scope * @returns {Promise} */ async includePolymorphicTo(entities, sourceName, targetName, relationName, foreignKey, discriminator, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasOneResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasOneResolver.includePolymorphicTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasOneResolver.includePolymorphicTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasOneResolver.includePolymorphicTo requires a non-empty String, but %v was given.', relationName ); if (!foreignKey || typeof foreignKey !== "string") throw new InvalidArgumentError( 'The parameter "foreignKey" of HasOneResolver.includePolymorphicTo requires a non-empty String, but %v was given.', foreignKey ); if (!discriminator || typeof discriminator !== "string") throw new InvalidArgumentError( 'The parameter "discriminator" of HasOneResolver.includePolymorphicTo requires a non-empty String, but %v was given.', discriminator ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasOneResolver.includePolymorphicTo should be an Object, but %v was given.', scope ); const sourcePkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( sourceName ); const sourceIds = []; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of HasOneResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entity ); const sourceId = entity[sourcePkPropName]; if (sourceIds.includes(sourceId)) return; sourceIds.push(sourceId); }); const promises = []; const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); scope = scope ? cloneDeep(scope) : {}; const targetBySourceId = /* @__PURE__ */ new Map(); sourceIds.forEach((sourceId) => { const filter = cloneDeep(scope); filter.where = { and: [ { [foreignKey]: sourceId, [discriminator]: sourceName }, ...scope.where ? [scope.where] : [] ] }; filter.limit = 1; promises.push( targetRepository.find(filter).then((result) => { if (result.length) targetBySourceId.set(sourceId, result[0]); }) ); }); await Promise.all(promises); Array.from(targetBySourceId.keys()).forEach((sourceId) => { const sources = entities.filter((v) => v[sourcePkPropName] === sourceId); sources.forEach((v) => v[relationName] = targetBySourceId.get(sourceId)); }); } /** * Include polymorphic by relation name. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} targetRelationName * @param {object|undefined} scope * @returns {Promise} */ async includePolymorphicByRelationName(entities, sourceName, targetName, relationName, targetRelationName, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasOneResolver.includePolymorphicByRelationName requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasOneResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasOneResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasOneResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', relationName ); if (!targetRelationName || typeof targetRelationName !== "string") throw new InvalidArgumentError( 'The parameter "targetRelationName" of HasOneResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', targetRelationName ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasOneResolver.includePolymorphicByRelationName should be an Object, but %v was given.', scope ); const targetRelationDef = this.getService( ModelDefinitionUtils ).getRelationDefinitionByName(targetName, targetRelationName); if (targetRelationDef.type !== RelationType.BELONGS_TO) throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "hasOne" relation, so it requires the target relation %v to be a polymorphic "belongsTo", but %v type was given.', relationName, sourceName, targetRelationName, targetRelationDef.type ); if (!targetRelationDef.polymorphic) throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "hasOne" relation, so it requires the target relation %v to be a polymorphic too.', relationName, sourceName, targetRelationName ); const foreignKey = targetRelationDef.foreignKey || `${targetRelationName}Id`; const discriminator = targetRelationDef.discriminator || `${targetRelationName}Type`; return this.includePolymorphicTo( entities, sourceName, targetName, relationName, foreignKey, discriminator, scope ); } }; __name(_HasOneResolver, "HasOneResolver"); HasOneResolver = _HasOneResolver; } }); // src/relations/has-many-resolver.js var import_js_service26, _HasManyResolver, HasManyResolver; var init_has_many_resolver = __esm({ "src/relations/has-many-resolver.js"() { "use strict"; import_js_service26 = require("@e22m4u/js-service"); init_utils(); init_definition(); init_errors(); init_repository2(); init_definition(); _HasManyResolver = class _HasManyResolver extends import_js_service26.Service { /** * Include to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} foreignKey * @param {object|undefined} scope * @returns {Promise} */ async includeTo(entities, sourceName, targetName, relationName, foreignKey, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasManyResolver.includeTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasManyResolver.includeTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasManyResolver.includeTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasManyResolver.includeTo requires a non-empty String, but %v was given.', relationName ); if (!foreignKey || typeof foreignKey !== "string") throw new InvalidArgumentError( 'The parameter "foreignKey" of HasManyResolver.includeTo requires a non-empty String, but %v was given.', foreignKey ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasManyResolver.includeTo should be an Object, but %v was given.', scope ); const sourcePkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( sourceName ); const sourceIds = []; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of HasManyResolver.includeTo requires an Array of Object, but %v was given.', entity ); const sourceId = entity[sourcePkPropName]; if (sourceIds.includes(sourceId)) return; sourceIds.push(sourceId); }); const promises = []; const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); scope = scope ? cloneDeep(scope) : {}; const targetsBySourceId = /* @__PURE__ */ new Map(); sourceIds.forEach((sourceId) => { const filter = cloneDeep(scope); filter.where = { and: [{ [foreignKey]: sourceId }, ...scope.where ? [scope.where] : []] }; promises.push( targetRepository.find(filter).then((result) => { var _a; if (result.length) { let targets = (_a = targetsBySourceId.get(sourceId)) != null ? _a : []; targets = [...targets, ...result]; targetsBySourceId.set(sourceId, targets); } }) ); }); await Promise.all(promises); entities.forEach((entity) => { var _a; const sourceId = entity[sourcePkPropName]; entity[relationName] = (_a = targetsBySourceId.get(sourceId)) != null ? _a : []; }); } /** * Include polymorphic to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} foreignKey * @param {string} discriminator * @param {object|undefined} scope * @returns {Promise} */ async includePolymorphicTo(entities, sourceName, targetName, relationName, foreignKey, discriminator, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasManyResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasManyResolver.includePolymorphicTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasManyResolver.includePolymorphicTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasManyResolver.includePolymorphicTo requires a non-empty String, but %v was given.', relationName ); if (!foreignKey || typeof foreignKey !== "string") throw new InvalidArgumentError( 'The parameter "foreignKey" of HasManyResolver.includePolymorphicTo requires a non-empty String, but %v was given.', foreignKey ); if (!discriminator || typeof discriminator !== "string") throw new InvalidArgumentError( 'The parameter "discriminator" of HasManyResolver.includePolymorphicTo requires a non-empty String, but %v was given.', discriminator ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasManyResolver.includePolymorphicTo should be an Object, but %v was given.', scope ); const sourcePkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( sourceName ); const sourceIds = []; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of HasManyResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entity ); const sourceId = entity[sourcePkPropName]; if (sourceIds.includes(sourceId)) return; sourceIds.push(sourceId); }); const promises = []; const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); scope = scope ? cloneDeep(scope) : {}; const targetsBySourceId = /* @__PURE__ */ new Map(); sourceIds.forEach((sourceId) => { const filter = cloneDeep(scope); filter.where = { and: [ { [foreignKey]: sourceId, [discriminator]: sourceName }, ...scope.where ? [scope.where] : [] ] }; promises.push( targetRepository.find(filter).then((result) => { var _a; if (result.length) { let targets = (_a = targetsBySourceId.get(sourceId)) != null ? _a : []; targets = [...targets, ...result]; targetsBySourceId.set(sourceId, targets); } }) ); }); await Promise.all(promises); entities.forEach((entity) => { var _a; const sourceId = entity[sourcePkPropName]; entity[relationName] = (_a = targetsBySourceId.get(sourceId)) != null ? _a : []; }); } /** * Include polymorphic by relation name. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string} targetRelationName * @param {object|undefined} scope * @returns {Promise} */ async includePolymorphicByRelationName(entities, sourceName, targetName, relationName, targetRelationName, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of HasManyResolver.includePolymorphicByRelationName requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of HasManyResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of HasManyResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of HasManyResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', relationName ); if (!targetRelationName || typeof targetRelationName !== "string") throw new InvalidArgumentError( 'The parameter "targetRelationName" of HasManyResolver.includePolymorphicByRelationName requires a non-empty String, but %v was given.', targetRelationName ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of HasManyResolver.includePolymorphicByRelationName should be an Object, but %v was given.', scope ); const targetRelationDef = this.getService( ModelDefinitionUtils ).getRelationDefinitionByName(targetName, targetRelationName); if (targetRelationDef.type !== RelationType.BELONGS_TO) throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "hasMany" relation, so it requires the target relation %v to be a polymorphic "belongsTo", but %v type was given.', relationName, sourceName, targetRelationName, targetRelationDef.type ); if (!targetRelationDef.polymorphic) throw new InvalidArgumentError( 'The relation %v of the model %v is a polymorphic "hasMany" relation, so it requires the target relation %v to be a polymorphic too.', relationName, sourceName, targetRelationName ); const foreignKey = targetRelationDef.foreignKey || `${targetRelationName}Id`; const discriminator = targetRelationDef.discriminator || `${targetRelationName}Type`; return this.includePolymorphicTo( entities, sourceName, targetName, relationName, foreignKey, discriminator, scope ); } }; __name(_HasManyResolver, "HasManyResolver"); HasManyResolver = _HasManyResolver; } }); // src/relations/belongs-to-resolver.js var import_js_service27, _BelongsToResolver, BelongsToResolver; var init_belongs_to_resolver = __esm({ "src/relations/belongs-to-resolver.js"() { "use strict"; import_js_service27 = require("@e22m4u/js-service"); init_utils(); init_utils(); init_errors(); init_repository2(); init_definition(); _BelongsToResolver = class _BelongsToResolver extends import_js_service27.Service { /** * Include to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string|undefined} foreignKey * @param {object|undefined} scope * @returns {Promise} */ async includeTo(entities, sourceName, targetName, relationName, foreignKey = void 0, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of BelongsToResolver.includeTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of BelongsToResolver.includeTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of BelongsToResolver.includeTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of BelongsToResolver.includeTo requires a non-empty String, but %v was given.', relationName ); if (foreignKey && typeof foreignKey !== "string") throw new InvalidArgumentError( 'The provided parameter "foreignKey" of BelongsToResolver.includeTo should be a String, but %v was given.', foreignKey ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of BelongsToResolver.includeTo should be an Object, but %v was given.', scope ); if (foreignKey == null) foreignKey = `${relationName}Id`; const targetIds = entities.reduce((acc, entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of BelongsToResolver.includeTo requires an Array of Object, but %v was given.', entity ); const targetId = entity[foreignKey]; return targetId != null ? [...acc, targetId] : acc; }, []); const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); const targetPkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( targetName ); scope = scope ? cloneDeep(scope) : {}; const filter = cloneDeep(scope); filter.where = { and: [ { [targetPkPropName]: { inq: targetIds } }, ...scope.where ? [scope.where] : [] ] }; const targets = await targetRepository.find(filter); entities.forEach((entity) => { const target = targets.find( (e) => e[targetPkPropName] === entity[foreignKey] ); if (target) entity[relationName] = target; }); } /** * Include polymorphic to. * * @param {object[]} entities * @param {string} sourceName * @param {string} relationName * @param {string|undefined} foreignKey * @param {string|undefined} discriminator * @param {object|undefined} scope * @returns {Promise} */ async includePolymorphicTo(entities, sourceName, relationName, foreignKey = void 0, discriminator = void 0, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of BelongsToResolver.includePolymorphicTo requires a non-empty String, but %v was given.', sourceName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of BelongsToResolver.includePolymorphicTo requires a non-empty String, but %v was given.', relationName ); if (foreignKey && typeof foreignKey !== "string") throw new InvalidArgumentError( 'The provided parameter "foreignKey" of BelongsToResolver.includePolymorphicTo should be a String, but %v was given.', foreignKey ); if (discriminator && typeof discriminator !== "string") throw new InvalidArgumentError( 'The provided parameter "discriminator" of BelongsToResolver.includePolymorphicTo should be a String, but %v was given.', discriminator ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of BelongsToResolver.includePolymorphicTo should be an Object, but %v was given.', scope ); if (foreignKey == null) { const singularRelationName = singularize(relationName); foreignKey = `${singularRelationName}Id`; } if (discriminator == null) { const singularRelationName = singularize(relationName); discriminator = `${singularRelationName}Type`; } const targetIdsByTargetName = {}; entities.forEach((entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires an Array of Object, but %v was given.', entity ); const targetId = entity[foreignKey]; const targetName = entity[discriminator]; if (targetId == null || targetName == null) return; if (targetIdsByTargetName[targetName] == null) targetIdsByTargetName[targetName] = []; if (!targetIdsByTargetName[targetName].includes(targetId)) targetIdsByTargetName[targetName].push(targetId); }); const promises = []; const targetNames = Object.keys(targetIdsByTargetName); scope = scope ? cloneDeep(scope) : {}; const targetEntitiesByTargetNames = {}; targetNames.forEach((targetName) => { let targetRepository; try { targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); } catch (error) { if (error instanceof InvalidArgumentError) { if (error.message === `The model "${targetName}" is not defined.` || error.message === `The model "${targetName}" does not have a specified datasource.`) { return; } } else { throw error; } } const targetPkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( targetName ); const targetFilter = cloneDeep(scope); const targetIds = targetIdsByTargetName[targetName]; targetFilter.where = { and: [ { [targetPkPropName]: { inq: targetIds } }, ...scope.where ? [scope.where] : [] ] }; const promise = targetRepository.find(targetFilter).then((result) => { var _a; targetEntitiesByTargetNames[targetName] = [ ...(_a = targetEntitiesByTargetNames[targetName]) != null ? _a : [], ...result ]; }); promises.push(promise); }); await Promise.all(promises); entities.forEach((entity) => { var _a; const targetId = entity[foreignKey]; const targetName = entity[discriminator]; if (targetId == null || targetName == null || targetEntitiesByTargetNames[targetName] == null) { return; } const targetEntities = (_a = targetEntitiesByTargetNames[targetName]) != null ? _a : []; const targetPkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( targetName ); const target = targetEntities.find((e) => e[targetPkPropName] === targetId); if (target) entity[relationName] = target; }); } }; __name(_BelongsToResolver, "BelongsToResolver"); BelongsToResolver = _BelongsToResolver; } }); // src/relations/references-many-resolver.js var import_js_service28, _ReferencesManyResolver, ReferencesManyResolver; var init_references_many_resolver = __esm({ "src/relations/references-many-resolver.js"() { "use strict"; import_js_service28 = require("@e22m4u/js-service"); init_utils(); init_utils(); init_errors(); init_repository2(); init_definition(); _ReferencesManyResolver = class _ReferencesManyResolver extends import_js_service28.Service { /** * Include to. * * @param {object[]} entities * @param {string} sourceName * @param {string} targetName * @param {string} relationName * @param {string|undefined} foreignKey * @param {object|undefined} scope * @returns {Promise} */ async includeTo(entities, sourceName, targetName, relationName, foreignKey = void 0, scope = void 0) { if (!entities || !Array.isArray(entities)) throw new InvalidArgumentError( 'The parameter "entities" of ReferencesManyResolver.includeTo requires an Array of Object, but %v was given.', entities ); if (!sourceName || typeof sourceName !== "string") throw new InvalidArgumentError( 'The parameter "sourceName" of ReferencesManyResolver.includeTo requires a non-empty String, but %v was given.', sourceName ); if (!targetName || typeof targetName !== "string") throw new InvalidArgumentError( 'The parameter "targetName" of ReferencesManyResolver.includeTo requires a non-empty String, but %v was given.', targetName ); if (!relationName || typeof relationName !== "string") throw new InvalidArgumentError( 'The parameter "relationName" of ReferencesManyResolver.includeTo requires a non-empty String, but %v was given.', relationName ); if (foreignKey && typeof foreignKey !== "string") throw new InvalidArgumentError( 'The provided parameter "foreignKey" of ReferencesManyResolver.includeTo should be a String, but %v was given.', foreignKey ); if (scope && (typeof scope !== "object" || Array.isArray(scope))) throw new InvalidArgumentError( 'The provided parameter "scope" of ReferencesManyResolver.includeTo should be an Object, but %v was given.', scope ); if (foreignKey == null) { const singularRelationName = singularize(relationName); foreignKey = `${singularRelationName}Ids`; } const targetIds = entities.reduce((acc, entity) => { if (!entity || typeof entity !== "object" || Array.isArray(entity)) throw new InvalidArgumentError( 'The parameter "entities" of ReferencesManyResolver.includeTo requires an Array of Object, but %v was given.', entity ); const ids = entity[foreignKey]; if (Array.isArray(ids)) ids.forEach((id) => { if (id == null || acc.includes(id)) return; acc.push(id); }); return acc; }, []); const targetRepository = this.getService(RepositoryRegistry).getRepository(targetName); const targetPkPropName = this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName( targetName ); scope = scope ? cloneDeep(scope) : {}; const filter = cloneDeep(scope); filter.where = { and: [ { [targetPkPropName]: { inq: targetIds } }, ...scope.where ? [scope.where] : [] ] }; const targets = await targetRepository.find(filter); entities.forEach((entity) => { const ids = entity[foreignKey]; entity[relationName] = []; if (Array.isArray(ids)) targets.forEach((target) => { const targetId = target[targetPkPropName]; if (ids.includes(targetId)) entity[relationName].push(target); }); }); } }; __name(_ReferencesManyResolver, "ReferencesManyResolver"); ReferencesManyResolver = _ReferencesManyResolver; } }); // src/relations/index.js var init_relations2 = __esm({ "src/relations/index.js"() { "use strict"; init_has_one_resolver(); init_has_many_resolver(); init_belongs_to_resolver(); init_references_many_resolver(); } }); // src/filter/include-clause-tool.js var import_js_service29, _IncludeClauseTool, IncludeClauseTool; var init_include_clause_tool = __esm({ "src/filter/include-clause-tool.js"() { "use strict"; import_js_service29 = require("@e22m4u/js-service"); init_definition(); init_relations2(); init_relations2(); init_where_clause_tool(); init_order_clause_tool(); init_slice_clause_tool(); init_errors(); init_relations2(); init_fields_clause_tool(); init_definition(); init_relations2(); _IncludeClauseTool = class _IncludeClauseTool extends import_js_service29.Service { /** * Include to. * * @param {object[]} entities * @param {string} modelName * @param {IncludeClause|undefined} clause * @returns {Promise} */ async includeTo(entities, modelName, clause) { clause = _IncludeClauseTool.normalizeIncludeClause(clause); const promises = []; clause.forEach((inclusion) => { const relDef = this.getService( ModelDefinitionUtils ).getRelationDefinitionByName(modelName, inclusion.relation); switch (relDef.type) { // BELONGS_TO case RelationType.BELONGS_TO: if (relDef.polymorphic) { promises.push( this.getService(BelongsToResolver).includePolymorphicTo( entities, modelName, inclusion.relation, relDef.foreignKey, relDef.discriminator, inclusion.scope ) ); } else { promises.push( this.getService(BelongsToResolver).includeTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, inclusion.scope ) ); } break; // HAS_ONE case RelationType.HAS_ONE: if (relDef.polymorphic && typeof relDef.polymorphic === "string") { promises.push( this.getService(HasOneResolver).includePolymorphicByRelationName( entities, modelName, relDef.model, inclusion.relation, relDef.polymorphic, inclusion.scope ) ); } else if (relDef.polymorphic) { promises.push( this.getService(HasOneResolver).includePolymorphicTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, relDef.discriminator, inclusion.scope ) ); } else { promises.push( this.getService(HasOneResolver).includeTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, inclusion.scope ) ); } break; // HAS_MANY case RelationType.HAS_MANY: if (relDef.polymorphic && typeof relDef.polymorphic === "string") { promises.push( this.getService(HasManyResolver).includePolymorphicByRelationName( entities, modelName, relDef.model, inclusion.relation, relDef.polymorphic, inclusion.scope ) ); } else if (relDef.polymorphic) { promises.push( this.getService(HasManyResolver).includePolymorphicTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, relDef.discriminator, inclusion.scope ) ); } else { promises.push( this.getService(HasManyResolver).includeTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, inclusion.scope ) ); } break; case RelationType.REFERENCES_MANY: promises.push( this.getService(ReferencesManyResolver).includeTo( entities, modelName, relDef.model, inclusion.relation, relDef.foreignKey, inclusion.scope ) ); break; default: throw new InvalidArgumentError( "The relation type %v does not have an inclusion resolver.", relDef.type ); } }); await Promise.all(promises); } /** * Validate include clause. * * @param {IncludeClause|undefined} clause */ static validateIncludeClause(clause) { if (clause == null) { } else if (clause && typeof clause === "string") { } else if (Array.isArray(clause)) { const relNames = []; clause.flat(Infinity).forEach((el) => { this.validateIncludeClause(el); if (typeof el === "string") { relNames.push(el); } else if (typeof el === "object") { Object.keys(el).forEach((key) => { if (Object.prototype.hasOwnProperty.call(el, key)) relNames.push(key); }); } }); const duplicateNames = relNames.filter( (name, i) => relNames.indexOf(name) !== i ); if (duplicateNames.length) throw new InvalidArgumentError( 'The provided option "include" has duplicates of %v.', duplicateNames[0] ); } else if (typeof clause === "object") { if ("relation" in clause) { if (!clause.relation || typeof clause.relation !== "string") throw new InvalidArgumentError( 'The provided option "relation" should be a non-empty String, but %v was given.', clause.relation ); if ("scope" in clause && clause) this.validateScopeClause(clause.scope); } else { Object.keys(clause).forEach((key) => { if (!Object.prototype.hasOwnProperty.call(clause, key)) return; this.validateIncludeClause(key); this.validateIncludeClause(clause[key]); }); } } else { throw new InvalidArgumentError( 'The provided option "include" should have a non-empty String, an Object or an Array, but %v was given.', clause ); } } /** * Validate scope clause. * * @param {object|undefined} clause */ static validateScopeClause(clause) { if (clause == null) return; if (typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( 'The provided option "scope" should be an Object, but %v was given.', clause ); if (clause.where != null) { WhereClauseTool.validateWhereClause(clause.where); } if (clause.order != null) { OrderClauseTool.validateOrderClause(clause.order); } if (clause.skip != null) { SliceClauseTool.validateSkipClause(clause.skip); } if (clause.limit != null) { SliceClauseTool.validateLimitClause(clause.limit); } if (clause.fields != null) { FieldsClauseTool.validateFieldsClause(clause.fields); } if (clause.include != null) { _IncludeClauseTool.validateIncludeClause(clause.include); } } /** * Normalize include clause. * * @param {IncludeClause|undefined} clause * @returns {object[]} */ static normalizeIncludeClause(clause) { let result = []; if (clause == null) { return result; } else if (clause && typeof clause === "string") { result.push({ relation: clause }); } else if (Array.isArray(clause)) { clause.flat(Infinity).forEach((el) => { el = this.normalizeIncludeClause(el); result = [...result, ...el]; }); const relNames = result.map((v) => v.relation); const duplicateNames = relNames.filter( (name, i) => relNames.indexOf(name) !== i ); if (duplicateNames.length) throw new InvalidArgumentError( 'The provided option "include" has duplicates of %v.', duplicateNames[0] ); } else if (typeof clause === "object") { if ("relation" in clause) { if (!clause.relation || typeof clause.relation !== "string") throw new InvalidArgumentError( 'The provided option "relation" should be a non-empty String, but %v was given.', clause.relation ); const normalized = { relation: clause.relation }; const scope = this.normalizeScopeClause(clause.scope); if (scope) normalized.scope = scope; result.push(normalized); } else { Object.keys(clause).forEach((key) => { if (!Object.prototype.hasOwnProperty.call(clause, key)) return; this.validateIncludeClause(key); const normalized = { relation: key }; const include = this.normalizeIncludeClause(clause[key]); if (include.length) normalized.scope = { include }; result.push(normalized); }); } } else { throw new InvalidArgumentError( 'The provided option "include" should have a non-empty String, an Object or an Array, but %v was given.', clause ); } return result; } /** * Normalize scope clause. * * @param {object|undefined} clause * @returns {object|undefined} */ static normalizeScopeClause(clause) { if (clause == null) return; if (typeof clause !== "object" || Array.isArray(clause)) throw new InvalidArgumentError( 'The provided option "scope" should be an Object, but %v was given.', clause ); const result = {}; if (clause.where != null) { WhereClauseTool.validateWhereClause(clause.where); result.where = clause.where; } if (clause.order != null) { OrderClauseTool.validateOrderClause(clause.order); result.order = clause.order; } if (clause.skip != null) { SliceClauseTool.validateSkipClause(clause.skip); result.skip = clause.skip; } if (clause.limit != null) { SliceClauseTool.validateLimitClause(clause.limit); result.limit = clause.limit; } if (clause.fields != null) { FieldsClauseTool.validateFieldsClause(clause.fields); result.fields = clause.fields; } if (clause.include != null) { result.include = this.normalizeIncludeClause(clause.include); } if (Object.keys(result).length) return result; return void 0; } }; __name(_IncludeClauseTool, "IncludeClauseTool"); IncludeClauseTool = _IncludeClauseTool; } }); // src/filter/index.js var init_filter = __esm({ "src/filter/index.js"() { "use strict"; init_slice_clause_tool(); init_order_clause_tool(); init_where_clause_tool(); init_fields_clause_tool(); init_include_clause_tool(); init_operator_clause_tool(); } }); // src/index.js var index_exports = {}; __export(index_exports, { ADAPTER_CLASS_NAME: () => ADAPTER_CLASS_NAME, Adapter: () => Adapter, AdapterLoader: () => AdapterLoader, AdapterRegistry: () => AdapterRegistry, BelongsToResolver: () => BelongsToResolver, DEFAULT_PRIMARY_KEY_PROPERTY_NAME: () => DEFAULT_PRIMARY_KEY_PROPERTY_NAME, DataType: () => DataType, DatabaseSchema: () => DatabaseSchema, DatasourceDefinitionValidator: () => DatasourceDefinitionValidator, DefinitionRegistry: () => DefinitionRegistry, FieldsClauseTool: () => FieldsClauseTool, HasManyResolver: () => HasManyResolver, HasOneResolver: () => HasOneResolver, IncludeClauseTool: () => IncludeClauseTool, InvalidArgumentError: () => InvalidArgumentError, InvalidOperatorValueError: () => InvalidOperatorValueError, ModelDataSanitizer: () => ModelDataSanitizer, ModelDefinitionUtils: () => ModelDefinitionUtils, ModelDefinitionValidator: () => ModelDefinitionValidator, NotImplementedError: () => NotImplementedError, OperatorClauseTool: () => OperatorClauseTool, OrderClauseTool: () => OrderClauseTool, PrimaryKeysDefinitionValidator: () => PrimaryKeysDefinitionValidator, PropertiesDefinitionValidator: () => PropertiesDefinitionValidator, PropertyUniqueness: () => PropertyUniqueness, PropertyUniquenessValidator: () => PropertyUniquenessValidator, ReferencesManyResolver: () => ReferencesManyResolver, RelationType: () => RelationType, RelationsDefinitionValidator: () => RelationsDefinitionValidator, Repository: () => Repository, RepositoryRegistry: () => RepositoryRegistry, SliceClauseTool: () => SliceClauseTool, WhereClauseTool: () => WhereClauseTool, capitalize: () => capitalize, cloneDeep: () => cloneDeep, excludeObjectKeys: () => excludeObjectKeys, getValueByPath: () => getValueByPath, isDeepEqual: () => isDeepEqual, isPlainObject: () => isPlainObject, isPromise: () => isPromise, likeToRegexp: () => likeToRegexp, modelNameToModelKey: () => modelNameToModelKey, selectObjectKeys: () => selectObjectKeys, singularize: () => singularize, stringToRegexp: () => stringToRegexp }); module.exports = __toCommonJS(index_exports); init_utils(); init_errors(); init_filter(); init_adapter2(); // src/database-schema.js var import_js_service30 = require("@e22m4u/js-service"); init_repository2(); init_definition(); init_repository2(); var _DatabaseSchema = class _DatabaseSchema extends import_js_service30.Service { /** * Define datasource. * * @param {object} datasourceDef * @returns {this} */ defineDatasource(datasourceDef) { this.getService(DefinitionRegistry).addDatasource(datasourceDef); return this; } /** * Define model. * * @param {object} modelDef * @returns {this} */ defineModel(modelDef) { this.getService(DefinitionRegistry).addModel(modelDef); return this; } /** * Get repository. * * @param {string} modelName * @returns {Repository} */ getRepository(modelName) { return this.getService(RepositoryRegistry).getRepository(modelName); } }; __name(_DatabaseSchema, "DatabaseSchema"); var DatabaseSchema = _DatabaseSchema; // src/index.js init_relations2(); init_definition(); init_repository2(); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ADAPTER_CLASS_NAME, Adapter, AdapterLoader, AdapterRegistry, BelongsToResolver, DEFAULT_PRIMARY_KEY_PROPERTY_NAME, DataType, DatabaseSchema, DatasourceDefinitionValidator, DefinitionRegistry, FieldsClauseTool, HasManyResolver, HasOneResolver, IncludeClauseTool, InvalidArgumentError, InvalidOperatorValueError, ModelDataSanitizer, ModelDefinitionUtils, ModelDefinitionValidator, NotImplementedError, OperatorClauseTool, OrderClauseTool, PrimaryKeysDefinitionValidator, PropertiesDefinitionValidator, PropertyUniqueness, PropertyUniquenessValidator, ReferencesManyResolver, RelationType, RelationsDefinitionValidator, Repository, RepositoryRegistry, SliceClauseTool, WhereClauseTool, capitalize, cloneDeep, excludeObjectKeys, getValueByPath, isDeepEqual, isPlainObject, isPromise, likeToRegexp, modelNameToModelKey, selectObjectKeys, singularize, stringToRegexp });