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

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.
Files changed (58) hide show
  1. package/README.md +21 -0
  2. package/lib/index.d.ts +2 -1
  3. package/lib/index.d.ts.map +1 -1
  4. package/lib/index.js +3 -1
  5. package/lib/repositories/BaseRepository.d.ts +21 -1
  6. package/lib/repositories/BaseRepository.d.ts.map +1 -1
  7. package/lib/repositories/BaseRepository.js +57 -1
  8. package/lib/repositories/common/ApiKeyRepository.d.ts +5 -6
  9. package/lib/repositories/common/ApiKeyRepository.d.ts.map +1 -1
  10. package/lib/repositories/common/ApiKeyRepository.js +21 -9
  11. package/lib/repositories/common/UserRepository.d.ts +1 -32
  12. package/lib/repositories/common/UserRepository.d.ts.map +1 -1
  13. package/lib/repositories/common/UserRepository.js +5 -63
  14. package/lib/repositories/dashboard/DashboardUserConfigRepository.d.ts +17 -0
  15. package/lib/repositories/dashboard/DashboardUserConfigRepository.d.ts.map +1 -0
  16. package/lib/repositories/dashboard/DashboardUserConfigRepository.js +48 -0
  17. package/lib/scripts/migrate.d.ts +2 -0
  18. package/lib/scripts/migrate.d.ts.map +1 -0
  19. package/lib/scripts/migrate.js +7 -0
  20. package/lib/scripts/migrateDry.d.ts +2 -0
  21. package/lib/scripts/migrateDry.d.ts.map +1 -0
  22. package/lib/scripts/migrateDry.js +7 -0
  23. package/lib/scripts/validateSchema.d.ts +2 -0
  24. package/lib/scripts/validateSchema.d.ts.map +1 -0
  25. package/lib/scripts/validateSchema.js +9 -0
  26. package/lib/scripts/validateSchemaDryRun.d.ts +2 -0
  27. package/lib/scripts/validateSchemaDryRun.d.ts.map +1 -0
  28. package/lib/scripts/validateSchemaDryRun.js +9 -0
  29. package/lib/services/MigrationService.d.ts +20 -0
  30. package/lib/services/MigrationService.d.ts.map +1 -0
  31. package/lib/services/MigrationService.js +57 -0
  32. package/lib/services/RepoSubscriptionService.d.ts +30 -0
  33. package/lib/services/RepoSubscriptionService.d.ts.map +1 -0
  34. package/lib/services/RepoSubscriptionService.js +21 -0
  35. package/lib/tests/repositories/BaseRepository.spec.js +5 -5
  36. package/lib/tests/repositories/common/UserRepository.spec.js +9 -10
  37. package/lib/tests/repositories/dashboard/UserConfigRepository.spec.js +3 -3
  38. package/lib/tests/testsUtil.d.ts +9 -0
  39. package/lib/tests/testsUtil.d.ts.map +1 -1
  40. package/lib/tests/testsUtil.js +19 -1
  41. package/lib/util/DbSchemaUpdater.d.ts +7 -0
  42. package/lib/util/DbSchemaUpdater.d.ts.map +1 -0
  43. package/lib/util/DbSchemaUpdater.js +19 -0
  44. package/lib/util/DocumentCleaner.d.ts +2 -2
  45. package/lib/util/DocumentCleaner.d.ts.map +1 -1
  46. package/lib/validators/BaseValidator.d.ts +36 -1
  47. package/lib/validators/BaseValidator.d.ts.map +1 -1
  48. package/lib/validators/BaseValidator.js +74 -0
  49. package/lib/validators/common/ApiKeyValidator.d.ts +1 -0
  50. package/lib/validators/common/ApiKeyValidator.d.ts.map +1 -1
  51. package/lib/validators/common/ApiKeyValidator.js +25 -0
  52. package/lib/validators/common/UserValidator.d.ts +1 -0
  53. package/lib/validators/common/UserValidator.d.ts.map +1 -1
  54. package/lib/validators/common/UserValidator.js +24 -0
  55. package/lib/validators/dashboard/UserConfigValidator.d.ts +1 -0
  56. package/lib/validators/dashboard/UserConfigValidator.d.ts.map +1 -1
  57. package/lib/validators/dashboard/UserConfigValidator.js +27 -2
  58. package/package.json +9 -5
