@aneuhold/be-ts-db-lib 1.0.8 → 1.0.9

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,16 +9,7 @@ This is used to actually interact with databases in personal projects.
9
9
  ### Creating a new Repository
10
10
 
11
11
  1. Copy an existing one over
12
- 2. Make sure to register the repository in the `RepoSubscriptionService`, even if nothing needs to be setup, just as a future precaution.
13
-
14
- ## Subscription System
15
-
16
- ```mermaid
17
- sequenceDiagram
18
- Note over UserRepository: getRepo called
19
- UserRepository->>ApiKeyRepository: getSubscribers called
20
- ApiKeyRepository->>UserRepository: Subscribes
21
- ```
12
+ 1. Create an associated validator
22
13
 
23
14
  ## Schema Validation for DB
24
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"UserRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/UserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,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,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAOlC;;OAEG;IACH,MAAM,CAAC,OAAO;CAMf"}
1
+ {"version":3,"file":"UserRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/UserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAM/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,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAQlC;;OAEG;IACH,MAAM,CAAC,OAAO;CAMf"}
@@ -7,6 +7,7 @@ const BaseRepository_1 = __importDefault(require("../BaseRepository"));
7
7
  const UserValidator_1 = __importDefault(require("../../validators/common/UserValidator"));
8
8
  const ApiKeyRepository_1 = __importDefault(require("./ApiKeyRepository"));
9
9
  const DashboardUserConfigRepository_1 = __importDefault(require("../dashboard/DashboardUserConfigRepository"));
10
+ const DashboardTaskRepository_1 = __importDefault(require("../dashboard/DashboardTaskRepository"));
10
11
  /**
11
12
  * The repository that contains {@link User} documents.
12
13
  */
