@travetto/model-mongo 8.0.4 → 8.0.6

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
@@ -21,7 +21,7 @@ Supported features:
21
21
  * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L10)
22
22
  * [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
23
23
  * [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#L21)
24
- * [Aggregate](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/aggregate.ts#L43)
24
+ * [Aggregate](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/aggregate.ts#L56)
25
25
  * [Query Crud](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/crud.ts#L11)
26
26
  * [Facet](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/facet.ts#L14)
27
27
  * [Suggest](https://github.com/travetto/travetto/tree/main/module/model-query/src/types/suggest.ts#L12)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-mongo",
3
- "version": "8.0.4",
3
+ "version": "8.0.6",
4
4
  "description": "Mongo backing for the travetto model module.",
5
5
  "keywords": [
6
6
  "database",
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@travetto/config": "^8.0.3",
33
- "@travetto/model": "^8.0.3",
34
- "@travetto/model-indexed": "^8.0.3",
35
- "@travetto/model-query": "^8.0.4",
33
+ "@travetto/model": "^8.0.4",
34
+ "@travetto/model-indexed": "^8.0.4",
35
+ "@travetto/model-query": "^8.0.6",
36
36
  "mongodb": "^7.6.0"
37
37
  },
38
38
  "peerDependencies": {
package/src/service.ts CHANGED
@@ -63,10 +63,10 @@ import {
63
63
  ModelQuerySuggestUtil,
64
64
  type ModelQuerySupport,
65
65
  ModelQueryUtil,
66
+ type NumberFieldAggregateResult,
66
67
  type PageableModelQuery,
67
68
  QueryVerifier,
68
69
  type ValidComparableFields,
69
- type ValidNumericFields,
70
70
  type ValidStringFields,
71
71
  type WhereClause
72
72
  } from '@travetto/model-query';
@@ -80,7 +80,6 @@ import {
80
80
  type Class,
81
81
  castTo,
82
82
  JSONUtil,
83
- RuntimeError,
84
83
  ShutdownManager,
85
84
  TypedObject
86
85
  } from '@travetto/runtime';
@@ -105,6 +104,13 @@ const handleDuplicateKeyError = (cls: Class, id: string, error: unknown): unknow
105
104
  return error;
106
105
  };
107
106
 
107
+ function isNotFoundError(error: unknown): error is MongoServerError {
108
+ return (
109
+ (error instanceof MongoServerError && (error.code === 26 || error.codeName === 'NamespaceNotFound')) ||
110
+ (error instanceof Error && /ns not found/i.test(error.message))
111
+ );
112
+ }
113
+
108
114
  export const ModelBlobNamespace = '__blobs';
109
115
 
110
116
  /**
@@ -257,13 +263,15 @@ export class MongoModelService
257
263
  async createStorage(): Promise<void> {}
258
264
 
259
265
  async deleteStorage(): Promise<void> {
260
- await this.#db.dropDatabase();
266
+ await ModelStorageUtil.runAndIgnoreNotFound(() => this.#db.dropDatabase(), isNotFoundError);
261
267
  }
262
268
 
263
269
  async upsertModel(cls: Class): Promise<void> {
264
270
  const col = await this.getStore(cls);
265
271
  const indices = [...ModelRegistryIndex.getIndices(cls).map(idx => MongoUtil.getIndex(cls, idx)), ...MongoUtil.getExtraIndices(cls)];
266
- const existingIndices = (await col.indexes().catch(() => [])).filter(idx => idx.name !== '_id_');
272
+ const existingIndices = ((await ModelStorageUtil.runAndIgnoreNotFound(() => col.indexes(), isNotFoundError)) ?? []).filter(
273
+ idx => idx.name !== '_id_'
274
+ );
267
275
 
268
276
  const pendingMap = Object.fromEntries(indices.map(pair => [pair[1].name!, pair]));
269
277
  const existingMap = Object.fromEntries(existingIndices.map(idx => [idx.name!, idx.key]));
@@ -290,13 +298,17 @@ export class MongoModelService
290
298
  }
291
299
  }
292
300
 
301
+ async deleteModel<T extends ModelType>(cls: Class<T>): Promise<void> {
302
+ await ModelStorageUtil.runAndIgnoreNotFound(() => this.#db.collection(ModelRegistryIndex.getStoreName(cls)).drop(), isNotFoundError);
303
+ }
304
+
293
305
  async truncateModel<T extends ModelType>(cls: Class<T>): Promise<void> {
294
306
  const col = await this.getStore(cls);
295
307
  await col.deleteMany({});
296
308
  }
297
309
 
298
310
  async truncateBlob(): Promise<void> {
299
- await this.#bucket.drop().catch(() => {});
311
+ await this.#bucket.drop();
300
312
  }
301
313
 
302
314
  /**
@@ -738,7 +750,7 @@ export class MongoModelService
738
750
  }
739
751
 
740
752
  // Aggregate
741
- async aggregateFieldByQuery<T extends ModelType, F extends ValidComparableFields<T>>(
753
+ async aggregateFieldByQuery<T extends ModelType, const F extends ValidComparableFields<T>>(
742
754
  cls: Class<T>,
743
755
  field: F,
744
756
  query?: ModelQuery<T>
@@ -747,38 +759,28 @@ export class MongoModelService
747
759
 
748
760
  const collection = await this.getStore(cls);
749
761
 
750
- const where = ModelQueryUtil.getWhereClause(cls, query?.where);
751
- let queryObject: Record<string, unknown> = { [field]: { $exists: true, $ne: null } };
752
-
753
- if (where) {
754
- queryObject = { $and: [queryObject, MongoUtil.extractWhereFilter(cls, where)] };
755
- }
762
+ const where = ModelQueryUtil.getWhereClause(cls, {
763
+ $and: [query?.where ?? {}, { [field]: { $exists: true } }]
764
+ });
756
765
 
757
- const isDate = SchemaRegistryIndex.getNestedFieldConfig(cls, field)!.type === Date;
766
+ const isDate = SchemaRegistryIndex.getNestedFieldConfig(cls, field)?.type === Date;
758
767
 
759
768
  const groupFields: Record<string, unknown> = {
760
769
  _id: null,
761
770
  count: { $sum: 1 },
762
- min: { $min: `$${String(field)}` },
763
- max: { $max: `$${String(field)}` }
771
+ min: { $min: `$${field}` },
772
+ max: { $max: `$${field}` },
773
+ ...(isDate
774
+ ? {}
775
+ : {
776
+ avg: { $avg: `$${field}` },
777
+ sum: { $sum: `$${field}` }
778
+ })
764
779
  };
765
- if (!isDate) {
766
- groupFields.avg = { $avg: `$${String(field)}` };
767
- groupFields.sum = { $sum: `$${String(field)}` };
768
- }
769
-
770
- const aggregations: object[] = [{ $match: queryObject }, { $group: groupFields }];
771
-
772
- const result = await collection
773
- .aggregate<{
774
- _id: null;
775
- count?: number;
776
- min?: unknown;
777
- max?: unknown;
778
- avg?: unknown;
779
- sum?: unknown;
780
- }>(aggregations)
781
- .toArray();
780
+
781
+ const aggregations: object[] = [{ $match: MongoUtil.extractWhereFilter(cls, where) }, { $group: groupFields }];
782
+
783
+ const result = await collection.aggregate<NumberFieldAggregateResult>(aggregations).toArray();
782
784
 
783
785
  const row = result.length ? result[0] : { count: 0 };
784
786
  return ModelQueryAggregateUtil.resolveAggregate(cls, field, row);