@dmptool/utils 1.0.0

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.
@@ -0,0 +1,273 @@
1
+ import { AnyAnswerType } from '@dmptool/types';
2
+ export interface LoadPlanInfo {
3
+ id: number;
4
+ dmpId: string;
5
+ projectId: number;
6
+ versionedTemplateId: number;
7
+ createdById: number;
8
+ created: string;
9
+ modifiedById: number;
10
+ modified: string;
11
+ title: string;
12
+ status: string;
13
+ visibility: string;
14
+ featured: boolean;
15
+ registeredBy?: number;
16
+ registered?: string;
17
+ languageId: string;
18
+ }
19
+ export interface LoadProjectInfo {
20
+ id: number;
21
+ title: string;
22
+ abstractText?: string;
23
+ startDate?: string;
24
+ endDate?: string;
25
+ dmptool_research_domain?: string;
26
+ }
27
+ export interface LoadFundingInfo {
28
+ id: number;
29
+ uri?: string;
30
+ name: string;
31
+ status: string;
32
+ grantId?: string;
33
+ funderProjectNumber?: string;
34
+ funderOpportunityNumber?: string;
35
+ }
36
+ export interface LoadMemberInfo {
37
+ id: number;
38
+ uri?: string;
39
+ name?: string;
40
+ email?: string;
41
+ givenName?: string;
42
+ surName?: string;
43
+ orcid?: string;
44
+ isPrimaryContact: boolean;
45
+ roles: string;
46
+ }
47
+ export interface LoadDatasetInfo {
48
+ title: string;
49
+ type: string;
50
+ personal_data: string;
51
+ sensitive_data: string;
52
+ dataset_id: {
53
+ identifier: string;
54
+ type: string;
55
+ };
56
+ }
57
+ export interface LoadRelatedWorkInfo {
58
+ identifier: string;
59
+ workType?: string;
60
+ }
61
+ export interface LoadNarrativeQuestionInfo {
62
+ questionId: number;
63
+ questionText: string;
64
+ questionOrder: number;
65
+ answerId: number;
66
+ answerJSON: AnyAnswerType;
67
+ }
68
+ export interface LoadNarrativeSectionInfo {
69
+ sectionId: number;
70
+ sectionTitle: string;
71
+ sectionDescription?: string;
72
+ sectionOrder: number;
73
+ question: LoadNarrativeQuestionInfo[];
74
+ }
75
+ export interface LoadNarrativeInfo {
76
+ templateId: number;
77
+ templateTitle: string;
78
+ templateDescription?: string;
79
+ templateVersion?: string;
80
+ section: LoadNarrativeSectionInfo[];
81
+ }
82
+ export interface RDACommonStandardAffiliation {
83
+ name: string;
84
+ affiliation_id?: {
85
+ identifier: string;
86
+ type: string;
87
+ };
88
+ }
89
+ export interface RDACommonStandardContact {
90
+ name: string;
91
+ mbox: string;
92
+ contact_id: {
93
+ identifier: string;
94
+ type: string;
95
+ }[];
96
+ affiliation?: RDACommonStandardAffiliation[];
97
+ }
98
+ export interface RDACommonStandardContributor {
99
+ contributor_id: {
100
+ identifier: string;
101
+ type: string;
102
+ }[];
103
+ name: string;
104
+ affiliation?: RDACommonStandardAffiliation[];
105
+ role: string[];
106
+ }
107
+ export interface RDACommonStandardProject {
108
+ title: string;
109
+ description?: string;
110
+ start?: string;
111
+ end?: string;
112
+ project_id: {
113
+ identifier: string;
114
+ type: string;
115
+ }[];
116
+ funding?: {
117
+ name: string;
118
+ funding_status: string;
119
+ grant_id?: {
120
+ identifier: string;
121
+ type: string;
122
+ };
123
+ funder_id?: {
124
+ identifier: string;
125
+ type: string;
126
+ };
127
+ }[];
128
+ }
129
+ export interface RDACommonStandardRelatedWork {
130
+ identifier: string;
131
+ type: string;
132
+ relation_type?: string;
133
+ resource_type?: string;
134
+ }
135
+ export interface RDACommonStandardDataset {
136
+ title: string;
137
+ type: string;
138
+ description?: string;
139
+ dataset_id: {
140
+ identifier: string;
141
+ type: string;
142
+ };
143
+ personal_data?: string;
144
+ sensitive_data?: string;
145
+ data_quality_assurance?: string[];
146
+ is_reused?: boolean;
147
+ issued?: string;
148
+ keyword?: string[];
149
+ language?: string;
150
+ metadata?: {
151
+ description?: string;
152
+ language: string;
153
+ metadata_standard_id: {
154
+ identifier: string;
155
+ type: string;
156
+ }[];
157
+ }[];
158
+ preservation_statement?: string;
159
+ security_and_privacy?: {
160
+ title: string;
161
+ description: string;
162
+ }[];
163
+ alternate_identifier?: {
164
+ identifier: string;
165
+ type: string;
166
+ }[];
167
+ technical_resource?: {
168
+ name: string;
169
+ description?: string;
170
+ technical_resource_id: {
171
+ identifier: string;
172
+ type: string;
173
+ }[];
174
+ }[];
175
+ distribution?: RDACommonStandardDistribution[];
176
+ }
177
+ export interface RDACommonStandardDistribution {
178
+ title: string;
179
+ description?: string;
180
+ access_url?: string;
181
+ download_url?: string;
182
+ byte_size?: number;
183
+ format?: string[];
184
+ data_access: string;
185
+ issued?: string;
186
+ license?: {
187
+ license_ref: string;
188
+ start_date?: string;
189
+ }[];
190
+ host: RDACommonStandardHost;
191
+ }
192
+ export interface RDACommonStandardHost {
193
+ title: string;
194
+ description?: string;
195
+ url: string;
196
+ host_id: {
197
+ identifier: string;
198
+ type: string;
199
+ }[];
200
+ availability?: string;
201
+ backup_frequency?: string;
202
+ backup_type?: string;
203
+ certified_with?: string;
204
+ geo_location?: string;
205
+ pid_system?: string[];
206
+ storage_type?: string;
207
+ support_versioning?: string;
208
+ }
209
+ export interface RDACommonStandardIdentifierType {
210
+ identifier: string;
211
+ type: StandardIdentifierType;
212
+ }
213
+ export declare enum StandardIdentifierType {
214
+ ARK = "ark",
215
+ DOI = "doi",
216
+ HANDLE = "handle",
217
+ ROR = "ror",
218
+ URL = "url",
219
+ OTHER = "other"
220
+ }
221
+ export interface DMPExtensionFunderProjectType {
222
+ project_id: {
223
+ identifier: string;
224
+ type: StandardIdentifierType;
225
+ };
226
+ funder_id: {
227
+ identifier: string;
228
+ type: StandardIdentifierType;
229
+ };
230
+ project_identifier: {
231
+ identifier: string;
232
+ type: StandardIdentifierType;
233
+ };
234
+ }
235
+ export interface DMPExtensionFunderOpportunityType {
236
+ project_id: {
237
+ identifier: string;
238
+ type: StandardIdentifierType;
239
+ };
240
+ funder_id: {
241
+ identifier: string;
242
+ type: StandardIdentifierType;
243
+ };
244
+ opportunity_identifier: {
245
+ identifier: string;
246
+ type: StandardIdentifierType;
247
+ };
248
+ }
249
+ interface DMPExtensionNarrativeAnswer {
250
+ id: number;
251
+ json: AnyAnswerType;
252
+ }
253
+ interface DMPExtensionNarrativeQuestion {
254
+ id: number;
255
+ text: string;
256
+ order: number;
257
+ answer?: DMPExtensionNarrativeAnswer;
258
+ }
259
+ interface DMPExtensionNarrativeSection {
260
+ id: number;
261
+ title: string;
262
+ description?: string;
263
+ order: number;
264
+ question: DMPExtensionNarrativeQuestion[];
265
+ }
266
+ export interface DMPExtensionNarrative {
267
+ id: number;
268
+ title: string;
269
+ description?: string;
270
+ version?: string;
271
+ section: DMPExtensionNarrativeSection[];
272
+ }
273
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StandardIdentifierType = void 0;
4
+ var StandardIdentifierType;
5
+ (function (StandardIdentifierType) {
6
+ StandardIdentifierType["ARK"] = "ark";
7
+ StandardIdentifierType["DOI"] = "doi";
8
+ StandardIdentifierType["HANDLE"] = "handle";
9
+ StandardIdentifierType["ROR"] = "ror";
10
+ StandardIdentifierType["URL"] = "url";
11
+ StandardIdentifierType["OTHER"] = "other";
12
+ })(StandardIdentifierType || (exports.StandardIdentifierType = StandardIdentifierType = {}));
package/dist/rds.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Function to run a SQL query against the MySQL database.
3
+ *
4
+ * @param query the SQL query to run
5
+ * @param params the parameters to use in the query
6
+ * @returns the results of the query
7
+ */
8
+ export declare const queryTable: (query: string, params?: any[]) => Promise<{
9
+ results: any[];
10
+ fields: any[];
11
+ }>;
package/dist/rds.js ADDED
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.queryTable = void 0;
37
+ const mysql = __importStar(require("mysql2/promise"));
38
+ const date_fns_1 = require("date-fns");
39
+ /**
40
+ * Connect to the MySQL database and run a query.
41
+ * @returns A new connection to the MySQL database.
42
+ */
43
+ const createConnection = async () => {
44
+ var _a, _b, _c, _d;
45
+ const args = {
46
+ host: (_a = process.env.RDS_HOST) !== null && _a !== void 0 ? _a : 'localhost',
47
+ port: process.env.RDS_PORT ? Number.parseInt(process.env.RDS_PORT) : 3306,
48
+ user: (_b = process.env.RDS_USER) !== null && _b !== void 0 ? _b : 'root',
49
+ password: (_c = process.env.RDS_PASSWORD) !== null && _c !== void 0 ? _c : 'password',
50
+ database: (_d = process.env.RDS_DATABASE) !== null && _d !== void 0 ? _d : 'dmp',
51
+ multipleStatements: false,
52
+ };
53
+ return mysql.createConnection(args);
54
+ };
55
+ /**
56
+ * Function to convert the incoming value into an appropriate type for insertion
57
+ * into a SQL query.
58
+ * @param val the incoming value to convert
59
+ * @param type the type of the incoming value
60
+ * @returns the converted value
61
+ */
62
+ const prepareValue = (val, type) => {
63
+ if (val === null || val === undefined) {
64
+ return null;
65
+ }
66
+ switch (type) {
67
+ case 'number':
68
+ return Number(val);
69
+ case 'json':
70
+ return JSON.stringify(val);
71
+ case Object:
72
+ case Array:
73
+ return JSON.stringify(val);
74
+ case 'boolean':
75
+ return Boolean(val);
76
+ default:
77
+ if ((0, date_fns_1.isDate)(val)) {
78
+ const date = new Date(val).toISOString();
79
+ return (0, date_fns_1.formatISO9075)(date);
80
+ }
81
+ else if (Array.isArray(val)) {
82
+ return JSON.stringify(val);
83
+ }
84
+ else {
85
+ return String(val);
86
+ }
87
+ }
88
+ };
89
+ /**
90
+ * Function to run a SQL query against the MySQL database.
91
+ *
92
+ * @param query the SQL query to run
93
+ * @param params the parameters to use in the query
94
+ * @returns the results of the query
95
+ */
96
+ // Runs the provided SQL query and returns the results
97
+ const queryTable = async (query, params = []) => {
98
+ const connection = await createConnection();
99
+ // Remove all tabs and new lines
100
+ const sql = query.split(/[\s\t\n]+/).join(' ');
101
+ // Prepare the values for the query
102
+ const vals = params.map((val) => prepareValue(val, typeof val));
103
+ // Run the query and then close the connection
104
+ const [results, fields] = await connection.query(sql, vals);
105
+ await connection.end();
106
+ return { results: results, fields: fields };
107
+ };
108
+ exports.queryTable = queryTable;
package/dist/s3.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { GetObjectCommandOutput, PutObjectCommandOutput } from "@aws-sdk/client-s3";
2
+ export interface DMPToolListObjectsOutput {
3
+ key: string;
4
+ lastModified: Date;
5
+ size: number;
6
+ }
7
+ /**
8
+ * List the contents of a bucket that match a key prefix.
9
+ *
10
+ * @param bucket The name of the bucket to list.
11
+ * @param keyPrefix The prefix to filter the results by.
12
+ * @returns A list of objects that match the key prefix, or undefined if the
13
+ * bucket or key prefix are invalid.
14
+ */
15
+ export declare const listObjects: (bucket: string, keyPrefix: string) => Promise<DMPToolListObjectsOutput[] | []>;
16
+ /**
17
+ * Get an object from the specified bucket.
18
+ *
19
+ * @param bucket The name of the bucket to get the object from.
20
+ * @param key The key of the object to get.
21
+ * @returns The object, or undefined if the bucket or key are invalid.
22
+ */
23
+ export declare const getObject: (bucket: string, key: string) => Promise<GetObjectCommandOutput | undefined>;
24
+ /**
25
+ * Put an object into the specified bucket.
26
+ *
27
+ * @param bucket The name of the bucket to put the object into.
28
+ * @param key The key of the object to put.
29
+ * @param body The object to put.
30
+ * @param contentType The content type of the object.
31
+ * @param contentEncoding The content encoding of the object.
32
+ * @returns The response from the S3 putObject operation, or undefined if the
33
+ * bucket or key are invalid.
34
+ */
35
+ export declare const putObject: (bucket: string, key: string, body: any, contentType?: string, contentEncoding?: string) => Promise<PutObjectCommandOutput | undefined>;
36
+ /**
37
+ * Generate a Pre-signed URL for an S3 object.
38
+ *
39
+ * @param bucket The name of the bucket to generate the URL for.
40
+ * @param key The key of the object to generate the URL for.
41
+ * @param usePutMethod Whether to use the PUT method for the URL. Defaults to false.
42
+ * @returns The Pre-signed URL, or undefined if the bucket or key are invalid.
43
+ */
44
+ export declare const getPresignedURL: (bucket: string, key: string, usePutMethod?: boolean) => Promise<string | undefined>;
package/dist/s3.js ADDED
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPresignedURL = exports.putObject = exports.getObject = exports.listObjects = void 0;
4
+ const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
5
+ const client_s3_1 = require("@aws-sdk/client-s3");
6
+ const s3Client = new client_s3_1.S3Client({});
7
+ /**
8
+ * List the contents of a bucket that match a key prefix.
9
+ *
10
+ * @param bucket The name of the bucket to list.
11
+ * @param keyPrefix The prefix to filter the results by.
12
+ * @returns A list of objects that match the key prefix, or undefined if the
13
+ * bucket or key prefix are invalid.
14
+ */
15
+ const listObjects = async (bucket, keyPrefix) => {
16
+ if (bucket && bucket.trim() !== '') {
17
+ const listObjectsCommand = new client_s3_1.ListObjectsV2Command({
18
+ Bucket: bucket,
19
+ Prefix: keyPrefix
20
+ });
21
+ const response = await s3Client.send(listObjectsCommand);
22
+ if (Array.isArray(response.Contents) && response.Contents.length > 0) {
23
+ const objects = [];
24
+ for (const obj of response.Contents) {
25
+ if (obj && obj.Key && obj.LastModified && obj.Size) {
26
+ objects.push({
27
+ key: obj.Key,
28
+ lastModified: obj.LastModified,
29
+ size: obj.Size
30
+ });
31
+ }
32
+ }
33
+ return objects;
34
+ }
35
+ }
36
+ return [];
37
+ };
38
+ exports.listObjects = listObjects;
39
+ /**
40
+ * Get an object from the specified bucket.
41
+ *
42
+ * @param bucket The name of the bucket to get the object from.
43
+ * @param key The key of the object to get.
44
+ * @returns The object, or undefined if the bucket or key are invalid.
45
+ */
46
+ const getObject = async (bucket, key) => {
47
+ if (bucket && key && bucket.trim() !== '' && key.trim() !== '') {
48
+ const command = new client_s3_1.GetObjectCommand({ Bucket: bucket, Key: key });
49
+ return await s3Client.send(command);
50
+ }
51
+ return undefined;
52
+ };
53
+ exports.getObject = getObject;
54
+ /**
55
+ * Put an object into the specified bucket.
56
+ *
57
+ * @param bucket The name of the bucket to put the object into.
58
+ * @param key The key of the object to put.
59
+ * @param body The object to put.
60
+ * @param contentType The content type of the object.
61
+ * @param contentEncoding The content encoding of the object.
62
+ * @returns The response from the S3 putObject operation, or undefined if the
63
+ * bucket or key are invalid.
64
+ */
65
+ const putObject = async (bucket, key, body, contentType = 'application/json', contentEncoding = 'utf-8') => {
66
+ if (bucket && key && bucket.trim() !== '' && key.trim() !== '') {
67
+ const command = new client_s3_1.PutObjectCommand({
68
+ Bucket: bucket,
69
+ Key: key,
70
+ Body: body,
71
+ ContentType: contentType,
72
+ ContentEncoding: contentEncoding,
73
+ });
74
+ return await s3Client.send(command);
75
+ }
76
+ return undefined;
77
+ };
78
+ exports.putObject = putObject;
79
+ /**
80
+ * Generate a Pre-signed URL for an S3 object.
81
+ *
82
+ * @param bucket The name of the bucket to generate the URL for.
83
+ * @param key The key of the object to generate the URL for.
84
+ * @param usePutMethod Whether to use the PUT method for the URL. Defaults to false.
85
+ * @returns The Pre-signed URL, or undefined if the bucket or key are invalid.
86
+ */
87
+ const getPresignedURL = async (bucket, key, usePutMethod = false) => {
88
+ if (bucket && key && bucket.trim() !== '' && key.trim() !== '') {
89
+ const params = { Bucket: bucket, Key: key };
90
+ const command = usePutMethod
91
+ ? new client_s3_1.PutObjectCommand(params)
92
+ : new client_s3_1.GetObjectCommand(params);
93
+ return await (0, s3_request_presigner_1.getSignedUrl)(s3Client, command, { expiresIn: 900 });
94
+ ;
95
+ }
96
+ return undefined;
97
+ };
98
+ exports.getPresignedURL = getPresignedURL;
package/dist/ssm.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Retrieve a variable from the SSM Parameter store.
3
+ *
4
+ * @param key The name of the variable to retrieve.
5
+ * @returns The value of the variable, or undefined if the variable could not be found.
6
+ * @throws
7
+ */
8
+ export declare const getSSMParameter: (key: string) => Promise<string | undefined>;
package/dist/ssm.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSSMParameter = void 0;
4
+ const client_ssm_1 = require("@aws-sdk/client-ssm");
5
+ const general_1 = require("./general");
6
+ // Create an SSM client
7
+ const client = new client_ssm_1.SSMClient();
8
+ const ENV = process.env.NODE_ENV === 'production'
9
+ ? 'prd' : (process.env.NODE_ENV === 'staging'
10
+ ? 'stg' : 'dev');
11
+ const KEY_PREFIX = `/uc3/dmp/tool/${ENV}/`;
12
+ /**
13
+ * Retrieve a variable from the SSM Parameter store.
14
+ *
15
+ * @param key The name of the variable to retrieve.
16
+ * @returns The value of the variable, or undefined if the variable could not be found.
17
+ * @throws
18
+ */
19
+ const getSSMParameter = async (key) => {
20
+ var _a;
21
+ if (key && key.trim() !== '') {
22
+ const command = new client_ssm_1.GetParameterCommand({
23
+ Name: `${KEY_PREFIX}${key}`,
24
+ WithDecryption: true
25
+ });
26
+ const response = await client.send(command);
27
+ if (!(0, general_1.isNullOrUndefined)(response) && !(0, general_1.isNullOrUndefined)(response.Parameter)) {
28
+ return (_a = response.Parameter) === null || _a === void 0 ? void 0 : _a.Value;
29
+ }
30
+ }
31
+ return undefined;
32
+ };
33
+ exports.getSSMParameter = getSSMParameter;
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@dmptool/utils",
3
+ "version": "1.0.0",
4
+ "description": "Helper/Utility functions for use in the DMP Tool services. Particularly AWS tooling and maDMP serialization",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "license": "MIT",
8
+ "files": [
9
+ "dist",
10
+ "schemas"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.js",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "build": "npm run clean && tsc",
24
+ "clean": "rm -rf dist",
25
+ "lint": "eslint . --ignore-pattern dist/ --ignore-pattern node_modules/",
26
+ "prepublishOnly": "npm run build",
27
+ "test": "jest --config jest.config.ts",
28
+ "prepare": "npm run build",
29
+ "postinstall": "husky || true",
30
+ "type-check": "tsc --noEmit",
31
+ "trivy-high": "./scripts/trivy-high.sh",
32
+ "trivy-med": "./scripts/trivy-med.sh"
33
+ },
34
+ "dependencies": {
35
+ "@aws-sdk/client-cloudformation": "^3.966.0",
36
+ "@aws-sdk/client-dynamodb": "^3.966.0",
37
+ "@aws-sdk/client-eventbridge": "^3.968.0",
38
+ "@aws-sdk/client-s3": "^3.966.0",
39
+ "@aws-sdk/client-sns": "^3.967.0",
40
+ "@aws-sdk/client-ssm": "^3.966.0",
41
+ "@aws-sdk/s3-request-presigner": "^3.966.0",
42
+ "@aws-sdk/util-dynamodb": "^3.966.0",
43
+ "@dmptool/types": "2.3.0",
44
+ "@elastic/ecs-pino-format": "^1.5.0",
45
+ "date-fns": "^4.1.0",
46
+ "jsonschema": "^1.5.0",
47
+ "mysql2": "^3.16.0",
48
+ "pino": "^10.1.1",
49
+ "pino-lambda": "^4.4.1"
50
+ },
51
+ "devDependencies": {
52
+ "@eslint/js": "^9.26.0",
53
+ "@types/jest": "^29.5.14",
54
+ "@types/node": "^20.4.3",
55
+ "aws-sdk-client-mock": "^4.1.0",
56
+ "eslint": "^9.26.0",
57
+ "husky": "^9.1.7",
58
+ "jest": "^29.7.0",
59
+ "jest-expect-message": "^1.1.3",
60
+ "ts-jest": "^29.3.3",
61
+ "ts-node": "^10.9.2",
62
+ "ts-node-dev": "^2.0.0",
63
+ "typescript": "^5.2.2",
64
+ "typescript-eslint": "^8.32.1"
65
+ }
66
+ }