@travetto/model-mongo 8.0.0-alpha.25 → 8.0.0-alpha.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-mongo",
3
- "version": "8.0.0-alpha.25",
3
+ "version": "8.0.0-alpha.27",
4
4
  "type": "module",
5
5
  "description": "Mongo backing for the travetto model module.",
6
6
  "keywords": [
@@ -26,14 +26,14 @@
26
26
  "directory": "module/model-mongo"
27
27
  },
28
28
  "dependencies": {
29
- "@travetto/config": "^8.0.0-alpha.22",
30
- "@travetto/model": "^8.0.0-alpha.23",
31
- "@travetto/model-indexed": "^8.0.0-alpha.25",
32
- "@travetto/model-query": "^8.0.0-alpha.24",
29
+ "@travetto/config": "^8.0.0-alpha.23",
30
+ "@travetto/model": "^8.0.0-alpha.24",
31
+ "@travetto/model-indexed": "^8.0.0-alpha.26",
32
+ "@travetto/model-query": "^8.0.0-alpha.26",
33
33
  "mongodb": "^7.5.0"
34
34
  },
35
35
  "peerDependencies": {
36
- "@travetto/cli": "^8.0.0-alpha.28"
36
+ "@travetto/cli": "^8.0.0-alpha.29"
37
37
  },
38
38
  "peerDependenciesMeta": {
39
39
  "@travetto/cli": {
@@ -265,7 +265,7 @@ export class MongoUtil {
265
265
  const overlap = [...pendingKeySet.intersection(existingKeySet)];
266
266
  changed ||= overlap.length !== pendingKeySet.size;
267
267
 
268
- for (let i = 0; i < overlap.length && !changed; i++) {
268
+ for (let i = 0; i < overlap.length && !changed; i += 1) {
269
269
  changed ||= existingFields[overlap[i]] !== pendingKey[overlap[i]];
270
270
  }
271
271
 
package/src/service.ts CHANGED
@@ -31,7 +31,8 @@ import {
31
31
  ModelStorageUtil,
32
32
  type ModelType,
33
33
  NotFoundError,
34
- type OptionalId
34
+ type OptionalId,
35
+ UniqueError
35
36
  } from '@travetto/model';
36
37
  import {
37
38
  type FullKeyedIndexBody,
@@ -85,7 +86,17 @@ type BlobRaw = GridFSFile & { metadata?: BinaryMetadata };
85
86
 
86
87
  type MongoTextSearch = RootFilterOperators<unknown>['$text'];
87
88
 
88
- const isDuplicateKeyError = (error: unknown): boolean => error instanceof MongoServerError && error.message.includes('duplicate key error');
89
+ const handleDuplicateKeyError = (cls: Class, id: string, error: unknown): unknown => {
90
+ if (error instanceof MongoServerError && error.message.includes('duplicate key error')) {
91
+ if (error.message.includes('_id_') || (error.keyPattern && '_id' in error.keyPattern)) {
92
+ return new ExistsError(cls, id);
93
+ }
94
+ const match = error.message.match(/index: ([\w$]+)/);
95
+ const constraint = match ? match[1] : error.keyPattern ? Object.keys(error.keyPattern).join(',') : 'unique';
96
+ return new UniqueError(cls, constraint, { detail: error.message });
97
+ }
98
+ return error;
99
+ };
89
100
 
90
101
  export const ModelBlobNamespace = '__blobs';
91
102
 
@@ -312,7 +323,7 @@ export class MongoModelService
312
323
  }
313
324
  return this.postUpdate(cleaned, id);
314
325
  } catch (error) {
315
- throw isDuplicateKeyError(error) ? new ExistsError(cls, id) : error;
326
+ throw handleDuplicateKeyError(cls, id, error);
316
327
  }
317
328
  }
318
329
 
@@ -335,7 +346,7 @@ export class MongoModelService
335
346
  try {
336
347
  await store.updateOne(this.getIdFilter(cls, id, false), { $set: cleaned }, { upsert: true });
337
348
  } catch (error) {
338
- throw isDuplicateKeyError(error) ? new ExistsError(cls, id) : error;
349
+ throw handleDuplicateKeyError(cls, id, error);
339
350
  }
340
351
  return this.postUpdate(cleaned, id);
341
352
  }