@@ -0,0 +1,57 @@
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
+ // @ts-ignore
7
+ // @ts-nocheck
8
+ const core_ts_lib_1 = require("@aneuhold/core-ts-lib");
9
+ const UserRepository_1 = __importDefault(require("../repositories/common/UserRepository"));
10
+ /**
11
+ * A service for migrating the DB to a new state after an existing document
12
+ * change.
13
+ *
14
+ * This entire class is ignored from ESLint and TypeScript to allow for
15
+ * manipulating the DB in any way necessary.
16
+ */
17
+ class MigrationService {
18
+ /**
19
+ * A function that can be used to migrate the DB to a new state after an
20
+ * existing document change.
21
+ *
22
+ * ❗️ BEWARE!!! ❗️
23
+ * TRIPLE CHECK THAT THIS IS WHAT YOU WANT TO DO BEFORE RUNNING THIS FUNCTION.
24
+ *
25
+ * @param dryRun Whether or not to actually make the changes or just log them.
26
+ */
27
+ static async migrateDb(dryRun = false) {
28
+ const userRepo = UserRepository_1.default.getRepo();
29
+ const allUsers = (await userRepo.getAll());
30
+ const updatedUsers = [];
31
+ allUsers.forEach((user) => {
32
+ if (user.password) {
33
+ core_ts_lib_1.Logger.error(`User with ID: ${user._id} has a password in the wrong spot.`);
34
+ user.auth.password = user.password;
35
+ delete user.password;
36
+ updatedUsers.push(user);
37
+ }
38
+ });
39
+ if (dryRun) {
40
+ if (updatedUsers.length > 0) {
41
+ core_ts_lib_1.Logger.info(`Would update ${updatedUsers.length} users.`);
42
+ }
43
+ else {
44
+ core_ts_lib_1.Logger.success('No changes to make.');
45
+ }
46
+ return;
47
+ }
48
+ if (updatedUsers.length > 0) {
49
+ core_ts_lib_1.Logger.info(`Updating ${updatedUsers.length} users.`);
50
+ await userRepo.updateMany(updatedUsers);
51
+ }
52
+ else {
53
+ core_ts_lib_1.Logger.success('No changes to make.');
54
+ }
55
+ }
56
+ }
57
+ exports.default = MigrationService;
@@ -0,0 +1,30 @@
1
+ import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
3
+ export type RepoSubscribers<TDocType extends BaseDocument> = {
4
+ insertNew: InsertNewSubscriber<TDocType>[];
5
+ updateMany: UpdateManySubscriber<TDocType>[];
6
+ deleteOne: DeleteOneSubscriber[];
7
+ deleteList: DeleteListSubscriber[];
8
+ };
9
+ export type RepoListeners<TDocType extends BaseDocument> = {
10
+ insertNew?: InsertNewSubscriber<TDocType>;
11
+ updateMany?: UpdateManySubscriber<TDocType>;
12
+ deleteOne?: DeleteOneSubscriber;
13
+ deleteList?: DeleteListSubscriber;
14
+ };
15
+ export type InsertNewSubscriber<TDocType extends BaseDocument> = (doc: TDocType) => Promise<void>;
16
+ export type UpdateManySubscriber<TDocType extends BaseDocument> = (docs: TDocType[]) => Promise<void>;
17
+ export type DeleteOneSubscriber = (docId: ObjectId) => Promise<void>;
18
+ export type DeleteListSubscriber = (docIds: ObjectId[]) => Promise<void>;
19
+ /**
20
+ * A subscription service that allows repositories to subscribe to events
21
+ * that happen in other repositories.
22
+ */
23
+ export default class RepoSubscriptionService {
24
+ /**
25
+ * A utility method to get a default empty set of subscribers for a
26
+ * repository.
27
+ */
28
+ static getDefaultSubscribers<TDocType extends BaseDocument>(): RepoSubscribers<TDocType>;
29
+ }
30
+ //# sourceMappingURL=RepoSubscriptionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoSubscriptionService.d.ts","sourceRoot":"","sources":["../../src/services/RepoSubscriptionService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,MAAM,MAAM,eAAe,CAAC,QAAQ,SAAS,YAAY,IAAI;IAC3D,SAAS,EAAE,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3C,UAAU,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC7C,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,UAAU,EAAE,oBAAoB,EAAE,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,QAAQ,SAAS,YAAY,IAAI;IACzD,SAAS,CAAC,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,YAAY,IAAI,CAC/D,GAAG,EAAE,QAAQ,KACV,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,oBAAoB,CAAC,QAAQ,SAAS,YAAY,IAAI,CAChE,IAAI,EAAE,QAAQ,EAAE,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C;;;OAGG;IACH,MAAM,CAAC,qBAAqB,CAC1B,QAAQ,SAAS,YAAY,KAC1B,eAAe,CAAC,QAAQ,CAAC;CAQ/B"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * A subscription service that allows repositories to subscribe to events
5
+ * that happen in other repositories.
6
+ */
7
+ class RepoSubscriptionService {
8
+ /**
9
+ * A utility method to get a default empty set of subscribers for a
10
+ * repository.
11
+ */
12
+ static getDefaultSubscribers() {
13
+ return {
14
+ insertNew: [],
15
+ updateMany: [],
16
+ deleteOne: [],
17
+ deleteList: []
18
+ };
19
+ }
20
+ }
21
+ exports.default = RepoSubscriptionService;
@@ -8,10 +8,10 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
8
  const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
