From 37a627d8e0a11bcd219cfba0f2f5740c9be055d2 Mon Sep 17 00:00:00 2001 From: "f.marayeu" Date: Wed, 17 Apr 2024 09:44:35 +0200 Subject: [PATCH] migrate to TS --- .gitignore | 3 +- index.js => index.ts | 27 +- jest.config.ts | 4 + package-lock.json | 673 ++++++++++++++++++++++++++++++++++++- package.json | 15 +- src/picture.js | 27 -- src/picture.ts | 23 ++ taf/api/controller.js | 24 -- taf/api/controller.ts | 36 ++ tests/api/api.test.js | 56 --- tests/api/api.test.ts | 64 ++++ tests/unit/picture.test.js | 53 --- tests/unit/picture.test.ts | 43 +++ tsconfig.json | 10 + types/request.ts | 3 + 15 files changed, 876 insertions(+), 185 deletions(-) rename index.js => index.ts (51%) create mode 100644 jest.config.ts delete mode 100644 src/picture.js create mode 100644 src/picture.ts delete mode 100644 taf/api/controller.js create mode 100644 taf/api/controller.ts delete mode 100644 tests/api/api.test.js create mode 100644 tests/api/api.test.ts delete mode 100644 tests/unit/picture.test.js create mode 100644 tests/unit/picture.test.ts create mode 100644 tsconfig.json create mode 100644 types/request.ts diff --git a/.gitignore b/.gitignore index 7f32e4b..eec5979 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode -node_modules \ No newline at end of file +node_modules +.idea \ No newline at end of file diff --git a/index.js b/index.ts similarity index 51% rename from index.js rename to index.ts index 4404d61..b1a5bee 100644 --- a/index.js +++ b/index.ts @@ -1,31 +1,28 @@ -import express from 'express' +import express, { Express, Request, Response } from "express"; import fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import { getImagePathByName } from './src/picture.js' +import { getImagePathByName } from "./src/picture"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); -const PATH_TO_IMAGES = './images'; -const PICTURES = fs.readdirSync(PATH_TO_IMAGES); +const PATH_TO_IMAGES: string = './images'; +const PICTURES: string[] = fs.readdirSync(PATH_TO_IMAGES); -const app = express(); +const app: Express = express(); +const appPort: number = 3001; app.use(express.json()); -app.get('/random_picture', (req, res) => { +app.get('/random_picture', (req: Request, res: Response) => { console.log(__dirname); - res.sendFile(getImagePathByName(PATH_TO_IMAGES, PICTURES), { root: __dirname }); + res.sendFile(getImagePathByName(PATH_TO_IMAGES, PICTURES, undefined), { root: __dirname }); }) -app.post('/picture', (req, res) => { +app.post('/picture', (req: Request, res: Response) => { const requestedPicture = req.body.picture; if (!requestedPicture) { return res.sendStatus(400); } - let pathToImage; + let pathToImage: string = ''; try{ pathToImage = `${__dirname}/${getImagePathByName(PATH_TO_IMAGES, PICTURES, requestedPicture)}`; } catch (error) { @@ -37,7 +34,7 @@ app.post('/picture', (req, res) => { res.sendStatus(400); } - fs.access(pathToImage, fs.constants.F_OK, (err) => { + fs.access(pathToImage, fs.constants.F_OK, (err: Error | null) => { if (err) { res.sendStatus(404); } else { @@ -47,4 +44,4 @@ app.post('/picture', (req, res) => { }) -app.listen(3001, () => console.log('API Server is up and running...')); +app.listen(appPort, () => console.log('API Server is up and running...')); diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..7209e0c --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,4 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index af33cab..1d94c10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,16 @@ "axios": "^1.6.8", "express": "^4.18.3", "jest": "^29.7.0" + }, + "devDependencies": { + "@jest/globals": "^29.7.0", + "@types/axios": "^0.14.0", + "@types/express": "^4.17.21", + "@types/jest": "^29.5.12", + "@types/node": "^20.12.7", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" } }, "node_modules/@ampproject/remapping": { @@ -635,6 +645,28 @@ "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -986,6 +1018,40 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, + "node_modules/@types/axios": { + "version": "0.14.0", + "resolved": "https://registry.npmmirror.com/@types/axios/-/axios-0.14.0.tgz", + "integrity": "sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==", + "deprecated": "This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed!", + "dev": true, + "dependencies": { + "axios": "*" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1023,6 +1089,49 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.0", + "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1031,6 +1140,12 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1052,14 +1167,63 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "node_modules/@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "version": "20.12.7", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/qs": { + "version": "6.9.14", + "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -1090,6 +1254,27 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1132,6 +1317,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", @@ -1326,6 +1517,18 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmmirror.com/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz", @@ -1532,6 +1735,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1620,6 +1829,15 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -2928,6 +3146,12 @@ "node": ">=8" } }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2977,6 +3201,12 @@ "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz", @@ -3721,6 +3951,125 @@ "node": ">=0.6" } }, + "node_modules/ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmmirror.com/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz", @@ -3749,6 +4098,19 @@ "node": ">= 0.6" } }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", @@ -3785,6 +4147,12 @@ "node": ">= 0.4.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true + }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -3896,6 +4264,15 @@ "node": ">=12" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4363,6 +4740,27 @@ "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4641,6 +5039,39 @@ "@sinonjs/commons": "^3.0.0" } }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "devOptional": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, + "@types/axios": { + "version": "0.14.0", + "resolved": "https://registry.npmmirror.com/@types/axios/-/axios-0.14.0.tgz", + "integrity": "sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==", + "dev": true, + "requires": { + "axios": "*" + } + }, "@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4678,6 +5109,49 @@ "@babel/types": "^7.20.7" } }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.19.0", + "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -4686,6 +5160,12 @@ "@types/node": "*" } }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -4707,14 +5187,63 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "version": "20.12.7", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "requires": { "undici-types": "~5.26.4" } }, + "@types/qs": { + "version": "6.9.14", + "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -4742,6 +5271,18 @@ "negotiator": "0.6.3" } }, + "acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "devOptional": true + }, + "acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "devOptional": true + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4772,6 +5313,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", @@ -4931,6 +5478,15 @@ "update-browserslist-db": "^1.0.13" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmmirror.com/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz", @@ -5088,6 +5644,12 @@ "prompts": "^2.0.1" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5147,6 +5709,12 @@ "resolved": "https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true + }, "diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -6131,6 +6699,12 @@ "p-locate": "^4.1.0" } }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", @@ -6170,6 +6744,12 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz", @@ -6737,6 +7317,69 @@ "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmmirror.com/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "devOptional": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz", @@ -6756,6 +7399,12 @@ "mime-types": "~2.1.24" } }, + "typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "devOptional": true + }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", @@ -6780,6 +7429,12 @@ "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true + }, "v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -6864,6 +7519,12 @@ "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index e1e7a05..f2608c3 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,9 @@ "name": "js_api_test", "version": "1.0.0", "description": "", - "main": "index.js", - "type": "module", + "main": "index.ts", "scripts": { - "start": "node index.js", + "start": "npx ts-node index.ts", "build": "docker run --name nodejs-image-demo -p 3001:3001 -d nodejs-image-demo", "test": "node --experimental-vm-modules ./node_modules/.bin/jest", "unit-tests": "node --experimental-vm-modules ./node_modules/.bin/jest tests/unit", @@ -19,5 +18,15 @@ "axios": "^1.6.8", "express": "^4.18.3", "jest": "^29.7.0" + }, + "devDependencies": { + "@jest/globals": "^29.7.0", + "@types/axios": "^0.14.0", + "@types/express": "^4.17.21", + "@types/jest": "^29.5.12", + "@types/node": "^20.12.7", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" } } diff --git a/src/picture.js b/src/picture.js deleted file mode 100644 index 8875f13..0000000 --- a/src/picture.js +++ /dev/null @@ -1,27 +0,0 @@ -import path from 'path'; - -function getImagePathByName(prefix, pictures, pictureName) { - if (pictureName === undefined) { - const randomPictureName = pictures[Math.floor(Math.random() * pictures.length)]; - console.log(`Following picture has been chosen: ${randomPictureName}`); - return path.join(prefix, randomPictureName); - } - - if (typeof pictureName !== 'string'){ - throw new TypeError(`Value ${pictureName} is not a string!`); - } - - if (pictures.includes(pictureName)) { - return path.join(prefix, pictureName); - } - - for (const picture of pictures) { - if (path.parse(picture).name === pictureName) { - return path.join(prefix, picture); - } - } - - return ''; -} - -export { getImagePathByName }; diff --git a/src/picture.ts b/src/picture.ts new file mode 100644 index 0000000..1a6c792 --- /dev/null +++ b/src/picture.ts @@ -0,0 +1,23 @@ +import path from 'path'; + +function getImagePathByName(prefix:string, pictures:string[], pictureName:string = undefined):string { + if (pictureName === undefined) { + const randomPictureName = pictures[Math.floor(Math.random() * pictures.length)]; + console.log(`Following picture has been chosen: ${randomPictureName}`); + return path.join(prefix, randomPictureName); + } + + if (pictures.includes(pictureName)) { + return path.join(prefix, pictureName); + } + + for (const picture of pictures) { + if (path.parse(picture).name === pictureName) { + return path.join(prefix, picture); + } + } + + return ''; +} + +export { getImagePathByName }; diff --git a/taf/api/controller.js b/taf/api/controller.js deleted file mode 100644 index c24768c..0000000 --- a/taf/api/controller.js +++ /dev/null @@ -1,24 +0,0 @@ -import axios from "axios"; - - -class ApiServiceController { - constructor(baseUrl, defaultHeaders, timeout = 5000) { - this.baseUrl = baseUrl; - this.headers = defaultHeaders; - this.timeout = timeout; - this.request = axios.create() - } - - async sendRequest(path, method = 'GET', payload = null, headers = null) { - return await this.request[method.toLowerCase()](`${this.baseUrl}${path}`, payload) - .then((response) => { - return response; - }) - .catch((error) => { - console.log(error); - return error; - }) - } -} - -export { ApiServiceController }; diff --git a/taf/api/controller.ts b/taf/api/controller.ts new file mode 100644 index 0000000..fb29047 --- /dev/null +++ b/taf/api/controller.ts @@ -0,0 +1,36 @@ +import axios, { AxiosInstance, ResponseType } from "axios"; +import { HeadersType, MethodType, PayloadType } from "../../types/request"; + +interface DefaultHeaders { + [key: string]: string; // Allows any string key with a string value +} + +class ApiServiceController { + private baseUrl: string; + private headers: DefaultHeaders; + private timeout: number; + private request: AxiosInstance; + + constructor(baseUrl: string, defaultHeaders: DefaultHeaders = null, timeout: number = 5000) { + this.baseUrl = baseUrl; + this.headers = defaultHeaders; + this.timeout = timeout; + this.request = axios.create({ + baseURL: this.baseUrl, + headers: this.headers, + timeout: this.timeout, + }); + } + + async sendRequest(path: string, method: MethodType = 'GET', payload: PayloadType | null = null, headers: HeadersType | null = null): Promise { + try { + const response: ResponseType = await this.request[method.toLowerCase()](path, payload, headers); + return response; + } catch (error) { + // console.error(error.message); + throw error; + } + } +} + +export { ApiServiceController }; \ No newline at end of file diff --git a/tests/api/api.test.js b/tests/api/api.test.js deleted file mode 100644 index b61bef6..0000000 --- a/tests/api/api.test.js +++ /dev/null @@ -1,56 +0,0 @@ -import { beforeAll, describe, expect, test } from '@jest/globals'; -import { ApiServiceController } from '../../taf/api/controller.js' -import e from 'express'; - -describe('Test /random_picture GET API endpoint', () => { - let apiController; - - beforeAll(() => { - apiController = new ApiServiceController('http://localhost:3001'); - }) - - it.each([ - [null], - [null], - ])('Test /random_picture endpoint', async (test_case) => { - let response = await apiController.sendRequest('/random_picture'); - expect(response.status).toBe(200); - expect(response.headers['content-type']).toMatch(/image\/.*/); - }) - - it.each([ - ['/random_endpoint'], - ['/'], - ])('Test get unexisting endpoint', async (endpoint) => { - let error = await apiController.sendRequest(endpoint); - expect(error.response.status).toBe(404); - expect(error.response.statusText).toBe('Not Found'); - }) -}) - -describe('Test /picture POST API endpoint', () => { - let apiController; - - beforeAll(() => { - apiController = new ApiServiceController('http://localhost:3001'); - }) - - it.each([ - [{picture: 'image_1.jpeg'}], - [{picture: 'image_2'}], - ])('Test /picture endpoint', async (payload) => { - let response = await apiController.sendRequest('/picture', 'post', payload); - expect(response.status).toBe(200); - expect(response.headers['content-type']).toMatch(/image\/.*/); - }) - - it.each([ - [{picture: ''}, 400, 'Bad Request'], - [{picture: 'non_existing_image.jpeg'}, 404, 'Not Found'], - [{picture: {pictureName: 'image_2'}}, 400, 'Bad Request'], - ])('Test /picture endpoint with non-existing image', async (payload, error_code, error_message) => { - let error = await apiController.sendRequest('/picture', 'post', payload); - expect(error.response.status).toBe(error_code); - expect(error.response.statusText).toBe(error_message); - }) -}) \ No newline at end of file diff --git a/tests/api/api.test.ts b/tests/api/api.test.ts new file mode 100644 index 0000000..e71e0be --- /dev/null +++ b/tests/api/api.test.ts @@ -0,0 +1,64 @@ +import { beforeAll, describe, expect, it } from '@jest/globals'; +import { ApiServiceController } from '../../taf/api/controller' +import { AxiosError, AxiosResponse } from 'axios'; +import { PayloadType } from '../../types/request'; + +let apiController: ApiServiceController; + + +describe('Test /random_picture GET API endpoint', () => { + + beforeAll(() => { + apiController = new ApiServiceController('http://localhost:3001'); + }) + + it.each([ + [null], + [null], + ])('Test /random_picture endpoint', async (test_case) => { + const response: AxiosResponse = await apiController.sendRequest('/random_picture'); + expect(response.status).toBe(200); + expect(response.headers['content-type']).toMatch(/image\/.*/); + }) + + it.each([ + ['/random_endpoint'], + ['/'], + ])('Test get unexisting endpoint', async (endpoint) => { + let error: AxiosError + expect(async () => { + error = await apiController.sendRequest(endpoint); + }).rejects.toThrow(AxiosError); + + }) +}) + +describe('Test /picture POST API endpoint', () => { + + beforeAll(() => { + apiController = new ApiServiceController('http://localhost:3001'); + }) + + it.each([ + [{picture: 'image_1.jpeg'}], + [{picture: 'image_2'}], + ])('Test /picture endpoint', async (payload) => { + const response: AxiosResponse = await apiController.sendRequest('/picture', 'POST', payload); + expect(response.status).toBe(200); + expect(response.headers['content-type']).toMatch(/image\/.*/); + }) + + it.each([ + [{ picture: '' }, 400, 'Bad Request'], + [{ picture: 'non_existing_image.jpeg' }, 404, 'Not Found'], + ])('Test /picture endpoint with non-existing image', async (payload, error_code, error_message) => { + try { + await apiController.sendRequest('/picture', 'POST', payload); + throw new Error('there should have been an error in the instructions above, but this raised') + } catch (error) { + expect(error.response.status).toBe(error_code); + expect(error.response.statusText).toBe(error_message); + } + }) +}) + diff --git a/tests/unit/picture.test.js b/tests/unit/picture.test.js deleted file mode 100644 index af528b6..0000000 --- a/tests/unit/picture.test.js +++ /dev/null @@ -1,53 +0,0 @@ -import { beforeAll, describe, expect, test } from '@jest/globals'; -import { getImagePathByName } from '../../src/picture.js' - -describe('Test function getImagePathByName', () => { - - let images; - - beforeAll(() => { - images = [ - 'random_image1.jpeg', - 'random_image2.jpg', - 'random_image3.img', - 'random_image4.exe', - 'random_image5' - ]; - }) - - test('Function getImagePathByName returns random value of the provided list', () => { - const randomValue = getImagePathByName('', images); - expect(images).toContain(randomValue); - }) - - test('Function getImagePathByName correctly works with prefix', () => { - const prefix = 'random_prefix' - const imagesPaths = images.map((imageName) => `${prefix}/${imageName}`); - const randomValue = getImagePathByName(prefix, images); - expect(imagesPaths).toContain(randomValue); - }) - - it.each([ - ['path', 'random_image1', 'path/random_image1.jpeg'], - ['other/path', 'random_image1.jpeg', 'other/path/random_image1.jpeg'], - ])('Function getImagePathByName returns correct path by picture name', (pathPrefix, imageName, expectedResult) => { - expect(getImagePathByName(pathPrefix, images, imageName)).toEqual(expectedResult); - }) - - it.each([ - ['path', 'not_exists_image1.jpeg', ''], - ['', 'not_exists_image2', ''], - ])('Function getImagePathByName returns empty string when imageName is not found', (pathPrefix, imageName, expectedResult) => { - expect(getImagePathByName(pathPrefix, images, imageName)).toBe(expectedResult); - }) - - it.each([ - ['path', [1,2,3], 'Value 1,2,3 is not a string!'], - ['', {a: 1, b: '1'}, "Value [object Object] is not a string!"], - ['1', 333, 'Value 333 is not a string!'], - ])('Function getImagePathByName throw an error when imageName is not string', (pathPrefix, imageName, expectedResult) => { - expect(() => { - getImagePathByName(pathPrefix, images, imageName); - }).toThrow(expectedResult); - }) -}) diff --git a/tests/unit/picture.test.ts b/tests/unit/picture.test.ts new file mode 100644 index 0000000..2043793 --- /dev/null +++ b/tests/unit/picture.test.ts @@ -0,0 +1,43 @@ +import { beforeAll, describe, expect, test } from '@jest/globals'; +import { getImagePathByName } from '../../src/picture' + +describe('Test function getImagePathByName', () => { + + let images: string[]; + + beforeAll(() => { + images = [ + 'random_image1.jpeg', + 'random_image2.jpg', + 'random_image3.img', + 'random_image4.exe', + 'random_image5' + ]; + }) + + test('Function getImagePathByName returns random value of the provided list', () => { + const randomValue = getImagePathByName('', images); + expect(images).toContain(randomValue); + }) + + test('Function getImagePathByName correctly works with prefix', () => { + const prefix = 'random_prefix' + const imagesPaths = images.map((imageName) => `${prefix}/${imageName}`); + const randomValue = getImagePathByName(prefix, images); + expect(imagesPaths).toContain(randomValue); + }) + + it.each([ + ['path', 'random_image1', 'path/random_image1.jpeg'], + ['other/path', 'random_image1.jpeg', 'other/path/random_image1.jpeg'], + ])('Function getImagePathByName returns correct path by picture name', (pathPrefix, imageName, expectedResult) => { + expect(getImagePathByName(pathPrefix, images, imageName)).toEqual(expectedResult); + }) + + it.each([ + ['path', 'not_exists_image1.jpeg', ''], + ['', 'not_exists_image2', ''], + ])('Function getImagePathByName returns empty string when imageName is not found', (pathPrefix, imageName, expectedResult) => { + expect(getImagePathByName(pathPrefix, images, imageName)).toBe(expectedResult); + }) +}) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..cc12738 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "module": "commonjs", /* Specify what module code is generated. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "moduleResolution": "node", + "resolveJsonModule": true, + } +} diff --git a/types/request.ts b/types/request.ts new file mode 100644 index 0000000..83f26ef --- /dev/null +++ b/types/request.ts @@ -0,0 +1,3 @@ +export type MethodType = 'GET' | 'PUT' | 'POST' | 'DELETE'; +export type HeadersType = { [key: string]: string }; +export type PayloadType = { [key: string]: string | { [key: string]: string } };