@e22m4u/js-repository-mongodb-adapter 0.7.2 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.mocharc.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extension": ["js"],
3
+ "spec": "src/**/*.spec.js",
4
+ "require": "./mocha.setup.js"
5
+ }
@@ -28,7 +28,6 @@ module.exports = __toCommonJS(index_exports);
28
28
 
29
29
  // src/mongodb-adapter.js
30
30
  var import_mongodb2 = require("mongodb");
31
- var import_mongodb3 = require("mongodb");
32
31
 
33
32
  // node_modules/@e22m4u/js-service/src/errors/invalid-argument-error.js
34
33
  var import_js_format = require("@e22m4u/js-format");
@@ -991,17 +990,6 @@ function transformValuesDeep(value, transformer) {
991
990
  }
992
991
  __name(transformValuesDeep, "transformValuesDeep");
993
992
 
994
- // src/utils/model-name-to-collection-name.js
995
- function modelNameToCollectionName(modelName) {
996
- const ccName = toCamelCase2(modelName);
997
- const woModel = ccName.replace(/Model$/i, "");
998
- if (woModel.length <= 2) {
999
- return pluralize(ccName);
1000
- }
1001
- return pluralize(woModel);
1002
- }
1003
- __name(modelNameToCollectionName, "modelNameToCollectionName");
1004
-
1005
993
  // src/mongodb-adapter.js
