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

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/lib/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import ApiKeyRepository from './repositories/common/ApiKeyRepository';
2
2
  import UserRepository from './repositories/common/UserRepository';
3
+ import DashboardTaskRepository from './repositories/dashboard/DashboardTaskRepository';
3
4
  import DashboardUserConfigRepository from './repositories/dashboard/DashboardUserConfigRepository';
4
5
  import DocumentDb from './util/DocumentDb';
5
- export { UserRepository, ApiKeyRepository, DocumentDb, DashboardUserConfigRepository };
6
+ export { UserRepository, ApiKeyRepository, DashboardTaskRepository, DashboardUserConfigRepository, DocumentDb };
6
7
  export type {};
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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,6BAA6B,MAAM,wDAAwD,CAAC;AACnG,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,6BAA6B,EAC9B,CAAC;AAGF,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,uBAAuB,MAAM,kDAAkD,CAAC;AACvF,OAAO,6BAA6B,MAAM,wDAAwD,CAAC;AACnG,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,6BAA6B,EAC7B,UAAU,EACX,CAAC;AAGF,YAAY,EAAE,CAAC"}
package/lib/index.js CHANGED
@@ -3,11 +3,13 @@ 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
- exports.DashboardUserConfigRepository = exports.DocumentDb = exports.ApiKeyRepository = exports.UserRepository = void 0;
6
+ exports.DocumentDb = exports.DashboardUserConfigRepository = exports.DashboardTaskRepository = exports.ApiKeyRepository = exports.UserRepository = void 0;
7
7
  const ApiKeyRepository_1 = __importDefault(require("./repositories/common/ApiKeyRepository"));
8
8
  exports.ApiKeyRepository = ApiKeyRepository_1.default;
9
9
  const UserRepository_1 = __importDefault(require("./repositories/common/UserRepository"));
10
10
  exports.UserRepository = UserRepository_1.default;
11
+ const DashboardTaskRepository_1 = __importDefault(require("./repositories/dashboard/DashboardTaskRepository"));
12
+ exports.DashboardTaskRepository = DashboardTaskRepository_1.default;
11
13
  const DashboardUserConfigRepository_1 = __importDefault(require("./repositories/dashboard/DashboardUserConfigRepository"));
12
14
  exports.DashboardUserConfigRepository = DashboardUserConfigRepository_1.default;
13
15
  const DocumentDb_1 = __importDefault(require("./util/DocumentDb"));
@@ -1,5 +1,5 @@
1
1
  import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
- import { BulkWriteResult, Collection, DeleteResult, UpdateResult } from 'mongodb';
2
+ import { BulkWriteResult, Collection, DeleteResult, Filter, UpdateResult } from 'mongodb';
3
3
  import { Document, ObjectId } from 'bson';
4
4
  import IValidator from '../validators/BaseValidator';
5
5
  import { RepoListeners } from '../services/RepoSubscriptionService';
