index.cjs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. var __defProp = Object.defineProperty;
  2. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  3. var __getOwnPropNames = Object.getOwnPropertyNames;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  6. var __export = (target, all) => {
  7. for (var name in all)
  8. __defProp(target, name, { get: all[name], enumerable: true });
  9. };
  10. var __copyProps = (to, from, except, desc) => {
  11. if (from && typeof from === "object" || typeof from === "function") {
  12. for (let key of __getOwnPropNames(from))
  13. if (!__hasOwnProp.call(to, key) && key !== except)
  14. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  15. }
  16. return to;
  17. };
  18. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  19. // src/index.js
  20. var index_exports = {};
  21. __export(index_exports, {
  22. MongodbAdapter: () => MongodbAdapter
  23. });
  24. module.exports = __toCommonJS(index_exports);
  25. // src/mongodb-adapter.js
  26. var import_mongodb2 = require("mongodb");
  27. var import_mongodb3 = require("mongodb");
  28. // src/utils/is-iso-date.js
  29. function isIsoDate(value) {
  30. if (!value) return false;
  31. if (value instanceof Date) return true;
  32. if (!/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(value)) return false;
  33. const d = new Date(value);
  34. return d instanceof Date && !isNaN(d.getTime()) && d.toISOString() === value;
  35. }
  36. __name(isIsoDate, "isIsoDate");
  37. // src/utils/is-object-id.js
  38. var import_mongodb = require("mongodb");
  39. function isObjectId(value) {
  40. if (!value) return false;
  41. if (value instanceof import_mongodb.ObjectId) return true;
  42. if (typeof value !== "string") return false;
  43. return value.match(/^[a-fA-F0-9]{24}$/) != null;
  44. }
  45. __name(isObjectId, "isObjectId");
  46. // src/utils/create-mongodb-url.js
  47. var import_js_repository = require("@e22m4u/js-repository");
  48. function createMongodbUrl(options = {}) {
  49. if (!options || typeof options !== "object" || Array.isArray(options))
  50. throw new import_js_repository.InvalidArgumentError(
  51. 'The first argument of "createMongodbUrl" must be an Object, but %v given.',
  52. options
  53. );
  54. if (options.protocol && typeof options.protocol !== "string")
  55. throw new import_js_repository.InvalidArgumentError(
  56. 'MongoDB option "protocol" must be a String, but %v given.',
  57. options.protocol
  58. );
  59. if (options.hostname && typeof options.hostname !== "string")
  60. throw new import_js_repository.InvalidArgumentError(
  61. 'MongoDB option "hostname" must be a String, but %v given.',
  62. options.hostname
  63. );
  64. if (options.host && typeof options.host !== "string")
  65. throw new import_js_repository.InvalidArgumentError(
  66. 'MongoDB option "host" must be a String, but %v given.',
  67. options.host
  68. );
  69. if (options.port && typeof options.port !== "number" && typeof options.port !== "string") {
  70. throw new import_js_repository.InvalidArgumentError(
  71. 'MongoDB option "port" must be a Number or a String, but %v given.',
  72. options.port
  73. );
  74. }
  75. if (options.database && typeof options.database !== "string")
  76. throw new import_js_repository.InvalidArgumentError(
  77. 'MongoDB option "database" must be a String, but %v given.',
  78. options.database
  79. );
  80. if (options.db && typeof options.db !== "string")
  81. throw new import_js_repository.InvalidArgumentError(
  82. 'MongoDB option "db" must be a String, but %v given.',
  83. options.db
  84. );
  85. if (options.username && typeof options.username !== "string")
  86. throw new import_js_repository.InvalidArgumentError(
  87. 'MongoDB option "username" must be a String, but %v given.',
  88. options.username
  89. );
  90. if (options.password && typeof options.password !== "string" && typeof options.password !== "number") {
  91. throw new import_js_repository.InvalidArgumentError(
  92. 'MongoDB option "password" must be a String or a Number, but %v given.',
  93. options.password
  94. );
  95. }
  96. if (options.pass && typeof options.pass !== "string" && typeof options.pass !== "number") {
  97. throw new import_js_repository.InvalidArgumentError(
  98. 'MongoDB option "pass" must be a String or a Number, but %v given.',
  99. options.pass
  100. );
  101. }
  102. const protocol = options.protocol || "mongodb";
  103. const hostname = options.hostname || options.host || "127.0.0.1";
  104. const port = options.port || 27017;
  105. const database = options.database || options.db || "database";
  106. const username = options.username || options.user;
  107. const password = options.password || options.pass || void 0;
  108. let portUrl = "";
  109. if (protocol !== "mongodb+srv") {
  110. portUrl = ":" + port;
  111. }
  112. if (username && password) {
  113. return `${protocol}://${username}:${password}@${hostname}${portUrl}/${database}`;
  114. } else {
  115. return `${protocol}://${hostname}${portUrl}/${database}`;
  116. }
  117. }
  118. __name(createMongodbUrl, "createMongodbUrl");
  119. // src/utils/transform-values-deep.js
  120. var import_js_repository2 = require("@e22m4u/js-repository");
  121. function transformValuesDeep(value, transformer) {
  122. if (!transformer || typeof transformer !== "function")
  123. throw new import_js_repository2.InvalidArgumentError(
  124. 'The second argument of "transformValuesDeep" must be a Function, but %v given.',
  125. transformer
  126. );
  127. if (Array.isArray(value)) {
  128. value.forEach((v, i) => value[i] = transformValuesDeep(v, transformer));
  129. return value;
  130. } else if (value && typeof value === "object") {
  131. if (!value.constructor || value.constructor && value.constructor.name === "Object") {
  132. Object.keys(value).forEach((key) => {
  133. if (Object.prototype.hasOwnProperty.call(value, key))
  134. value[key] = transformValuesDeep(value[key], transformer);
  135. });
  136. return value;
  137. } else {
  138. return transformer(value);
  139. }
  140. } else {
  141. return transformer(value);
  142. }
  143. }
  144. __name(transformValuesDeep, "transformValuesDeep");
  145. // src/mongodb-adapter.js
  146. var import_js_repository3 = require("@e22m4u/js-repository");
  147. var import_js_repository4 = require("@e22m4u/js-repository");
  148. var import_js_repository5 = require("@e22m4u/js-repository");
  149. // node_modules/@e22m4u/js-service/src/errors/invalid-argument-error.js
  150. var import_js_format = require("@e22m4u/js-format");
  151. // src/mongodb-adapter.js
  152. var import_js_repository6 = require("@e22m4u/js-repository");
  153. var import_js_repository7 = require("@e22m4u/js-repository");
  154. var import_js_repository8 = require("@e22m4u/js-repository");
  155. var import_js_repository9 = require("@e22m4u/js-repository");
  156. var import_js_repository10 = require("@e22m4u/js-repository");
  157. var MONGODB_OPTION_NAMES = [
  158. "appname",
  159. "authMechanism",
  160. "authMechanismProperties",
  161. "authSource",
  162. "compressors",
  163. "connectTimeoutMS",
  164. "directConnection",
  165. "heartbeatFrequencyMS",
  166. "journal",
  167. "loadBalanced",
  168. "localThresholdMS",
  169. "maxIdleTimeMS",
  170. "maxPoolSize",
  171. "maxConnecting",
  172. "maxStalenessSeconds",
  173. "minPoolSize",
  174. "proxyHost",
  175. "proxyPort",
  176. "proxyUsername",
  177. "proxyPassword",
  178. "readConcernLevel",
  179. "readPreference",
  180. "readPreferenceTags",
  181. "replicaSet",
  182. "retryReads",
  183. "retryWrites",
  184. "serverSelectionTimeoutMS",
  185. "serverSelectionTryOnce",
  186. "socketTimeoutMS",
  187. "srvMaxHosts",
  188. "srvServiceName",
  189. "ssl",
  190. "timeoutMS",
  191. "tls",
  192. "tlsAllowInvalidCertificates",
  193. "tlsAllowInvalidHostnames",
  194. "tlsCAFile",
  195. "tlsCertificateKeyFile",
  196. "tlsCertificateKeyFilePassword",
  197. "tlsInsecure",
  198. "w",
  199. "waitQueueTimeoutMS",
  200. "wTimeoutMS",
  201. "zlibCompressionLevel"
  202. ];
  203. var DEFAULT_SETTINGS = {
  204. // connectTimeoutMS: 2500,
  205. // serverSelectionTimeoutMS: 2500,
  206. };
  207. var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapter {
  208. /**
  209. * Mongodb instance.
  210. *
  211. * @type {MongoClient}
  212. * @private
  213. */
  214. _client;
  215. /**
  216. * Client.
  217. *
  218. * @returns {MongoClient}
  219. */
  220. get client() {
  221. return this._client;
  222. }
  223. /**
  224. * Collections.
  225. *
  226. * @type {Map<any, any>}
  227. * @private
  228. */
  229. _collections = /* @__PURE__ */ new Map();
  230. /**
  231. * Constructor.
  232. *
  233. * @param {ServiceContainer} container
  234. * @param settings
  235. */
  236. constructor(container, settings) {
  237. settings = Object.assign({}, DEFAULT_SETTINGS, settings || {});
  238. settings.protocol = settings.protocol || "mongodb";
  239. settings.hostname = settings.hostname || settings.host || "127.0.0.1";
  240. settings.port = settings.port || 27017;
  241. settings.database = settings.database || settings.db || "database";
  242. super(container, settings);
  243. const options = (0, import_js_repository7.selectObjectKeys)(this.settings, MONGODB_OPTION_NAMES);
  244. const url = createMongodbUrl(this.settings);
  245. this._client = new import_mongodb3.MongoClient(url, options);
  246. }
  247. /**
  248. * Get id prop name.
  249. *
  250. * @param modelName
  251. * @private
  252. */
  253. _getIdPropName(modelName) {
  254. return this.getService(import_js_repository8.ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
  255. modelName
  256. );
  257. }
  258. /**
  259. * Get id col name.
  260. *
  261. * @param modelName
  262. * @private
  263. */
  264. _getIdColName(modelName) {
  265. return this.getService(import_js_repository8.ModelDefinitionUtils).getPrimaryKeyAsColumnName(
  266. modelName
  267. );
  268. }
  269. /**
  270. * Coerce id.
  271. *
  272. * @param value
  273. * @returns {ObjectId|*}
  274. * @private
  275. */
  276. _coerceId(value) {
  277. if (value == null) return value;
  278. if (isObjectId(value)) return new import_mongodb2.ObjectId(value);
  279. return value;
  280. }
  281. /**
  282. * Coerce date.
  283. *
  284. * @param value
  285. * @returns {Date|*}
  286. * @private
  287. */
  288. _coerceDate(value) {
  289. if (value == null) return value;
  290. if (value instanceof Date) return value;
  291. if (isIsoDate(value)) return new Date(value);
  292. return value;
  293. }
  294. /**
  295. * To database.
  296. *
  297. * @param {string} modelName
  298. * @param {object} modelData
  299. * @returns {object}
  300. * @private
  301. */
  302. _toDatabase(modelName, modelData) {
  303. const tableData = this.getService(
  304. import_js_repository8.ModelDefinitionUtils
  305. ).convertPropertyNamesToColumnNames(modelName, modelData);
  306. const idColName = this._getIdColName(modelName);
  307. if (idColName !== "id" && idColName !== "_id")
  308. throw new import_js_repository9.InvalidArgumentError(
  309. 'MongoDB is not supporting custom names of the primary key. Do use "id" as a primary key instead of %v.',
  310. idColName
  311. );
  312. if (idColName in tableData && idColName !== "_id") {
  313. tableData._id = tableData[idColName];
  314. delete tableData[idColName];
  315. }
  316. return transformValuesDeep(tableData, (value) => {
  317. if (value instanceof import_mongodb2.ObjectId) return value;
  318. if (value instanceof Date) return value;
  319. if (isObjectId(value)) return new import_mongodb2.ObjectId(value);
  320. if (isIsoDate(value)) return new Date(value);
  321. return value;
  322. });
  323. }
  324. /**
  325. * From database.
  326. *
  327. * @param {string} modelName
  328. * @param {object} tableData
  329. * @returns {object}
  330. * @private
  331. */
  332. _fromDatabase(modelName, tableData) {
  333. if ("_id" in tableData) {
  334. const idColName = this._getIdColName(modelName);
  335. if (idColName !== "id" && idColName !== "_id")
  336. throw new import_js_repository9.InvalidArgumentError(
  337. 'MongoDB is not supporting custom names of the primary key. Do use "id" as a primary key instead of %v.',
  338. idColName
  339. );
  340. if (idColName !== "_id") {
  341. tableData[idColName] = tableData._id;
  342. delete tableData._id;
  343. }
  344. }
  345. const modelData = this.getService(
  346. import_js_repository8.ModelDefinitionUtils
  347. ).convertColumnNamesToPropertyNames(modelName, tableData);
  348. return transformValuesDeep(modelData, (value) => {
  349. if (value instanceof import_mongodb2.ObjectId) return String(value);
  350. if (value instanceof Date) return value.toISOString();
  351. return value;
  352. });
  353. }
  354. /**
  355. * Get collection.
  356. *
  357. * @param {string} modelName
  358. * @returns {*}
  359. * @private
  360. */
  361. _getCollection(modelName) {
  362. let collection = this._collections.get(modelName);
  363. if (collection) return collection;
  364. const tableName = this.getService(import_js_repository8.ModelDefinitionUtils).getTableNameByModelName(modelName);
  365. collection = this.client.db(this.settings.database).collection(tableName);
  366. this._collections.set(modelName, collection);
  367. return collection;
  368. }
  369. /**
  370. * Get id type.
  371. *
  372. * @param modelName
  373. * @returns {string|*}
  374. * @private
  375. */
  376. _getIdType(modelName) {
  377. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  378. const pkPropName = utils.getPrimaryKeyAsPropertyName(modelName);
  379. return utils.getDataTypeByPropertyName(modelName, pkPropName);
  380. }
  381. /**
  382. * Get col name.
  383. *
  384. * @param {string} modelName
  385. * @param {string} propName
  386. * @returns {string}
  387. * @private
  388. */
  389. _getColName(modelName, propName) {
  390. if (!propName || typeof propName !== "string")
  391. throw new import_js_repository9.InvalidArgumentError(
  392. "Property name must be a non-empty String, but %v given.",
  393. propName
  394. );
  395. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  396. let colName = propName;
  397. try {
  398. colName = utils.getColumnNameByPropertyName(modelName, propName);
  399. } catch (error) {
  400. if (!(error instanceof import_js_repository9.InvalidArgumentError) || error.message.indexOf("does not have the property") === -1) {
  401. throw error;
  402. }
  403. }
  404. return colName;
  405. }
  406. /**
  407. * Convert prop names chain to col names chain.
  408. *
  409. * @param {string} modelName
  410. * @param {string} propsChain
  411. * @returns {string}
  412. * @private
  413. */
  414. _convertPropNamesChainToColNamesChain(modelName, propsChain) {
  415. if (!modelName || typeof modelName !== "string")
  416. throw new import_js_repository9.InvalidArgumentError(
  417. "Model name must be a non-empty String, but %v given.",
  418. modelName
  419. );
  420. if (!propsChain || typeof propsChain !== "string")
  421. throw new import_js_repository9.InvalidArgumentError(
  422. "Properties chain must be a non-empty String, but %v given.",
  423. propsChain
  424. );
  425. propsChain = propsChain.replace(/\.{2,}/g, ".");
  426. const propNames = propsChain.split(".");
  427. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  428. let currModelName = modelName;
  429. return propNames.map((currPropName) => {
  430. if (!currModelName) return currPropName;
  431. const colName = this._getColName(currModelName, currPropName);
  432. currModelName = utils.getModelNameOfPropertyValueIfDefined(
  433. currModelName,
  434. currPropName
  435. );
  436. return colName;
  437. }).join(".");
  438. }
  439. /**
  440. * Build projection.
  441. *
  442. * @param {string} modelName
  443. * @param {string|string[]} fields
  444. * @returns {Record<string, number>|undefined}
  445. * @private
  446. */
  447. _buildProjection(modelName, fields) {
  448. if (fields == null) return;
  449. if (Array.isArray(fields) === false) fields = [fields];
  450. if (!fields.length) return;
  451. if (fields.indexOf("_id") === -1) fields.push("_id");
  452. return fields.reduce((acc, field) => {
  453. if (!field || typeof field !== "string")
  454. throw new import_js_repository9.InvalidArgumentError(
  455. 'The provided option "fields" should be a non-empty String or an Array of non-empty String, but %v given.',
  456. field
  457. );
  458. let colName = this._convertPropNamesChainToColNamesChain(
  459. modelName,
  460. field
  461. );
  462. acc[colName] = 1;
  463. return acc;
  464. }, {});
  465. }
  466. /**
  467. * Build sort.
  468. *
  469. * @param {string} modelName
  470. * @param {string|string[]} clause
  471. * @returns {object|undefined}
  472. * @private
  473. */
  474. _buildSort(modelName, clause) {
  475. if (clause == null) return;
  476. if (Array.isArray(clause) === false) clause = [clause];
  477. if (!clause.length) return;
  478. const idPropName = this._getIdPropName(modelName);
  479. return clause.reduce((acc, order) => {
  480. if (!order || typeof order !== "string")
  481. throw new import_js_repository9.InvalidArgumentError(
  482. 'The provided option "order" should be a non-empty String or an Array of non-empty String, but %v given.',
  483. order
  484. );
  485. const direction = order.match(/\s+(A|DE)SC$/);
  486. let field = order.replace(/\s+(A|DE)SC$/, "").trim();
  487. if (field === idPropName) {
  488. field = "_id";
  489. } else {
  490. try {
  491. field = this._convertPropNamesChainToColNamesChain(modelName, field);
  492. } catch (error) {
  493. if (!(error instanceof import_js_repository9.InvalidArgumentError) || error.message.indexOf("does not have the property") === -1) {
  494. throw error;
  495. }
  496. }
  497. }
  498. acc[field] = direction && direction[1] === "DE" ? -1 : 1;
  499. return acc;
  500. }, {});
  501. }
  502. /**
  503. * Build query.
  504. *
  505. * @param {string} modelName
  506. * @param {object} clause
  507. * @returns {object}
  508. * @private
  509. */
  510. _buildQuery(modelName, clause) {
  511. if (clause == null) return;
  512. if (typeof clause !== "object" || Array.isArray(clause))
  513. throw new import_js_repository9.InvalidArgumentError(
  514. 'The provided option "where" should be an Object, but %v given.',
  515. clause
  516. );
  517. const query = {};
  518. const idPropName = this._getIdPropName(modelName);
  519. Object.keys(clause).forEach((key) => {
  520. var _a, _b;
  521. if (String(key).indexOf("$") !== -1)
  522. throw new import_js_repository9.InvalidArgumentError(
  523. 'The symbol "$" is not supported, but %v given.',
  524. key
  525. );
  526. let cond = clause[key];
  527. if (key === "and" || key === "or" || key === "nor") {
  528. if (cond == null) return;
  529. if (!Array.isArray(cond))
  530. throw new import_js_repository10.InvalidOperatorValueError(key, "an Array", cond);
  531. if (cond.length === 0) return;
  532. cond = cond.map((c) => this._buildQuery(modelName, c));
  533. cond = cond.filter((c) => c != null);
  534. const opKey = "$" + key;
  535. query[opKey] = (_a = query[opKey]) != null ? _a : [];
  536. query[opKey] = [...query[opKey], ...cond];
  537. return;
  538. }
  539. if (key === idPropName) {
  540. key = "_id";
  541. } else {
  542. key = this._convertPropNamesChainToColNamesChain(modelName, key);
  543. }
  544. if (typeof cond === "string") {
  545. query[key] = this._coerceId(cond);
  546. query[key] = this._coerceDate(query[key]);
  547. return;
  548. }
  549. if (cond instanceof import_mongodb2.ObjectId) {
  550. query[key] = cond;
  551. return;
  552. }
  553. if (cond && cond.constructor && cond.constructor.name === "Object") {
  554. const opConds = [];
  555. if ("eq" in cond) {
  556. let eq = this._coerceId(cond.eq);
  557. eq = this._coerceDate(eq);
  558. opConds.push({ $eq: eq });
  559. }
  560. if ("neq" in cond) {
  561. let neq = this._coerceId(cond.neq);
  562. neq = this._coerceDate(neq);
  563. opConds.push({ $ne: neq });
  564. }
  565. if ("gt" in cond) {
  566. const gt = this._coerceDate(cond.gt);
  567. opConds.push({ $gt: gt });
  568. }
  569. if ("lt" in cond) {
  570. const lt = this._coerceDate(cond.lt);
  571. opConds.push({ $lt: lt });
  572. }
  573. if ("gte" in cond) {
  574. const gte = this._coerceDate(cond.gte);
  575. opConds.push({ $gte: gte });
  576. }
  577. if ("lte" in cond) {
  578. const lte = this._coerceDate(cond.lte);
  579. opConds.push({ $lte: lte });
  580. }
  581. if ("inq" in cond) {
  582. if (!cond.inq || !Array.isArray(cond.inq))
  583. throw new import_js_repository10.InvalidOperatorValueError(
  584. "inq",
  585. "an Array of possible values",
  586. cond.inq
  587. );
  588. const inq = cond.inq.map((v) => {
  589. v = this._coerceId(v);
  590. v = this._coerceDate(v);
  591. return v;
  592. });
  593. opConds.push({ $in: inq });
  594. }
  595. if ("nin" in cond) {
  596. if (!cond.nin || !Array.isArray(cond.nin))
  597. throw new import_js_repository10.InvalidOperatorValueError(
  598. "nin",
  599. "an Array of possible values",
  600. cond
  601. );
  602. const nin = cond.nin.map((v) => {
  603. v = this._coerceId(v);
  604. v = this._coerceDate(v);
  605. return v;
  606. });
  607. opConds.push({ $nin: nin });
  608. }
  609. if ("between" in cond) {
  610. if (!Array.isArray(cond.between) || cond.between.length !== 2)
  611. throw new import_js_repository10.InvalidOperatorValueError(
  612. "between",
  613. "an Array of 2 elements",
  614. cond.between
  615. );
  616. const gte = this._coerceDate(cond.between[0]);
  617. const lte = this._coerceDate(cond.between[1]);
  618. opConds.push({ $gte: gte, $lte: lte });
  619. }
  620. if ("exists" in cond) {
  621. if (typeof cond.exists !== "boolean")
  622. throw new import_js_repository10.InvalidOperatorValueError(
  623. "exists",
  624. "a Boolean",
  625. cond.exists
  626. );
  627. opConds.push({ $exists: cond.exists });
  628. }
  629. if ("like" in cond) {
  630. if (typeof cond.like !== "string" && !(cond.like instanceof RegExp))
  631. throw new import_js_repository10.InvalidOperatorValueError(
  632. "like",
  633. "a String or RegExp",
  634. cond.like
  635. );
  636. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.like) });
  637. }
  638. if ("nlike" in cond) {
  639. if (typeof cond.nlike !== "string" && !(cond.nlike instanceof RegExp))
  640. throw new import_js_repository10.InvalidOperatorValueError(
  641. "nlike",
  642. "a String or RegExp",
  643. cond.nlike
  644. );
  645. opConds.push({ $not: (0, import_js_repository6.stringToRegexp)(cond.nlike) });
  646. }
  647. if ("ilike" in cond) {
  648. if (typeof cond.ilike !== "string" && !(cond.ilike instanceof RegExp))
  649. throw new import_js_repository10.InvalidOperatorValueError(
  650. "ilike",
  651. "a String or RegExp",
  652. cond.ilike
  653. );
  654. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.ilike, "i") });
  655. }
  656. if ("nilike" in cond) {
  657. if (typeof cond.nilike !== "string" && !(cond.nilike instanceof RegExp)) {
  658. throw new import_js_repository10.InvalidOperatorValueError(
  659. "nilike",
  660. "a String or RegExp",
  661. cond.nilike
  662. );
  663. }
  664. opConds.push({ $not: (0, import_js_repository6.stringToRegexp)(cond.nilike, "i") });
  665. }
  666. if ("regexp" in cond) {
  667. if (typeof cond.regexp !== "string" && !(cond.regexp instanceof RegExp)) {
  668. throw new import_js_repository10.InvalidOperatorValueError(
  669. "regexp",
  670. "a String or RegExp",
  671. cond.regexp
  672. );
  673. }
  674. const flags = cond.flags || void 0;
  675. if (flags && typeof flags !== "string")
  676. throw new import_js_repository9.InvalidArgumentError(
  677. "RegExp flags must be a String, but %v given.",
  678. cond.flags
  679. );
  680. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.regexp, flags) });
  681. }
  682. if (opConds.length === 1) {
  683. query[key] = opConds[0];
  684. } else if (opConds.length > 1) {
  685. query["$and"] = (_b = query["$and"]) != null ? _b : [];
  686. opConds.forEach((c) => query["$and"].push({ [key]: c }));
  687. }
  688. return;
  689. }
  690. query[key] = cond;
  691. });
  692. return Object.keys(query).length ? query : void 0;
  693. }
  694. /**
  695. * Create.
  696. *
  697. * @param {string} modelName
  698. * @param {object} modelData
  699. * @param {object|undefined} filter
  700. * @returns {Promise<object>}
  701. */
  702. async create(modelName, modelData, filter = void 0) {
  703. const idPropName = this._getIdPropName(modelName);
  704. const idValue = modelData[idPropName];
  705. if (idValue == null || idValue === "" || idValue === 0) {
  706. const pkType = this._getIdType(modelName);
  707. if (pkType !== import_js_repository4.DataType.STRING && pkType !== import_js_repository4.DataType.ANY)
  708. throw new import_js_repository9.InvalidArgumentError(
  709. "MongoDB unable to generate primary keys of %s. Do provide your own value for the %v property or set property type to String.",
  710. (0, import_js_repository5.capitalize)(pkType),
  711. idPropName
  712. );
  713. delete modelData[idPropName];
  714. }
  715. const tableData = this._toDatabase(modelName, modelData);
  716. const table = this._getCollection(modelName);
  717. const { insertedId } = await table.insertOne(tableData);
  718. const projection = this._buildProjection(
  719. modelName,
  720. filter && filter.fields
  721. );
  722. const insertedData = await table.findOne({ _id: insertedId }, { projection });
  723. return this._fromDatabase(modelName, insertedData);
  724. }
  725. /**
  726. * Replace by id.
  727. *
  728. * @param {string} modelName
  729. * @param {string|number} id
  730. * @param {object} modelData
  731. * @param {object|undefined} filter
  732. * @returns {Promise<object>}
  733. */
  734. async replaceById(modelName, id, modelData, filter = void 0) {
  735. id = this._coerceId(id);
  736. const idPropName = this._getIdPropName(modelName);
  737. modelData[idPropName] = id;
  738. const tableData = this._toDatabase(modelName, modelData);
  739. const table = this._getCollection(modelName);
  740. const { matchedCount } = await table.replaceOne({ _id: id }, tableData);
  741. if (matchedCount < 1)
  742. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  743. const projection = this._buildProjection(
  744. modelName,
  745. filter && filter.fields
  746. );
  747. const replacedData = await table.findOne({ _id: id }, { projection });
  748. return this._fromDatabase(modelName, replacedData);
  749. }
  750. /**
  751. * Replace or create.
  752. *
  753. * @param {string} modelName
  754. * @param {object} modelData
  755. * @param {object|undefined} filter
  756. * @returns {Promise<object>}
  757. */
  758. async replaceOrCreate(modelName, modelData, filter = void 0) {
  759. const idPropName = this._getIdPropName(modelName);
  760. let idValue = modelData[idPropName];
  761. idValue = this._coerceId(idValue);
  762. if (idValue == null || idValue === "" || idValue === 0) {
  763. const pkType = this._getIdType(modelName);
  764. if (pkType !== import_js_repository4.DataType.STRING && pkType !== import_js_repository4.DataType.ANY)
  765. throw new import_js_repository9.InvalidArgumentError(
  766. "MongoDB unable to generate primary keys of %s. Do provide your own value for the %v property or set property type to String.",
  767. (0, import_js_repository5.capitalize)(pkType),
  768. idPropName
  769. );
  770. delete modelData[idPropName];
  771. idValue = void 0;
  772. }
  773. const tableData = this._toDatabase(modelName, modelData);
  774. const table = this._getCollection(modelName);
  775. if (idValue == null) {
  776. const { insertedId } = await table.insertOne(tableData);
  777. idValue = insertedId;
  778. } else {
  779. const { upsertedId } = await table.replaceOne({ _id: idValue }, tableData, {
  780. upsert: true
  781. });
  782. if (upsertedId) idValue = upsertedId;
  783. }
  784. const projection = this._buildProjection(
  785. modelName,
  786. filter && filter.fields
  787. );
  788. const upsertedData = await table.findOne({ _id: idValue }, { projection });
  789. return this._fromDatabase(modelName, upsertedData);
  790. }
  791. /**
  792. * Patch.
  793. *
  794. * @param {string} modelName
  795. * @param {object} modelData
  796. * @param {object|undefined} where
  797. * @returns {Promise<number>}
  798. */
  799. async patch(modelName, modelData, where = void 0) {
  800. const idPropName = this._getIdPropName(modelName);
  801. delete modelData[idPropName];
  802. const query = this._buildQuery(modelName, where) || {};
  803. const tableData = this._toDatabase(modelName, modelData);
  804. const table = this._getCollection(modelName);
  805. const { matchedCount } = await table.updateMany(query, { $set: tableData });
  806. return matchedCount;
  807. }
  808. /**
  809. * Patch by id.
  810. *
  811. * @param {string} modelName
  812. * @param {string|number} id
  813. * @param {object} modelData
  814. * @param {object|undefined} filter
  815. * @returns {Promise<object>}
  816. */
  817. async patchById(modelName, id, modelData, filter = void 0) {
  818. id = this._coerceId(id);
  819. const idPropName = this._getIdPropName(modelName);
  820. delete modelData[idPropName];
  821. const tableData = this._toDatabase(modelName, modelData);
  822. const table = this._getCollection(modelName);
  823. const { matchedCount } = await table.updateOne({ _id: id }, { $set: tableData });
  824. if (matchedCount < 1)
  825. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  826. const projection = this._buildProjection(
  827. modelName,
  828. filter && filter.fields
  829. );
  830. const patchedData = await table.findOne({ _id: id }, { projection });
  831. return this._fromDatabase(modelName, patchedData);
  832. }
  833. /**
  834. * Find.
  835. *
  836. * @param {string} modelName
  837. * @param {object|undefined} filter
  838. * @returns {Promise<object[]>}
  839. */
  840. async find(modelName, filter = void 0) {
  841. filter = filter || {};
  842. const query = this._buildQuery(modelName, filter.where);
  843. const sort = this._buildSort(modelName, filter.order);
  844. const limit = filter.limit || void 0;
  845. const skip = filter.skip || void 0;
  846. const projection = this._buildProjection(modelName, filter.fields);
  847. const collection = this._getCollection(modelName);
  848. const options = { sort, limit, skip, projection };
  849. const tableItems = await collection.find(query, options).toArray();
  850. return tableItems.map((v) => this._fromDatabase(modelName, v));
  851. }
  852. /**
  853. * Find by id.
  854. *
  855. * @param {string} modelName
  856. * @param {string|number} id
  857. * @param {object|undefined} filter
  858. * @returns {Promise<object>}
  859. */
  860. async findById(modelName, id, filter = void 0) {
  861. id = this._coerceId(id);
  862. const table = this._getCollection(modelName);
  863. const projection = this._buildProjection(
  864. modelName,
  865. filter && filter.fields
  866. );
  867. const patchedData = await table.findOne({ _id: id }, { projection });
  868. if (!patchedData)
  869. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  870. return this._fromDatabase(modelName, patchedData);
  871. }
  872. /**
  873. * Delete.
  874. *
  875. * @param {string} modelName
  876. * @param {object|undefined} where
  877. * @returns {Promise<number>}
  878. */
  879. async delete(modelName, where = void 0) {
  880. const table = this._getCollection(modelName);
  881. const query = this._buildQuery(modelName, where);
  882. const { deletedCount } = await table.deleteMany(query);
  883. return deletedCount;
  884. }
  885. /**
  886. * Delete by id.
  887. *
  888. * @param {string} modelName
  889. * @param {string|number} id
  890. * @returns {Promise<boolean>}
  891. */
  892. async deleteById(modelName, id) {
  893. id = this._coerceId(id);
  894. const table = this._getCollection(modelName);
  895. const { deletedCount } = await table.deleteOne({ _id: id });
  896. return deletedCount > 0;
  897. }
  898. /**
  899. * Exists.
  900. *
  901. * @param {string} modelName
  902. * @param {string|number} id
  903. * @returns {Promise<boolean>}
  904. */
  905. async exists(modelName, id) {
  906. id = this._coerceId(id);
  907. const table = this._getCollection(modelName);
  908. const result = await table.findOne({ _id: id }, {});
  909. return result != null;
  910. }
  911. /**
  912. * Count.
  913. *
  914. * @param {string} modelName
  915. * @param {object|undefined} where
  916. * @returns {Promise<number>}
  917. */
  918. async count(modelName, where = void 0) {
  919. const query = this._buildQuery(modelName, where);
  920. const table = this._getCollection(modelName);
  921. return await table.count(query);
  922. }
  923. };
  924. __name(_MongodbAdapter, "MongodbAdapter");
  925. var MongodbAdapter = _MongodbAdapter;
  926. // Annotate the CommonJS export names for ESM import in node:
  927. 0 && (module.exports = {
  928. MongodbAdapter
  929. });