dce-expresskit 4.0.0-beta-logreviewer.1

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 (99) hide show
  1. package/.eslintrc.js +93 -0
  2. package/LICENSE +21 -0
  3. package/README.md +17 -0
  4. package/genEncodedSecret.ts +107 -0
  5. package/genSalt.ts +15 -0
  6. package/lib/constants/LOG_REVIEW_PAGE_SIZE.d.ts +6 -0
  7. package/lib/constants/LOG_REVIEW_PAGE_SIZE.js +9 -0
  8. package/lib/constants/LOG_REVIEW_PAGE_SIZE.js.map +1 -0
  9. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.d.ts +6 -0
  10. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js +13 -0
  11. package/lib/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.js.map +1 -0
  12. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.d.ts +7 -0
  13. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js +14 -0
  14. package/lib/constants/LOG_REVIEW_STATUS_ROUTE.js.map +1 -0
  15. package/lib/constants/LOG_ROUTE_PATH.d.ts +6 -0
  16. package/lib/constants/LOG_ROUTE_PATH.js +13 -0
  17. package/lib/constants/LOG_ROUTE_PATH.js.map +1 -0
  18. package/lib/constants/ROUTE_PATH_PREFIX.d.ts +6 -0
  19. package/lib/constants/ROUTE_PATH_PREFIX.js +9 -0
  20. package/lib/constants/ROUTE_PATH_PREFIX.js.map +1 -0
  21. package/lib/errors/ErrorWithCode.d.ts +9 -0
  22. package/lib/errors/ErrorWithCode.js +33 -0
  23. package/lib/errors/ErrorWithCode.js.map +1 -0
  24. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.d.ts +9 -0
  25. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js +17 -0
  26. package/lib/helpers/addDBEditorEndpoints/generateEndpointPath.js.map +1 -0
  27. package/lib/helpers/addDBEditorEndpoints/index.d.ts +41 -0
  28. package/lib/helpers/addDBEditorEndpoints/index.js +134 -0
  29. package/lib/helpers/addDBEditorEndpoints/index.js.map +1 -0
  30. package/lib/helpers/dataSigner.d.ts +40 -0
  31. package/lib/helpers/dataSigner.js +242 -0
  32. package/lib/helpers/dataSigner.js.map +1 -0
  33. package/lib/helpers/genRouteHandler.d.ts +75 -0
  34. package/lib/helpers/genRouteHandler.js +662 -0
  35. package/lib/helpers/genRouteHandler.js.map +1 -0
  36. package/lib/helpers/getLogReviewerLogs.d.ts +27 -0
  37. package/lib/helpers/getLogReviewerLogs.js +238 -0
  38. package/lib/helpers/getLogReviewerLogs.js.map +1 -0
  39. package/lib/helpers/handleError.d.ts +18 -0
  40. package/lib/helpers/handleError.js +51 -0
  41. package/lib/helpers/handleError.js.map +1 -0
  42. package/lib/helpers/handleSuccess.d.ts +8 -0
  43. package/lib/helpers/handleSuccess.js +20 -0
  44. package/lib/helpers/handleSuccess.js.map +1 -0
  45. package/lib/helpers/initCrossServerCredentialCollection.d.ts +11 -0
  46. package/lib/helpers/initCrossServerCredentialCollection.js +15 -0
  47. package/lib/helpers/initCrossServerCredentialCollection.js.map +1 -0
  48. package/lib/helpers/initLogCollection.d.ts +11 -0
  49. package/lib/helpers/initLogCollection.js +26 -0
  50. package/lib/helpers/initLogCollection.js.map +1 -0
  51. package/lib/helpers/initServer.d.ts +45 -0
  52. package/lib/helpers/initServer.js +292 -0
  53. package/lib/helpers/initServer.js.map +1 -0
  54. package/lib/helpers/parseUserAgent.d.ts +17 -0
  55. package/lib/helpers/parseUserAgent.js +108 -0
  56. package/lib/helpers/parseUserAgent.js.map +1 -0
  57. package/lib/helpers/visitEndpointOnAnotherServer/index.d.ts +18 -0
  58. package/lib/helpers/visitEndpointOnAnotherServer/index.js +89 -0
  59. package/lib/helpers/visitEndpointOnAnotherServer/index.js.map +1 -0
  60. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.d.ts +23 -0
  61. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js +236 -0
  62. package/lib/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.js.map +1 -0
  63. package/lib/html/genErrorPage.d.ts +19 -0
  64. package/lib/html/genErrorPage.js +27 -0
  65. package/lib/html/genErrorPage.js.map +1 -0
  66. package/lib/html/genInfoPage.d.ts +13 -0
  67. package/lib/html/genInfoPage.js +16 -0
  68. package/lib/html/genInfoPage.js.map +1 -0
  69. package/lib/index.d.ts +11 -0
  70. package/lib/index.js +68 -0
  71. package/lib/index.js.map +1 -0
  72. package/lib/types/CrossServerCredential.d.ts +11 -0
  73. package/lib/types/CrossServerCredential.js +3 -0
  74. package/lib/types/CrossServerCredential.js.map +1 -0
  75. package/lib/types/ExpressKitErrorCode.d.ts +31 -0
  76. package/lib/types/ExpressKitErrorCode.js +38 -0
  77. package/lib/types/ExpressKitErrorCode.js.map +1 -0
  78. package/package.json +53 -0
  79. package/src/constants/LOG_REVIEW_PAGE_SIZE.ts +7 -0
  80. package/src/errors/ErrorWithCode.tsx +15 -0
  81. package/src/helpers/addDBEditorEndpoints/generateEndpointPath.ts +16 -0
  82. package/src/helpers/addDBEditorEndpoints/index.ts +130 -0
  83. package/src/helpers/dataSigner.ts +319 -0
  84. package/src/helpers/genRouteHandler.ts +920 -0
  85. package/src/helpers/getLogReviewerLogs.ts +259 -0
  86. package/src/helpers/handleError.ts +66 -0
  87. package/src/helpers/handleSuccess.ts +18 -0
  88. package/src/helpers/initCrossServerCredentialCollection.ts +19 -0
  89. package/src/helpers/initLogCollection.ts +30 -0
  90. package/src/helpers/initServer.ts +283 -0
  91. package/src/helpers/parseUserAgent.ts +108 -0
  92. package/src/helpers/visitEndpointOnAnotherServer/index.ts +70 -0
  93. package/src/helpers/visitEndpointOnAnotherServer/sendServerToServerRequest.ts +257 -0
  94. package/src/html/genErrorPage.ts +144 -0
  95. package/src/html/genInfoPage.ts +101 -0
  96. package/src/index.ts +125 -0
  97. package/src/types/CrossServerCredential.ts +16 -0
  98. package/src/types/ExpressKitErrorCode.ts +37 -0
  99. package/tsconfig.json +19 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,93 @@