@@ -63,7 +63,7 @@ export default abstract class BaseRepository<TBasetype extends BaseDocument> {
63
63
  * This is purposefully changing the type because of some weird restrictions
64
64
  * with the `mongodb` package types.
65
65
  */
66
- private getFilterWithDefault;
66
+ protected getFilterWithDefault(filter?: Filter<Document>): Filter<Document>;
67
67
  /**
68
68
  * Cleans the update object by removing the `_id` field and running the
69
69
  * default update cleaner if there is one.
@@ -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,EACL,eAAe,EACf,UAAU,EACV,YAAY,EAEZ,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,UAAU,MAAM,6BAA6B,CAAC;AAErD,OAAgC,EAC9B,aAAa,EACd,MAAM,qCAAqC,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,SAAS,SAAS,YAAY;IAkBvE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,oBAAoB,CAAC;IAnB/B,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IAEjC,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC,SAAS,CAAC,WAAW,2EACwC;IAE7D;;;;;;;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;IAQ7B,SAAS,CAAC,QAAQ,CAAC,gBAAgB,IAAI,IAAI;IAE3C;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC;IAgBhD,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAavD,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAM1D,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAOpC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAQrD,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQjD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ9C,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAS3D;;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;;;;OAIG;IACG,UAAU,CACd,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GACrC,OAAO,CAAC,eAAe,CAAC;IAoB3B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;CAO1B"}
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,EACL,eAAe,EACf,UAAU,EACV,YAAY,EACZ,MAAM,EACN,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,UAAU,MAAM,6BAA6B,CAAC;AAErD,OAAgC,EAC9B,aAAa,EACd,MAAM,qCAAqC,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,SAAS,SAAS,YAAY;IAkBvE,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa,CAAC;IACtB,OAAO,CAAC,oBAAoB,CAAC;IAnB/B,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;IAEjC,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC,SAAS,CAAC,WAAW,2EACwC;IAE7D;;;;;;;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;IAQ7B,SAAS,CAAC,QAAQ,CAAC,gBAAgB,IAAI,IAAI;IAE3C;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC;IAgBhD,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAavD,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAM1D,MAAM,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAOpC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAQrD,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQjD,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ9C,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAS3D;;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;;;;OAIG;IACG,UAAU,CACd,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GACrC,OAAO,CAAC,eAAe,CAAC;IAoB3B;;;;;OAKG;IACH,SAAS,CAAC,oBAAoB,CAC5B,MAAM,GAAE,MAAM,CAAC,QAAQ,CAAM,GAC5B,MAAM,CAAC,QAAQ,CAAC;IAOnB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;CAO1B"}
@@ -1,4 +1,5 @@
1
1
  import { DashboardTask, User } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
2
3
  import DashboardBaseRepository from './DashboardBaseRepository';
3
4
  import { RepoListeners } from '../../services/RepoSubscriptionService';
4
5
  /**
@@ -13,5 +14,10 @@ export default class DashboardTaskRepository extends DashboardBaseRepository<Das
13
14
  * Gets the singleton instance of the {@link DashboardTaskRepository}.
14
15
  */
15
16
  static getRepo(): DashboardTaskRepository;
17
+ /**
18
+ * Gets all tasks for a given user.
19
+ * @param userId The ID of the user to get tasks for.
20
+ */
21
+ getAllForUser(userId: ObjectId): Promise<DashboardTask[]>;
16
22
  }
17
23
  //# sourceMappingURL=DashboardTaskRepository.d.ts.map