9
9
  const testsUtil_1 = require("../testsUtil");
10
10
  const DocumentDb_1 = __importDefault(require("../../util/DocumentDb"));
11
- const UserConfigRepository_1 = __importDefault(require("../../repositories/dashboard/UserConfigRepository"));
11
+ const DashboardUserConfigRepository_1 = __importDefault(require("../../repositories/dashboard/DashboardUserConfigRepository"));
12
12
  it('can create a new document and delete it', async () => {
13
13
  const userRepository = UserRepository_1.default.getRepo();
14
- const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
14
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
15
15
  const createResult = await userRepository.insertNew(newUser);
16
16
  expect(createResult).toBeTruthy();
17
17
  await (0, testsUtil_1.cleanupDoc)(userRepository, newUser);
@@ -20,16 +20,16 @@ it('can create a new document and delete it', async () => {
20
20
  it.skip('can add a new test user', async () => {
21
21
  const userRepository = UserRepository_1.default.getRepo();
22
22
  const newUser = new core_ts_db_lib_1.User('someUser');
23
- newUser.password = crypto_1.default.randomUUID();
23
+ newUser.auth.password = crypto_1.default.randomUUID();
24
24
  const createResult = await userRepository.insertNew(newUser);
25
25
  expect(createResult).toBeTruthy();
26
26
  });
27
- it('can create a dashboard config for a user', async () => {
27
+ it.skip('can create a dashboard config for a user', async () => {
28
28
  const userRepo = UserRepository_1.default.getRepo();
29
29
  const user = await userRepo.get({ userName: 'usernameHere' });
30
30
  expect(user).toBeTruthy();
31
31
  if (user) {
32
- const configRepo = UserConfigRepository_1.default.getRepo();
32
+ const configRepo = DashboardUserConfigRepository_1.default.getRepo();
33
33
  const newConfig = new core_ts_db_lib_1.DashboardUserConfig(user._id);
34
34
  newConfig.enableDevMode = true;
35
35
  await configRepo.insertNew(newConfig);
@@ -3,7 +3,6 @@ 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 crypto_1 = __importDefault(require("crypto"));
7
6
  const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
7
  const UserRepository_1 = __importDefault(require("../../../repositories/common/UserRepository"));
9
8
  const testsUtil_1 = require("../../testsUtil");
@@ -12,13 +11,13 @@ const DocumentDb_1 = __importDefault(require("../../../util/DocumentDb"));
12
11
  const userRepo = UserRepository_1.default.getRepo();
13
12
  describe('Create operations', () => {
14
13
  it('can create a new user', async () => {
15
- const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
14
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
16
15
  const insertResult = await userRepo.insertNew(newUser);
17
16
  expect(insertResult).toBeTruthy();
18
17
  await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
19
18
  });
20
19
  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());
20
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
22
21
  const insertResult = await userRepo.insertNew(newUser);
23
22
  expect(insertResult).toBeTruthy();
24
23
  const apiKey = await ApiKeyRepository_1.default.getRepo().get({
@@ -32,7 +31,7 @@ describe('Create operations', () => {
32
31
  expect(apiKeyThatShouldNotExist).toBeFalsy();
33
32
  });
34
33
  it('throws if the username is a duplicate username', async () => {
35
- const duplicateUserName = `${crypto_1.default.randomUUID()}`;
34
+ const duplicateUserName = (0, testsUtil_1.getTestUserName)();
36
35
  const newUser1 = new core_ts_db_lib_1.User(duplicateUserName);
37
36
  const newUser2 = new core_ts_db_lib_1.User(duplicateUserName);
38
37
  const insertResult = await userRepo.insertNew(newUser1);
@@ -45,8 +44,8 @@ describe('Create operations', () => {
45
44
  });
46
45
  describe('Update operations', () => {
47
46
  it('succeeds in updating the username if the username doesnt already exist', async () => {
48
- const userName1 = crypto_1.default.randomUUID();
49
- const userName2 = crypto_1.default.randomUUID();
47
+ const userName1 = (0, testsUtil_1.getTestUserName)();
48
+ const userName2 = (0, testsUtil_1.getTestUserName)();
50
49
  const newUser = new core_ts_db_lib_1.User(userName1);
51
50
  // Insert the user
52
51
  const insertResult = await userRepo.insertNew(newUser);
@@ -58,15 +57,15 @@ describe('Update operations', () => {
58
57
  await (0, testsUtil_1.cleanupDoc)(userRepo, newUser);
59
58
  });
60
59
  it('throws if no id is defined', async () => {
61
- const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
60
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
62
61
  delete newUser._id;
63
62
  await (0, testsUtil_1.expectToThrow)(async () => {
64
63
  await userRepo.update(newUser);
65
64
  });
66
65
  });
67
66
  it('throws if the username is updated and already exists', async () => {
68
- const userName1 = crypto_1.default.randomUUID();
69
- const userName2 = crypto_1.default.randomUUID();
67
+ const userName1 = (0, testsUtil_1.getTestUserName)();
68
+ const userName2 = (0, testsUtil_1.getTestUserName)();
70
69
  const newUser = new core_ts_db_lib_1.User(userName1);
71
70
  const userWithOtherUserName = new core_ts_db_lib_1.User(userName2);
72
71
  // Insert the users
@@ -85,7 +84,7 @@ describe('Update operations', () => {
85
84
  ]);
86
85
  });
87
86
  it('throws if the user doesnt exist', async () => {
88
- const newUser = new core_ts_db_lib_1.User(crypto_1.default.randomUUID());
87
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)());
89
88
  // Try to update the user
90
89
  await (0, testsUtil_1.expectToThrow)(async () => {
91
90
  await userRepo.update(newUser);
@@ -8,9 +8,9 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
8
8
  const UserRepository_1 = __importDefault(require("../../../repositories/common/UserRepository"));
9
9
  const testsUtil_1 = require("../../testsUtil");
10
10
  const DocumentDb_1 = __importDefault(require("../../../util/DocumentDb"));
11
- const UserConfigRepository_1 = __importDefault(require("../../../repositories/dashboard/UserConfigRepository"));
11
+ const DashboardUserConfigRepository_1 = __importDefault(require("../../../repositories/dashboard/DashboardUserConfigRepository"));
12
12
  const userRepo = UserRepository_1.default.getRepo();
13
- const configRepo = UserConfigRepository_1.default.getRepo();
13
+ const configRepo = DashboardUserConfigRepository_1.default.getRepo();
14
14
  describe('Create operations', () => {
15
15
  it('can create a new user config', async () => {
16
16
  // User configs are created automatically when a new user is created
@@ -42,7 +42,7 @@ afterAll(async () => {
42
42
  return DocumentDb_1.default.closeDbConnection();
43
43
  });
44
44
  async function createNewTestUser() {
45
- const newUser = new core_ts_db_lib_1.User(`${crypto_1.default.randomUUID()}userconfigtest`);
45
+ const newUser = new core_ts_db_lib_1.User((0, testsUtil_1.getTestUserName)(`${crypto_1.default.randomUUID()}userconfigtest`));
46
46
  newUser.projectAccess.dashboard = true;
47
47
  const insertResult = await userRepo.insertNew(newUser);
48
48
  expect(insertResult).toBeTruthy();
@@ -1,6 +1,15 @@
1
1
  import { BaseDocument } from '@aneuhold/core-ts-db-lib';
2
2
  import BaseRepository from '../repositories/BaseRepository';
3
+ /**
4
+ * A random series of characters for tests to help identify test users.
5
+ */
6
+ export declare const TEST_USER_NAME_PREFIX = "lkahwsetpiohweat";
3
7
  export declare function expectToThrow(func: () => Promise<void>): Promise<void>;
8
+ /**
9
+ * Gets a test user name with a standardized prefix so that they can all be
10
+ * identified and deleted if anything goes wrong in the tests.
11
+ */
12
+ export declare function getTestUserName(username?: string): string;
4
13
  /**
5
14
  * Removes the provided doc from the DB
6
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"testsUtil.d.ts","sourceRoot":"","sources":["../../src/tests/testsUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAE5D,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,iBAQ5D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,SAAS,YAAY,EAC5D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,GAAG,EAAE,QAAQ,iBAMd;AAED,wBAAsB,WAAW,CAAC,QAAQ,SAAS,YAAY,EAC7D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,IAAI,EAAE,QAAQ,EAAE,iBAOjB"}
1
+ {"version":3,"file":"testsUtil.d.ts","sourceRoot":"","sources":["../../src/tests/testsUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,iBAQ5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,UAGhD;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,SAAS,YAAY,EAC5D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,GAAG,EAAE,QAAQ,iBAMd;AAED,wBAAsB,WAAW,CAAC,QAAQ,SAAS,YAAY,EAC7D,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,EAC9B,IAAI,EAAE,QAAQ,EAAE,iBAOjB"}
@@ -1,6 +1,14 @@
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 });
3
- exports.cleanupDocs = exports.cleanupDoc = exports.expectToThrow = void 0;
6
+ exports.cleanupDocs = exports.cleanupDoc = exports.getTestUserName = exports.expectToThrow = exports.TEST_USER_NAME_PREFIX = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ /**
9
+ * A random series of characters for tests to help identify test users.
10
+ */
11
+ exports.TEST_USER_NAME_PREFIX = 'lkahwsetpiohweat';
4
12
  async function expectToThrow(func) {
5
13
  let threwError = false;
6
14
  try {
@@ -12,6 +20,16 @@ async function expectToThrow(func) {
12
20
  expect(threwError).toBeTruthy();
13
21
  }
14
22
  exports.expectToThrow = expectToThrow;
23
+ /**
24
+ * Gets a test user name with a standardized prefix so that they can all be
25
+ * identified and deleted if anything goes wrong in the tests.
26
+ */
27
+ function getTestUserName(username) {
28
+ if (!username)
29
+ return `${exports.TEST_USER_NAME_PREFIX}-${crypto_1.default.randomUUID()}`;
30
+ return `${exports.TEST_USER_NAME_PREFIX}-${username}`;
31
+ }
32
+ exports.getTestUserName = getTestUserName;
15
33
  /**
16
34
  * Removes the provided doc from the DB
17
35
  */
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A class that can be used to validate and update the DB and all repositories.
3
+ */
4
+ export default class DbSchemaUpdater {
5
+ static updateSchemaForAllRepos(dryRun?: boolean): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=DbSchemaUpdater.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,19 @@
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 ApiKeyValidator_1 = __importDefault(require("../validators/common/ApiKeyValidator"));
7
+ const UserValidator_1 = __importDefault(require("../validators/common/UserValidator"));
8
+ const UserConfigValidator_1 = __importDefault(require("../validators/dashboard/UserConfigValidator"));
9
+ /**
10
+ * A class that can be used to validate and update the DB and all repositories.
11
+ */
12
+ class DbSchemaUpdater {
13
+ static async updateSchemaForAllRepos(dryRun = false) {
14
+ await new UserValidator_1.default().validateRepositoryInDb(dryRun);
15
+ await new ApiKeyValidator_1.default().validateRepositoryInDb(dryRun);
16
+ await new UserConfigValidator_1.default().validateRepositoryInDb(dryRun);
17
+ }
18
+ }
19
+ exports.default = DbSchemaUpdater;
@@ -1,11 +1,11 @@
1
- import { BaseDocument, BaseDocumentWithType, BaseDocumentWithUserId } from '@aneuhold/core-ts-db-lib';
1
+ import { BaseDocument, BaseDocumentWithType, RequiredUserId } from '@aneuhold/core-ts-db-lib';
2
2
  /**
3
3
  * A class which contains some standard methods for cleaning update documents
4
4
  * before they are sent to the database.
5
5
  */
6
6
  export default class CleanDocument {
7
7
  static id<TDocType extends BaseDocument>(updateDoc: Partial<TDocType>): Partial<TDocType>;
8
- static userId<TDocType extends BaseDocumentWithUserId>(updateDoc: Partial<TDocType>): Partial<TDocType>;
8
+ static userId<TDocType extends RequiredUserId>(updateDoc: Partial<TDocType>): Partial<TDocType>;
9
9
  static docType<TDocType extends BaseDocumentWithType>(updateDoc: Partial<TDocType>): Partial<TDocType>;
10
10
  }
11
11
  //# sourceMappingURL=DocumentCleaner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentCleaner.d.ts","sourceRoot":"","sources":["../../src/util/DocumentCleaner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC,MAAM,CAAC,EAAE,CAAC,QAAQ,SAAS,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAMrE,MAAM,CAAC,MAAM,CAAC,QAAQ,SAAS,sBAAsB,EACnD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAO9B,MAAM,CAAC,OAAO,CAAC,QAAQ,SAAS,oBAAoB,EAClD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;CAM/B"}
1
+ {"version":3,"file":"DocumentCleaner.d.ts","sourceRoot":"","sources":["../../src/util/DocumentCleaner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC,MAAM,CAAC,EAAE,CAAC,QAAQ,SAAS,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAMrE,MAAM,CAAC,MAAM,CAAC,QAAQ,SAAS,cAAc,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;IAM3E,MAAM,CAAC,OAAO,CAAC,QAAQ,SAAS,oBAAoB,EAClD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC;CAM/B"}
@@ -1,4 +1,10 @@
1
- import { BaseDocument } from '@aneuhold/core-ts-db-lib';
1
+ import { BaseDocument, DocumentValidator } from '@aneuhold/core-ts-db-lib';
2
+ import { ObjectId } from 'bson';
3
+ export declare enum ObjectSchemaState {
4
+ Valid = 0,
5
+ InvalidAndCorrectable = 1,
6
+ InvalidAndUncorrectable = 2
7
+ }
2
8
  export default abstract class IValidator<TBaseType extends BaseDocument> {
3
9
  /**
4
10
  * Validates that an object that is supposed to be inserted in to the database
@@ -11,6 +17,35 @@ export default abstract class IValidator<TBaseType extends BaseDocument> {
11
17
  * At this point, the fields that do not change should already be stripped.
12
18
  */
13
19
  abstract validateUpdateObject(partialObject: Partial<TBaseType>): Promise<void>;
20
+ /**
21
+ * Validates the entire DB for the repository, and corrects where needed.
22
+ *
23
+ * This should only correct the records that this repository has a full
24
+ * understanding of.
25
+ *
26
+ * This can be a long-running process, so it should only be executed in a
27
+ * script.
28
+ *
29
+ * Make sure to use the {@link runStandardValidationForRepository} method
30
+ * to run the validation to make things easier.
31
+ */
32
+ abstract validateRepositoryInDb(dryRun: boolean): Promise<void>;
33
+ /**
34
+ * Runs the standard validation for a repository.
35
+ *
36
+ * @param shouldDelete A function that returns true if the document should be
37
+ * deleted. This should also log the specific error because it will not be
38
+ * logged elsewhere.
39
+ */
40
+ protected runStandardValidationForRepository(input: {
41
+ dryRun: boolean;
42
+ docName: string;
43
+ allDocs: Array<TBaseType>;
44
+ shouldDelete: (doc: TBaseType) => boolean;
45
+ documentValidator: DocumentValidator<TBaseType>;
46
+ deletionFunction: (docIdsToDelete: ObjectId[]) => Promise<void>;
47
+ updateFunction: (docsToUpdate: TBaseType[]) => Promise<void>;
48
+ }): Promise<void>;
14
49
  /**
15
50
  * Checks that all elements that exist in array1, exist in array2.
16
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"BaseValidator.d.ts","sourceRoot":"","sources":["../../src/validators/BaseValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,UAAU,CAAC,SAAS,SAAS,YAAY;IACrE;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5D;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAC3B,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,0BAA0B,CAClC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,EACtB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;CAIzB"}
1
+ {"version":3,"file":"BaseValidator.d.ts","sourceRoot":"","sources":["../../src/validators/BaseValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,oBAAY,iBAAiB;IAC3B,KAAK,IAAA;IACL,qBAAqB,IAAA;IACrB,uBAAuB,IAAA;CACxB;AAED,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,UAAU,CAAC,SAAS,SAAS,YAAY;IACrE;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5D;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAC3B,aAAa,EAAE,OAAO,CAAC,SAAS,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/D;;;;;;OAMG;cACa,kCAAkC,CAAC,KAAK,EAAE;QACxD,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1B,YAAY,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC;QAC1C,iBAAiB,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAChD,gBAAgB,EAAE,CAAC,cAAc,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAChE,cAAc,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9D;IAwED;;OAEG;IACH,SAAS,CAAC,0BAA0B,CAClC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,EACtB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;CAIzB"}
@@ -1,6 +1,80 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectSchemaState = void 0;
4
+ const core_ts_lib_1 = require("@aneuhold/core-ts-lib");
5
+ var ObjectSchemaState;
6
+ (function (ObjectSchemaState) {
7
+ ObjectSchemaState[ObjectSchemaState["Valid"] = 0] = "Valid";
8
+ ObjectSchemaState[ObjectSchemaState["InvalidAndCorrectable"] = 1] = "InvalidAndCorrectable";
9
+ ObjectSchemaState[ObjectSchemaState["InvalidAndUncorrectable"] = 2] = "InvalidAndUncorrectable";
10
+ })(ObjectSchemaState || (exports.ObjectSchemaState = ObjectSchemaState = {}));
3
11
  class IValidator {
12
+ /**
13
+ * Runs the standard validation for a repository.
14
+ *
15
+ * @param shouldDelete A function that returns true if the document should be
16
+ * deleted. This should also log the specific error because it will not be
17
+ * logged elsewhere.
18
+ */
19
+ async runStandardValidationForRepository(input) {
20
+ const { dryRun, docName, allDocs, shouldDelete, documentValidator, deletionFunction, updateFunction } = input;
21
+ const docIdsToDelete = [];
22
+ const docsToValidate = [];
23
+ const docsToUpdate = [];
24
+ let numInvalidDocs = 0;
25
+ // Check for docs that need to be deleted
26
+ allDocs.forEach((doc) => {
27
+ if (shouldDelete(doc)) {
28
+ docIdsToDelete.push(doc._id);
29
+ }
30
+ else {
31
+ docsToValidate.push(doc);
32
+ }
33
+ });
34
+ // Validate the rest
35
+ docsToValidate.forEach((doc) => {
36
+ const { updatedDoc, errors } = documentValidator(doc);
37
+ if (errors.length !== 0) {
38
+ core_ts_lib_1.Logger.error(`${docName} with ID: ${doc._id} is invalid. Errors:`);
39
+ numInvalidDocs += 1;
40
+ errors.forEach((error) => {
41
+ core_ts_lib_1.Logger.error(error);
42
+ });
43
+ docsToUpdate.push(updatedDoc);
44
+ }
45
+ });
46
+ if (dryRun) {
47
+ if (numInvalidDocs === 0) {
48
+ core_ts_lib_1.Logger.success(`No invalid ${docName}s found.`);
49
+ }
50
+ else {
51
+ core_ts_lib_1.Logger.info(`Would update ${numInvalidDocs} ${docName}s in the database.`);
52
+ }
53
+ if (docIdsToDelete.length === 0) {
54
+ core_ts_lib_1.Logger.success(`No ${docName}s to delete found.`);
55
+ }
56
+ else {
57
+ core_ts_lib_1.Logger.info(`Would delete ${docIdsToDelete.length} ${docName}s in the database.`);
58
+ }
59
+ return;
60
+ }
61
+ // Delete all invalid
62
+ if (docIdsToDelete.length !== 0) {
63
+ core_ts_lib_1.Logger.info(`Deleting ${docIdsToDelete.length} ${docName}s from the database.`);
64
+ await deletionFunction(docIdsToDelete);
65
+ }
66
+ else {
67
+ core_ts_lib_1.Logger.success(`No ${docName}s to delete found.`);
68
+ }
69
+ // Update all that need to be updated
70
+ if (docsToUpdate.length !== 0) {
71
+ core_ts_lib_1.Logger.info(`Updating ${docsToUpdate.length} ${docName}s in the database.`);
72
+ await updateFunction(docsToUpdate);
73
+ }
74
+ else {
75
+ core_ts_lib_1.Logger.success(`No ${docName}s to update found.`);
76
+ }
77
+ }
4
78
  /**
5
79
  * Checks that all elements that exist in array1, exist in array2.
6
80
  */
@@ -3,5 +3,6 @@ import IValidator from '../BaseValidator';
3
3
  export default class ApiKeyValidator extends IValidator<ApiKey> {
4
4
  validateNewObject(newApiKey: ApiKey): Promise<void>;
5
5
  validateUpdateObject(updatedApiKey: Partial<ApiKey>): Promise<void>;
6
+ validateRepositoryInDb(dryRun: boolean): Promise<void>;
6
7
  }
7
8
  //# sourceMappingURL=ApiKeyValidator.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"ApiKeyValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/common/ApiKeyValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAKlD,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;IAQnE,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CA2B7D"}
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const core_ts_lib_1 = require("@aneuhold/core-ts-lib");
7
+ const ApiKey_1 = require("@aneuhold/core-ts-db-lib/lib/documents/common/ApiKey");
7
8
  const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
8
9
  const BaseValidator_1 = __importDefault(require("../BaseValidator"));
9
10
  const ApiKeyRepository_1 = __importDefault(require("../../repositories/common/ApiKeyRepository"));
@@ -27,5 +28,29 @@ class ApiKeyValidator extends BaseValidator_1.default {
27
28
  // Throw, because API keys should not be updated. Only created and deleted.
28
29
  core_ts_lib_1.ErrorUtils.throwError(`API keys should not be updated at this time. Only created and deleted.`, updatedApiKey);
29
30
  }
31
+ async validateRepositoryInDb(dryRun) {
32
+ const apiKeyRepo = ApiKeyRepository_1.default.getRepo();
33
+ const allApiKeys = await apiKeyRepo.getAll();
34
+ const allUserIds = await UserRepository_1.default.getRepo().getAllIdsAsHash();
35
+ await this.runStandardValidationForRepository({
36
+ dryRun,
37
+ docName: 'API Key',
38
+ allDocs: allApiKeys,
39
+ shouldDelete: (apiKey) => {
40
+ if (!allUserIds[apiKey.userId.toString()]) {
41
+ core_ts_lib_1.Logger.error(`API Key with ID: ${apiKey._id} has no valid associated user.`);
42
+ return true;
43
+ }
44
+ return false;
45
+ },
46
+ documentValidator: ApiKey_1.validateApiKey,
47
+ deletionFunction: async (docIdsToDelete) => {
48
+ await apiKeyRepo.deleteList(docIdsToDelete);
49
+ },
50
+ updateFunction: async (docsToUpdate) => {
51
+ await apiKeyRepo.updateMany(docsToUpdate);
52
+ }
53
+ });
54
+ }
30
55
  }
31
56
  exports.default = ApiKeyValidator;
@@ -3,6 +3,7 @@ import IValidator from '../BaseValidator';
3
3
  export default class UserValidator extends IValidator<User> {
4
4
  validateNewObject(newUser: User): Promise<void>;
5
5
  validateUpdateObject(userToUpdate: Partial<User>): Promise<void>;
6
+ validateRepositoryInDb(dryRun: boolean): Promise<void>;
6
7
  /**
7
8
  * Checks if the username exists already and throws an error if it does.
8
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"UserValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/common/UserValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAEhD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAG1C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,UAAU,CAAC,IAAI,CAAC;IACnD,iBAAiB,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,oBAAoB,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BtE;;OAEG;YACW,qBAAqB;CAWpC"}
1
+ {"version":3,"file":"UserValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/common/UserValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,0BAA0B,CAAC;AAG9D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,UAAU,CAAC,IAAI,CAAC;IACnD,iBAAiB,CAAC,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/C,oBAAoB,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhE,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B5D;;OAEG;YACW,qBAAqB;CAWpC"}
@@ -7,6 +7,7 @@ const core_ts_db_lib_1 = require("@aneuhold/core-ts-db-lib");
7
7
  const core_ts_lib_1 = require("@aneuhold/core-ts-lib");
8
8
  const BaseValidator_1 = __importDefault(require("../BaseValidator"));
9
9
  const UserRepository_1 = __importDefault(require("../../repositories/common/UserRepository"));
10
+ const testsUtil_1 = require("../../tests/testsUtil");
10
11
  class UserValidator extends BaseValidator_1.default {
11
12
  async validateNewObject(newUser) {
12
13
  // Check if the username already exists
@@ -31,6 +32,29 @@ class UserValidator extends BaseValidator_1.default {
31
32
  await this.checkIfUserNameExists(userRepo, userToUpdate.userName);
32
33
  }
33
34
  }
35
+ async validateRepositoryInDb(dryRun) {
36
+ const userRepo = UserRepository_1.default.getRepo();
37
+ const allUsers = await userRepo.getAll();
38
+ await this.runStandardValidationForRepository({
39
+ dryRun,
40
+ docName: 'User',
41
+ allDocs: allUsers,
42
+ shouldDelete: (user) => {
43
+ if (user.userName.startsWith(testsUtil_1.TEST_USER_NAME_PREFIX)) {
44
+ core_ts_lib_1.Logger.error(`User with ID: ${user._id} is a test user and should be deleted`);
45
+ return true;
46
+ }
47
+ return false;
48
+ },
49
+ documentValidator: core_ts_db_lib_1.validateUser,
50
+ deletionFunction: async (docIdsToDelete) => {
51
+ await userRepo.deleteList(docIdsToDelete);
52
+ },
53
+ updateFunction: async (docsToUpdate) => {
54
+ await userRepo.updateMany(docsToUpdate);
55
+ }
56
+ });
57
+ }
34
58
  /**
35
59
  * Checks if the username exists already and throws an error if it does.
36
60
  */
@@ -3,5 +3,6 @@ import IValidator from '../BaseValidator';
3
3
  export default class DashboardUserConfigValidator extends IValidator<DashboardUserConfig> {
4
4
  validateNewObject(newUserConfig: DashboardUserConfig): Promise<void>;
5
5
  validateUpdateObject(updatedUserConfig: Partial<DashboardUserConfig>): Promise<void>;
6
+ validateRepositoryInDb(dryRun: boolean): Promise<void>;
6
7
  }
7
8
  //# sourceMappingURL=UserConfigValidator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserConfigValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/dashboard/UserConfigValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,OAAO,OAAO,4BAA6B,SAAQ,UAAU,CAAC,mBAAmB,CAAC;IACjF,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpE,oBAAoB,CACxB,iBAAiB,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAC9C,OAAO,CAAC,IAAI,CAAC;CASjB"}
1
+ {"version":3,"file":"UserConfigValidator.d.ts","sourceRoot":"","sources":["../../../src/validators/dashboard/UserConfigValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEpB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,OAAO,OAAO,4BAA6B,SAAQ,UAAU,CAAC,mBAAmB,CAAC;IACjF,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpE,oBAAoB,CACxB,iBAAiB,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAC9C,OAAO,CAAC,IAAI,CAAC;IAUV,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CA2B7D"}