1006
994
  var MONGODB_OPTION_NAMES = [
1007
995
  "ALPNProtocols",
@@ -1109,7 +1097,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1109
1097
  * Mongodb instance.
1110
1098
  *
1111
1099
  * @type {MongoClient}
1112
- * @private
1113
1100
  */
1114
1101
  _client;
1115
1102
  /**
@@ -1124,14 +1111,13 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1124
1111
  * Collections.
1125
1112
  *
1126
1113
  * @type {Map<any, any>}
1127
- * @private
1128
1114
  */
1129
1115
  _collections = /* @__PURE__ */ new Map();
1130
1116
  /**
1131
1117
  * Constructor.
1132
1118
  *
1133
1119
  * @param {ServiceContainer} container
1134
- * @param settings
1120
+ * @param {object} settings
1135
1121
  */
1136
1122
  constructor(container, settings) {
1137
1123
  settings = Object.assign({}, DEFAULT_SETTINGS, settings || {});
@@ -1142,13 +1128,13 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1142
1128
  super(container, settings);
1143
1129
  const options = (0, import_js_repository3.selectObjectKeys)(this.settings, MONGODB_OPTION_NAMES);
1144
1130
  const url = createMongodbUrl(this.settings);
1145
- this._client = new import_mongodb3.MongoClient(url, options);
1131
+ this._client = new import_mongodb2.MongoClient(url, options);
1146
1132
  }
1147
1133
  /**
1148
1134
  * Get id prop name.
1149
1135
  *
1150
- * @param modelName
1151
- * @private
1136
+ * @param {string} modelName
1137
+ * @returns {string}
1152
1138
  */
1153
1139
  _getIdPropName(modelName) {
1154
1140
  return this.getService(import_js_repository3.ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
@@ -1158,8 +1144,8 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1158
1144
  /**
1159
1145
  * Get id col name.
1160
1146
  *
1161
- * @param modelName
1162
- * @private
1147
+ * @param {string} modelName
1148
+ * @returns {string}
1163
1149
  */
1164
1150
  _getIdColName(modelName) {
1165
1151
  return this.getService(import_js_repository3.ModelDefinitionUtils).getPrimaryKeyAsColumnName(
@@ -1169,9 +1155,8 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1169
1155
  /**
1170
1156
  * Coerce id.
1171
1157
  *
1172
- * @param value
1158
+ * @param {*} value
1173
1159
  * @returns {ObjectId|*}
1174
- * @private
1175
1160
  */
1176
1161
  _coerceId(value) {
1177
1162
  if (value == null) return value;
@@ -1181,9 +1166,8 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1181
1166
  /**
1182
1167
  * Coerce date.
1183
1168
  *
1184
- * @param value
1169
+ * @param {Date|string|*} value
1185
1170
  * @returns {Date|*}
1186
- * @private
1187
1171
  */
1188
1172
  _coerceDate(value) {
1189
1173
  if (value == null) return value;
@@ -1197,7 +1181,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1197
1181
  * @param {string} modelName
1198
1182
  * @param {object} modelData
1199
1183
  * @returns {object}
1200
- * @private
1201
1184
  */
1202
1185
  _toDatabase(modelName, modelData) {
1203
1186
  const tableData = this.getService(
@@ -1227,7 +1210,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1227
1210
  * @param {string} modelName
1228
1211
  * @param {object} tableData
1229
1212
  * @returns {object}
1230
- * @private
1231
1213
  */
1232
1214
  _fromDatabase(modelName, tableData) {
1233
1215
  if ("_id" in tableData) {
@@ -1255,18 +1237,18 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1255
1237
  * Get collection name by model name.
1256
1238
  *
1257
1239
  * @param {string} modelName
1240
+ * @returns {string}
1258
1241
  */
1259
1242
  _getCollectionNameByModelName(modelName) {
1260
1243
  const modelDef = this.getService(import_js_repository3.DefinitionRegistry).getModel(modelName);
1261
1244
  if (modelDef.tableName != null) return modelDef.tableName;
1262
- return modelNameToCollectionName(modelDef.name);
1245
+ return pluralize(toCamelCase2(modelDef.name));
1263
1246
  }
1264
1247
  /**
1265
1248
  * Get collection.
1266
1249
  *
1267
1250
  * @param {string} modelName
1268
1251
  * @returns {*}
1269
- * @private
1270
1252
  */
1271
1253
  _getCollection(modelName) {
1272
1254
  let collection = this._collections.get(modelName);
@@ -1279,9 +1261,8 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1279
1261
  /**
1280
1262
  * Get id type.
1281
1263
  *
1282
- * @param modelName
1264
+ * @param {string} modelName
1283
1265
  * @returns {string|*}
1284
- * @private
1285
1266
  */
1286
1267
  _getIdType(modelName) {
1287
1268
  const utils = this.getService(import_js_repository3.ModelDefinitionUtils);
@@ -1294,7 +1275,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1294
1275
  * @param {string} modelName
1295
1276
  * @param {string} propName
1296
1277
  * @returns {string}
1297
- * @private
1298
1278
  */
1299
1279
  _getColName(modelName, propName) {
1300
1280
  if (!propName || typeof propName !== "string")
@@ -1319,7 +1299,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1319
1299
  * @param {string} modelName
1320
1300
  * @param {string} propsChain
1321
1301
  * @returns {string}
1322
- * @private
1323
1302
  */
1324
1303
  _convertPropNamesChainToColNamesChain(modelName, propsChain) {
1325
1304
  if (!modelName || typeof modelName !== "string")
@@ -1352,7 +1331,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1352
1331
  * @param {string} modelName
1353
1332
  * @param {string|string[]} fields
1354
1333
  * @returns {Record<string, number>|undefined}
1355
- * @private
1356
1334
  */
1357
1335
  _buildProjection(modelName, fields) {
1358
1336
  if (fields == null) return;
@@ -1379,7 +1357,6 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1379
1357
  * @param {string} modelName
1380
1358
  * @param {string|string[]} clause
1381
1359
  * @returns {object|undefined}
1382
- * @private
1383
1360
  */
1384
1361
  _buildSort(modelName, clause) {
1385
1362
  if (clause == null) return;
@@ -1414,8 +1391,7 @@ var _MongodbAdapter = class _MongodbAdapter extends import_js_repository3.Adapte
1414
1391
  *
1415
1392
  * @param {string} modelName
1416
1393
  * @param {object} clause
1417
- * @returns {object}
1418
- * @private
1394
+ * @returns {object|undefined}
1419
1395
  */
1420
1396
  _buildQuery(modelName, clause) {
1421
1397
  if (clause == null) return;
package/eslint.config.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import globals from 'globals';
2
2
  import eslintJs from '@eslint/js';
3
+ import eslintJsdocPlugin from 'eslint-plugin-jsdoc';
3
4
  import eslintMochaPlugin from 'eslint-plugin-mocha';
5
+ import eslintImportPlugin from 'eslint-plugin-import';
4
6
  import eslintPrettierConfig from 'eslint-config-prettier';
5
7
  import eslintChaiExpectPlugin from 'eslint-plugin-chai-expect';
6
8
 
@@ -13,14 +15,25 @@ export default [{
13
15
  },
14
16
  },
15
17
  plugins: {
18
+ 'jsdoc': eslintJsdocPlugin,
16
19
  'mocha': eslintMochaPlugin,
20
+ 'import': eslintImportPlugin,
17
21
  'chai-expect': eslintChaiExpectPlugin,
18
22
  },
19
23
  rules: {
20
24
  ...eslintJs.configs.recommended.rules,
21
25
  ...eslintPrettierConfig.rules,
26
+ ...eslintImportPlugin.flatConfigs.recommended.rules,
22
27
  ...eslintMochaPlugin.configs.recommended.rules,
23
28
  ...eslintChaiExpectPlugin.configs['recommended-flat'].rules,
29
+ ...eslintJsdocPlugin.configs['flat/recommended-error'].rules,
30
+ 'no-duplicate-imports': 'error',
31
+ 'jsdoc/reject-any-type': 0,
32
+ 'jsdoc/reject-function-type': 0,
33
+ 'jsdoc/require-param-description': 0,
34
+ 'jsdoc/require-returns-description': 0,
35
+ 'jsdoc/require-property-description': 0,
36
+ 'jsdoc/tag-lines': ['error', 'any', {startLines: 1}],
24
37
  },
25
38
  files: ['src/**/*.js'],
26
39
  }];
package/jsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext"
6
+ }
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-repository-mongodb-adapter",
3
- "version": "0.7.2",
3
+ "version": "0.8.1",
4
4
  "description": "MongoDB адаптер для @e22m4u/js-repository",
5
5
  "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
6
6
  "license": "MIT",
@@ -13,10 +13,10 @@
13
13
  "Datasource",
14
14
  "Relations"
15
15
  ],
16
- "homepage": "https://github.com/e22m4u/js-repository-mongodb-adapter",
16
+ "homepage": "https://gitrepos.ru/e22m4u/js-repository-mongodb-adapter",
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "git+https://github.com/e22m4u/js-repository-mongodb-adapter.git"
19
+ "url": "git+https://gitrepos.ru/e22m4u/js-repository-mongodb-adapter.git"
20
20
  },
21
21
  "type": "module",
22
22
  "module": "./src/index.js",
@@ -38,29 +38,31 @@
38
38
  "prepare": "husky"
39
39
  },
40
40
  "dependencies": {
41
- "@e22m4u/js-format": "~0.2.1",
41
+ "@e22m4u/js-format": "~0.3.0",
42
42
  "mongodb": "6.20.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "@e22m4u/js-repository": "~0.6.3"
45
+ "@e22m4u/js-repository": "~0.8.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@commitlint/cli": "~20.1.0",
49
49
  "@commitlint/config-conventional": "~20.0.0",
50
50
  "@eslint/js": "~9.39.1",
51
51
  "c8": "~10.1.3",
52
- "chai": "~6.2.0",
52
+ "chai": "~6.2.1",
53
53
  "chai-as-promised": "~8.0.2",
54
54
  "dotenv": "~17.2.3",
55
- "esbuild": "~0.25.12",
55
+ "esbuild": "~0.27.0",
56
56
  "eslint": "~9.39.1",
57
57
  "eslint-config-prettier": "~10.1.8",
58
58
  "eslint-plugin-chai-expect": "~3.1.0",
59
+ "eslint-plugin-import": "~2.32.0",
60
+ "eslint-plugin-jsdoc": "~61.4.1",
59
61
  "eslint-plugin-mocha": "~11.2.0",
60
62
  "globals": "~16.5.0",
61
63
  "husky": "~9.1.7",
62
64
  "mocha": "~11.7.5",
63
- "prettier": "~3.6.2",
64
- "rimraf": "~6.1.0"
65
+ "prettier": "~3.7.3",
66
+ "rimraf": "~6.1.2"
65
67
  }
66
68
  }
@@ -1,6 +1,5 @@
1
1
  /* eslint no-unused-vars: 0 */
2
- import {ObjectId} from 'mongodb';
3
- import {MongoClient} from 'mongodb';
2
+ import {ObjectId, MongoClient} from 'mongodb';
4
3
  import {ServiceContainer} from '@e22m4u/js-service';
5
4
 
6
5
  import {
@@ -17,11 +16,12 @@ import {
17
16
  } from '@e22m4u/js-repository';
18
17
 
19
18
  import {
19
+ pluralize,
20
20
  isIsoDate,
21
21
  isObjectId,
22
+ toCamelCase,
22
23
  createMongodbUrl,
23
24
  transformValuesDeep,
24
- modelNameToCollectionName,
25
25
  } from './utils/index.js';
26
26
 
27
27
  /**
@@ -148,7 +148,6 @@ export class MongodbAdapter extends Adapter {
148
148
  * Mongodb instance.
149
149
  *
150
150
  * @type {MongoClient}
151
- * @private
152
151
  */
153
152
  _client;
154
153
 
@@ -165,7 +164,6 @@ export class MongodbAdapter extends Adapter {
165
164
  * Collections.
166
165
  *
167
166
  * @type {Map<any, any>}
168
- * @private
169
167
  */
170
168
  _collections = new Map();
171
169
 
@@ -173,7 +171,7 @@ export class MongodbAdapter extends Adapter {
173
171
  * Constructor.
174
172
  *
175
173
  * @param {ServiceContainer} container
176
- * @param settings
174
+ * @param {object} settings
177
175
  */
178
176
  constructor(container, settings) {
179
177
  settings = Object.assign({}, DEFAULT_SETTINGS, settings || {});
@@ -190,8 +188,8 @@ export class MongodbAdapter extends Adapter {
190
188
  /**
191
189
  * Get id prop name.
192
190
  *
193
- * @param modelName
194
- * @private
191
+ * @param {string} modelName
192
+ * @returns {string}
195
193
  */
196
194
  _getIdPropName(modelName) {
197
195
  return this.getService(ModelDefinitionUtils).getPrimaryKeyAsPropertyName(
@@ -202,8 +200,8 @@ export class MongodbAdapter extends Adapter {
202
200
  /**
203
201
  * Get id col name.
204
202
  *
205
- * @param modelName
206
- * @private
203
+ * @param {string} modelName
204
+ * @returns {string}
207
205
  */
208
206
  _getIdColName(modelName) {
209
207
  return this.getService(ModelDefinitionUtils).getPrimaryKeyAsColumnName(
@@ -214,9 +212,8 @@ export class MongodbAdapter extends Adapter {
214
212
  /**
215
213
  * Coerce id.
216
214
  *
217
- * @param value
215
+ * @param {*} value
218
216
  * @returns {ObjectId|*}
219
- * @private
220
217
  */
221
218
  _coerceId(value) {
222
219
  if (value == null) return value;
@@ -227,9 +224,8 @@ export class MongodbAdapter extends Adapter {
227
224
  /**
228
225
  * Coerce date.
229
226
  *
230
- * @param value
227
+ * @param {Date|string|*} value
231
228
  * @returns {Date|*}
232
- * @private
233
229
  */
234
230
  _coerceDate(value) {
235
231
  if (value == null) return value;
@@ -244,7 +240,6 @@ export class MongodbAdapter extends Adapter {
244
240
  * @param {string} modelName
245
241
  * @param {object} modelData
246
242
  * @returns {object}
247
- * @private
248
243
  */
249
244
  _toDatabase(modelName, modelData) {
250
245
  const tableData = this.getService(
@@ -278,7 +273,6 @@ export class MongodbAdapter extends Adapter {
278
273
  * @param {string} modelName
279
274
  * @param {object} tableData
280
275
  * @returns {object}
281
- * @private
282
276
  */
283
277
  _fromDatabase(modelName, tableData) {
284
278
  if ('_id' in tableData) {
@@ -310,11 +304,16 @@ export class MongodbAdapter extends Adapter {
310
304
  * Get collection name by model name.
311
305
  *
312
306
  * @param {string} modelName
307
+ * @returns {string}
313
308
  */
314
309
  _getCollectionNameByModelName(modelName) {
315
310
  const modelDef = this.getService(DefinitionRegistry).getModel(modelName);
316
311
  if (modelDef.tableName != null) return modelDef.tableName;
317
- return modelNameToCollectionName(modelDef.name);
312
+ // если имя коллекции не определено явно (опция "tableName"),
313
+ // то выполняется приведение имени модели к стандартному camelCase
314
+ // во множественном числе
315
+ // "Article" -> "articles", "AccessToken" -> "accessTokens"
316
+ return pluralize(toCamelCase(modelDef.name));
318
317
  }
319
318
 
320
319
  /**
@@ -322,7 +321,6 @@ export class MongodbAdapter extends Adapter {
322
321
  *
323
322
  * @param {string} modelName
324
323
  * @returns {*}
325
- * @private
326
324
  */
327
325
  _getCollection(modelName) {
328
326
  let collection = this._collections.get(modelName);
@@ -338,9 +336,8 @@ export class MongodbAdapter extends Adapter {
338
336
  /**
339
337
  * Get id type.
340
338
  *
341
- * @param modelName
339
+ * @param {string} modelName
342
340
  * @returns {string|*}
343
- * @private
344
341
  */
345
342
  _getIdType(modelName) {
346
343
  const utils = this.getService(ModelDefinitionUtils);
@@ -354,7 +351,6 @@ export class MongodbAdapter extends Adapter {
354
351
  * @param {string} modelName
355
352
  * @param {string} propName
356
353
  * @returns {string}
357
- * @private
358
354
  */
359
355
  _getColName(modelName, propName) {
360
356
  if (!propName || typeof propName !== 'string')
@@ -383,7 +379,6 @@ export class MongodbAdapter extends Adapter {
383
379
  * @param {string} modelName
384
380
  * @param {string} propsChain
385
381
  * @returns {string}
386
- * @private
387
382
  */
388
383
  _convertPropNamesChainToColNamesChain(modelName, propsChain) {
389
384
  if (!modelName || typeof modelName !== 'string')
@@ -424,7 +419,6 @@ export class MongodbAdapter extends Adapter {
424
419
  * @param {string} modelName
425
420
  * @param {string|string[]} fields
426
421
  * @returns {Record<string, number>|undefined}
427
- * @private
428
422
  */
429
423
  _buildProjection(modelName, fields) {
430
424
  if (fields == null) return;
@@ -453,7 +447,6 @@ export class MongodbAdapter extends Adapter {
453
447
  * @param {string} modelName
454
448
  * @param {string|string[]} clause
455
449
  * @returns {object|undefined}
456
- * @private
457
450
  */
458
451
  _buildSort(modelName, clause) {
459
452
  if (clause == null) return;
@@ -493,8 +486,7 @@ export class MongodbAdapter extends Adapter {
493
486
  *
494
487
  * @param {string} modelName
495
488
  * @param {object} clause
496
- * @returns {object}
497
- * @private
489
+ * @returns {object|undefined}
498
490
  */
499
491
  _buildQuery(modelName, clause) {
500
492
  if (clause == null) return;
@@ -1,14 +1,16 @@
1
1
  import {expect} from 'chai';
2
- import {ObjectId} from 'mongodb';
3
- import {MongoClient} from 'mongodb';
4
2
  import {format} from '@e22m4u/js-format';
5
- import {DataType} from '@e22m4u/js-repository';
3
+ import {ObjectId, MongoClient} from 'mongodb';
6
4
  import {createMongodbUrl} from './utils/index.js';
7
5
  import {MongodbAdapter} from './mongodb-adapter.js';
8
- import {DatabaseSchema} from '@e22m4u/js-repository';
9
- import {AdapterRegistry} from '@e22m4u/js-repository';
10
- import {InvalidOperatorValueError} from '@e22m4u/js-repository';
11
- import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '@e22m4u/js-repository';
6
+
7
+ import {
8
+ DataType,
9
+ DatabaseSchema,
10
+ AdapterRegistry,
11
+ InvalidOperatorValueError,
12
+ DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK,
13
+ } from '@e22m4u/js-repository';
12
14
 
13
15
  const CONFIG = {
14
16
  host: process.env.MONGODB_HOST || 'localhost',
@@ -19,6 +21,11 @@ const CONFIG = {
19
21
  const MDB_CLIENT = new MongoClient(createMongodbUrl(CONFIG));
20
22
  const ADAPTERS_STACK = [];
21
23
 
24
+ /**
25
+ * Database schema factory.
26
+ *
27
+ * @returns {DatabaseSchema}
28
+ */
22
29
  function createSchema() {
23
30
  const schema = new DatabaseSchema();
24
31
  const adapter = new MongodbAdapter(schema.container, CONFIG);
@@ -62,26 +69,6 @@ describe('MongodbAdapter', function () {
62
69
  );
63
70
  });
64
71
 
65
- // prettier-ignore
66
- it('cuts off the "Model" suffix from the model name', async function () {
67
- const schema = createSchema();
68
- const modelNamesToCollectionNames = [
69
- ['camelCaseEntityModel', 'camelCaseEntities'],
70
- ['PascalCaseEntityModel', 'pascalCaseEntities'],
71
- ['snake_case_entity_model', 'snakeCaseEntities'],
72
- ['kebab-case-entity-model', 'kebabCaseEntities'],
73
- ['UPPER_SNAKE_CASE_ENTITY_MODEL', 'upperSnakeCaseEntities'],
74
- ['UPPER-KEBAB-CASE-ENTITY-MODEL', 'upperKebabCaseEntities'],
75
- ];
76
- modelNamesToCollectionNames.forEach(tuple =>
77
- schema.defineModel({name: tuple[0], datasource: 'mongodb'}),
78
- );
79
- const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
80
- modelNamesToCollectionNames.forEach(tuple =>
81
- expect(A._getCollectionNameByModelName(tuple[0])).to.be.eq(tuple[1]),
82
- );
83
- });
84
-
85
72
  it('converts already pluralized model name to camel case', async function () {
86
73
  const schema = createSchema();
87
74
  const modelNamesToCollectionNames = [
@@ -101,26 +88,6 @@ describe('MongodbAdapter', function () {
101
88
  );
102
89
  });
103
90
 
104
- // prettier-ignore
105
- it('converts already pluralized model name to camel case and cut off the "Model" suffix', async function () {
106
- const schema = createSchema();
107
- const modelNamesToCollectionNames = [
108
- ['camelCaseEntitiesModel', 'camelCaseEntities'],
109
- ['PascalCaseEntitiesModel', 'pascalCaseEntities'],
110
- ['snake_case_entities_model', 'snakeCaseEntities'],
111
- ['kebab-case-entities-model', 'kebabCaseEntities'],
112
- ['UPPER_SNAKE_CASE_ENTITIES_MODEL', 'upperSnakeCaseEntities'],
113
- ['UPPER-KEBAB-CASE-ENTITIES-MODEL', 'upperKebabCaseEntities'],
114
- ];
115
- modelNamesToCollectionNames.forEach(tuple =>
116
- schema.defineModel({name: tuple[0], datasource: 'mongodb'}),
117
- );
118
- const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
119
- modelNamesToCollectionNames.forEach(tuple =>
120
- expect(A._getCollectionNameByModelName(tuple[0])).to.be.eq(tuple[1]),
121
- );
122
- });
123
-
124
91
  it('returns the value from the "tableName" option if defined', async function () {
125
92
  const schema = createSchema();
126
93
  schema.defineModel({
@@ -136,31 +103,31 @@ describe('MongodbAdapter', function () {
136
103
  describe('_getCollection', function () {
137
104
  it('should create and return a new collection object on the first call', async function () {
138
105
  const schema = createSchema();
139
- schema.defineModel({name: 'myTestModel', datasource: 'mongodb'});
106
+ schema.defineModel({name: 'model', datasource: 'mongodb'});
140
107
  const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
141
- expect(A._collections.has('myTestModel')).to.be.false;
142
- const collection = A._getCollection('myTestModel');
108
+ expect(A._collections.has('model')).to.be.false;
109
+ const collection = A._getCollection('model');
143
110
  expect(collection).to.exist;
144
- expect(collection.collectionName).to.equal('myTests');
111
+ expect(collection.collectionName).to.equal('models');
145
112
  expect(collection.dbName).to.equal(CONFIG.database);
146
113
  });
147
114
 
148
115
  it('should cache the collection object after the first call', async function () {
149
116
  const schema = createSchema();
150
- schema.defineModel({name: 'myTestModel', datasource: 'mongodb'});
117
+ schema.defineModel({name: 'model', datasource: 'mongodb'});
151
118
  const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
152
- expect(A._collections.has('myTestModel')).to.be.false;
153
- A._getCollection('myTestModel');
154
- expect(A._collections.has('myTestModel')).to.be.true;
155
- expect(A._collections.get('myTestModel')).to.exist;
119
+ expect(A._collections.has('model')).to.be.false;
120
+ A._getCollection('model');
121
+ expect(A._collections.has('model')).to.be.true;
122
+ expect(A._collections.get('model')).to.exist;
156
123
  });
157
124
 
158
125
  it('should return the cached collection instance on subsequent calls', async function () {
159
126
  const schema = createSchema();
160
- schema.defineModel({name: 'myTestModel', datasource: 'mongodb'});
127
+ schema.defineModel({name: 'model', datasource: 'mongodb'});
161
128
  const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
162
- const collection1 = A._getCollection('myTestModel');
163
- const collection2 = A._getCollection('myTestModel');
129
+ const collection1 = A._getCollection('model');
130
+ const collection2 = A._getCollection('model');
164
131
  expect(collection2).to.equal(collection1);
165
132
  });
166
133
 
@@ -182,24 +149,6 @@ describe('MongodbAdapter', function () {
182
149
  });
183
150
  });
184
151
 
185
- it('cuts off the "Model" suffix from the model name', async function () {
186
- const schema = createSchema();
187
- const modelNamesToCollectionNames = [
188
- ['camelCaseEntityModel', 'camelCaseEntities'],
189
- ['PascalCaseEntityModel', 'pascalCaseEntities'],
190
- ['snake_case_entity_model', 'snakeCaseEntities'],
191
- ['kebab-case-entity-model', 'kebabCaseEntities'],
192
- ['UPPER_SNAKE_CASE_ENTITY_MODEL', 'upperSnakeCaseEntities'],
193
- ['UPPER-KEBAB-CASE-ENTITY-MODEL', 'upperKebabCaseEntities'],
194
- ];
195
- const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
196
- modelNamesToCollectionNames.forEach(tuple => {
197
- schema.defineModel({name: tuple[0], datasource: 'mongodb'});
198
- const collection = A._getCollection(tuple[0]);
199
- expect(collection.collectionName).to.equal(tuple[1]);
200
- });
201
- });
202
-
203
152
  it('converts already pluralized model name to camel case', async function () {
204
153
  const schema = createSchema();
205
154
  const modelNamesToCollectionNames = [
@@ -218,24 +167,6 @@ describe('MongodbAdapter', function () {
218
167
  });
219
168
  });
220
169
 
221
- it('converts already pluralized model name to camel case and cut off the "Model" suffix', async function () {
222
- const schema = createSchema();
223
- const modelNamesToCollectionNames = [
224
- ['camelCaseEntitiesModel', 'camelCaseEntities'],
225
- ['PascalCaseEntitiesModel', 'pascalCaseEntities'],
226
- ['snake_case_entities_model', 'snakeCaseEntities'],
227
- ['kebab-case-entities-model', 'kebabCaseEntities'],
228
- ['UPPER_SNAKE_CASE_ENTITIES_MODEL', 'upperSnakeCaseEntities'],
229
- ['UPPER-KEBAB-CASE-ENTITIES-MODEL', 'upperKebabCaseEntities'],
230
- ];
231
- const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
232
- modelNamesToCollectionNames.forEach(tuple => {
233
- schema.defineModel({name: tuple[0], datasource: 'mongodb'});
234
- const collection = A._getCollection(tuple[0]);
235
- expect(collection.collectionName).to.equal(tuple[1]);
236
- });
237
- });
238
-
239
170
  it('uses the value from the "tableName" option if defined', async function () {
240
171
  const schema = createSchema();
241
172
  const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
@@ -1,7 +1,23 @@
1
1
  import {InvalidArgumentError} from '@e22m4u/js-repository';
2
2
 
3
+ /**
4
+ * @typedef {object} MongoDBUrlOptions
5
+ * @property {string} [protocol]
6
+ * @property {string} [hostname]
7
+ * @property {string} [host]
8
+ * @property {number|string} [port]
9
+ * @property {string} [database]
10
+ * @property {string} [db]
11
+ * @property {string} [username]
12
+ * @property {string} [password]
13
+ * @property {string} [pass]
14
+ */
15
+
3
16
  /**
4
17
  * Generate the mongodb URL from the options.
18
+ *
19
+ * @param {MongoDBUrlOptions} options
20
+ * @returns {string}
5
21
  */
6
22
  export function createMongodbUrl(options = {}) {
7
23
  if (!options || typeof options !== 'object' || Array.isArray(options))
@@ -4,4 +4,3 @@ export * from './is-object-id.js';
4
4
  export * from './to-camel-case.js';
5
5
  export * from './create-mongodb-url.js';
6
6
  export * from './transform-values-deep.js';
7
- export * from './model-name-to-collection-name.js';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Is iso date.
3
3
  *
4
- * @param value
5
- * @return {boolean}
4
+ * @param {*} value
5
+ * @returns {boolean}
6
6
  */
7
7
  export function isIsoDate(value) {
8
8
  if (!value) return false;
@@ -3,8 +3,8 @@ import {ObjectId} from 'mongodb';
3
3
  /**
4
4
  * Is object id.
5
5
  *
6
- * @param value
7
- * @return {boolean}
6
+ * @param {*} value
7
+ * @returns {boolean}
8
8
  */
9
9
  export function isObjectId(value) {
10
10
  if (!value) return false;
@@ -1,11 +1,17 @@
1
1
  import {InvalidArgumentError} from '@e22m4u/js-repository';
2
2
 
3
+ /**
4
+ * @callback Transformer
5
+ * @param {*} value
6
+ * @returns {*}
7
+ */
8
+
3
9
  /**
4
10
  * Transform values deep.
5
11
  *
6
- * @param value
7
- * @param transformer
8
- * @return {*}
12
+ * @param {*} value
13
+ * @param {Transformer} transformer
14
+ * @returns {*}
9
15
  */
10
16
  export function transformValuesDeep(value, transformer) {
11
17
  if (!transformer || typeof transformer !== 'function')
package/.mocharc.cjs DELETED
@@ -1,7 +0,0 @@
1
- const path = require('path');
2
-
3
- module.exports = {
4
- extension: ['js'],
5
- spec: 'src/**/*.spec.js',
6
- require: [path.join(__dirname, 'mocha.setup.js')],
7
- }
@@ -1,26 +0,0 @@
1
- import {pluralize} from './pluralize.js';
2
- import {toCamelCase} from './to-camel-case.js';
3
-
4
- /**
5
- * Создает имя таблицы/коллекции по названию модели.
6
- *
7
- * @param {string} modelName
8
- * @returns {string}
9
- */
10
- export function modelNameToCollectionName(modelName) {
11
- // приведение имени класса к стандартному camelCase
12
- // "UserModel" -> "userModel", "Article" -> "article"
13
- const ccName = toCamelCase(modelName);
14
- // удаление постфикса "Model" с конца строки
15
- // "userModel" -> "user", "myModel" -> "my"
16
- const woModel = ccName.replace(/Model$/i, '');
17
- // если базовое имя слишком короткое (как "my" для "myModel"),
18
- // то используется имя, включающее постфикс "Model"
19
- if (woModel.length <= 2) {
20
- // pluralize('myModel') -> "myModels"
21
- return pluralize(ccName);
22
- }
23
- // для обычных имен обрабатывается без суффикса
24
- // pluralize('user') -> "users"
25
- return pluralize(woModel);
26
- }
@@ -1,89 +0,0 @@
1
- import {expect} from 'chai';
2
- import {modelNameToCollectionName} from './model-name-to-collection-name.js';
3
-
4
- describe('modelNameToCollectionName', function () {
5
- it('should correctly pluralize and remove the "Model" suffix for standard names', function () {
6
- expect(modelNameToCollectionName('userModel')).to.equal('users');
7
- expect(modelNameToCollectionName('UserModel')).to.equal('users');
8
- expect(modelNameToCollectionName('user_model')).to.equal('users');
9
- expect(modelNameToCollectionName('USER_MODEL')).to.equal('users');
10
- expect(modelNameToCollectionName('articleModel')).to.equal('articles');
11
- expect(modelNameToCollectionName('ArticleModel')).to.equal('articles');
12
- expect(modelNameToCollectionName('article_model')).to.equal('articles');
13
- expect(modelNameToCollectionName('ARTICLE_MODEL')).to.equal('articles');
14
- });
15
-
16
- it('should just pluralize names that do not have the "Model" suffix', function () {
17
- expect(modelNameToCollectionName('user')).to.equal('users');
18
- expect(modelNameToCollectionName('User')).to.equal('users');
19
- expect(modelNameToCollectionName('USER')).to.equal('users');
20
- expect(modelNameToCollectionName('article')).to.equal('articles');
21
- expect(modelNameToCollectionName('Article')).to.equal('articles');
22
- expect(modelNameToCollectionName('ARTICLE')).to.equal('articles');
23
- });
24
-
25
- it('should correctly handle already pluralized names with the "Model" suffix', function () {
26
- expect(modelNameToCollectionName('usersModel')).to.equal('users');
27
- expect(modelNameToCollectionName('UsersModel')).to.equal('users');
28
- expect(modelNameToCollectionName('users_model')).to.equal('users');
29
- expect(modelNameToCollectionName('USERS_MODEL')).to.equal('users');
30
- expect(modelNameToCollectionName('articlesModel')).to.equal('articles');
31
- expect(modelNameToCollectionName('ArticlesModel')).to.equal('articles');
32
- expect(modelNameToCollectionName('articles_model')).to.equal('articles');
33
- expect(modelNameToCollectionName('ARTICLES_MODEL')).to.equal('articles');
34
- });
35
-
36
- it('should correctly handle already pluralized names', function () {
37
- expect(modelNameToCollectionName('users')).to.equal('users');
38
- expect(modelNameToCollectionName('Users')).to.equal('users');
39
- expect(modelNameToCollectionName('USERS')).to.equal('users');
40
- expect(modelNameToCollectionName('articles')).to.equal('articles');
41
- expect(modelNameToCollectionName('Articles')).to.equal('articles');
42
- expect(modelNameToCollectionName('ARTICLES')).to.equal('articles');
43
- });
44
-
45
- it('should correctly handle different pluralization rules (like y -> ies)', function () {
46
- expect(modelNameToCollectionName('companyModel')).to.equal('companies');
47
- expect(modelNameToCollectionName('CompanyModel')).to.equal('companies');
48
- expect(modelNameToCollectionName('company_model')).to.equal('companies');
49
- expect(modelNameToCollectionName('COMPANY_MODEL')).to.equal('companies');
50
- });
51
-
52
- it('should correctly handle exceptions from pluralize (like status -> statuses)', function () {
53
- expect(modelNameToCollectionName('statusModel')).to.equal('statuses');
54
- expect(modelNameToCollectionName('StatusModel')).to.equal('statuses');
55
- expect(modelNameToCollectionName('status_model')).to.equal('statuses');
56
- expect(modelNameToCollectionName('STATUS_MODEL')).to.equal('statuses');
57
- });
58
-
59
- it('should handle edge cases where removing "Model" leaves a short word', function () {
60
- expect(modelNameToCollectionName('myModel')).to.equal('myModels');
61
- expect(modelNameToCollectionName('MyModel')).to.equal('myModels');
62
- expect(modelNameToCollectionName('my_model')).to.equal('myModels');
63
- expect(modelNameToCollectionName('MY_MODEL')).to.equal('myModels');
64
- expect(modelNameToCollectionName('doModel')).to.equal('doModels');
65
- expect(modelNameToCollectionName('DoModel')).to.equal('doModels');
66
- expect(modelNameToCollectionName('do_model')).to.equal('doModels');
67
- expect(modelNameToCollectionName('DO_MODEL')).to.equal('doModels');
68
- });
69
-
70
- it('should remove the "Model" suffix case-insensitively', function () {
71
- expect(modelNameToCollectionName('Usermodel')).to.equal('users');
72
- expect(modelNameToCollectionName('USERMODEL')).to.equal('users');
73
- });
74
-
75
- it('should handle names that contain "Model" but not at the end', function () {
76
- expect(modelNameToCollectionName('remodelAction')).to.equal(
77
- 'remodelActions',
78
- );
79
- expect(modelNameToCollectionName('RemodelAction')).to.equal(
80
- 'remodelActions',
81
- );
82
- expect(modelNameToCollectionName('remodel_action')).to.equal(
83
- 'remodelActions',
84
- );
85
- expect(modelNameToCollectionName('REMODEL_ACTION')).to.equal(
86
- 'remodelActions',
87
- );
88
- });
89
- });