index.cjs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  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. "ALPNProtocols",
  159. "allowPartialTrustChain",
  160. "appName",
  161. "auth",
  162. "authMechanism",
  163. "authMechanismProperties",
  164. "authSource",
  165. "autoEncryption",
  166. "autoSelectFamily",
  167. "autoSelectFamilyAttemptTimeout",
  168. "bsonRegExp",
  169. "ca",
  170. "cert",
  171. "checkKeys",
  172. "checkServerIdentity",
  173. "ciphers",
  174. "compressors",
  175. "connectTimeoutMS",
  176. "crl",
  177. "directConnection",
  178. "driverInfo",
  179. "ecdhCurve",
  180. "enableUtf8Validation",
  181. "family",
  182. "fieldsAsRaw",
  183. "forceServerObjectId",
  184. "heartbeatFrequencyMS",
  185. "hints",
  186. "ignoreUndefined",
  187. "journal",
  188. "keepAliveInitialDelay",
  189. "key",
  190. "loadBalanced",
  191. "localAddress",
  192. "localPort",
  193. "localThresholdMS",
  194. "lookup",
  195. "maxConnecting",
  196. "maxIdleTimeMS",
  197. "maxPoolSize",
  198. "maxStalenessSeconds",
  199. "minDHSize",
  200. "minHeartbeatFrequencyMS",
  201. "minPoolSize",
  202. "mongodbLogComponentSeverities",
  203. "mongodbLogMaxDocumentLength",
  204. "mongodbLogPath",
  205. "monitorCommands",
  206. "noDelay",
  207. "passphrase",
  208. "pfx",
  209. "pkFactory",
  210. "promoteBuffers",
  211. "promoteLongs",
  212. "promoteValues",
  213. "proxyHost",
  214. "proxyPassword",
  215. "proxyPort",
  216. "proxyUsername",
  217. "raw",
  218. "readConcern",
  219. "readConcernLevel",
  220. "readPreference",
  221. "readPreferenceTags",
  222. "rejectUnauthorized",
  223. "replicaSet",
  224. "retryReads",
  225. "retryWrites",
  226. "secureContext",
  227. "secureProtocol",
  228. "serializeFunctions",
  229. "serverApi",
  230. "serverMonitoringMode",
  231. "serverSelectionTimeoutMS",
  232. "servername",
  233. "session",
  234. "socketTimeoutMS",
  235. "srvMaxHosts",
  236. "srvServiceName",
  237. "ssl",
  238. "timeoutMS",
  239. "tls",
  240. "tlsAllowInvalidCertificates",
  241. "tlsAllowInvalidHostnames",
  242. "tlsCAFile",
  243. "tlsCRLFile",
  244. "tlsCertificateKeyFile",
  245. "tlsCertificateKeyFilePassword",
  246. "tlsInsecure",
  247. "useBigInt64",
  248. "w",
  249. "waitQueueTimeoutMS",
  250. "writeConcern",
  251. "wtimeoutMS",
  252. "zlibCompressionLevel"
  253. ];
  254. var DEFAULT_SETTINGS = {
  255. // connectTimeoutMS: 2500,
  256. // serverSelectionTimeoutMS: 2500,
  257. };
  258. var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapter {
  259. /**
  260. * Mongodb instance.
  261. *
  262. * @type {MongoClient}
  263. * @private
  264. */
  265. _client;
  266. /**
  267. * Client.
  268. *
  269. * @returns {MongoClient}
  270. */
  271. get client() {
  272. return this._client;
  273. }
  274. /**
  275. * Collections.
  276. *
  277. * @type {Map<any, any>}
  278. * @private
  279. */
  280. _collections = /* @__PURE__ */ new Map();
  281. /**
  282. * Constructor.
  283. *
  284. * @param {ServiceContainer} container
  285. * @param settings
  286. */
  287. constructor(container, settings) {
  288. settings = Object.assign({}, DEFAULT_SETTINGS, settings || {});
  289. settings.protocol = settings.protocol || "mongodb";
  290. settings.hostname = settings.hostname || settings.host || "127.0.0.1";
  291. settings.port = settings.port || 27017;
  292. settings.database = settings.database || settings.db || "database";
  293. super(container, settings);
  294. const options = (0, import_js_repository7.selectObjectKeys)(this.settings, MONGODB_OPTION_NAMES);
  295. const url = createMongodbUrl(this.settings);
  296. this._client = new import_mongodb3.MongoClient(url, options);
  297. }
  298. /**
  299. * Get id prop name.
  300. *
  301. * @param modelName
  302. * @private
  303. */
  304. _getIdPropName(modelName) {
  305. return this.getService(import_js_repository8.ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
  306. modelName
  307. );
  308. }
  309. /**
  310. * Get id col name.
  311. *
  312. * @param modelName
  313. * @private
  314. */
  315. _getIdColName(modelName) {
  316. return this.getService(import_js_repository8.ModelDefinitionUtils).getPrimaryKeyAsColumnName(
  317. modelName
  318. );
  319. }
  320. /**
  321. * Coerce id.
  322. *
  323. * @param value
  324. * @returns {ObjectId|*}
  325. * @private
  326. */
  327. _coerceId(value) {
  328. if (value == null) return value;
  329. if (isObjectId(value)) return new import_mongodb2.ObjectId(value);
  330. return value;
  331. }
  332. /**
  333. * Coerce date.
  334. *
  335. * @param value
  336. * @returns {Date|*}
  337. * @private
  338. */
  339. _coerceDate(value) {
  340. if (value == null) return value;
  341. if (value instanceof Date) return value;
  342. if (isIsoDate(value)) return new Date(value);
  343. return value;
  344. }
  345. /**
  346. * To database.
  347. *
  348. * @param {string} modelName
  349. * @param {object} modelData
  350. * @returns {object}
  351. * @private
  352. */
  353. _toDatabase(modelName, modelData) {
  354. const tableData = this.getService(
  355. import_js_repository8.ModelDefinitionUtils
  356. ).convertPropertyNamesToColumnNames(modelName, modelData);
  357. const idColName = this._getIdColName(modelName);
  358. if (idColName !== "id" && idColName !== "_id")
  359. throw new import_js_repository9.InvalidArgumentError(
  360. 'MongoDB is not supporting custom names of the primary key. Do use "id" as a primary key instead of %v.',
  361. idColName
  362. );
  363. if (idColName in tableData && idColName !== "_id") {
  364. tableData._id = tableData[idColName];
  365. delete tableData[idColName];
  366. }
  367. return transformValuesDeep(tableData, (value) => {
  368. if (value instanceof import_mongodb2.ObjectId) return value;
  369. if (value instanceof Date) return value;
  370. if (isObjectId(value)) return new import_mongodb2.ObjectId(value);
  371. if (isIsoDate(value)) return new Date(value);
  372. return value;
  373. });
  374. }
  375. /**
  376. * From database.
  377. *
  378. * @param {string} modelName
  379. * @param {object} tableData
  380. * @returns {object}
  381. * @private
  382. */
  383. _fromDatabase(modelName, tableData) {
  384. if ("_id" in tableData) {
  385. const idColName = this._getIdColName(modelName);
  386. if (idColName !== "id" && idColName !== "_id")
  387. throw new import_js_repository9.InvalidArgumentError(
  388. 'MongoDB is not supporting custom names of the primary key. Do use "id" as a primary key instead of %v.',
  389. idColName
  390. );
  391. if (idColName !== "_id") {
  392. tableData[idColName] = tableData._id;
  393. delete tableData._id;
  394. }
  395. }
  396. const modelData = this.getService(
  397. import_js_repository8.ModelDefinitionUtils
  398. ).convertColumnNamesToPropertyNames(modelName, tableData);
  399. return transformValuesDeep(modelData, (value) => {
  400. if (value instanceof import_mongodb2.ObjectId) return String(value);
  401. if (value instanceof Date) return value.toISOString();
  402. return value;
  403. });
  404. }
  405. /**
  406. * Get collection.
  407. *
  408. * @param {string} modelName
  409. * @returns {*}
  410. * @private
  411. */
  412. _getCollection(modelName) {
  413. let collection = this._collections.get(modelName);
  414. if (collection) return collection;
  415. const tableName = this.getService(import_js_repository8.ModelDefinitionUtils).getTableNameByModelName(modelName);
  416. collection = this.client.db(this.settings.database).collection(tableName);
  417. this._collections.set(modelName, collection);
  418. return collection;
  419. }
  420. /**
  421. * Get id type.
  422. *
  423. * @param modelName
  424. * @returns {string|*}
  425. * @private
  426. */
  427. _getIdType(modelName) {
  428. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  429. const pkPropName = utils.getPrimaryKeyAsPropertyName(modelName);
  430. return utils.getDataTypeByPropertyName(modelName, pkPropName);
  431. }
  432. /**
  433. * Get col name.
  434. *
  435. * @param {string} modelName
  436. * @param {string} propName
  437. * @returns {string}
  438. * @private
  439. */
  440. _getColName(modelName, propName) {
  441. if (!propName || typeof propName !== "string")
  442. throw new import_js_repository9.InvalidArgumentError(
  443. "Property name must be a non-empty String, but %v given.",
  444. propName
  445. );
  446. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  447. let colName = propName;
  448. try {
  449. colName = utils.getColumnNameByPropertyName(modelName, propName);
  450. } catch (error) {
  451. if (!(error instanceof import_js_repository9.InvalidArgumentError) || error.message.indexOf("does not have the property") === -1) {
  452. throw error;
  453. }
  454. }
  455. return colName;
  456. }
  457. /**
  458. * Convert prop names chain to col names chain.
  459. *
  460. * @param {string} modelName
  461. * @param {string} propsChain
  462. * @returns {string}
  463. * @private
  464. */
  465. _convertPropNamesChainToColNamesChain(modelName, propsChain) {
  466. if (!modelName || typeof modelName !== "string")
  467. throw new import_js_repository9.InvalidArgumentError(
  468. "Model name must be a non-empty String, but %v given.",
  469. modelName
  470. );
  471. if (!propsChain || typeof propsChain !== "string")
  472. throw new import_js_repository9.InvalidArgumentError(
  473. "Properties chain must be a non-empty String, but %v given.",
  474. propsChain
  475. );
  476. propsChain = propsChain.replace(/\.{2,}/g, ".");
  477. const propNames = propsChain.split(".");
  478. const utils = this.getService(import_js_repository8.ModelDefinitionUtils);
  479. let currModelName = modelName;
  480. return propNames.map((currPropName) => {
  481. if (!currModelName) return currPropName;
  482. const colName = this._getColName(currModelName, currPropName);
  483. currModelName = utils.getModelNameOfPropertyValueIfDefined(
  484. currModelName,
  485. currPropName
  486. );
  487. return colName;
  488. }).join(".");
  489. }
  490. /**
  491. * Build projection.
  492. *
  493. * @param {string} modelName
  494. * @param {string|string[]} fields
  495. * @returns {Record<string, number>|undefined}
  496. * @private
  497. */
  498. _buildProjection(modelName, fields) {
  499. if (fields == null) return;
  500. if (Array.isArray(fields) === false) fields = [fields];
  501. if (!fields.length) return;
  502. if (fields.indexOf("_id") === -1) fields.push("_id");
  503. return fields.reduce((acc, field) => {
  504. if (!field || typeof field !== "string")
  505. throw new import_js_repository9.InvalidArgumentError(
  506. 'The provided option "fields" should be a non-empty String or an Array of non-empty String, but %v given.',
  507. field
  508. );
  509. let colName = this._convertPropNamesChainToColNamesChain(
  510. modelName,
  511. field
  512. );
  513. acc[colName] = 1;
  514. return acc;
  515. }, {});
  516. }
  517. /**
  518. * Build sort.
  519. *
  520. * @param {string} modelName
  521. * @param {string|string[]} clause
  522. * @returns {object|undefined}
  523. * @private
  524. */
  525. _buildSort(modelName, clause) {
  526. if (clause == null) return;
  527. if (Array.isArray(clause) === false) clause = [clause];
  528. if (!clause.length) return;
  529. const idPropName = this._getIdPropName(modelName);
  530. return clause.reduce((acc, order) => {
  531. if (!order || typeof order !== "string")
  532. throw new import_js_repository9.InvalidArgumentError(
  533. 'The provided option "order" should be a non-empty String or an Array of non-empty String, but %v given.',
  534. order
  535. );
  536. const direction = order.match(/\s+(A|DE)SC$/);
  537. let field = order.replace(/\s+(A|DE)SC$/, "").trim();
  538. if (field === idPropName) {
  539. field = "_id";
  540. } else {
  541. try {
  542. field = this._convertPropNamesChainToColNamesChain(modelName, field);
  543. } catch (error) {
  544. if (!(error instanceof import_js_repository9.InvalidArgumentError) || error.message.indexOf("does not have the property") === -1) {
  545. throw error;
  546. }
  547. }
  548. }
  549. acc[field] = direction && direction[1] === "DE" ? -1 : 1;
  550. return acc;
  551. }, {});
  552. }
  553. /**
  554. * Build query.
  555. *
  556. * @param {string} modelName
  557. * @param {object} clause
  558. * @returns {object}
  559. * @private
  560. */
  561. _buildQuery(modelName, clause) {
  562. if (clause == null) return;
  563. if (typeof clause !== "object" || Array.isArray(clause))
  564. throw new import_js_repository9.InvalidArgumentError(
  565. 'The provided option "where" should be an Object, but %v given.',
  566. clause
  567. );
  568. const query = {};
  569. const idPropName = this._getIdPropName(modelName);
  570. Object.keys(clause).forEach((key) => {
  571. var _a, _b;
  572. if (String(key).indexOf("$") !== -1)
  573. throw new import_js_repository9.InvalidArgumentError(
  574. 'The symbol "$" is not supported, but %v given.',
  575. key
  576. );
  577. let cond = clause[key];
  578. if (key === "and" || key === "or" || key === "nor") {
  579. if (cond == null) return;
  580. if (!Array.isArray(cond))
  581. throw new import_js_repository10.InvalidOperatorValueError(key, "an Array", cond);
  582. if (cond.length === 0) return;
  583. cond = cond.map((c) => this._buildQuery(modelName, c));
  584. cond = cond.filter((c) => c != null);
  585. const opKey = "$" + key;
  586. query[opKey] = (_a = query[opKey]) != null ? _a : [];
  587. query[opKey] = [...query[opKey], ...cond];
  588. return;
  589. }
  590. if (key === idPropName) {
  591. key = "_id";
  592. } else {
  593. key = this._convertPropNamesChainToColNamesChain(modelName, key);
  594. }
  595. if (typeof cond === "string") {
  596. query[key] = this._coerceId(cond);
  597. query[key] = this._coerceDate(query[key]);
  598. return;
  599. }
  600. if (cond instanceof import_mongodb2.ObjectId) {
  601. query[key] = cond;
  602. return;
  603. }
  604. if (cond && cond.constructor && cond.constructor.name === "Object") {
  605. const opConds = [];
  606. if ("eq" in cond) {
  607. let eq = this._coerceId(cond.eq);
  608. eq = this._coerceDate(eq);
  609. opConds.push({ $eq: eq });
  610. }
  611. if ("neq" in cond) {
  612. let neq = this._coerceId(cond.neq);
  613. neq = this._coerceDate(neq);
  614. opConds.push({ $ne: neq });
  615. }
  616. if ("gt" in cond) {
  617. const gt = this._coerceDate(cond.gt);
  618. opConds.push({ $gt: gt });
  619. }
  620. if ("lt" in cond) {
  621. const lt = this._coerceDate(cond.lt);
  622. opConds.push({ $lt: lt });
  623. }
  624. if ("gte" in cond) {
  625. const gte = this._coerceDate(cond.gte);
  626. opConds.push({ $gte: gte });
  627. }
  628. if ("lte" in cond) {
  629. const lte = this._coerceDate(cond.lte);
  630. opConds.push({ $lte: lte });
  631. }
  632. if ("inq" in cond) {
  633. if (!cond.inq || !Array.isArray(cond.inq))
  634. throw new import_js_repository10.InvalidOperatorValueError(
  635. "inq",
  636. "an Array of possible values",
  637. cond.inq
  638. );
  639. const inq = cond.inq.map((v) => {
  640. v = this._coerceId(v);
  641. v = this._coerceDate(v);
  642. return v;
  643. });
  644. opConds.push({ $in: inq });
  645. }
  646. if ("nin" in cond) {
  647. if (!cond.nin || !Array.isArray(cond.nin))
  648. throw new import_js_repository10.InvalidOperatorValueError(
  649. "nin",
  650. "an Array of possible values",
  651. cond
  652. );
  653. const nin = cond.nin.map((v) => {
  654. v = this._coerceId(v);
  655. v = this._coerceDate(v);
  656. return v;
  657. });
  658. opConds.push({ $nin: nin });
  659. }
  660. if ("between" in cond) {
  661. if (!Array.isArray(cond.between) || cond.between.length !== 2)
  662. throw new import_js_repository10.InvalidOperatorValueError(
  663. "between",
  664. "an Array of 2 elements",
  665. cond.between
  666. );
  667. const gte = this._coerceDate(cond.between[0]);
  668. const lte = this._coerceDate(cond.between[1]);
  669. opConds.push({ $gte: gte, $lte: lte });
  670. }
  671. if ("exists" in cond) {
  672. if (typeof cond.exists !== "boolean")
  673. throw new import_js_repository10.InvalidOperatorValueError(
  674. "exists",
  675. "a Boolean",
  676. cond.exists
  677. );
  678. opConds.push({ $exists: cond.exists });
  679. }
  680. if ("like" in cond) {
  681. if (typeof cond.like !== "string" && !(cond.like instanceof RegExp))
  682. throw new import_js_repository10.InvalidOperatorValueError(
  683. "like",
  684. "a String or RegExp",
  685. cond.like
  686. );
  687. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.like) });
  688. }
  689. if ("nlike" in cond) {
  690. if (typeof cond.nlike !== "string" && !(cond.nlike instanceof RegExp))
  691. throw new import_js_repository10.InvalidOperatorValueError(
  692. "nlike",
  693. "a String or RegExp",
  694. cond.nlike
  695. );
  696. opConds.push({ $not: (0, import_js_repository6.stringToRegexp)(cond.nlike) });
  697. }
  698. if ("ilike" in cond) {
  699. if (typeof cond.ilike !== "string" && !(cond.ilike instanceof RegExp))
  700. throw new import_js_repository10.InvalidOperatorValueError(
  701. "ilike",
  702. "a String or RegExp",
  703. cond.ilike
  704. );
  705. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.ilike, "i") });
  706. }
  707. if ("nilike" in cond) {
  708. if (typeof cond.nilike !== "string" && !(cond.nilike instanceof RegExp)) {
  709. throw new import_js_repository10.InvalidOperatorValueError(
  710. "nilike",
  711. "a String or RegExp",
  712. cond.nilike
  713. );
  714. }
  715. opConds.push({ $not: (0, import_js_repository6.stringToRegexp)(cond.nilike, "i") });
  716. }
  717. if ("regexp" in cond) {
  718. if (typeof cond.regexp !== "string" && !(cond.regexp instanceof RegExp)) {
  719. throw new import_js_repository10.InvalidOperatorValueError(
  720. "regexp",
  721. "a String or RegExp",
  722. cond.regexp
  723. );
  724. }
  725. const flags = cond.flags || void 0;
  726. if (flags && typeof flags !== "string")
  727. throw new import_js_repository9.InvalidArgumentError(
  728. "RegExp flags must be a String, but %v given.",
  729. cond.flags
  730. );
  731. opConds.push({ $regex: (0, import_js_repository6.stringToRegexp)(cond.regexp, flags) });
  732. }
  733. if (opConds.length === 1) {
  734. query[key] = opConds[0];
  735. } else if (opConds.length > 1) {
  736. query["$and"] = (_b = query["$and"]) != null ? _b : [];
  737. opConds.forEach((c) => query["$and"].push({ [key]: c }));
  738. }
  739. return;
  740. }
  741. query[key] = cond;
  742. });
  743. return Object.keys(query).length ? query : void 0;
  744. }
  745. /**
  746. * Create.
  747. *
  748. * @param {string} modelName
  749. * @param {object} modelData
  750. * @param {object|undefined} filter
  751. * @returns {Promise<object>}
  752. */
  753. async create(modelName, modelData, filter = void 0) {
  754. const idPropName = this._getIdPropName(modelName);
  755. const idValue = modelData[idPropName];
  756. if (idValue == null || idValue === "" || idValue === 0) {
  757. const pkType = this._getIdType(modelName);
  758. if (pkType !== import_js_repository4.DataType.STRING && pkType !== import_js_repository4.DataType.ANY)
  759. throw new import_js_repository9.InvalidArgumentError(
  760. "MongoDB unable to generate primary keys of %s. Do provide your own value for the %v property or set property type to String.",
  761. (0, import_js_repository5.capitalize)(pkType),
  762. idPropName
  763. );
  764. delete modelData[idPropName];
  765. }
  766. const tableData = this._toDatabase(modelName, modelData);
  767. const table = this._getCollection(modelName);
  768. const { insertedId } = await table.insertOne(tableData);
  769. const projection = this._buildProjection(
  770. modelName,
  771. filter && filter.fields
  772. );
  773. const insertedData = await table.findOne({ _id: insertedId }, { projection });
  774. return this._fromDatabase(modelName, insertedData);
  775. }
  776. /**
  777. * Replace by id.
  778. *
  779. * @param {string} modelName
  780. * @param {string|number} id
  781. * @param {object} modelData
  782. * @param {object|undefined} filter
  783. * @returns {Promise<object>}
  784. */
  785. async replaceById(modelName, id, modelData, filter = void 0) {
  786. id = this._coerceId(id);
  787. const idPropName = this._getIdPropName(modelName);
  788. modelData[idPropName] = id;
  789. const tableData = this._toDatabase(modelName, modelData);
  790. const table = this._getCollection(modelName);
  791. const { matchedCount } = await table.replaceOne({ _id: id }, tableData);
  792. if (matchedCount < 1)
  793. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  794. const projection = this._buildProjection(
  795. modelName,
  796. filter && filter.fields
  797. );
  798. const replacedData = await table.findOne({ _id: id }, { projection });
  799. return this._fromDatabase(modelName, replacedData);
  800. }
  801. /**
  802. * Replace or create.
  803. *
  804. * @param {string} modelName
  805. * @param {object} modelData
  806. * @param {object|undefined} filter
  807. * @returns {Promise<object>}
  808. */
  809. async replaceOrCreate(modelName, modelData, filter = void 0) {
  810. const idPropName = this._getIdPropName(modelName);
  811. let idValue = modelData[idPropName];
  812. idValue = this._coerceId(idValue);
  813. if (idValue == null || idValue === "" || idValue === 0) {
  814. const pkType = this._getIdType(modelName);
  815. if (pkType !== import_js_repository4.DataType.STRING && pkType !== import_js_repository4.DataType.ANY)
  816. throw new import_js_repository9.InvalidArgumentError(
  817. "MongoDB unable to generate primary keys of %s. Do provide your own value for the %v property or set property type to String.",
  818. (0, import_js_repository5.capitalize)(pkType),
  819. idPropName
  820. );
  821. delete modelData[idPropName];
  822. idValue = void 0;
  823. }
  824. const tableData = this._toDatabase(modelName, modelData);
  825. const table = this._getCollection(modelName);
  826. if (idValue == null) {
  827. const { insertedId } = await table.insertOne(tableData);
  828. idValue = insertedId;
  829. } else {
  830. const { upsertedId } = await table.replaceOne({ _id: idValue }, tableData, {
  831. upsert: true
  832. });
  833. if (upsertedId) idValue = upsertedId;
  834. }
  835. const projection = this._buildProjection(
  836. modelName,
  837. filter && filter.fields
  838. );
  839. const upsertedData = await table.findOne({ _id: idValue }, { projection });
  840. return this._fromDatabase(modelName, upsertedData);
  841. }
  842. /**
  843. * Patch.
  844. *
  845. * @param {string} modelName
  846. * @param {object} modelData
  847. * @param {object|undefined} where
  848. * @returns {Promise<number>}
  849. */
  850. async patch(modelName, modelData, where = void 0) {
  851. const idPropName = this._getIdPropName(modelName);
  852. delete modelData[idPropName];
  853. const query = this._buildQuery(modelName, where) || {};
  854. const tableData = this._toDatabase(modelName, modelData);
  855. const table = this._getCollection(modelName);
  856. const { matchedCount } = await table.updateMany(query, { $set: tableData });
  857. return matchedCount;
  858. }
  859. /**
  860. * Patch by id.
  861. *
  862. * @param {string} modelName
  863. * @param {string|number} id
  864. * @param {object} modelData
  865. * @param {object|undefined} filter
  866. * @returns {Promise<object>}
  867. */
  868. async patchById(modelName, id, modelData, filter = void 0) {
  869. id = this._coerceId(id);
  870. const idPropName = this._getIdPropName(modelName);
  871. delete modelData[idPropName];
  872. const tableData = this._toDatabase(modelName, modelData);
  873. const table = this._getCollection(modelName);
  874. const { matchedCount } = await table.updateOne({ _id: id }, { $set: tableData });
  875. if (matchedCount < 1)
  876. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  877. const projection = this._buildProjection(
  878. modelName,
  879. filter && filter.fields
  880. );
  881. const patchedData = await table.findOne({ _id: id }, { projection });
  882. return this._fromDatabase(modelName, patchedData);
  883. }
  884. /**
  885. * Find.
  886. *
  887. * @param {string} modelName
  888. * @param {object|undefined} filter
  889. * @returns {Promise<object[]>}
  890. */
  891. async find(modelName, filter = void 0) {
  892. filter = filter || {};
  893. const query = this._buildQuery(modelName, filter.where);
  894. const sort = this._buildSort(modelName, filter.order);
  895. const limit = filter.limit || void 0;
  896. const skip = filter.skip || void 0;
  897. const projection = this._buildProjection(modelName, filter.fields);
  898. const collection = this._getCollection(modelName);
  899. const options = { sort, limit, skip, projection };
  900. const tableItems = await collection.find(query, options).toArray();
  901. return tableItems.map((v) => this._fromDatabase(modelName, v));
  902. }
  903. /**
  904. * Find by id.
  905. *
  906. * @param {string} modelName
  907. * @param {string|number} id
  908. * @param {object|undefined} filter
  909. * @returns {Promise<object>}
  910. */
  911. async findById(modelName, id, filter = void 0) {
  912. id = this._coerceId(id);
  913. const table = this._getCollection(modelName);
  914. const projection = this._buildProjection(
  915. modelName,
  916. filter && filter.fields
  917. );
  918. const patchedData = await table.findOne({ _id: id }, { projection });
  919. if (!patchedData)
  920. throw new import_js_repository9.InvalidArgumentError("Identifier %v is not found.", String(id));
  921. return this._fromDatabase(modelName, patchedData);
  922. }
  923. /**
  924. * Delete.
  925. *
  926. * @param {string} modelName
  927. * @param {object|undefined} where
  928. * @returns {Promise<number>}
  929. */
  930. async delete(modelName, where = void 0) {
  931. const table = this._getCollection(modelName);
  932. const query = this._buildQuery(modelName, where);
  933. const { deletedCount } = await table.deleteMany(query);
  934. return deletedCount;
  935. }
  936. /**
  937. * Delete by id.
  938. *
  939. * @param {string} modelName
  940. * @param {string|number} id
  941. * @returns {Promise<boolean>}
  942. */
  943. async deleteById(modelName, id) {
  944. id = this._coerceId(id);
  945. const table = this._getCollection(modelName);
  946. const { deletedCount } = await table.deleteOne({ _id: id });
  947. return deletedCount > 0;
  948. }
  949. /**
  950. * Exists.
  951. *
  952. * @param {string} modelName
  953. * @param {string|number} id
  954. * @returns {Promise<boolean>}
  955. */
  956. async exists(modelName, id) {
  957. id = this._coerceId(id);
  958. const table = this._getCollection(modelName);
  959. const result = await table.findOne({ _id: id }, {});
  960. return result != null;
  961. }
  962. /**
  963. * Count.
  964. *
  965. * @param {string} modelName
  966. * @param {object|undefined} where
  967. * @returns {Promise<number>}
  968. */
  969. async count(modelName, where = void 0) {
  970. const query = this._buildQuery(modelName, where);
  971. const table = this._getCollection(modelName);
  972. return await table.count(query);
  973. }
  974. };
  975. __name(_MongodbAdapter, "MongodbAdapter");
  976. var MongodbAdapter = _MongodbAdapter;
  977. // Annotate the CommonJS export names for ESM import in node:
  978. 0 && (module.exports = {
  979. MongodbAdapter
  980. });