@@ -1 +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"}
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,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,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;IAgBrD,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAElC;;OAEG;WACW,OAAO;IAOrB;;;OAGG;IACG,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAWhE"}
@@ -24,10 +24,10 @@ class DashboardTaskRepository extends DashboardBaseRepository_1.default {
24
24
  const taskRepo = DashboardTaskRepository.getRepo();
25
25
  return {
26
26
  deleteOne: async (userId) => {
27
- (await taskRepo.getCollection()).deleteOne({ userId });
27
+ await (await taskRepo.getCollection()).deleteOne({ userId });
28
28
  },
29
29
  deleteList: async (userIds) => {
30
- (await taskRepo.getCollection()).deleteMany({
30
+ await (await taskRepo.getCollection()).deleteMany({
31
31
  userId: { $in: userIds }
32
32
  });
33
33
  }
@@ -43,5 +43,20 @@ class DashboardTaskRepository extends DashboardBaseRepository_1.default {
43
43
  }
44
44
  return DashboardTaskRepository.singletonInstance;
45
45
  }
46
+ /**
47
+ * Gets all tasks for a given user.
48
+ * @param userId The ID of the user to get tasks for.
49
+ */
50
+ async getAllForUser(userId) {
51
+ const collection = await this.getCollection();
52
+ const filter = {
53
+ $and: [
54
+ this.getFilterWithDefault(),
55
+ { $or: [{ userId }, { sharedWith: userId }] }
56
+ ]
57
+ };
58
+ const result = await collection.find(filter).toArray();
59
+ return result;
60
+ }
46
61
  }
47
62
  exports.default = DashboardTaskRepository;
@@ -1,4 +1,5 @@
1
1
  import { DashboardUserConfig, User } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
2
3
  import DashboardBaseRepository from './DashboardBaseRepository';
3
4
  import { RepoListeners } from '../../services/RepoSubscriptionService';
4
5
  /**
@@ -13,5 +14,10 @@ export default class DashboardUserConfigRepository extends DashboardBaseReposito
13
14
  * Gets the singleton instance of the {@link DashboardUserConfigRepository}.
14
15
  */
15
16
  static getRepo(): DashboardUserConfigRepository;
17
+ /**
18
+ * Gets the config for a given user.
19
+ * @param userId The ID of the user to get the config for.
20
+ */
21
+ getForUser(userId: ObjectId): Promise<DashboardUserConfig | null>;
16
22
  }
17
23
  //# sourceMappingURL=DashboardUserConfigRepository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardUserConfigRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/dashboard/DashboardUserConfigRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA8B,SAAQ,uBAAuB,CAAC,mBAAmB,CAAC;IACrG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAgC;IAEhE,OAAO;IAQP,MAAM,CAAC,uBAAuB,IAAI,aAAa,CAAC,IAAI,CAAC;IAmBrD,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAElC;;OAEG;WACW,OAAO;CAOtB"}
1
+ {"version":3,"file":"DashboardUserConfigRepository.d.ts","sourceRoot":"","sources":["../../../src/repositories/dashboard/DashboardUserConfigRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,uBAAuB,MAAM,2BAA2B,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAEvE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,6BAA8B,SAAQ,uBAAuB,CAAC,mBAAmB,CAAC;IACrG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAgC;IAEhE,OAAO;IAQP,MAAM,CAAC,uBAAuB,IAAI,aAAa,CAAC,IAAI,CAAC;IAqBrD,SAAS,CAAC,gBAAgB,IAAI,IAAI;IAElC;;OAEG;WACW,OAAO;IAQrB;;;OAGG;IACG,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;CAKxE"}
@@ -19,10 +19,10 @@ class DashboardUserConfigRepository extends DashboardBaseRepository_1.default {
19
19
  const userConfigRepo = DashboardUserConfigRepository.getRepo();
20
20
  return {
21
21
  deleteOne: async (userId) => {
22
- (await userConfigRepo.getCollection()).deleteOne({ userId });
22
+ await (await userConfigRepo.getCollection()).deleteOne({ userId });
23
23
  },
24
24
  deleteList: async (userIds) => {
25
- (await userConfigRepo.getCollection()).deleteMany({
25
+ await (await userConfigRepo.getCollection()).deleteMany({
26
26
  userId: { $in: userIds }
27
27
  });
28
28
  },
@@ -44,5 +44,14 @@ class DashboardUserConfigRepository extends DashboardBaseRepository_1.default {
44
44
  }
45
45
  return DashboardUserConfigRepository.singletonInstance;
46
46
  }
47
+ /**
48
+ * Gets the config for a given user.
49
+ * @param userId The ID of the user to get the config for.
50
+ */
51
+ async getForUser(userId) {
52
+ const collection = await this.getCollection();
53
+ const result = await collection.findOne({ userId });
54
+ return result;
55
+ }
47
56
  }
48
57
  exports.default = DashboardUserConfigRepository;
@@ -38,7 +38,7 @@ it.skip('can create a dashboard config for a user', async () => {
38
38
  });
39
39
  it.skip(`can create a new task for a user`, async () => {
40
40
  const userRepo = UserRepository_1.default.getRepo();
41
- const user = await userRepo.get({ userName: 'testUser' });
41
+ const user = await userRepo.get({ userName: 'usernameHer' });
42
42
  expect(user).toBeTruthy();
43
43
  if (user) {
44
44
  const taskRepo = DashboardTaskRepository_1.default.getRepo();
@@ -104,5 +104,5 @@ it.skip('can delete all users', async () => {
104
104
  expect(result.acknowledged).toBeTruthy();
105
105
  });
106
106
  afterAll(async () => {
107
- return DocumentDb_1.default.closeDbConnection();
107
+ await DocumentDb_1.default.closeDbConnection();
108
108
  });
@@ -29,6 +29,23 @@ describe('Create operations', () => {
29
29
  expect(deletedTask).toBeFalsy();
30
30
  });
31
31
  });
32
+ describe('Get operations', () => {
33
+ it('can get a set of tasks for a user, without any tasks from other users', async () => {
34
+ const newUser = await createNewTestUser();
35
+ const newTask = new core_ts_db_lib_1.DashboardTask(newUser._id);
36
+ const insertResult = await taskRepo.insertNew(newTask);
37
+ expect(insertResult).toBeTruthy();
38
+ const otherUser = await createNewTestUser();
39
+ const otherUserTask = new core_ts_db_lib_1.DashboardTask(otherUser._id);
40
+ const insertResult2 = await taskRepo.insertNew(otherUserTask);
41
+ expect(insertResult2).toBeTruthy();
42
+ const tasks = await taskRepo.getAllForUser(newUser._id);
43
+ expect(tasks.length).toBe(1);
44
+ expect(tasks[0]._id).toEqual(newTask._id);
45
+ await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
46
+ await (0, testsUtil_1.cleanupDoc)(userRepo, otherUser);
47
+ });
48
+ });
32
49
  afterAll(async () => {
33
50
  return DocumentDb_1.default.closeDbConnection();
34
51
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aneuhold/be-ts-db-lib",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
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",