@@ -19,6 +20,7 @@ class UserRepository extends BaseRepository_1.default {
19
20
  setupSubscribers() {
20
21
  this.subscribeToChanges(ApiKeyRepository_1.default.getListenersForUserRepo());
21
22
  this.subscribeToChanges(DashboardUserConfigRepository_1.default.getListenersForUserRepo());
23
+ this.subscribeToChanges(DashboardTaskRepository_1.default.getListenersForUserRepo());
22
24
  }
23
25
  /**
24
26
  * Gets the singleton instance of the {@link UserRepository}.
@@ -0,0 +1,17 @@
1
+ import { DashboardTask, User } from '@aneuhold/core-ts-db-lib';
2
+ import DashboardBaseRepository from './DashboardBaseRepository';
3
+ import { RepoListeners } from '../../services/RepoSubscriptionService';
4
+ /**
5
+ * The repository that contains {@link DashboardTask} documents.
6
+ */
7
+ export default class DashboardTaskRepository extends DashboardBaseRepository<DashboardTask> {
8
+ private static singletonInstance;
9
+ private constructor();
10
+ static getListenersForUserRepo(): RepoListeners<User>;
11
+ protected setupSubscribers(): void;
12
+ /**
13
+ * Gets the singleton instance of the {@link DashboardTaskRepository}.
14
+ */
15
+ static getRepo(): DashboardTaskRepository;
16
+ }
17
+ //# sourceMappingURL=DashboardTaskRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardTaskRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/dashboard/DashboardTaskRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAGvE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,uBAAuB,CAAC,aAAa,CAAC;IACzF,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAE1D,OAAO;IAaP,MAAM,CAAC,uBAAuB,IAAI,aAAa,CAAC,IAAI,CAAC;IAcrD,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAElC;;OAEG;WACW,OAAO;CAMtB"}
@@ -0,0 +1,47 @@
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 DocumentCleaner_1 = __importDefault(require("../../util/DocumentCleaner"));
9
+ const TaskValidator_1 = __importDefault(require("../../validators/dashboard/TaskValidator"));
10
+ /**
11
+ * The repository that contains {@link DashboardTask} documents.
12
+ */
13
+ class DashboardTaskRepository extends DashboardBaseRepository_1.default {
14
+ static singletonInstance;
15
+ constructor() {
16
+ super(core_ts_db_lib_1.DashboardTask.docType, new TaskValidator_1.default(), (task) => {
17
+ const docCopy = DocumentCleaner_1.default.userId(task);
18
+ delete docCopy.createdDate;
19
+ docCopy.lastUpdatedDate = new Date();
20
+ return docCopy;
21
+ });
22
+ }
23
+ static getListenersForUserRepo() {
24
+ const taskRepo = DashboardTaskRepository.getRepo();
25
+ return {
26
+ deleteOne: async (userId) => {
27
+ (await taskRepo.getCollection()).deleteOne({ userId });
28
+ },
29
+ deleteList: async (userIds) => {
30
+ (await taskRepo.getCollection()).deleteMany({
31
+ userId: { $in: userIds }
32
+ });
33
+ }
34
+ };
35
+ }
36
+ setupSubscribers() { }
37
+ /**
38
+ * Gets the singleton instance of the {@link DashboardTaskRepository}.
39
+ */
40
+ static getRepo() {
41
+ if (!DashboardTaskRepository.singletonInstance) {
42
+ DashboardTaskRepository.singletonInstance = new DashboardTaskRepository();
43
+ }
44
+ return DashboardTaskRepository.singletonInstance;
45
+ }
46
+ }
47
+ exports.default = DashboardTaskRepository;
@@ -9,6 +9,7 @@ const UserRepository_1 = __importDefault(require("../../repositories/common/User
9
9
  const testsUtil_1 = require("../testsUtil");
10
10
  const DocumentDb_1 = __importDefault(require("../../util/DocumentDb"));
11
11
  const DashboardUserConfigRepository_1 = __importDefault(require("../../repositories/dashboard/DashboardUserConfigRepository"));
12
+ const DashboardTaskRepository_1 = __importDefault(require("../../repositories/dashboard/DashboardTaskRepository"));
12
13
  it('can create a new document and delete it', async () => {
13
14
  const userRepository = UserRepository_1.default.getRepo();
14
15
  const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
@@ -35,6 +36,17 @@ it.skip('can create a dashboard config for a user', async () => {
35
36
  await configRepo.insertNew(newConfig);
36
37
  }
37
38
  });
39
+ it.skip(`can create a new task for a user`, async () => {
40
+ const userRepo = UserRepository_1.default.getRepo();
41
+ const user = await userRepo.get({ userName: 'testUser' });
42
+ expect(user).toBeTruthy();
43
+ if (user) {
44
+ const taskRepo = DashboardTaskRepository_1.default.getRepo();
45
+ const newTask = new core_ts_db_lib_1.DashboardTask(user._id);
46
+ newTask.title = 'Test Task';
47
+ await taskRepo.insertNew(newTask);
48
+ }
49
+ });
38
50
  afterAll(async () => {
39
51
  return DocumentDb_1.default.closeDbConnection();
40
52
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TaskRepository.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskRepository.spec.d.ts","sourceRoot":"","sources":["../../../../src/tests/repositories/dashboard/TaskRepository.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
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 DashboardTaskRepository_1 = __importDefault(require("../../../repositories/dashboard/DashboardTaskRepository"));
12
+ const userRepo = UserRepository_1.default.getRepo();
13
+ const taskRepo = DashboardTaskRepository_1.default.getRepo();
14
+ describe('Create operations', () => {
15
+ it('can create a new task', async () => {
16
+ const newUser = await createNewTestUser();
17
+ const newTask = new core_ts_db_lib_1.DashboardTask(newUser._id);
18
+ const insertResult = await taskRepo.insertNew(newTask);
19
+ expect(insertResult).toBeTruthy();
20
+ const insertedTask = await taskRepo.get({ _id: newTask._id });
21
+ expect(insertedTask).toBeTruthy();
22
+ expect(typeof insertedTask?.createdDate).toBe('object');
23
+ if (!insertedTask) {
24
+ return;
25
+ }
26
+ await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
27
+ // Task should be deleted
28
+ const deletedTask = await taskRepo.get({ _id: newTask._id });
29
+ expect(deletedTask).toBeFalsy();
30
+ });
31
+ });
32
+ afterAll(async () => {
33
+ return DocumentDb_1.default.closeDbConnection();
34
+ });
35
+ async function createNewTestUser() {
36
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)(`${crypto_1.default.randomUUID()}dashboardTaskTest`));
37
+ const insertResult = await userRepo.insertNew(newUser);
38
+ expect(insertResult).toBeTruthy();
39
+ return newUser;
40
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"DbSchemaUpdater.d.ts","sourceRoot":"","sources":["../../src/util/DbSchemaUpdater.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;WACrB,uBAAuB,CAAC,MAAM,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAKpE"}
1
+ {"version":3,"file":"DbSchemaUpdater.d.ts","sourceRoot":"","sources":["../../src/util/DbSchemaUpdater.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,eAAe;WACrB,uBAAuB,CAAC,MAAM,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAMpE"}
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const ApiKeyValidator_1 = __importDefault(require("../validators/common/ApiKeyValidator"));
7
7
  const UserValidator_1 = __importDefault(require("../validators/common/UserValidator"));
8
+ const TaskValidator_1 = __importDefault(require("../validators/dashboard/TaskValidator"));
8
9
  const UserConfigValidator_1 = __importDefault(require("../validators/dashboard/UserConfigValidator"));
9
10
  /**
10
11
  * A class that can be used to validate and update the DB and all repositories.
@@ -14,6 +15,7 @@ class DbSchemaUpdater {
14
15
  await new UserValidator_1.default().validateRepositoryInDb(dryRun);
15
16
  await new ApiKeyValidator_1.default().validateRepositoryInDb(dryRun);
16
17
  await new UserConfigValidator_1.default().validateRepositoryInDb(dryRun);
18
+ await new TaskValidator_1.default().validateRepositoryInDb(dryRun);
17
19
  }
18
20
  }
19
21
  exports.default = DbSchemaUpdater;
@@ -0,0 +1,8 @@
1
+ import { DashboardTask } from '@aneuhold/core-ts-db-lib';
2
+ import IValidator from '../BaseValidator';
3
+ export default class DashboardTaskValidator extends IValidator<DashboardTask> {
4
+ validateNewObject(newTask: DashboardTask): Promise<void>;
5
+ validateUpdateObject(updatedTask: Partial<DashboardTask>): Promise<void>;
6
+ validateRepositoryInDb(dryRun: boolean): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=TaskValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/dashboard/TaskValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyB,MAAM,0BAA0B,CAAC;AAGhF,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,OAAO,OAAO,sBAAuB,SAAQ,UAAU,CAAC,aAAa,CAAC;IACrE,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxD,oBAAoB,CACxB,WAAW,EAAE,OAAO,CAAC,aAAa,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC;IAUV,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CA0C7D"}
@@ -0,0 +1,63 @@
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 core_ts_lib_1 = require("@aneuhold/core-ts-lib");
8
+ const BaseValidator_1 = __importDefault(require("../BaseValidator"));
9
+ const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
10
+ const DashboardTaskRepository_1 = __importDefault(require("../../repositories/dashboard/DashboardTaskRepository"));
11
+ class DashboardTaskValidator extends BaseValidator_1.default {
12
+ async validateNewObject(newTask) {
13
+ // Check if the user exists, and any shared users exist
14
+ const userRepo = UserRepository_1.default.getRepo();
15
+ const users = [newTask.userId, ...newTask.sharedWith];
16
+ const usersFound = await userRepo.getList(users);
17
+ if (usersFound.length !== users.length) {
18
+ core_ts_lib_1.ErrorUtils.throwError(`Not all users exist. Found: ${usersFound.length}, expected: ${users.length}`, newTask);
19
+ }
20
+ }
21
+ async validateUpdateObject(updatedTask) {
22
+ // Check if an id is defined
23
+ if (!updatedTask._id) {
24
+ core_ts_lib_1.ErrorUtils.throwError(`No _id defined for DashboardTask update.`, updatedTask);
25
+ }
26
+ }
27
+ async validateRepositoryInDb(dryRun) {
28
+ const taskRepo = DashboardTaskRepository_1.default.getRepo();
29
+ const allTasks = await taskRepo.getAll();
30
+ const allUserIds = await UserRepository_1.default.getRepo().getAllIdsAsHash();
31
+ await this.runStandardValidationForRepository({
32
+ dryRun,
33
+ docName: 'Dashboard Task',
34
+ allDocs: allTasks,
35
+ shouldDelete: (task) => {
36
+ if (!allUserIds[task.userId.toString()]) {
37
+ core_ts_lib_1.Logger.error(`Dashboard Task with ID: ${task._id} has no valid associated owner (user).`);
38
+ return true;
39
+ }
40
+ return false;
41
+ },
42
+ documentValidator: (task) => {
43
+ const { updatedDoc, errors } = (0, core_ts_db_lib_1.validateDashboardTask)(task);
44
+ const sharedWithUserIds = [...task.sharedWith];
45
+ sharedWithUserIds.forEach((userId) => {
46
+ if (!allUserIds[userId.toString()]) {
47
+ errors.push(`User with ID: ${userId} does not exist in sharedWith property of task with ID: ${task._id}.`);
48
+ // eslint-disable-next-line no-param-reassign
49
+ task.sharedWith = task.sharedWith.filter((id) => id.toString() !== userId.toString());
50
+ }
51
+ });
52
+ return { updatedDoc, errors };
53
+ },
54
+ deletionFunction: async (docIdsToDelete) => {
55
+ await taskRepo.deleteList(docIdsToDelete);
56
+ },
57
+ updateFunction: async (docsToUpdate) => {
58
+ await taskRepo.updateMany(docsToUpdate);
59
+ }
60
+ });
61
+ }
62
+ }
63
+ exports.default = DashboardTaskValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aneuhold/be-ts-db-lib",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
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",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@aneuhold/be-ts-lib": "^1.0.6",
44
- "@aneuhold/core-ts-db-lib": "^1.0.13",
44
+ "@aneuhold/core-ts-db-lib": "^1.0.16",
45
45
  "@aneuhold/core-ts-lib": "^1.1.9",
46
46
  "bson": "^6.2.0",
47
47
  "mongodb": "^6.3.0"