@aneuhold/be-ts-db-lib 1.0.2 → 1.0.4

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
@@ -1,5 +1,7 @@
1
1
  # Personal Backend Database Library
2
2
 
3
+ ![npm](https://img.shields.io/npm/v/%40aneuhold%2Fbe-ts-db-lib)
4
+
3
5
  This is used to actually interact with databases in personal projects.
4
6
 
5
7
  ## Dependencies
package/lib/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- export {};
1
+ import ApiKeyRepository from './repositories/common/ApiKeyRepository';
2
+ import UserRepository from './repositories/common/UserRepository';
3
+ import DocumentDb from './util/DocumentDb';
4
+ export { UserRepository, ApiKeyRepository, DocumentDb };
2
5
  export type {};
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC;AAGV,YAAY,EAAE,CAAC"}
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;AAClE,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC;AAGxD,YAAY,EAAE,CAAC"}
package/lib/index.js CHANGED
@@ -1,2 +1,12 @@
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.DocumentDb = 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;
11
+ const DocumentDb_1 = __importDefault(require("./util/DocumentDb"));
12
+ exports.DocumentDb = DocumentDb_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 add the default team that consists of just the user if it
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,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAG/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;;;;;;;;;;OAUG;IACG,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;CAQrD"}
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 add the default team that consists of just the user if it
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 first
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;
@@ -15,6 +15,14 @@ it('can create a new document and delete it', async () => {
15
15
  expect(createResult).toBeTruthy();
16
16
  await (0, testsUtil_1.cleanupDoc)(userRepository, newUser);
17
17
  });
18
+ // -- Manual Database Operations Section -- //
19
+ it.skip('can add a new test user', async () => {
20
+ const userRepository = UserRepository_1.default.getRepo();
21
+ const newUser = new core_ts_db_lib_1.User('someUser');
22
+ newUser.password = crypto_1.default.randomUUID();
23
+ const createResult = await userRepository.insertNew(newUser);
24
+ expect(createResult).toBeTruthy();
25
+ });
18
26
  afterAll(async () => {
19
27
  return DocumentDb_1.default.closeDbConnection();
20
28
  });
@@ -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.2",
3
+ "version": "1.0.4",
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.1",
40
- "@aneuhold/core-ts-lib": "^1.1.6",
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
  },