@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 +1 -10
- package/lib/repositories/common/UserRepository.d.ts.map +1 -1
- package/lib/repositories/common/UserRepository.js +2 -0
- package/lib/repositories/dashboard/DashboardTaskRepository.d.ts +17 -0
- package/lib/repositories/dashboard/DashboardTaskRepository.d.ts.map +1 -0
- package/lib/repositories/dashboard/DashboardTaskRepository.js +47 -0
- package/lib/tests/repositories/BaseRepository.spec.js +12 -0
- package/lib/tests/repositories/dashboard/TaskRepository.spec.d.ts +2 -0
- package/lib/tests/repositories/dashboard/TaskRepository.spec.d.ts.map +1 -0
- package/lib/tests/repositories/dashboard/TaskRepository.spec.js +40 -0
- package/lib/util/DbSchemaUpdater.d.ts.map +1 -1
- package/lib/util/DbSchemaUpdater.js +2 -0
- package/lib/validators/dashboard/TaskValidator.d.ts +8 -0
- package/lib/validators/dashboard/TaskValidator.d.ts.map +1 -0
- package/lib/validators/dashboard/TaskValidator.js +63 -0
- package/package.json +2 -2
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
|
-
|
|
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;
|
|
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 @@
|
|
|
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":"
|
|
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.
|
|
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.
|
|
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"
|