@galadrim/galadmin 0.1.236 → 0.2.7

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 (66) hide show
  1. package/.github/workflows/main.yml +34 -3
  2. package/README.md +65 -0
  3. package/dist/api.d.ts +16 -0
  4. package/dist/api.js +240 -189
  5. package/dist/api.js.map +1 -1
  6. package/dist/index.js +25 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/tsconfig.tsbuildinfo +1 -1
  9. package/dist/types/config.d.ts +6 -1
  10. package/dist/utils/dbManager.d.ts +5 -0
  11. package/dist/utils/dbManager.js +146 -11
  12. package/dist/utils/dbManager.js.map +1 -1
  13. package/dist/utils/imageDimensions.d.ts +5 -0
  14. package/dist/utils/imageDimensions.js +98 -0
  15. package/dist/utils/imageDimensions.js.map +1 -0
  16. package/jest.config.js +43 -0
  17. package/jest.integration.config.js +16 -0
  18. package/package.json +30 -10
  19. package/src/api.ts +284 -217
  20. package/src/front/src/App.test.js +28 -0
  21. package/src/front/src/components/OutsideClickHandler.test.js +53 -0
  22. package/src/front/src/components/RedirectToFirstView.test.js +38 -0
  23. package/src/front/src/utils/checkRequiredColumns.test.js +46 -0
  24. package/src/front/src/utils/evalExpression.test.js +29 -0
  25. package/src/index.ts +26 -3
  26. package/src/types/config.ts +13 -1
  27. package/src/utils/dbManager.ts +243 -102
  28. package/src/utils/imageDimensions.ts +112 -0
  29. package/tests/__mocks__/@aws-sdk/client-s3.js +6 -0
  30. package/tests/__mocks__/@aws-sdk/s3-request-presigner.js +3 -0
  31. package/tests/__mocks__/@google-cloud/storage.js +7 -0
  32. package/tests/__mocks__/argon2.js +3 -0
  33. package/tests/__mocks__/axios.js +7 -0
  34. package/tests/__mocks__/connect-pg-simple.js +24 -0
  35. package/tests/__mocks__/express-mysql-session.js +24 -0
  36. package/tests/__mocks__/mysql2/promise.js +3 -0
  37. package/tests/__mocks__/pg.js +3 -0
  38. package/tests/__mocks__/rollup.js +5 -0
  39. package/tests/__mocks__/ssh2-sftp-client.js +10 -0
  40. package/tests/api-helpers.test.ts +376 -0
  41. package/tests/dbManager.init.test.ts +129 -0
  42. package/tests/dbManager.test.ts +265 -0
  43. package/tests/edge-cases.test.ts +167 -0
  44. package/tests/helpers/app.ts +69 -0
  45. package/tests/helpers/fakeDb.ts +66 -0
  46. package/tests/helpers/fakePool.ts +76 -0
  47. package/tests/helpers/fixtures.ts +68 -0
  48. package/tests/imageDimensions.test.ts +111 -0
  49. package/tests/index.sessionStore.test.ts +19 -0
  50. package/tests/index.test.ts +412 -0
  51. package/tests/integration/__mocks__/axios.js +3 -0
  52. package/tests/integration/dbHarness.ts +381 -0
  53. package/tests/integration/dbManager.integration.test.ts +69 -0
  54. package/tests/integration/globalSetup.ts +43 -0
  55. package/tests/integration/globalTeardown.ts +42 -0
  56. package/tests/integration/routes.authorization.integration.test.ts +319 -0
  57. package/tests/integration/routes.config.integration.test.ts +189 -0
  58. package/tests/integration/routes.crud.integration.test.ts +805 -0
  59. package/tests/integration/routes.custom.integration.test.ts +376 -0
  60. package/tests/integration/routes.foreign.integration.test.ts +306 -0
  61. package/tests/integration/routes.importExport.integration.test.ts +404 -0
  62. package/tests/integration/routes.integration.test.ts +366 -0
  63. package/tests/integration/routes.postgresql.integration.test.ts +88 -0
  64. package/tests/integration/routes.records.integration.test.ts +634 -0
  65. package/tests/integration/routes.upload.integration.test.ts +425 -0
  66. package/tests/setup/silence-console.ts +15 -0