1
+ const config = {
2
+ extends: [
3
+ 'airbnb',
4
+ 'airbnb/hooks',
5
+ ],
6
+ overrides: [
7
+ {
8
+ files: [
9
+ '*.ts',
10
+ '*.tsx',
11
+ ],
12
+ extends: [
13
+ 'airbnb-typescript',
14
+ ],
15
+ parserOptions: {
16
+ project: './tsconfig.json',
17
+ tsconfigRootDir: __dirname,
18
+ sourceType: 'module',
19
+ },
20
+ rules: {
21
+ '@typescript-eslint/lines-between-class-members': 'off',
22
+ '@typescript-eslint/no-unused-expressions': 'off',
23
+ },
24
+ },
25
+ ],
26
+ rules: {
27
+ 'arrow-body-style': [
28
+ 'warn',
29
+ 'always',
30
+ ],
31
+ 'react/prop-types': 'off',
32
+ 'react/function-component-definition': [
33
+ 2,
34
+ {
35
+ namedComponents: 'arrow-function',
36
+ },
37
+ ],
38
+ 'no-spaced-func': 'off',
39
+ 'react-hooks/exhaustive-deps': 'off',
40
+ 'lines-between-class-members': 'off',
41
+ 'no-case-declarations': 'off',
42
+ 'react/require-default-props': 'off',
43
+ 'react/react-in-jsx-scope': 'off',
44
+ 'arrow-parens': [
45
+ 'warn',
46
+ 'always',
47
+ ],
48
+ 'comma-dangle': [
49
+ 'error',
50
+ {
51
+ arrays: 'always-multiline',
52
+ objects: 'always-multiline',
53
+ imports: 'always-multiline',
54
+ exports: 'always-multiline',
55
+ functions: 'always-multiline',
56
+ },
57
+ ],
58
+ 'consistent-return': 'off',
59
+ 'id-length': 'off',
60
+ 'max-len': [
61
+ 'error',
62
+ {
63
+ code: 125,
64
+ ignoreStrings: true,
65
+ ignoreTemplateLiterals: true,
66
+ ignoreUrls: true,
67
+ },
68
+ ],
69
+ 'newline-per-chained-call': [
70
+ 'error',
71
+ {
72
+ ignoreChainWithDepth: 2,
73
+ },
74
+ ],
75
+ 'no-plusplus': [
76
+ 'warn',
77
+ {
78
+ allowForLoopAfterthoughts: true,
79
+ },
80
+ ],
81
+ 'prefer-template': 1,
82
+ radix: 'error',
83
+ 'no-await-in-loop': 'off',
84
+ 'max-params': [
85
+ 'warn',
86
+ {
87
+ max: 3,
88
+ },
89
+ ],
90
+ },
91
+ };
92
+
93
+ module.exports = config;
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harvard Edtech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # dce-expresskit
2
+
3
+ Shared functions, helpers, and tools for Harvard DCE Express-based servers
4
+
5
+ ## Quickstart
6
+
7
+ 1. Install `dce-expresskit` into your React project:
8
+
9
+ ```bash
10
+ npm install dce-expresskit --save
11
+ ```
12
+
13
+ 2. Import `dce-expresskit` components into your React component:
14
+
15
+ ```js
16
+ import { genRouteHandler } from 'dce-expresskit';
17
+ ```
@@ -0,0 +1,107 @@
1
+ // Import crypto lib
2
+ import crypto from 'crypto';
3
+
4
+ // Prompt
5
+ import readline from 'readline';
6
+
7
+ // Create a readline interface
8
+ const readlineInterface = readline.createInterface({
9
+ input: process.stdin,
10
+ output: process.stdout
11
+ });
12
+
13
+ /**
14
+ * Prompt user for input
15
+ * @author Gabe Abrams
16
+ * @param question the question to ask the user
17
+ * @returns the text from the user
18
+ */
19
+ const prompt = (question: string): Promise<string> => {
20
+ return new Promise((resolve, reject) => {
21
+ readlineInterface.question(question, (answer: string) => {
22
+ if (!answer || answer.trim().length === 0) {
23
+ console.log('\nValue cannot be empty. Exiting...');
24
+ process.exit(0);
25
+ }
26
+
27
+ resolve(answer);
28
+ });
29
+ });
30
+ };
31
+
32
+ // All chars for randomizer
33
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
34
+
35
+ (async () => {
36
+ console.log('––––– Generate Encoded Secret –––––');
37
+ console.log('\nFirst, we need info on the *receiving* server');
38
+ console.log('This is the server that hosts the cross-server endpoint, the one that receives requests from the sending server.\n');
39
+
40
+ // Get salt
41
+ console.log('Encoding salt on the *receiving* server')
42
+ const salt = await prompt('Salt: ');
43
+
44
+ // Get host
45
+ console.log('Hostname of the *receiving* server');
46
+ const host = await prompt('Host: ');
47
+
48
+ console.log('\n\nSecond, we need info on the *sending* server');
49
+ console.log('This is the server that sends requests to the receiving server.\n');
50
+
51
+ // Get key
52
+ console.log('Short unique key for the *sending* server (only letters and dashes, no whitespace)')
53
+ const key = (await prompt('Key: ')).trim();
54
+
55
+ // Get description
56
+ console.log('Human-readable description of the *sending* server')
57
+ const description = await prompt('Description: ');
58
+
59
+ // Generate a random secret
60
+ let secret = '';
61
+ for (let i = 0; i < 32; i++) {
62
+ secret += chars.charAt(Math.floor(Math.random() * chars.length));
63
+ }
64
+ secret = Buffer.from(secret).toString('base64');
65
+
66
+ // Encryption process based on:
67
+ // https://medium.com/@tony.infisical/guide-to-nodes-crypto-module-for-encryption-decryption-65c077176980
68
+
69
+ // Create a random initialization vector
70
+ const iv = crypto.randomBytes(12).toString('base64');
71
+
72
+ // Create a cipher
73
+ console.log('salt', salt, Buffer.from(salt, 'base64'));
74
+ const cipher = crypto.createCipheriv(
75
+ 'aes-256-gcm',
76
+ Buffer.from(salt, 'base64'),
77
+ Buffer.from(iv, 'base64'),
78
+ );
79
+
80
+ // Encrypt the string
81
+ let ciphertext = cipher.update(secret, 'utf8', 'base64');
82
+
83
+ // Finalize the encryption
84
+ ciphertext += cipher.final('base64');
85
+
86
+ // Get the authentication tag
87
+ const tag = cipher.getAuthTag();
88
+
89
+ // JSONify the encrypted data
90
+ const encryptionPack = encodeURIComponent(JSON.stringify({
91
+ ciphertext,
92
+ iv,
93
+ tag,
94
+ }));
95
+
96
+ // Show the encrypted data
97
+ console.log('\n\n');
98
+ console.log('––––– Done! What\'s Next: –––––');
99
+ console.log('');
100
+ console.log('On the *sending* server, !!APPEND!! the following to the DCEKIT_CROSS_SERVER_CREDENTIALS env var:');
101
+ console.log(`|${host}:${key}:${secret}|`);
102
+ console.log('');
103
+ console.log('On the *receiving* server, add an entry to its "CrossServerCredential" collection:');
104
+ console.log(`{ "description": "${description}", "key": "${key}", "encodedeSecret": "${encryptionPack}", "scopes": [] }`);
105
+ console.log('');
106
+ console.log('For all scopes that the server should have access to, add them to the "scopes" array.');
107
+ })();
package/genSalt.ts ADDED
@@ -0,0 +1,15 @@
1
+ // All chars for randomizer
2
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
3
+
4
+ // Generate a random salt
5
+ let salt = '';
6
+ for (let i = 0; i < 32; i++) {
7
+ salt += chars.charAt(Math.floor(Math.random() * chars.length));
8
+ }
9
+ salt = Buffer.from(salt).toString('base64');
10
+
11
+ // Generates 32 byte salt
12
+ console.log('New *receiving* server salt:')
13
+
14
+ Buffer.from("Hello World").toString('base64')
15
+ console.log(salt);
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Log reviewer page size
3
+ * @author Yuen Ler Chow
4
+ */
5
+ declare const LOG_REVIEW_PAGE_SIZE = 100;
6
+ export default LOG_REVIEW_PAGE_SIZE;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Log reviewer page size
5
+ * @author Yuen Ler Chow
6
+ */
7
+ var LOG_REVIEW_PAGE_SIZE = 100;
8
+ exports.default = LOG_REVIEW_PAGE_SIZE;
9
+ //# sourceMappingURL=LOG_REVIEW_PAGE_SIZE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_PAGE_SIZE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_PAGE_SIZE.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,kBAAe,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Path of the route for storing client-side logs
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const LOG_REVIEW_ROUTE_PATH_PREFIX = "/admin/dce-expresskit/logs";
6
+ export default LOG_REVIEW_ROUTE_PATH_PREFIX;
@@ -0,0 +1,13 @@
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
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Path of the route for storing client-side logs
9
+ * @author Gabe Abrams
10
+ */
11
+ var LOG_REVIEW_ROUTE_PATH_PREFIX = "/admin".concat(ROUTE_PATH_PREFIX_1.default, "/logs");
12
+ exports.default = LOG_REVIEW_ROUTE_PATH_PREFIX;
13
+ //# sourceMappingURL=LOG_REVIEW_ROUTE_PATH_PREFIX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_ROUTE_PATH_PREFIX.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_ROUTE_PATH_PREFIX.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;GAGG;AACH,IAAM,4BAA4B,GAAG,gBAAS,2BAAiB,UAAO,CAAC;AAEvE,kBAAe,4BAA4B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Route for checking the status of the current user's
3
+ * access to log review
4
+ * @author Gabe Abrams
5
+ */
6
+ declare const LOG_REVIEW_STATUS_ROUTE = "/dce-expresskit/logs/access_allowed";
7
+ export default LOG_REVIEW_STATUS_ROUTE;
@@ -0,0 +1,14 @@
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
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Route for checking the status of the current user's
9
+ * access to log review
10
+ * @author Gabe Abrams
11
+ */
12
+ var LOG_REVIEW_STATUS_ROUTE = "".concat(ROUTE_PATH_PREFIX_1.default, "/logs/access_allowed");
13
+ exports.default = LOG_REVIEW_STATUS_ROUTE;
14
+ //# sourceMappingURL=LOG_REVIEW_STATUS_ROUTE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_REVIEW_STATUS_ROUTE.js","sourceRoot":"","sources":["../../src/constants/LOG_REVIEW_STATUS_ROUTE.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;;GAIG;AACH,IAAM,uBAAuB,GAAG,UAAG,2BAAiB,yBAAsB,CAAC;AAE3E,kBAAe,uBAAuB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Path of the route for storing client-side logs
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const LOG_ROUTE_PATH = "/dce-expresskit/log";
6
+ export default LOG_ROUTE_PATH;
@@ -0,0 +1,13 @@
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
+ var ROUTE_PATH_PREFIX_1 = __importDefault(require("./ROUTE_PATH_PREFIX"));
7
+ /**
8
+ * Path of the route for storing client-side logs
9
+ * @author Gabe Abrams
10
+ */
11
+ var LOG_ROUTE_PATH = "".concat(ROUTE_PATH_PREFIX_1.default, "/log");
12
+ exports.default = LOG_ROUTE_PATH;
13
+ //# sourceMappingURL=LOG_ROUTE_PATH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LOG_ROUTE_PATH.js","sourceRoot":"","sources":["../../src/constants/LOG_ROUTE_PATH.ts"],"names":[],"mappings":";;;;;AAAA,0EAAoD;AAEpD;;;GAGG;AACH,IAAM,cAAc,GAAG,UAAG,2BAAiB,SAAM,CAAC;AAElD,kBAAe,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Path that all routes start with
3
+ * @author Gabe Abrams
4
+ */
5
+ declare const ROUTE_PATH_PREFIX = "/dce-expresskit";
6
+ export default ROUTE_PATH_PREFIX;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Path that all routes start with
5
+ * @author Gabe Abrams
6
+ */
7
+ var ROUTE_PATH_PREFIX = '/dce-expresskit';
8
+ exports.default = ROUTE_PATH_PREFIX;
9
+ //# sourceMappingURL=ROUTE_PATH_PREFIX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ROUTE_PATH_PREFIX.js","sourceRoot":"","sources":["../../src/constants/ROUTE_PATH_PREFIX.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,IAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,kBAAe,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * An error with a code
3
+ * @author Gabe Abrams
4
+ */
5
+ declare class ErrorWithCode extends Error {
6
+ code: string;
7
+ constructor(message: string, code: string);
8
+ }
9
+ export default ErrorWithCode;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ /**
19
+ * An error with a code
20
+ * @author Gabe Abrams
21
+ */
22
+ var ErrorWithCode = /** @class */ (function (_super) {
23
+ __extends(ErrorWithCode, _super);
24
+ function ErrorWithCode(message, code) {
25
+ var _this = _super.call(this, message) || this;
26
+ _this.name = 'ErrorWithCode';
27
+ _this.code = code;
28
+ return _this;
29
+ }
30
+ return ErrorWithCode;
31
+ }(Error));
32
+ exports.default = ErrorWithCode;
33
+ //# sourceMappingURL=ErrorWithCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorWithCode.js","sourceRoot":"","sources":["../../src/errors/ErrorWithCode.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA;;;GAGG;AACH;IAA4B,iCAAK;IAG/B,uBAAY,OAAe,EAAE,IAAY;QACvC,YAAA,MAAK,YAAC,OAAO,CAAC,SAAC;QACf,KAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,KAAI,CAAC,IAAI,GAAG,IAAI,CAAC;;IACnB,CAAC;IACH,oBAAC;AAAD,CAAC,AARD,CAA4B,KAAK,GAQhC;AAED,kBAAe,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generates the endpoint path for the given collection name
3
+ * @author Yuen Ler Chow
4
+ * @param collectionName the name of the collection
5
+ * @param [adminsOnly] true if the endpoint is for admins only
6
+ * @returns the endpoint path
7
+ */
8
+ declare const generateEndpointPath: (collectionName: string, adminsOnly?: boolean) => string;
9
+ export default generateEndpointPath;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Generates the endpoint path for the given collection name
5
+ * @author Yuen Ler Chow
6
+ * @param collectionName the name of the collection
7
+ * @param [adminsOnly] true if the endpoint is for admins only
8
+ * @returns the endpoint path
9
+ */
10
+ var generateEndpointPath = function (collectionName, adminsOnly) {
11
+ // Determine prefix based on whether the endpoint is for admins only
12
+ var userPath = adminsOnly ? 'admin' : 'ttm';
13
+ // Return the endpoint path
14
+ return "/api/".concat(userPath, "/dce-reactkit/dbeditor/").concat(collectionName);
15
+ };
16
+ exports.default = generateEndpointPath;
17
+ //# sourceMappingURL=generateEndpointPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateEndpointPath.js","sourceRoot":"","sources":["../../../src/helpers/addDBEditorEndpoints/generateEndpointPath.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,IAAM,oBAAoB,GAAG,UAAC,cAAsB,EAAE,UAAoB;IACxE,oEAAoE;IACpE,IAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAE9C,2BAA2B;IAC3B,OAAO,eAAQ,QAAQ,oCAA0B,cAAc,CAAE,CAAC;AACpE,CAAC,CAAC;AAEF,kBAAe,oBAAoB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import express from 'express';
2
+ /**
3
+ * Interface for a collection in the database
4
+ * @author Yuen Ler Chow
5
+ */
6
+ type DCEMangoCollection = {
7
+ /**
8
+ * Find all items in the collection that match the filter query
9
+ * @param filterQuery query for the filter
10
+ * @returns list of items that match the filter query
11
+ */
12
+ find: (filterQuery: any) => Promise<any[]>;
13
+ /**
14
+ * Insert an item into the collection
15
+ * @param item the item to insert
16
+ */
17
+ insert: (item: any) => Promise<void>;
18
+ /**
19
+ * Delete an item in the collection
20
+ * @param id the id of the item to delete
21
+ */
22
+ delete: (filterQuery: {
23
+ id: string;
24
+ }) => Promise<void>;
25
+ };
26
+ /**
27
+ * Add all routes for the DBEditor
28
+ * @author Yuen Ler Chow
29
+ * @param opts object containing all arguments
30
+ * @param opts.app express app to add routes too
31
+ * @param opts.collectionName the name of the collection
32
+ * @param opts.adminsOnly true if the endpoint is for admins only
33
+ * @param opts.collection dce-mango db collection
34
+ */
35
+ declare const addDBEditorEndpoints: (opts: {
36
+ app: express.Application;
37
+ collectionName: string;
38
+ adminsOnly: boolean;
39
+ collection: DCEMangoCollection;
40
+ }) => void;
41
+ export default addDBEditorEndpoints;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ // Import dce-reactkit
43
+ var dce_reactkit_1 = require("dce-reactkit");
44
+ // Import shared helpers
45
+ var genRouteHandler_1 = __importDefault(require("../genRouteHandler"));
46
+ var generateEndpointPath_1 = __importDefault(require("./generateEndpointPath"));
47
+ /**
48
+ * Add all routes for the DBEditor
49
+ * @author Yuen Ler Chow
50
+ * @param opts object containing all arguments
51
+ * @param opts.app express app to add routes too
52
+ * @param opts.collectionName the name of the collection
53
+ * @param opts.adminsOnly true if the endpoint is for admins only
54
+ * @param opts.collection dce-mango db collection
55
+ */
56
+ var addDBEditorEndpoints = function (opts) {
57
+ var app = opts.app, collectionName = opts.collectionName, adminsOnly = opts.adminsOnly, collection = opts.collection;
58
+ // Generate the endpoint path
59
+ var endpointPath = (0, generateEndpointPath_1.default)(collectionName, adminsOnly);
60
+ /**
61
+ * List all items in the collection
62
+ * @author Yuen Ler Chow
63
+ * @returns {any[]} the list of items in the collection
64
+ */
65
+ app.get(endpointPath, (0, genRouteHandler_1.default)({
66
+ paramTypes: {
67
+ filterQuery: dce_reactkit_1.ParamType.JSONOptional,
68
+ },
69
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
70
+ var filterQuery, categories;
71
+ var _c;
72
+ var params = _b.params;
73
+ return __generator(this, function (_d) {
74
+ switch (_d.label) {
75
+ case 0:
76
+ filterQuery = (_c = params.filterQuery) !== null && _c !== void 0 ? _c : {};
77
+ return [4 /*yield*/, collection.find(filterQuery)];
78
+ case 1:
79
+ categories = _d.sent();
80
+ return [2 /*return*/, categories];
81
+ }
82
+ });
83
+ }); },
84
+ }));
85
+ /**
86
+ * Create a new item in the collection
87
+ * @author Yuen Ler Chow
88
+ * @param {any} item the item to create
89
+ */
90
+ app.post(endpointPath, (0, genRouteHandler_1.default)({
91
+ paramTypes: {
92
+ item: dce_reactkit_1.ParamType.JSON,
93
+ },
94
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
95
+ var item;
96
+ var params = _b.params;
97
+ return __generator(this, function (_c) {
98
+ switch (_c.label) {
99
+ case 0:
100
+ item = params.item;
101
+ return [4 /*yield*/, collection.insert(item)];
102
+ case 1:
103
+ _c.sent();
104
+ return [2 /*return*/];
105
+ }
106
+ });
107
+ }); },
108
+ }));
109
+ /**
110
+ * Remove an item from the collection by id
111
+ * @author Yuen Ler Chow
112
+ */
113
+ app.delete("".concat(endpointPath, "/:id"), (0, genRouteHandler_1.default)({
114
+ paramTypes: {
115
+ id: dce_reactkit_1.ParamType.String,
116
+ },
117
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
118
+ var id;
119
+ var params = _b.params;
120
+ return __generator(this, function (_c) {
121
+ switch (_c.label) {
122
+ case 0:
123
+ id = params.id;
124
+ return [4 /*yield*/, collection.delete({ id: id })];
125
+ case 1:
126
+ _c.sent();
127
+ return [2 /*return*/];
128
+ }
129
+ });
130
+ }); },
131
+ }));
132
+ };
133
+ exports.default = addDBEditorEndpoints;
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/helpers/addDBEditorEndpoints/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,sBAAsB;AACtB,6CAEsB;AAEtB,wBAAwB;AACxB,uEAAiD;AACjD,gFAA0D;AAyB1D;;;;;;;;GAQG;AACH,IAAM,oBAAoB,GAAG,UAC3B,IAKC;IAGC,IAAA,GAAG,GAID,IAAI,IAJH,EACH,cAAc,GAGZ,IAAI,eAHQ,EACd,UAAU,GAER,IAAI,WAFI,EACV,UAAU,GACR,IAAI,WADI,CACH;IAET,6BAA6B;IAC7B,IAAM,YAAY,GAAG,IAAA,8BAAoB,EAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAEtE;;;;OAIG;IACH,GAAG,CAAC,GAAG,CACL,YAAY,EACZ,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,WAAW,EAAE,wBAAS,CAAC,YAAY;SACpC;QACD,OAAO,EAAE,iEAAO,EAAU;;;gBAAR,MAAM,YAAA;;;;wBAChB,WAAW,GAAG,MAAA,MAAM,CAAC,WAAW,mCAAI,EAAE,CAAC;wBAC1B,qBAAM,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAA;;wBAA/C,UAAU,GAAG,SAAkC;wBACrD,sBAAO,UAAU,EAAC;;;aACnB;KACF,CAAC,CACH,CAAC;IAEF;;;;OAIG;IACH,GAAG,CAAC,IAAI,CACN,YAAY,EACZ,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,IAAI,EAAE,wBAAS,CAAC,IAAI;SACrB;QACD,OAAO,EAAE,iEAAO,EAEf;;gBADC,MAAM,YAAA;;;;wBAIJ,IAAI,GACF,MAAM,KADJ,CACK;wBAEX,qBAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAA;;wBAA7B,SAA6B,CAAC;;;;aAC/B;KACF,CAAC,CACH,CAAC;IAEF;;;OAGG;IACH,GAAG,CAAC,MAAM,CACR,UAAG,YAAY,SAAM,EACrB,IAAA,yBAAe,EAAC;QACd,UAAU,EAAE;YACV,EAAE,EAAE,wBAAS,CAAC,MAAM;SACrB;QACD,OAAO,EAAE,iEAAO,EAEf;;gBADC,MAAM,YAAA;;;;wBAIJ,EAAE,GACA,MAAM,GADN,CACO;wBAEX,qBAAM,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,IAAA,EAAE,CAAC,EAAA;;wBAA/B,SAA+B,CAAC;;;;aACjC;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,oBAAoB,CAAC"}