@aneuhold/be-ts-db-lib 1.0.4 → 1.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.
Files changed (27) hide show
  1. package/README.md +4 -0
  2. package/lib/repositories/BaseRepository.d.ts +27 -3
  3. package/lib/repositories/BaseRepository.d.ts.map +1 -1
  4. package/lib/repositories/BaseRepository.js +45 -9
  5. package/lib/repositories/common/UserRepository.d.ts.map +1 -1
  6. package/lib/repositories/common/UserRepository.js +10 -4
  7. package/lib/repositories/dashboard/DashboardBaseRepository.d.ts +11 -0
  8. package/lib/repositories/dashboard/DashboardBaseRepository.d.ts.map +1 -0
  9. package/lib/repositories/dashboard/DashboardBaseRepository.js +21 -0
  10. package/lib/repositories/dashboard/UserConfigRepository.d.ts +18 -0
  11. package/lib/repositories/dashboard/UserConfigRepository.d.ts.map +1 -0
  12. package/lib/repositories/dashboard/UserConfigRepository.js +37 -0
  13. package/lib/tests/repositories/BaseRepository.spec.js +12 -0
  14. package/lib/tests/repositories/common/UserRepository.spec.d.ts.map +1 -0
  15. package/lib/tests/repositories/{UserRepository.spec.js → common/UserRepository.spec.js} +4 -4
  16. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.d.ts +2 -0
  17. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.d.ts.map +1 -0
  18. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.js +50 -0
  19. package/lib/util/DocumentCleaner.d.ts +11 -0
  20. package/lib/util/DocumentCleaner.d.ts.map +1 -0
  21. package/lib/util/DocumentCleaner.js +24 -0
  22. package/lib/validators/dashboard/UserConfigValidator.d.ts +7 -0
  23. package/lib/validators/dashboard/UserConfigValidator.d.ts.map +1 -0
  24. package/lib/validators/dashboard/UserConfigValidator.js +33 -0
  25. package/package.json +4 -4
  26. package/lib/tests/repositories/UserRepository.spec.d.ts.map +0 -1
  27. /package/lib/tests/repositories/{UserRepository.spec.d.ts → common/UserRepository.spec.d.ts} +0 -0
package/README.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  This is used to actually interact with databases in personal projects.
6
6
 
7
+ ## Manual Database Operations
8
+
9
+ Go ahead and run these as code in a test in the BaseRepository.spec.ts file.
10
+
7
11
  ## Dependencies
8
12
 
