@aneuhold/be-ts-db-lib 1.0.2 → 1.0.3
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 +2 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +8 -0
- package/lib/repositories/common/ApiKeyRepository.d.ts +19 -0
- package/lib/repositories/common/ApiKeyRepository.d.ts.map +1 -0
- package/lib/repositories/common/ApiKeyRepository.js +35 -0
- package/lib/repositories/common/UserRepository.d.ts +25 -5
- package/lib/repositories/common/UserRepository.d.ts.map +1 -1
- package/lib/repositories/common/UserRepository.js +45 -6
- package/lib/tests/repositories/UserRepository.spec.js +21 -0
- package/lib/validators/common/ApiKeyValidator.d.ts +7 -0
- package/lib/validators/common/ApiKeyValidator.d.ts.map +1 -0
- package/lib/validators/common/ApiKeyValidator.js +31 -0
- package/package.json +4 -3
package/README.md
CHANGED
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,wCAAwC,CAAC;AACtE,OAAO,cAAc,MAAM,sCAAsC,CAAC;AAGlE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;AAG5C,YAAY,EAAE,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ApiKeyRepository = exports.UserRepository = void 0;
|
|
7
|
+
const ApiKeyRepository_1 = __importDefault(require("./repositories/common/ApiKeyRepository"));
|
|
8
|
+
exports.ApiKeyRepository = ApiKeyRepository_1.default;
|
|
9
|
+
const UserRepository_1 = __importDefault(require("./repositories/common/UserRepository"));
|
|
10
|
+
exports.UserRepository = UserRepository_1.default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ApiKey } from '@aneuhold/core-ts-db-lib';
|
|
2
|
+
import { DeleteResult } from 'mongodb';
|
|
3
|
+
import { ObjectId } from 'bson';
|
|
4
|
+
import BaseRepository from '../BaseRepository';
|
|
5
|
+
/**
|
|
6
|
+
* The repository that contains {@link User} documents.
|
|
7
|
+
*/
|
|
8
|
+
export default class ApiKeyRepository extends BaseRepository<ApiKey> {
|
|
9
|
+
private static COLLECTION_NAME;
|
|
10
|
+
private static singletonInstance;
|
|
11
|
+
private constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Gets the singleton instance of the {@link ApiKeyRepository}.
|
|
14
|
+
*/
|
|
15
|
+
static getRepo(): ApiKeyRepository;
|
|
16
|
+
deleteByUserId(userId: ObjectId): Promise<DeleteResult>;
|
|
17
|
+
deleteByUserIds(userIds: ObjectId[]): Promise<DeleteResult>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ApiKeyRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiKeyRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/ApiKeyRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAG/C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc,CAAC,MAAM,CAAC;IAClE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAa;IAE3C,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAmB;IAEnD,OAAO;IAIP;;OAEG;WACW,OAAO;IAOf,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,35 @@
|
|
|
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 ApiKeyValidator_1 = __importDefault(require("../../validators/common/ApiKeyValidator"));
|
|
8
|
+
/**
|
|
9
|
+
* The repository that contains {@link User} documents.
|
|
10
|
+
*/
|
|
11
|
+
class ApiKeyRepository extends BaseRepository_1.default {
|
|
12
|
+
static COLLECTION_NAME = 'apiKeys';
|
|
13
|
+
static singletonInstance;
|
|
14
|
+
constructor() {
|
|
15
|
+
super(ApiKeyRepository.COLLECTION_NAME, new ApiKeyValidator_1.default());
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Gets the singleton instance of the {@link ApiKeyRepository}.
|
|
19
|
+
*/
|
|
20
|
+
static getRepo() {
|
|
21
|
+
if (!ApiKeyRepository.singletonInstance) {
|
|
22
|
+
ApiKeyRepository.singletonInstance = new ApiKeyRepository();
|
|
23
|
+
}
|
|
24
|
+
return ApiKeyRepository.singletonInstance;
|
|
25
|
+
}
|
|
26
|
+
async deleteByUserId(userId) {
|
|
27
|
+
const collection = await this.getCollection();
|
|
28
|
+
return collection.deleteOne({ userId });
|
|
29
|
+
}
|
|
30
|
+
async deleteByUserIds(userIds) {
|
|
31
|
+
const collection = await this.getCollection();
|
|
32
|
+
return collection.deleteMany({ userId: { $in: userIds } });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = ApiKeyRepository;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { User } from '@aneuhold/core-ts-db-lib';
|
|
2
|
+
import { DeleteResult } from 'mongodb';
|
|
3
|
+
import { ObjectId } from 'bson';
|
|
2
4
|
import BaseRepository from '../BaseRepository';
|
|
3
5
|
/**
|
|
4
6
|
* The repository that contains {@link User} documents.
|
|
@@ -14,14 +16,32 @@ export default class UserRepository extends BaseRepository<User> {
|
|
|
14
16
|
/**
|
|
15
17
|
* Inserts a new user.
|
|
16
18
|
*
|
|
17
|
-
* This will
|
|
18
|
-
* doesn't already exist. If it does exist, it will add that team to the
|
|
19
|
-
* user's {@link User.currentTeamsIncludingUser} array.
|
|
19
|
+
* This will create a new API key for the user as well.
|
|
20
20
|
*
|
|
21
21
|
* @override
|
|
22
|
-
*
|
|
23
|
-
* @returns The user with the additional team, or null if the insert failed.
|
|
24
22
|
*/
|
|
25
23
|
insertNew(newUser: User): Promise<User | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Deletes a user.
|
|
26
|
+
*
|
|
27
|
+
* This will delete the API key for the user as well if there is one.
|
|
28
|
+
*
|
|
29
|
+
* @override
|
|
30
|
+
*/
|
|
31
|
+
delete(userId: ObjectId): Promise<DeleteResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Deletes a list of users.
|
|
34
|
+
*
|
|
35
|
+
* This will delete the API keys for the users as well if there are any.
|
|
36
|
+
*
|
|
37
|
+
* @override
|
|
38
|
+
*/
|
|
39
|
+
deleteList(userIds: ObjectId[]): Promise<DeleteResult>;
|
|
40
|
+
/**
|
|
41
|
+
* This should not be used except for testing purposes
|
|
42
|
+
*
|
|
43
|
+
* @override
|
|
44
|
+
*/
|
|
45
|
+
deleteAll(): Promise<DeleteResult>;
|
|
26
46
|
}
|
|
27
47
|
//# sourceMappingURL=UserRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/common/UserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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"}
|
|
@@ -3,8 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
|
|
6
7
|
const BaseRepository_1 = __importDefault(require("../BaseRepository"));
|
|
7
8
|
const UserValidator_1 = __importDefault(require("../../validators/common/UserValidator"));
|
|
9
|
+
const ApiKeyRepository_1 = __importDefault(require("./ApiKeyRepository"));
|
|
8
10
|
/**
|
|
9
11
|
* The repository that contains {@link User} documents.
|
|
10
12
|
*/
|
|
@@ -26,21 +28,58 @@ class UserRepository extends BaseRepository_1.default {
|
|
|
26
28
|
/**
|
|
27
29
|
* Inserts a new user.
|
|
28
30
|
*
|
|
29
|
-
* This will
|
|
30
|
-
* doesn't already exist. If it does exist, it will add that team to the
|
|
31
|
-
* user's {@link User.currentTeamsIncludingUser} array.
|
|
31
|
+
* This will create a new API key for the user as well.
|
|
32
32
|
*
|
|
33
33
|
* @override
|
|
34
|
-
*
|
|
35
|
-
* @returns The user with the additional team, or null if the insert failed.
|
|
36
34
|
*/
|
|
37
35
|
async insertNew(newUser) {
|
|
38
|
-
// Insert the new user
|
|
36
|
+
// Insert the new user then the new API Key
|
|
39
37
|
const insertResult = await super.insertNew(newUser);
|
|
40
38
|
if (!insertResult) {
|
|
41
39
|
return null;
|
|
42
40
|
}
|
|
41
|
+
await ApiKeyRepository_1.default.getRepo().insertNew(new core_ts_db_lib_1.ApiKey(newUser._id));
|
|
43
42
|
return newUser;
|
|
44
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Deletes a user.
|
|
46
|
+
*
|
|
47
|
+
* This will delete the API key for the user as well if there is one.
|
|
48
|
+
*
|
|
49
|
+
* @override
|
|
50
|
+
*/
|
|
51
|
+
async delete(userId) {
|
|
52
|
+
const [deleteResult] = await Promise.all([
|
|
53
|
+
super.delete(userId),
|
|
54
|
+
ApiKeyRepository_1.default.getRepo().deleteByUserId(userId)
|
|
55
|
+
]);
|
|
56
|
+
return deleteResult;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Deletes a list of users.
|
|
60
|
+
*
|
|
61
|
+
* This will delete the API keys for the users as well if there are any.
|
|
62
|
+
*
|
|
63
|
+
* @override
|
|
64
|
+
*/
|
|
65
|
+
async deleteList(userIds) {
|
|
66
|
+
const [deleteResult] = await Promise.all([
|
|
67
|
+
super.deleteList(userIds),
|
|
68
|
+
ApiKeyRepository_1.default.getRepo().deleteByUserIds(userIds)
|
|
69
|
+
]);
|
|
70
|
+
return deleteResult;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* This should not be used except for testing purposes
|
|
74
|
+
*
|
|
75
|
+
* @override
|
|
76
|
+
*/
|
|
77
|
+
async deleteAll() {
|
|
78
|
+
const [deleteResult] = await Promise.all([
|
|
79
|
+
super.deleteAll(),
|
|
80
|
+
ApiKeyRepository_1.default.getRepo().deleteAll()
|
|
81
|
+
]);
|
|
82
|
+
return deleteResult;
|
|
83
|
+
}
|
|
45
84
|
}
|
|
46
85
|
exports.default = UserRepository;
|
|
@@ -8,8 +8,29 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
|
|
|
8
8
|
const testsUtil_1 = require("../testsUtil");
|
|
9
9
|
const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
|
|
10
10
|
const DocumentDb_1 = __importDefault(require("../../util/DocumentDb"));
|
|
11
|
+
const ApiKeyRepository_1 = __importDefault(require("../../repositories/common/ApiKeyRepository"));
|
|
11
12
|
const userRepo = UserRepository_1.default.getRepo();
|
|
12
13
|
describe('Create operations', () => {
|
|
14
|
+
it('can create a new user', async () => {
|
|
15
|
+
const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
|
|
16
|
+
const insertResult = await userRepo.insertNew(newUser);
|
|
17
|
+
expect(insertResult).toBeTruthy();
|
|
18
|
+
await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
|
|
19
|
+
});
|
|
20
|
+
it('can create a new user and the new user gets an API key', async () => {
|
|
21
|
+
const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
|
|
22
|
+
const insertResult = await userRepo.insertNew(newUser);
|
|
23
|
+
expect(insertResult).toBeTruthy();
|
|
24
|
+
const apiKey = await ApiKeyRepository_1.default.getRepo().get({
|
|
25
|
+
userId: newUser._id
|
|
26
|
+
});
|
|
27
|
+
expect(apiKey).toBeTruthy();
|
|
28
|
+
await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
|
|
29
|
+
const apiKeyThatShouldNotExist = await ApiKeyRepository_1.default.getRepo().get({
|
|
30
|
+
userId: newUser._id
|
|
31
|
+
});
|
|
32
|
+
expect(apiKeyThatShouldNotExist).toBeFalsy();
|
|
33
|
+
});
|
|
13
34
|
it('throws if the username is a duplicate username', async () => {
|
|
14
35
|
const duplicateUserName = `${crypto_1.default.randomUUID()}`;
|
|
15
36
|
const newUser1 = new core_ts_db_lib_1.User(duplicateUserName);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ApiKey } from '@aneuhold/core-ts-db-lib';
|
|
2
|
+
import IValidator from '../BaseValidator';
|
|
3
|
+
export default class ApiKeyValidator extends IValidator<ApiKey> {
|
|
4
|
+
validateNewObject(newApiKey: ApiKey): Promise<void>;
|
|
5
|
+
validateUpdateObject(updatedApiKey: Partial<ApiKey>): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=ApiKeyValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiKeyValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/common/ApiKeyValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAGlD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAG1C,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,UAAU,CAAC,MAAM,CAAC;IACvD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBnD,oBAAoB,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAO1E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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 UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
|
|
8
|
+
const BaseValidator_1 = __importDefault(require("../BaseValidator"));
|
|
9
|
+
const ApiKeyRepository_1 = __importDefault(require("../../repositories/common/ApiKeyRepository"));
|
|
10
|
+
class ApiKeyValidator extends BaseValidator_1.default {
|
|
11
|
+
async validateNewObject(newApiKey) {
|
|
12
|
+
// Check if the user exists
|
|
13
|
+
const userRepo = UserRepository_1.default.getRepo();
|
|
14
|
+
const userInDb = await userRepo.get({ _id: newApiKey.userId });
|
|
15
|
+
if (!userInDb) {
|
|
16
|
+
core_ts_lib_1.ErrorUtils.throwError(`User with ID: ${newApiKey.userId} does not exist in the database.`, newApiKey);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// Check if the user already has an API key
|
|
20
|
+
const apiKeyRepo = ApiKeyRepository_1.default.getRepo();
|
|
21
|
+
const apiKeyInDb = await apiKeyRepo.get({ userId: newApiKey.userId });
|
|
22
|
+
if (apiKeyInDb) {
|
|
23
|
+
core_ts_lib_1.ErrorUtils.throwError(`User with ID: ${newApiKey.userId} already has an API key.`, newApiKey);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async validateUpdateObject(updatedApiKey) {
|
|
27
|
+
// Throw, because API keys should not be updated. Only created and deleted.
|
|
28
|
+
core_ts_lib_1.ErrorUtils.throwError(`API keys should not be updated at this time. Only created and deleted.`, updatedApiKey);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.default = ApiKeyValidator;
|
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.3",
|
|
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",
|
|
@@ -32,12 +32,13 @@
|
|
|
32
32
|
"unlink:coredb": "yarn unlink @aneuhold/core-ts-db-lib && yarn install --force",
|
|
33
33
|
"unlink:bets": "yarn unlink @aneuhold/be-ts-lib && yarn install --force",
|
|
34
34
|
"upgrade:all": "yarn upgrade --latest",
|
|
35
|
+
"upgrade:core": "yarn upgrade --latest --pattern @aneuhold",
|
|
35
36
|
"test": "jest"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"@aneuhold/be-ts-lib": "^1.0.3",
|
|
39
|
-
"@aneuhold/core-ts-db-lib": "^1.0.
|
|
40
|
-
"@aneuhold/core-ts-lib": "^1.1.
|
|
40
|
+
"@aneuhold/core-ts-db-lib": "^1.0.3",
|
|
41
|
+
"@aneuhold/core-ts-lib": "^1.1.7",
|
|
41
42
|
"bson": "^6.2.0",
|
|
42
43
|
"mongodb": "^6.3.0"
|
|
43
44
|
},
|