@@ -359,12 +359,17 @@ export type AuthRole = {
359
359
  filters?: string;
360
360
  useArgon2?: boolean;
361
361
  };
362
+ export type TrustedUser = {
363
+ role: string;
364
+ userId?: string | number;
365
+ };
362
366
  export type Config = {
363
367
  enriched?: boolean;
364
368
  name: string;
365
369
  sessionSecret: string;
366
370
  useMysql2?: boolean;
367
- auth: {
371
+ trustedAuth?: (req: any) => TrustedUser | null | Promise<TrustedUser | null>;
372
+ auth?: {
368
373
  username: string;
369
374
  password: string;
370
375
  };
@@ -1,4 +1,9 @@
1
1
  export declare function quoteIdentifier(name: string, dbType: string): string;
2
+ export declare function convertQuery(mysqlQuery: any, params: any): {
3
+ pgQuery: string;
4
+ pgParams: any[];
5
+ };
6
+ export declare function quotePostgresQuery(query: any): any;
2
7
  export default class dbManager {
3
8
  _db: any;
4
9
  dbType: any;
@@ -1,30 +1,73 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.quoteIdentifier = quoteIdentifier;
4
+ exports.convertQuery = convertQuery;
5
+ exports.quotePostgresQuery = quotePostgresQuery;
4
6
  const mysql = require("mysql");
5
7
  const mysql2 = require("mysql2");
6
8
  const pg = require("pg");
7
9
  function quoteIdentifier(name, dbType) {
8
- const quoteChar = dbType === "POSTGRESQL" ? '"' : '`';
10
+ const quoteChar = dbType === "POSTGRESQL" ? '"' : "`";
9
11
  return quoteChar + name + quoteChar;
10
12
  }
13
+ function endOfLiteralOrComment(query, start) {
14
+ const ch = query.charAt(start);
15
+ const next = query.charAt(start + 1);
16
+ if (ch === '-' && next === '-') {
17
+ const newline = query.indexOf('\n', start);
18
+ return newline === -1 ? query.length : newline;
19
+ }
20
+ if (ch === '/' && next === '*') {
21
+ const close = query.indexOf('*/', start + 2);
22
+ return close === -1 ? query.length : close + 2;
23
+ }
24
+ if (ch !== "'") {
25
+ return -1;
26
+ }
27
+ const prefix = query.charAt(start - 1);
28
+ const backslashEscapes = (prefix === 'E' || prefix === 'e') && !/[\w$]/.test(query.charAt(start - 2));
29
+ let index = start + 1;
30
+ while (index < query.length) {
31
+ const current = query.charAt(index);
32
+ if (backslashEscapes && current === '\\') {
33
+ index += 2;
34
+ }
35
+ else if (current === "'" && query.charAt(index + 1) === "'") {
36
+ index += 2;
37
+ }
38
+ else if (current === "'") {
39
+ return index + 1;
40
+ }
41
+ else {
42
+ index++;
43
+ }
44
+ }
45
+ return query.length;
46
+ }
11
47
  function convertQuery(mysqlQuery, params) {
12
- let pgQuery = '';
48
+ let pgQuery = "";
13
49
  let pgParams = [];
14
50
  let paramIndex = 1;
15
51
  let charIndex = 0;
16
52
  while (charIndex < mysqlQuery.length) {
17
- if (mysqlQuery.charAt(charIndex) === '?' && mysqlQuery.charAt(charIndex + 1) === '?') {
53
+ const ch = mysqlQuery.charAt(charIndex);
54
+ const next = mysqlQuery.charAt(charIndex + 1);
55
+ const verbatimEnd = endOfLiteralOrComment(mysqlQuery, charIndex);
56
+ if (verbatimEnd !== -1) {
57
+ pgQuery += mysqlQuery.slice(charIndex, verbatimEnd);
58
+ charIndex = verbatimEnd;
59
+ }
60
+ else if (ch === "?" && next === "?") {
18
61
  pgQuery += params.shift();
19
62
  charIndex += 2;
20
63
  }
21
- else if (mysqlQuery.charAt(charIndex) === '?') {
64
+ else if (ch === "?") {
22
65
  pgQuery += `$${paramIndex++}`;
23
66
  pgParams.push(params.shift());
24
67
  charIndex++;
25
68
  }
26
69
  else {
27
- pgQuery += mysqlQuery.charAt(charIndex);
70
+ pgQuery += ch;
28
71
  charIndex++;
29
72
  }
30
73
  }
@@ -35,7 +78,95 @@ function convertQuery(mysqlQuery, params) {
35
78
  }
36
79
  function quotePostgresQuery(query) {
37
80
  query = query.replace(/`/g, '"');
38
- const reservedWords = ["1", "COUNT", "*", "UPDATE", "SELECT", "SET", "=", "INSERT", "INTO", "DELETE", "FROM", "WHERE", "AND", "OR", "JOIN", "ON", "AS", "IN", "ILIKE", "LIKE", "EXISTS", "ALL", "ANY", "NOT", "NULL", "TRUE", "FALSE", "GROUP", "BY", "ORDER", "LIMIT", "OFFSET", "DESC", "VALUES", "LEFT", "RIGHT", "USING", "CONCAT", "CASE", "WHEN", "THEN", "ELSE", "END", "ASC", "IS", "INTERVAL", "CURRENT_DATE", "SUM", "COALESCE", "-", "ROUND", "DATE_TRUNC", "<>", "+", "DISTINCT", "MAX", "MIN", "AVG", "BIT_AND", "BIT_OR", "BOOL_AND", "BOOL_OR", "XMLAGG", "STRING_AGG", "EVERY", "CORR", "COVAR_POP", "COVAR_SAMP", "VAR_POP", "VAR_SAMP", "VARIANCE", "REGR_SLOPE", "REGR_INTERCEPT", "REGR_COUNT", "REGR_R2", "REGR_AVGX", "REGR_AVGY", "REGR_SXX", "REGR_SXY", "REGR_SYY"];
81
+ const reservedWords = [
82
+ "1",
83
+ "COUNT",
84
+ "*",
85
+ "UPDATE",
86
+ "SELECT",
87
+ "SET",
88
+ "=",
89
+ "INSERT",
90
+ "INTO",
91
+ "DELETE",
92
+ "FROM",
93
+ "WHERE",
94
+ "AND",
95
+ "OR",
96
+ "JOIN",
97
+ "ON",
98
+ "AS",
99
+ "IN",
100
+ "ILIKE",
101
+ "LIKE",
102
+ "EXISTS",
103
+ "ALL",
104
+ "ANY",
105
+ "NOT",
106
+ "NULL",
107
+ "TRUE",
108
+ "FALSE",
109
+ "GROUP",
110
+ "BY",
111
+ "ORDER",
112
+ "LIMIT",
113
+ "OFFSET",
114
+ "DESC",
115
+ "VALUES",
116
+ "LEFT",
117
+ "RIGHT",
118
+ "USING",
119
+ "CONCAT",
120
+ "CONCAT_WS",
121
+ "CASE",
122
+ "WHEN",
123
+ "THEN",
124
+ "ELSE",
125
+ "END",
126
+ "ASC",
127
+ "IS",
128
+ "INTERVAL",
129
+ "CURRENT_DATE",
130
+ "SUM",
131
+ "COALESCE",
132
+ "HAVING",
133
+ "WITH",
134
+ "-",
135
+ "ROUND",
136
+ "DATE_TRUNC",
137
+ "<>",
138
+ "+",
139
+ "DISTINCT",
140
+ "MAX",
141
+ "MIN",
142
+ "AVG",
143
+ "BIT_AND",
144
+ "BIT_OR",
145
+ "BOOL_AND",
146
+ "BOOL_OR",
147
+ "XMLAGG",
148
+ "STRING_AGG",
149
+ "EVERY",
150
+ "CORR",
151
+ "COVAR_POP",
152
+ "COVAR_SAMP",
153
+ "VAR_POP",
154
+ "VAR_SAMP",
155
+ "VARIANCE",
156
+ "REGR_SLOPE",
157
+ "REGR_INTERCEPT",
158
+ "REGR_COUNT",
159
+ "REGR_R2",
160
+ "REGR_AVGX",
161
+ "REGR_AVGY",
162
+ "REGR_SXX",
163
+ "REGR_SXY",
164
+ "REGR_SYY",
165
+ "CONFLICT",
166
+ "DO",
167
+ "EXCLUDED",
168
+ "RETURNING",
169
+ ];
39
170
  const wordsToAddQuotes = new Set();
40
171
  const parts = query.split(/[ ,\(\)]/);
41
172
  let inString = false;
@@ -47,7 +178,11 @@ function quotePostgresQuery(query) {
47
178
  if (part.split(/['"]/).length % 2 === 0) {
48
179
  inString = !inString;
49
180
  }
50
- if (inString || part.startsWith("$") || part.includes("'") || part.includes('"') || reservedWords.includes(part.toUpperCase())) {
181
+ if (inString ||
182
+ part.startsWith("$") ||
183
+ part.includes("'") ||
184
+ part.includes('"') ||
185
+ reservedWords.includes(part.toUpperCase())) {
51
186
  }
52
187
  else {
53
188
  for (let x of part.split(".")) {
@@ -60,7 +195,7 @@ function quotePostgresQuery(query) {
60
195
  let newQuery = query;
61
196
  for (let word of wordsToAddQuotes) {
62
197
  if (word !== "*") {
63
- newQuery = newQuery.replace(new RegExp(`(?<!["\'])\\b${word}\\b(?!["\'])`, 'g'), `"${word}"`);
198
+ newQuery = newQuery.replace(new RegExp(`(?<!["\'])\\b${word}\\b(?!["\'])`, "g"), `"${word}"`);
64
199
  }
65
200
  }
66
201
  newQuery = newQuery.replace(/\) LIKE /g, ") ILIKE ");
@@ -77,9 +212,9 @@ class dbManager {
77
212
  password: config.mysql.password,
78
213
  database: config.mysql.database,
79
214
  port: config.mysql.port || 3306,
80
- charset: 'UTF8MB4_GENERAL_CI',
215
+ charset: "UTF8MB4_GENERAL_CI",
81
216
  dateStrings: true,
82
- multipleStatements: config.mysql.multipleStatements === true
217
+ multipleStatements: config.mysql.multipleStatements === true,
83
218
  });
84
219
  this.dbType = "MYSQL";
85
220
  }
@@ -90,7 +225,7 @@ class dbManager {
90
225
  password: config.postgresql.password,
91
226
  database: config.postgresql.database,
92
227
  port: config.postgresql.port || 5432,
93
- ssl: config.postgresql.ssl
228
+ ssl: config.postgresql.ssl,
94
229
  });
95
230
  this.dbType = "POSTGRESQL";
96
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dbManager.js","sourceRoot":"","sources":["../../src/utils/dbManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dbManager.js","sourceRoot":"","sources":["../../src/utils/dbManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type ImageDimensions = {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ export declare function getImageDimensions(filePath: string): Promise<ImageDimensions | null>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getImageDimensions = getImageDimensions;
4
+ const fs_1 = require("fs");
5
+ const PNG_SIGNATURE = Buffer.from([
6
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
7
+ ]);
8
+ const HEADER_LIMIT = 2 * 1024 * 1024;
9
+ async function readHeader(filePath) {
10
+ const handle = await fs_1.promises.open(filePath, "r");
11
+ try {
12
+ const length = Math.min(HEADER_LIMIT, (await handle.stat()).size);
13
+ const buffer = Buffer.alloc(length);
14
+ await handle.read(buffer, 0, length, 0);
15
+ return buffer;
16
+ }
17
+ finally {
18
+ await handle.close();
19
+ }
20
+ }
21
+ function parsePngDimensions(header) {
22
+ if (header.length < 24 || header.toString("latin1", 12, 16) !== "IHDR") {
23
+ return null;
24
+ }
25
+ const width = header.readUInt32BE(16);
26
+ const height = header.readUInt32BE(20);
27
+ return width > 0 && height > 0 ? { width, height } : null;
28
+ }
29
+ function parseGifDimensions(header) {
30
+ const signature = header.toString("latin1", 0, 6);
31
+ if (signature !== "GIF87a" && signature !== "GIF89a") {
32
+ return null;
33
+ }
34
+ const width = header.readUInt16LE(6);
35
+ const height = header.readUInt16LE(8);
36
+ return width > 0 && height > 0 ? { width, height } : null;
37
+ }
38
+ function parseJpegDimensions(header) {
39
+ let offset = 2;
40
+ while (offset + 4 <= header.length) {
41
+ if (header[offset] !== 0xff) {
42
+ return null;
43
+ }
44
+ const marker = header[offset + 1];
45
+ if (marker === 0x01 ||
46
+ marker === 0xd8 ||
47
+ marker === 0xd9 ||
48
+ (marker >= 0xd0 && marker <= 0xd7)) {
49
+ offset += 2;
50
+ continue;
51
+ }
52
+ if (marker === 0xda || marker === 0xd9) {
53
+ return null;
54
+ }
55
+ const segmentLength = header.readUInt16BE(offset + 2);
56
+ if (segmentLength < 2) {
57
+ return null;
58
+ }
59
+ const isFrameHeader = marker >= 0xc0 &&
60
+ marker <= 0xcf &&
61
+ marker !== 0xc4 &&
62
+ marker !== 0xc8 &&
63
+ marker !== 0xcc;
64
+ if (isFrameHeader) {
65
+ if (offset + 9 > header.length) {
66
+ return null;
67
+ }
68
+ const height = header.readUInt16BE(offset + 5);
69
+ const width = header.readUInt16BE(offset + 7);
70
+ return width > 0 && height > 0 ? { width, height } : null;
71
+ }
72
+ offset += 2 + segmentLength;
73
+ }
74
+ return null;
75
+ }
76
+ async function getImageDimensions(filePath) {
77
+ let header;
78
+ try {
79
+ header = await readHeader(filePath);
80
+ }
81
+ catch (_a) {
82
+ return null;
83
+ }
84
+ if (header.length >= 8 && header.subarray(0, 8).equals(PNG_SIGNATURE)) {
85
+ return parsePngDimensions(header);
86
+ }
87
+ if (header.length >= 10 && header.toString("latin1", 0, 3) === "GIF") {
88
+ return parseGifDimensions(header);
89
+ }
90
+ if (header.length >= 3 &&
91
+ header[0] === 0xff &&
92
+ header[1] === 0xd8 &&
93
+ header[2] === 0xff) {
94
+ return parseJpegDimensions(header);
95
+ }
96
+ return null;
97
+ }
98
+ //# sourceMappingURL=imageDimensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageDimensions.js","sourceRoot":"","sources":["../../src/utils/imageDimensions.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1,43 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ module.exports = {
3
+ preset: "ts-jest",
4
+ testEnvironment: "node",
5
+ roots: ["<rootDir>/tests"],
6
+ testMatch: ["**/*.test.ts"],
7
+ testPathIgnorePatterns: [
8
+ "/node_modules/",
9
+ "/src/front/",
10
+ "/tests/integration/",
11
+ ],
12
+ // Avoid a duplicate "axios" manual mock with the integration project's own
13
+ // __mocks__ dir (jest.integration.config.js resets this to rediscover it).
14
+ modulePathIgnorePatterns: ["/tests/integration/__mocks__/"],
15
+ transform: {
16
+ "^.+\\.tsx?$": [
17
+ "ts-jest",
18
+ {
19
+ tsconfig: {
20
+ module: "commonjs",
21
+ target: "es2019",
22
+ esModuleInterop: false,
23
+ strict: false,
24
+ skipLibCheck: true,
25
+ resolveJsonModule: true,
26
+ allowSyntheticDefaultImports: true,
27
+ },
28
+ diagnostics: true,
29
+ },
30
+ ],
31
+ },
32
+ clearMocks: true,
33
+ setupFilesAfterEnv: ["<rootDir>/tests/setup/silence-console.ts"],
34
+ verbose: false,
35
+ coveragePathIgnorePatterns: ["/node_modules/", "/tests/", "/src/front/"],
36
+ coverageThreshold: {
37
+ global: {
38
+ lines: 90,
39
+ functions: 85,
40
+ statements: 90,
41
+ },
42
+ },
43
+ };
@@ -0,0 +1,16 @@
1
+ const base = require("./jest.config.js");
2
+
3
+ module.exports = {
4
+ ...base,
5
+ roots: ["<rootDir>/tests/integration"],
6
+ modulePathIgnorePatterns: [], // scoped axios mock lives under this project
7
+ // The base config excludes /tests/integration/ so the default unit run
8
+ // never picks these up; integration runs must not inherit that.
9
+ testPathIgnorePatterns: ["/node_modules/", "/src/front/"],
10
+ testTimeout: 60000,
11
+ // Shared containers + TRUNCATE require all files to run serially; enforce
12
+ // it here so ad-hoc runs (IDE, npx) can't parallelize them.
13
+ maxWorkers: 1,
14
+ globalSetup: "<rootDir>/tests/integration/globalSetup.ts",
15
+ globalTeardown: "<rootDir>/tests/integration/globalTeardown.ts",
16
+ };
package/package.json CHANGED
@@ -1,31 +1,43 @@
1
1
  {
2
2
  "name": "@galadrim/galadmin",
3
- "version": "0.1.236",
3
+ "version": "0.2.7",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
- "test": "echo \"Error: no test specified\" && exit 1",
6
+ "test": "jest",
7
+ "test:unit": "jest",
8
+ "test:watch": "jest --watch",
9
+ "test:coverage": "TEST_INTEGRATION=1 jest --coverage --runInBand --projects jest.config.js jest.integration.config.js",
10
+ "test:integration": "TEST_INTEGRATION=1 jest --config jest.integration.config.js --runInBand",
11
+ "test:all": "npm run test:unit && npm run test:integration",
7
12
  "build": "tsc"
8
13
  },
14
+ "engines": {
15
+ "node": ">=22"
16
+ },
9
17
  "author": "",
10
18
  "license": "ISC",
19
+ "overrides": {
20
+ "express-mysql-session": {
21
+ "mysql2": "^3.24.3"
22
+ }
23
+ },
11
24
  "dependencies": {
25
+ "@aws-sdk/client-s3": "^3.1114.0",
26
+ "@aws-sdk/s3-request-presigner": "^3.1114.0",
12
27
  "@babel/core": "^7.15.0",
13
28
  "@babel/preset-env": "^7.15.0",
14
29
  "@babel/preset-react": "^7.14.5",
15
30
  "@emotion/react": "^11.11.1",
16
- "@google-cloud/storage": "^7.17.2",
31
+ "@google-cloud/storage": "^8.0.1",
17
32
  "@rollup/plugin-babel": "^5.3.0",
18
33
  "@rollup/plugin-node-resolve": "^13.0.4",
19
- "@aws-sdk/client-s3": "^3.1114.0",
20
- "@aws-sdk/s3-request-presigner": "^3.1114.0",
21
- "argon2": "^0.31.2",
22
- "axios": "^0.28.1",
34
+ "argon2": "^0.45.1",
35
+ "axios": "^1.20.0",
23
36
  "bcryptjs": "^2.4.3",
24
37
  "connect-pg-simple": "^9.0.1",
25
38
  "express": "^4.17.1",
26
- "express-mysql-session": "^2.1.6",
39
+ "express-mysql-session": "^3.0.3",
27
40
  "express-session": "^1.17.2",
28
- "image-size": "^1.0.0",
29
41
  "mime": "^2.5.2",
30
42
  "moment": "^2.29.1",
31
43
  "multiparty": "^4.2.2",
@@ -34,15 +46,23 @@
34
46
  "patch-package": "^8.0.0",
35
47
  "pg": "^8.11.3",
36
48
  "rollup": "^2.56.2",
37
- "serialize-javascript": "^6.0.0",
49
+ "serialize-javascript": "^7.1.1",
38
50
  "ssh2-sftp-client": "^9.0.4",
39
51
  "uuid": "^9.0.1"
40
52
  },
41
53
  "devDependencies": {
54
+ "@testcontainers/mysql": "^12.1.0",
55
+ "@testcontainers/postgresql": "^12.1.0",
42
56
  "@types/express": "^4.17.13",
43
57
  "@types/express-session": "1.17.0",
58
+ "@types/jest": "^30.0.0",
44
59
  "@types/mime": "^2.0.3",
45
60
  "@types/node": "^16.18.11",
61
+ "@types/supertest": "^7.2.1",
62
+ "jest": "^29.7.0",
63
+ "supertest": "^7.2.2",
64
+ "testcontainers": "^12.1.0",
65
+ "ts-jest": "^29.4.12",
46
66
  "typescript": "^5.9.3"
47
67
  },
48
68
  "repository": {