9
13
  - [`core-ts-db-lib`](https://github.com/aneuhold/core-ts-db-lib)
@@ -1,16 +1,26 @@
1
1
  import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
2
  import { Collection, DeleteResult, UpdateResult } from 'mongodb';
3
- import { ObjectId } from 'bson';
3
+ import { Document, ObjectId } from 'bson';
4
4
  import IValidator from '../validators/BaseValidator';
5
5
  /**
6
6
  * A base repository that implements a lot of the normal CRUD operations.
7
7
  */
8
8
  export default abstract class BaseRepository<TBasetype extends BaseDocument> {
9
9
  private validator;
10
+ private defaultFilter?;
11
+ private defaultUpdateCleaner?;
10
12
  protected collectionName: string;
11
13
  private collection?;
12
- constructor(collectionName: string, validator: IValidator<TBasetype>);
13
- protected getCollection(): Promise<Collection<import("bson").Document>>;
14
+ /**
15
+ * Constructs a new base repository.
16
+ *
17
+ * @param defaultUpdateCleaner this is a function that will be run on the
18
+ * update object before it is sent to the DB. This is useful for removing
19
+ * fields that should not be updated. Only remove fields that are at the
20
+ * top-level of the object. _id is already removed.
21
+ */
22
+ constructor(collectionName: string, validator: IValidator<TBasetype>, defaultFilter?: Partial<TBasetype> | undefined, defaultUpdateCleaner?: ((doc: Partial<TBasetype>) => Partial<TBasetype>) | undefined);
23
+ protected getCollection(): Promise<Collection<Document>>;
14
24
  insertNew(newDoc: TBasetype): Promise<TBasetype | null>;
15
25
  get(filter: Partial<TBasetype>): Promise<TBasetype | null>;
16
26
  getAll(): Promise<TBasetype[]>;
@@ -27,5 +37,19 @@ export default abstract class BaseRepository<TBasetype extends BaseDocument> {
27
37
  * This base method strips the `_id` before updating.
28
38
  */
29
39
  update(updatedDoc: Partial<TBasetype>): Promise<UpdateResult>;
40
+ /**
41
+ * Gets the filter with the default filter applied if there is one.
42
+ *
43
+ * This is purposefully changing the type because of some weird restrictions
44
+ * with the `mongodb` package types.
45
+ */
46
+ private getFilterWithDefault;
47
+ /**
48
+ * Cleans the update object by removing the `_id` field and running the
49
+ * default update cleaner if there is one.
50
+ *
51
+ * Returns a shallow copy of the object.
52
+ */
53
+ private cleanUpdateObject;
30
54
  }
31
55
  //# sourceMappingURL=BaseRepository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/BaseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,UAAU,MAAM,6BAA6B,CAAC;AAErD;;GAEG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,SAAS,SAAS,YAAY;IAOvE,OAAO,CAAC,SAAS;IANnB,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IAEjC,OAAO,CAAC,UAAU,CAAC,CAAa;gBAG9B,cAAc,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC;cAK1B,aAAa;IAOvB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAUvD,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAM1D,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAO9B,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMjD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAK9C,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAK3D;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAKxC;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;CAYpE"}
1
+ {"version":3,"file":"BaseRepository.d.ts","sourceRoot":"","sources":["../../src/repositories/BaseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAU,YAAY,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,UAAU,MAAM,6BAA6B,CAAC;AAGrD;;GAEG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,SAAS,SAAS,YAAY;IAevE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,oBAAoB,CAAC;IAhB/B,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IAEjC,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC;;;;;;;OAOG;gBAED,cAAc,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,EAChC,aAAa,CAAC,gCAAoB,EAClC,oBAAoB,CAAC,SACtB,QAAQ,SAAS,CAAC,KACpB,QAAQ,SAAS,CAAC,aAAA;cAKT,aAAa;IAOvB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAUvD,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAM1D,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAO9B,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQjD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAK9C,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAK3D;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAKxC;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnE;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;CAO1B"}
@@ -4,15 +4,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const DocumentDb_1 = __importDefault(require("../util/DocumentDb"));
7
+ const DocumentCleaner_1 = __importDefault(require("../util/DocumentCleaner"));
7
8
  /**
8
9
  * A base repository that implements a lot of the normal CRUD operations.
9
10
  */
10
11
  class BaseRepository {
11
12
  validator;
13
+ defaultFilter;
14
+ defaultUpdateCleaner;
12
15
  collectionName;
13
16
  collection;
14
- constructor(collectionName, validator) {
17
+ /**
18
+ * Constructs a new base repository.
19
+ *
20
+ * @param defaultUpdateCleaner this is a function that will be run on the
21
+ * update object before it is sent to the DB. This is useful for removing
22
+ * fields that should not be updated. Only remove fields that are at the
23
+ * top-level of the object. _id is already removed.
24
+ */
25
+ constructor(collectionName, validator, defaultFilter, defaultUpdateCleaner) {
15
26
  this.validator = validator;
27
+ this.defaultFilter = defaultFilter;
28
+ this.defaultUpdateCleaner = defaultUpdateCleaner;
16
29
  this.collectionName = collectionName;
17
30
  }
18
31
  async getCollection() {
@@ -32,18 +45,20 @@ class BaseRepository {
32
45
  }
33
46
  async get(filter) {
34
47
  const collection = await this.getCollection();
35
- const result = await collection.findOne(filter);
48
+ const result = await collection.findOne(this.getFilterWithDefault(filter));
36
49
  return result;
37
50
  }
38
51
  async getAll() {
39
52
  const collection = await this.getCollection();
40
- const result = await collection.find().toArray();
53
+ const result = await collection.find(this.getFilterWithDefault()).toArray();
41
54
  // Set to unknown first because of some weird type things.
42
55
  return result;
43
56
  }
44
57
  async getList(docIds) {
45
58
  const collection = await this.getCollection();
46
- const result = await collection.find({ _id: { $in: docIds } }).toArray();
59
+ const result = await collection
60
+ .find(this.getFilterWithDefault({ _id: { $in: docIds } }))
61
+ .toArray();
47
62
  return result;
48
63
  }
49
64
  async delete(docId) {
@@ -59,7 +74,7 @@ class BaseRepository {
59
74
  */
60
75
  async deleteAll() {
61
76
  const collection = await this.getCollection();
62
- return collection.deleteMany({});
77
+ return collection.deleteMany(this.getFilterWithDefault());
63
78
  }
64
79
  /**
65
80
  * Updates the provided doc in the DB.
@@ -70,10 +85,31 @@ class BaseRepository {
70
85
  const collection = await this.getCollection();
71
86
  await this.validator.validateUpdateObject(updatedDoc);
72
87
  const docId = updatedDoc._id;
73
- // Create a copy so that there aren't side-effects
74
- const docCopy = { ...updatedDoc };
75
- delete docCopy._id;
76
- return collection.updateOne({ _id: docId }, { $set: docCopy });
88
+ const cleanedDoc = this.cleanUpdateObject(updatedDoc);
89
+ return collection.updateOne({ _id: docId }, { $set: cleanedDoc });
90
+ }
91
+ /**
92
+ * Gets the filter with the default filter applied if there is one.
93
+ *
94
+ * This is purposefully changing the type because of some weird restrictions
95
+ * with the `mongodb` package types.
96
+ */
97
+ getFilterWithDefault(filter = {}) {
98
+ if (!this.defaultFilter) {
99
+ return filter;
100
+ }
101
+ return { ...filter, ...this.defaultFilter };
102
+ }
103
+ /**
104
+ * Cleans the update object by removing the `_id` field and running the
105
+ * default update cleaner if there is one.
106
+ *
107
+ * Returns a shallow copy of the object.
108
+ */
109
+ cleanUpdateObject(updatedDoc) {
110
+ return this.defaultUpdateCleaner
111
+ ? this.defaultUpdateCleaner(DocumentCleaner_1.default.id(updatedDoc))
112
+ : DocumentCleaner_1.default.id(updatedDoc);
77
113
  }
78
114
  }
79
115
  exports.default = BaseRepository;
@@ -1 +1 @@
1
- {"version":3,"file":"UserRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/UserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAI/C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,cAAc,CAAC,IAAI,CAAC;IAC9D,OAAO,CAAC,MAAM,CAAC,eAAe,CAAW;IAEzC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAiB;IAEjD,OAAO;IAIP;;OAEG;WACW,OAAO;IAOrB;;;;;;OAMG;IACG,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAUpD;;;;;;OAMG;IACG,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAQrD;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ5D;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;CAOzC"}
1
+ {"version":3,"file":"UserRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/UserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAK/C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,cAAc,CAAC,IAAI,CAAC;IAC9D,OAAO,CAAC,MAAM,CAAC,eAAe,CAAW;IAEzC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAiB;IAEjD,OAAO;IAIP;;OAEG;WACW,OAAO;IAOrB;;;;;;OAMG;IACG,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAcpD;;;;;;OAMG;IACG,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IASrD;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAS5D;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;CAQzC"}
@@ -7,6 +7,7 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
7
7
  const BaseRepository_1 = __importDefault(require("../BaseRepository"));
8
8
  const UserValidator_1 = __importDefault(require("../../validators/common/UserValidator"));
9
9
  const ApiKeyRepository_1 = __importDefault(require("./ApiKeyRepository"));
10
+ const UserConfigRepository_1 = __importDefault(require("../dashboard/UserConfigRepository"));
10
11
  /**
11
12
  * The repository that contains {@link User} documents.
12
13
  */
@@ -33,12 +34,14 @@ class UserRepository extends BaseRepository_1.default {
33
34
  * @override
34
35
  */
35
36
  async insertNew(newUser) {
36
- // Insert the new user then the new API Key
37
37
  const insertResult = await super.insertNew(newUser);
38
38
  if (!insertResult) {
39
39
  return null;
40
40
  }
41
41
  await ApiKeyRepository_1.default.getRepo().insertNew(new core_ts_db_lib_1.ApiKey(newUser._id));
42
+ if (insertResult.projectAccess.dashboard) {
43
+ await UserConfigRepository_1.default.getRepo().insertNew(new core_ts_db_lib_1.DashboardUserConfig(newUser._id));
44
+ }
42
45
  return newUser;
43
46
  }
44
47
  /**
@@ -51,7 +54,8 @@ class UserRepository extends BaseRepository_1.default {
51
54
  async delete(userId) {
52
55
  const [deleteResult] = await Promise.all([
53
56
  super.delete(userId),
54
- ApiKeyRepository_1.default.getRepo().deleteByUserId(userId)
57
+ ApiKeyRepository_1.default.getRepo().deleteByUserId(userId),
58
+ UserConfigRepository_1.default.getRepo().deleteByUserId(userId)
55
59
  ]);
56
60
  return deleteResult;
57
61
  }
@@ -65,7 +69,8 @@ class UserRepository extends BaseRepository_1.default {
65
69
  async deleteList(userIds) {
66
70
  const [deleteResult] = await Promise.all([
67
71
  super.deleteList(userIds),
68
- ApiKeyRepository_1.default.getRepo().deleteByUserIds(userIds)
72
+ ApiKeyRepository_1.default.getRepo().deleteByUserIds(userIds),
73
+ UserConfigRepository_1.default.getRepo().deleteByUserIds(userIds)
69
74
  ]);
70
75
  return deleteResult;
71
76
  }
@@ -77,7 +82,8 @@ class UserRepository extends BaseRepository_1.default {
77
82
  async deleteAll() {
78
83
  const [deleteResult] = await Promise.all([
79
84
  super.deleteAll(),
80
- ApiKeyRepository_1.default.getRepo().deleteAll()
85
+ ApiKeyRepository_1.default.getRepo().deleteAll(),
86
+ UserConfigRepository_1.default.getRepo().deleteAll()
81
87
  ]);
82
88
  return deleteResult;
83
89
  }
@@ -0,0 +1,11 @@
1
+ import { BaseDocumentWithType } from '@aneuhold/core-ts-db-lib';
2
+ import BaseRepository from '../BaseRepository';
3
+ import IValidator from '../../validators/BaseValidator';
4
+ /**
5
+ * A base repository for the `dashboard` collection.
6
+ */
7
+ export default abstract class DashboardBaseRepository<TBaseType extends BaseDocumentWithType> extends BaseRepository<TBaseType> {
8
+ private static COLLECTION_NAME;
9
+ constructor(docType: string, validator: IValidator<TBaseType>, updateCleaner?: (doc: Partial<TBaseType>) => Partial<TBaseType>);
10
+ }
11
+ //# sourceMappingURL=DashboardBaseRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardBaseRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/dashboard/DashboardBaseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAC/C,OAAO,UAAU,MAAM,gCAAgC,CAAC;AAGxD;;GAEG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,uBAAuB,CACnD,SAAS,SAAS,oBAAoB,CACtC,SAAQ,cAAc,CAAC,SAAS,CAAC;IACjC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAe;gBAG3C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,UAAU,CAAC,SAAS,CAAC,EAChC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,SAAS,CAAC;CAclE"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const BaseRepository_1 = __importDefault(require("../BaseRepository"));
7
+ const DocumentCleaner_1 = __importDefault(require("../../util/DocumentCleaner"));
8
+ /**
9
+ * A base repository for the `dashboard` collection.
10
+ */
11
+ class DashboardBaseRepository extends BaseRepository_1.default {
12
+ static COLLECTION_NAME = 'dashboard';
13
+ constructor(docType, validator, updateCleaner) {
14
+ const defaultUpdateCleaner = (updatedDoc) => updateCleaner
15
+ ? updateCleaner(DocumentCleaner_1.default.docType(updatedDoc))
16
+ : DocumentCleaner_1.default.docType(updatedDoc);
17
+ const defaultFilter = { docType };
18
+ super(DashboardBaseRepository.COLLECTION_NAME, validator, defaultFilter, defaultUpdateCleaner);
19
+ }
20
+ }
21
+ exports.default = DashboardBaseRepository;
@@ -0,0 +1,18 @@
1
+ import { DashboardUserConfig } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
3
+ import { DeleteResult } from 'mongodb';
4
+ import DashboardBaseRepository from './DashboardBaseRepository';
5
+ /**
6
+ * The repository that contains {@link DashboardUserConfig} documents.
7
+ */
8
+ export default class DashboardUserConfigRepository extends DashboardBaseRepository<DashboardUserConfig> {
9
+ private static singletonInstance;
10
+ private constructor();
11
+ /**
12
+ * Gets the singleton instance of the {@link DashboardUserConfigRepository}.
13
+ */
14
+ static getRepo(): DashboardUserConfigRepository;
15
+ deleteByUserId(userId: ObjectId): Promise<DeleteResult>;
16
+ deleteByUserIds(userIds: ObjectId[]): Promise<DeleteResult>;
17
+ }
18
+ //# sourceMappingURL=UserConfigRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserConfigRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/dashboard/UserConfigRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAIhE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA8B,SAAQ,uBAAuB,CAAC,mBAAmB,CAAC;IACrG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAgC;IAEhE,OAAO;IAQP;;OAEG;WACW,OAAO;IAQf,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAKvD,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;CAIlE"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
7
+ const DashboardBaseRepository_1 = __importDefault(require("./DashboardBaseRepository"));
8
+ const UserConfigValidator_1 = __importDefault(require("../../validators/dashboard/UserConfigValidator"));
9
+ const DocumentCleaner_1 = __importDefault(require("../../util/DocumentCleaner"));
10
+ /**
11
+ * The repository that contains {@link DashboardUserConfig} documents.
12
+ */
13
+ class DashboardUserConfigRepository extends DashboardBaseRepository_1.default {
14
+ static singletonInstance;
15
+ constructor() {
16
+ super(core_ts_db_lib_1.DashboardUserConfig.docType, new UserConfigValidator_1.default(), DocumentCleaner_1.default.userId);
17
+ }
18
+ /**
19
+ * Gets the singleton instance of the {@link DashboardUserConfigRepository}.
20
+ */
21
+ static getRepo() {
22
+ if (!DashboardUserConfigRepository.singletonInstance) {
23
+ DashboardUserConfigRepository.singletonInstance =
24
+ new DashboardUserConfigRepository();
25
+ }
26
+ return DashboardUserConfigRepository.singletonInstance;
27
+ }
28
+ async deleteByUserId(userId) {
29
+ const collection = await this.getCollection();
30
+ return collection.deleteOne({ userId });
31
+ }
32
+ async deleteByUserIds(userIds) {
33
+ const collection = await this.getCollection();
34
+ return collection.deleteMany({ userId: { $in: userIds } });
35
+ }
36
+ }
37
+ exports.default = DashboardUserConfigRepository;
@@ -8,6 +8,7 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
8
  const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
9
9
  const testsUtil_1 = require("../testsUtil");
10
10
  const DocumentDb_1 = __importDefault(require("../../util/DocumentDb"));
11
+ const UserConfigRepository_1 = __importDefault(require("../../repositories/dashboard/UserConfigRepository"));
11
12
  it('can create a new document and delete it', async () => {
12
13
  const userRepository = UserRepository_1.default.getRepo();
13
14
  const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
@@ -23,6 +24,17 @@ it.skip('can add a new test user', async () => {
23
24
  const createResult = await userRepository.insertNew(newUser);
24
25
  expect(createResult).toBeTruthy();
25
26
  });
27
+ it('can create a dashboard config for a user', async () => {
28
+ const userRepo = UserRepository_1.default.getRepo();
29
+ const user = await userRepo.get({ userName: 'usernameHere' });
30
+ expect(user).toBeTruthy();
31
+ if (user) {
32
+ const configRepo = UserConfigRepository_1.default.getRepo();
33
+ const newConfig = new core_ts_db_lib_1.DashboardUserConfig(user._id);
34
+ newConfig.enableDevMode = true;
35
+ await configRepo.insertNew(newConfig);
36
+ }
37
+ });
26
38
  afterAll(async () => {
27
39
  return DocumentDb_1.default.closeDbConnection();
28
40
  });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserRepository.spec.d.ts","sourceRoot":"","sources":["../../../../src/tests/repositories/common/UserRepository.spec.ts"],"names":[],"mappings":""}
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const crypto_1 = __importDefault(require("crypto"));
7
7
  const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
- const testsUtil_1 = require("../testsUtil");
9
- const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
10
- const DocumentDb_1 = __importDefault(require("../../util/DocumentDb"));
11
- const ApiKeyRepository_1 = __importDefault(require("../../repositories/common/ApiKeyRepository"));
8
+ const UserRepository_1 = __importDefault(require("../../../repositories/common/UserRepository"));
9
+ const testsUtil_1 = require("../../testsUtil");
10
+ const ApiKeyRepository_1 = __importDefault(require("../../../repositories/common/ApiKeyRepository"));
11
+ const DocumentDb_1 = __importDefault(require("../../../util/DocumentDb"));
12
12
  const userRepo = UserRepository_1.default.getRepo();
13
13
  describe('Create operations', () => {
14
14
  it('can create a new user', async () => {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=UserConfigRepository.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserConfigRepository.spec.d.ts","sourceRoot":"","sources":["../../../../src/tests/repositories/dashboard/UserConfigRepository.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const crypto_1 = __importDefault(require("crypto"));
7
+ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
+ const UserRepository_1 = __importDefault(require("../../../repositories/common/UserRepository"));
9
+ const testsUtil_1 = require("../../testsUtil");
10
+ const DocumentDb_1 = __importDefault(require("../../../util/DocumentDb"));
11
+ const UserConfigRepository_1 = __importDefault(require("../../../repositories/dashboard/UserConfigRepository"));
12
+ const userRepo = UserRepository_1.default.getRepo();
13
+ const configRepo = UserConfigRepository_1.default.getRepo();
14
+ describe('Create operations', () => {
15
+ it('can create a new user config', async () => {
16
+ // User configs are created automatically when a new user is created
17
+ const newUser = await createNewTestUser();
18
+ const newConfig = await configRepo.get({ userId: newUser._id });
19
+ expect(newConfig).toBeTruthy();
20
+ if (!newConfig) {
21
+ return;
22
+ }
23
+ await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
24
+ });
25
+ });
26
+ describe('Update operations', () => {
27
+ it('can update an existing user config', async () => {
28
+ const newUser = await createNewTestUser();
29
+ const newConfig = await configRepo.get({ userId: newUser._id });
30
+ expect(newConfig).toBeTruthy();
31
+ if (!newConfig) {
32
+ return;
33
+ }
34
+ newConfig.enableDevMode = true;
35
+ await configRepo.update(newConfig);
36
+ const updatedConfig = await configRepo.get({ _id: newConfig._id });
37
+ expect(updatedConfig?.enableDevMode).toBe(true);
38
+ await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
39
+ });
40
+ });
41
+ afterAll(async () => {
42
+ return DocumentDb_1.default.closeDbConnection();
43
+ });
44
+ async function createNewTestUser() {
45
+ const newUser = new core_ts_db_lib_1.User(`${crypto_1.default.randomUUID()}userconfigtest`);
46
+ newUser.projectAccess.dashboard = true;
47
+ const insertResult = await userRepo.insertNew(newUser);
48
+ expect(insertResult).toBeTruthy();
49
+ return newUser;
50
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseDocument, BaseDocumentWithType, BaseDocumentWithUserId } from '@aneuhold/core-ts-db-lib';
2
+ /**
3
+ * A class which contains some standard methods for cleaning update documents
4
+ * before they are sent to the database.
5
+ */
6
+ export default class CleanDocument {
7
+ static id<TDocType extends BaseDocument>(updateDoc: Partial<TDocType>): Partial<TDocType>;
8
+ static userId<TDocType extends BaseDocumentWithUserId>(updateDoc: Partial<TDocType>): Partial<TDocType>;
9
+ static docType<TDocType extends BaseDocumentWithType>(updateDoc: Partial<TDocType>): Partial<TDocType>;
10
+ }
11
+ //# sourceMappingURL=DocumentCleaner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocumentCleaner.d.ts","sourceRoot":"","sources":["../../src/util/DocumentCleaner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC,MAAM,CAAC,EAAE,CAAC,QAAQ,SAAS,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAMrE,MAAM,CAAC,MAAM,CAAC,QAAQ,SAAS,sBAAsB,EACnD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAO9B,MAAM,CAAC,OAAO,CAAC,QAAQ,SAAS,oBAAoB,EAClD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;CAM/B"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * A class which contains some standard methods for cleaning update documents
5
+ * before they are sent to the database.
6
+ */
7
+ class CleanDocument {
8
+ static id(updateDoc) {
9
+ const docCopy = { ...updateDoc };
10
+ delete docCopy._id;
11
+ return docCopy;
12
+ }
13
+ static userId(updateDoc) {
14
+ const docCopy = { ...updateDoc };
15
+ delete docCopy.userId;
16
+ return docCopy;
17
+ }
18
+ static docType(updateDoc) {
19
+ const docCopy = { ...updateDoc };
20
+ delete docCopy.docType;
21
+ return docCopy;
22
+ }
23
+ }
24
+ exports.default = CleanDocument;
@@ -0,0 +1,7 @@
1
+ import { DashboardUserConfig } from '@aneuhold/core-ts-db-lib';
2
+ import IValidator from '../BaseValidator';
3
+ export default class DashboardUserConfigValidator extends IValidator<DashboardUserConfig> {
4
+ validateNewObject(newUserConfig: DashboardUserConfig): Promise<void>;
5
+ validateUpdateObject(updatedUserConfig: Partial<DashboardUserConfig>): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=UserConfigValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserConfigValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/dashboard/UserConfigValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,OAAO,OAAO,4BAA6B,SAAQ,UAAU,CAAC,mBAAmB,CAAC;IACjF,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpE,oBAAoB,CACxB,iBAAiB,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAC9C,OAAO,CAAC,IAAI,CAAC;CASjB"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const core_ts_lib_1 = require("@aneuhold/core-ts-lib");
7
+ const BaseValidator_1 = __importDefault(require("../BaseValidator"));
8
+ const UserConfigRepository_1 = __importDefault(require("../../repositories/dashboard/UserConfigRepository"));
9
+ const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
10
+ class DashboardUserConfigValidator extends BaseValidator_1.default {
11
+ async validateNewObject(newUserConfig) {
12
+ // Check if the config already exists for the user
13
+ const configRepo = UserConfigRepository_1.default.getRepo();
14
+ const existingConfig = await configRepo.get({
15
+ userId: newUserConfig.userId
16
+ });
17
+ if (existingConfig) {
18
+ core_ts_lib_1.ErrorUtils.throwError(`Config already exists for user: ${newUserConfig.userId}`, newUserConfig);
19
+ }
20
+ const userRepo = UserRepository_1.default.getRepo();
21
+ const user = await userRepo.get({ _id: newUserConfig.userId });
22
+ if (!user) {
23
+ core_ts_lib_1.ErrorUtils.throwError(`User does not exist: ${newUserConfig.userId}`, newUserConfig);
24
+ }
25
+ }
26
+ async validateUpdateObject(updatedUserConfig) {
27
+ // Check if an id is defined
28
+ if (!updatedUserConfig._id) {
29
+ core_ts_lib_1.ErrorUtils.throwError(`No _id defined for DashboardUserConfig update.`, updatedUserConfig);
30
+ }
31
+ }
32
+ }
33
+ exports.default = DashboardUserConfigValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aneuhold/be-ts-db-lib",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "A backend database library meant to actually interact with various databases in personal projects",
5
5
  "author": "Anton G Neuhold Jr <agneuhold@gmail.com>",
6
6
  "license": "MIT",
@@ -36,9 +36,9 @@
36
36
  "test": "jest"
37
37
  },
38
38
  "dependencies": {
39
- "@aneuhold/be-ts-lib": "^1.0.3",
40
- "@aneuhold/core-ts-db-lib": "^1.0.3",
41
- "@aneuhold/core-ts-lib": "^1.1.7",
39
+ "@aneuhold/be-ts-lib": "^1.0.5",
40
+ "@aneuhold/core-ts-db-lib": "^1.0.8",
41
+ "@aneuhold/core-ts-lib": "^1.1.8",
42
42
  "bson": "^6.2.0",
43
43
  "mongodb": "^6.3.0"
44
44
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"UserRepository.spec.d.ts","sourceRoot":"","sources":["../../../src/tests/repositories/UserRepository.spec.ts"],"names":[],"mappings":""}