@e22m4u/js-repository 0.0.41 → 0.0.42

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/README.md CHANGED
@@ -9,7 +9,7 @@ npm install @e22m4u/js-repository
9
9
  ```
10
10
 
11
11
  Опционально устанавливаем адаптер. Например, если используется
12
- *MongoDB*, то для подключения потребуется добавить
12
+ *MongoDB*, то для подключения потребуется установить
13
13
  [адаптер mongodb](https://www.npmjs.com/package/@e22m4u/js-repository-mongodb-adapter)
14
14
  как отдельную зависимость.
15
15
 
@@ -167,7 +167,7 @@ schema.defineModel({
167
167
  ```json
168
168
  {
169
169
  "id": 1,
170
- "name": "Burger King at Avenue Mall",
170
+ "name": "Burger King",
171
171
  "location": {
172
172
  "lat": 32.412891,
173
173
  "lng": 34.7660061
@@ -230,7 +230,7 @@ const rep = schema.getRepository('place');
230
230
 
231
231
  ```js
232
232
  const place = await rep.create({
233
- "name": "Burger King at Avenue Mall",
233
+ "name": "Burger King",
234
234
  "location": {
235
235
  "lat": 32.412891,
236
236
  "lng": 34.7660061
@@ -240,7 +240,7 @@ const place = await rep.create({
240
240
  console.log(place);
241
241
  // {
242
242
  // "id": 1,
243
- // "name": "Burger King at Avenue Mall",
243
+ // "name": "Burger King",
244
244
  // "location": {
245
245
  // "lat": 32.412891,
246
246
  // "lng": 34.7660061
@@ -257,22 +257,73 @@ console.log(place);
257
257
  ```js
258
258
  // {
259
259
  // "id": 1,
260
- // "name": "Burger King at Avenue Mall",
260
+ // "name": "Burger King",
261
261
  // "location": {
262
262
  // "lat": 32.412891,
263
263
  // "lng": 34.7660061
264
264
  // }
265
265
  // }
266
266
  const result = rep.replaceById(place.id, {
267
- name: 'Terminal 21 Shopping Mall',
268
- address: 'Sukhumvit 19 Alley'
267
+ name: 'Starbucks',
268
+ address: 'Sukhumvit Alley'
269
269
  });
270
270
 
271
271
  console.log(result);
272
272
  // {
273
273
  // "id": 1,
274
- // "name": "Terminal 21 Shopping Mall",
275
- // "address": "Sukhumvit 19 Alley"
274
+ // "name": "Starbucks",
275
+ // "address": "Sukhumvit Alley"
276
+ // }
277
+ ```
278
+
279
+ #### replaceOrCreate(data, filter = undefined)
280
+
281
+ Если вы знакомы с методом PUT в архитектуре REST, когда документ
282
+ добавляется, если его не существовало, или же обновляется существующий,
283
+ то `replaceOrCreate` работает схожим образом. Если параметр
284
+ `data` передаваемый первым аргументом будет содержать идентификатор,
285
+ то метод будет вести себя как `replaceById`, в противном случае будет
286
+ создан новый документ.
287
+
288
+ ```js
289
+ // {
290
+ // "id": 1,
291
+ // "name": "Starbucks",
292
+ // "address": "Sukhumvit Alley"
293
+ // }
294
+ const result = rep.replaceOrCreate({
295
+ id: 1,
296
+ name: 'Airport',
297
+ city: 'Antalya',
298
+ code: 'AYT'
299
+ });
300
+
301
+ console.log(result);
302
+ // {
303
+ // "id": 1,
304
+ // "name": "Airport",
305
+ // "city": "Antalya"
306
+ // "code": "AYT"
307
+ // }
308
+ ```
309
+
310
+ В примере выше был передан первичный ключ `id` для поиска и
311
+ замены существующего документа. Теперь рассмотрим создание
312
+ документа с новым идентификатором.
313
+
314
+ ```js
315
+ const result = rep.replaceOrCreate({
316
+ name: 'Airport',
317
+ city: 'Bangkok',
318
+ code: 'BKK',
319
+ });
320
+
321
+ console.log(result);
322
+ // {
323
+ // "id": 2,
324
+ // "name": "Airport",
325
+ // "city": "Bangkok",
326
+ // "code": "BKK"
276
327
  // }
277
328
  ```
278
329
 
@@ -284,21 +335,22 @@ console.log(result);
284
335
 
285
336
  ```js
286
337
  // {
287
- // "id": 1,
288
- // "name": "Terminal 21 Shopping Mall",
289
- // "address": "Sukhumvit 19 Alley"
338
+ // "id": 2,
339
+ // "name": "Airport",
340
+ // "city": "Bangkok",
341
+ // "code": "BKK"
290
342
  // }
291
343
  const result = rep.patchById(place.id, {
292
- address: 'Moo 6',
293
- city: 'Pattaya',
344
+ city: 'Moscow',
345
+ code: 'SVO'
294
346
  });
295
347
 
296
348
  console.log(result);
297
349
  // {
298
- // "id": 1,
299
- // "name": "Terminal 21 Shopping Mall",
300
- // "address": "Moo 6",
301
- // "city": "Pattaya"
350
+ // "id": 2,
351
+ // "name": "Airport",
352
+ // "city": "Moscow",
353
+ // "code": "SVO"
302
354
  // }
303
355
  ```
304
356
 
@@ -669,7 +721,7 @@ schema.defineModel({
669
721
  order: {
670
722
  type: 'hasOne',
671
723
  model: 'order',
672
- foreignKey: 'customerId', // опционально
724
+ foreignKey: 'customerId', // поле целевой модели
673
725
  },
674
726
  },
675
727
  });
@@ -721,7 +773,7 @@ schema.defineModel({
721
773
  orders: {
722
774
  type: 'hasMany',
723
775
  model: 'order',
724
- foreignKey: 'customerId', // опционально
776
+ foreignKey: 'customerId', // поле целевой модели
725
777
  },
726
778
  },
727
779
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-repository",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "Абстракция для работы с базами данных для Node.js",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -1589,11 +1589,11 @@ describe('MemoryAdapter', function () {
1589
1589
  properties: {
1590
1590
  foo: {
1591
1591
  type: DataType.STRING,
1592
- columnName: 'fooVal',
1592
+ columnName: 'fooCol',
1593
1593
  },
1594
1594
  bar: {
1595
1595
  type: DataType.STRING,
1596
- columnName: 'barVal',
1596
+ columnName: 'barCol',
1597
1597
  },
1598
1598
  },
1599
1599
  });
@@ -1610,17 +1610,17 @@ describe('MemoryAdapter', function () {
1610
1610
  const table = adapter._getTableOrCreate('model');
1611
1611
  const createdItems = Array.from(table.values());
1612
1612
  expect(createdItems).to.be.eql([
1613
- {[DEF_PK]: id1, fooVal: 'a', barVal: '1'},
1614
- {[DEF_PK]: id2, fooVal: 'b', barVal: '2'},
1615
- {[DEF_PK]: id3, fooVal: 'c', barVal: '2'},
1613
+ {[DEF_PK]: id1, fooCol: 'a', barCol: '1'},
1614
+ {[DEF_PK]: id2, fooCol: 'b', barCol: '2'},
1615
+ {[DEF_PK]: id3, fooCol: 'c', barCol: '2'},
1616
1616
  ]);
1617
1617
  const result = await adapter.patch('model', {foo: 'd'}, {bar: '2'});
1618
1618
  expect(result).to.be.eq(2);
1619
1619
  const patchedItems = Array.from(table.values());
1620
1620
  expect(patchedItems).to.be.eql([
1621
- {[DEF_PK]: id1, fooVal: 'a', barVal: '1'},
1622
- {[DEF_PK]: id2, fooVal: 'd', barVal: '2'},
1623
- {[DEF_PK]: id3, fooVal: 'd', barVal: '2'},
1621
+ {[DEF_PK]: id1, fooCol: 'a', barCol: '1'},
1622
+ {[DEF_PK]: id2, fooCol: 'd', barCol: '2'},
1623
+ {[DEF_PK]: id3, fooCol: 'd', barCol: '2'},
1624
1624
  ]);
1625
1625
  });
1626
1626
 
@@ -99,8 +99,8 @@ export declare type PolyBelongsToDefinition = {
99
99
  export declare type HasOneDefinition = {
100
100
  type: RelationType.HAS_ONE;
101
101
  model: string;
102
+ foreignKey: string;
102
103
  polymorphic?: false;
103
- foreignKey?: string;
104
104
  discriminator?: undefined;
105
105
  };
106
106
 
@@ -127,16 +127,7 @@ export declare type PolyHasOneDefinitionWithTargetRelationName = {
127
127
  /**
128
128
  * The polymorphic "hasOne" relation with target relation keys.
129
129
  *
130
- * @example Required options only.
131
- * ```
132
- * {
133
- * type: RelationType.HAS_ONE,
134
- * model: 'model',
135
- * polymorphic: true,
136
- * }
137
- * ```
138
- *
139
- * @example Verbose definition.
130
+ * @example
140
131
  * ```
141
132
  * {
142
133
  * type: RelationType.HAS_ONE,
@@ -151,8 +142,8 @@ export declare type PolyHasOneDefinitionWithTargetKeys = {
151
142
  type: RelationType.HAS_ONE;
152
143
  model: string;
153
144
  polymorphic: true;
154
- foreignKey?: string;
155
- discriminator?: string;
145
+ foreignKey: string;
146
+ discriminator: string;
156
147
  };
157
148
 
158
149
  /**
@@ -170,8 +161,8 @@ export declare type PolyHasOneDefinitionWithTargetKeys = {
170
161
  export declare type HasManyDefinition = {
171
162
  type: RelationType.HAS_MANY;
172
163
  model: string;
164
+ foreignKey: string;
173
165
  polymorphic?: false;
174
- foreignKey?: string;
175
166
  discriminator?: undefined;
176
167
  };
177
168
 
@@ -198,16 +189,7 @@ export declare type PolyHasManyDefinitionWithTargetRelationName = {
198
189
  /**
199
190
  * The polymorphic "hasMany" relation with target relation keys.
200
191
  *
201
- * @example Required options only.
202
- * ```
203
- * {
204
- * type: RelationType.HAS_MANY,
205
- * model: 'model',
206
- * polymorphic: true,
207
- * }
208
- * ```
209
- *
210
- * @example Verbose definition.
192
+ * @example
211
193
  * ```
212
194
  * {
213
195
  * type: RelationType.HAS_MANY,
@@ -222,8 +204,8 @@ export declare type PolyHasManyDefinitionWithTargetKeys = {
222
204
  type: RelationType.HAS_MANY;
223
205
  model: string;
224
206
  polymorphic: true;
225
- foreignKey?: string;
226
- discriminator?: string;
207
+ foreignKey: string;
208
+ discriminator: string;
227
209
  };
228
210
 
229
211
  /**
@@ -253,15 +253,15 @@ describe('RelationsDefinitionValidator', function () {
253
253
  const validate = v => {
254
254
  const foo = {
255
255
  type: RelationType.HAS_ONE,
256
- model: 'model',
257
- foreignKey: v,
256
+ model: v,
257
+ foreignKey: 'modelId',
258
258
  };
259
259
  return () => S.validate('model', {foo});
260
260
  };
261
261
  const error = v =>
262
262
  format(
263
263
  'The relation "foo" of the model "model" has the type "hasOne", ' +
264
- 'so it requires the option "foreignKey" to be a non-empty String, ' +
264
+ 'so it requires the option "model" to be a non-empty String, ' +
265
265
  'but %s given.',
266
266
  v,
267
267
  );
@@ -273,22 +273,22 @@ describe('RelationsDefinitionValidator', function () {
273
273
  expect(validate([])).to.throw(error('Array'));
274
274
  expect(validate(undefined)).to.throw(error('undefined'));
275
275
  expect(validate(null)).to.throw(error('null'));
276
- validate('modelId')();
276
+ validate('model')();
277
277
  });
278
278
 
279
- it('requires the option "foreignKey" to be a string', function () {
279
+ it('requires the option "foreignKey" to be a non-empty string', function () {
280
280
  const validate = v => {
281
281
  const foo = {
282
282
  type: RelationType.HAS_ONE,
283
- model: v,
284
- foreignKey: 'modelId',
283
+ model: 'model',
284
+ foreignKey: v,
285
285
  };
286
286
  return () => S.validate('model', {foo});
287
287
  };
288
288
  const error = v =>
289
289
  format(
290
290
  'The relation "foo" of the model "model" has the type "hasOne", ' +
291
- 'so it requires the option "model" to be a non-empty String, ' +
291
+ 'so it requires the option "foreignKey" to be a non-empty String, ' +
292
292
  'but %s given.',
293
293
  v,
294
294
  );
@@ -300,7 +300,7 @@ describe('RelationsDefinitionValidator', function () {
300
300
  expect(validate([])).to.throw(error('Array'));
301
301
  expect(validate(undefined)).to.throw(error('undefined'));
302
302
  expect(validate(null)).to.throw(error('null'));
303
- validate('model')();
303
+ validate('modelId')();
304
304
  });
305
305
 
306
306
  it('throws an error if the option "discriminator" is provided', function () {
@@ -479,15 +479,15 @@ describe('RelationsDefinitionValidator', function () {
479
479
  const validate = v => {
480
480
  const foo = {
481
481
  type: RelationType.HAS_MANY,
482
- model: 'model',
483
- foreignKey: v,
482
+ model: v,
483
+ foreignKey: 'modelId',
484
484
  };
485
485
  return () => S.validate('model', {foo});
486
486
  };
487
487
  const error = v =>
488
488
  format(
489
489
  'The relation "foo" of the model "model" has the type "hasMany", ' +
490
- 'so it requires the option "foreignKey" to be a non-empty String, ' +
490
+ 'so it requires the option "model" to be a non-empty String, ' +
491
491
  'but %s given.',
492
492
  v,
493
493
  );
@@ -499,22 +499,22 @@ describe('RelationsDefinitionValidator', function () {
499
499
  expect(validate([])).to.throw(error('Array'));
500
500
  expect(validate(undefined)).to.throw(error('undefined'));
501
501
  expect(validate(null)).to.throw(error('null'));
502
- validate('modelId')();
502
+ validate('model')();
503
503
  });
504
504
 
505
- it('requires the option "foreignKey" to be a string', function () {
505
+ it('requires the option "foreignKey" to be a non-empty string', function () {
506
506
  const validate = v => {
507
507
  const foo = {
508
508
  type: RelationType.HAS_MANY,
509
- model: v,
510
- foreignKey: 'modelId',
509
+ model: 'model',
510
+ foreignKey: v,
511
511
  };
512
512
  return () => S.validate('model', {foo});
513
513
  };
514
514
  const error = v =>
515
515
  format(
516
516
  'The relation "foo" of the model "model" has the type "hasMany", ' +
517
- 'so it requires the option "model" to be a non-empty String, ' +
517
+ 'so it requires the option "foreignKey" to be a non-empty String, ' +
518
518
  'but %s given.',
519
519
  v,
520
520
  );
@@ -526,7 +526,7 @@ describe('RelationsDefinitionValidator', function () {
526
526
  expect(validate([])).to.throw(error('Array'));
527
527
  expect(validate(undefined)).to.throw(error('undefined'));
528
528
  expect(validate(null)).to.throw(error('null'));
529
- validate('model')();
529
+ validate('modelId')();
530
530
  });
531
531
 
532
532
  it('throws an error if the option "discriminator" is provided', function () {
@@ -43,9 +43,9 @@ export declare type ItemFilterClause = Pick<FilterClause, 'fields' | 'include'>;
43
43
  * ```
44
44
  */
45
45
  export declare type WhereClause =
46
- | AndClause
47
- | OrClause
48
- | PropertiesClause;
46
+ & AndClause
47
+ & OrClause
48
+ & PropertiesClause;
49
49
 
50
50
  /**
51
51
  * Properties clause.
@@ -67,7 +67,8 @@ export type PropertiesClause = {
67
67
  | boolean
68
68
  | RegExp
69
69
  | null
70
- | undefined;
70
+ | undefined
71
+ | object;
71
72
  };
72
73
 
73
74
  /**