From 3862611231d6a7b945f8a4451f71b6544da473cb Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:47:49 +0300 Subject: [PATCH 01/10] feat: run linter, add package-lock.json modified: package-lock.json --- package-lock.json | 83 +++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2bfc1ab15..d0a46ed4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,6 +80,7 @@ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -2388,7 +2389,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -2575,7 +2575,6 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dev": true, - "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -2585,8 +2584,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/graceful-fs": { "version": "4.1.9", @@ -2637,8 +2635,7 @@ "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/lodash": { "version": "4.17.16", @@ -2653,6 +2650,7 @@ "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.19.2" } @@ -2718,6 +2716,7 @@ "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -2922,7 +2921,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -2932,29 +2930,25 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -2965,15 +2959,13 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -2986,7 +2978,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -2996,7 +2987,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -3005,15 +2995,13 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -3030,7 +3018,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -3044,7 +3031,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -3057,7 +3043,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3072,7 +3057,6 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, - "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" @@ -3082,15 +3066,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/acorn": { "version": "8.14.1", @@ -3098,6 +3080,7 @@ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3110,7 +3093,6 @@ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "peer": true, "peerDependencies": { "acorn": "^8" } @@ -3143,6 +3125,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3159,7 +3142,6 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "peer": true, "peerDependencies": { "ajv": "^6.9.1" } @@ -3451,6 +3433,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -3564,7 +3547,6 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, - "peer": true, "engines": { "node": ">=6.0" } @@ -3659,8 +3641,7 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", @@ -3914,8 +3895,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/escalade": { "version": "3.2.0", @@ -3934,6 +3914,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -3990,6 +3971,7 @@ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4033,7 +4015,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -4199,7 +4180,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "peer": true, "engines": { "node": ">=4.0" } @@ -4218,7 +4198,6 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.x" } @@ -4581,8 +4560,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/globals": { "version": "11.12.0", @@ -4934,6 +4912,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -5633,7 +5612,6 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, - "peer": true, "engines": { "node": ">=6.11.5" } @@ -5827,8 +5805,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-int64": { "version": "0.4.0", @@ -6138,6 +6115,7 @@ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -6257,7 +6235,6 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -6496,15 +6473,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -6533,7 +6508,6 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, - "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -6759,7 +6733,6 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.1.tgz", "integrity": "sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -6778,7 +6751,6 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", @@ -6813,7 +6785,6 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, - "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -6828,7 +6799,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -6844,7 +6814,6 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -7049,6 +7018,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -7159,6 +7129,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7295,7 +7266,6 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, - "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -7357,7 +7327,6 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, - "peer": true, "engines": { "node": ">=10.13.0" } From 7d54648c85ca095297404abd25186f68d2f4f4eb Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:00:58 +0300 Subject: [PATCH 02/10] chore: add jest types to tsconfig.json --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 75e87e7f9..a9caff62a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "sourceMap": true, "strict": true, "strictPropertyInitialization": false, - "target": "ES2020" + "target": "ES2020", + "types": ["node", "jest"] }, } From 11b616c645d7367d019074bc2406535254230b7b Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:09:59 +0300 Subject: [PATCH 03/10] feat: implement 01-simple-tests --- src/01-simple-tests/index.test.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/01-simple-tests/index.test.ts b/src/01-simple-tests/index.test.ts index fbbea85de..0c8643e15 100644 --- a/src/01-simple-tests/index.test.ts +++ b/src/01-simple-tests/index.test.ts @@ -1,32 +1,32 @@ -// Uncomment the code below and write your tests -// import { simpleCalculator, Action } from './index'; +import { describe, expect, test } from '@jest/globals'; +import { simpleCalculator, Action } from './index'; describe('simpleCalculator tests', () => { test('should add two numbers', () => { - // Write your test here + expect(simpleCalculator({ a: 345, b: 678, action: Action.Add })).toBe(1023); }); test('should subtract two numbers', () => { - // Write your test here + expect(simpleCalculator({ a: 987, b: 432, action: Action.Subtract })).toBe(555); }); test('should multiply two numbers', () => { - // Write your test here + expect(simpleCalculator({ a: 123, b: 456, action: Action.Multiply })).toBe(56088); }); test('should divide two numbers', () => { - // Write your test here + expect(simpleCalculator({ a: 864, b: 108, action: Action.Divide })).toBe(8); }); test('should exponentiate two numbers', () => { - // Write your test here + expect(simpleCalculator({ a: 11, b: 3, action: Action.Exponentiate })).toBe(1331); }); test('should return null for invalid action', () => { - // Write your test here + expect(simpleCalculator({ a: 345, b: 678, action: '%' })).toBeNull(); }); test('should return null for invalid arguments', () => { - // Write your test here + expect(simpleCalculator({ a: '345', b: 678, action: Action.Add })).toBeNull(); }); -}); +}); \ No newline at end of file From 0447db055ed78c945a069d2b7508a401046be9b4 Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:53:54 +0300 Subject: [PATCH 04/10] test: implement 02-table-tests modified: src/02-table-tests/index.test.ts --- src/02-table-tests/index.test.ts | 80 ++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/src/02-table-tests/index.test.ts b/src/02-table-tests/index.test.ts index 4f36e892e..5b7ad5260 100644 --- a/src/02-table-tests/index.test.ts +++ b/src/02-table-tests/index.test.ts @@ -1,17 +1,69 @@ -// Uncomment the code below and write your tests -/* import { simpleCalculator, Action } from './index'; +import { describe, expect, test } from '@jest/globals'; +import { simpleCalculator, Action } from './index'; -const testCases = [ - { a: 1, b: 2, action: Action.Add, expected: 3 }, - { a: 2, b: 2, action: Action.Add, expected: 4 }, - { a: 3, b: 2, action: Action.Add, expected: 5 }, - // continue cases for other actions -]; */ +var validCases: Array<{ + description: string; + input: { + a: number; + b: number; + action: Action; + }; + expected: number; +}> = [ + { + description: 'add two numbers', + input: { a: 345, b: 678, action: Action.Add }, + expected: 1023, + }, + { + description: 'subtract two numbers', + input: { a: 987, b: 432, action: Action.Subtract }, + expected: 555, + }, + { + description: 'multiply two numbers', + input: { a: 123, b: 456, action: Action.Multiply }, + expected: 56088, + }, + { + description: 'divide two numbers', + input: { a: 864, b: 108, action: Action.Divide }, + expected: 8, + }, + { + description: 'exponentiate two numbers', + input: { a: 11, b: 3, action: Action.Exponentiate }, + expected: 1331, + }, +]; -describe('simpleCalculator', () => { - // This test case is just to run this test suite, remove it when you write your own tests - test('should blah-blah', () => { - expect(true).toBe(true); +var invalidCases: Array<{ + description: string; + input: { + a: unknown; + b: unknown; + action: unknown; + }; + expected: null; +}> = [ + { + description: 'return null for invalid action', + input: { a: 345, b: 678, action: '%' }, + expected: null, + }, + { + description: 'return null for invalid arguments', + input: { a: '345', b: 678, action: Action.Add }, + expected: null, + }, +]; + +describe('simpleCalculator table tests', () => { + test.each(validCases)('should $description', ({ input, expected }) => { + expect(simpleCalculator(input)).toBe(expected); + }); + + test.each(invalidCases)('should $description', ({ input, expected }) => { + expect(simpleCalculator(input)).toBe(expected); }); - // Consider to use Jest table tests API to test all cases above -}); +}); \ No newline at end of file From 5111920216a466bd5172416bbfae67e6b727802a Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 20:32:46 +0300 Subject: [PATCH 05/10] feat: implement 03-error-handling-async modified: src/03-error-handling-async/index.test.ts --- src/03-error-handling-async/index.test.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/03-error-handling-async/index.test.ts b/src/03-error-handling-async/index.test.ts index 6e106a6d6..57bfb0620 100644 --- a/src/03-error-handling-async/index.test.ts +++ b/src/03-error-handling-async/index.test.ts @@ -1,30 +1,36 @@ -// Uncomment the code below and write your tests -// import { throwError, throwCustomError, resolveValue, MyAwesomeError, rejectCustomError } from './index'; +import { describe, expect, test } from '@jest/globals'; +import { + throwError + , throwCustomError + , resolveValue + , MyAwesomeError + , rejectCustomError +} from './index'; describe('resolveValue', () => { test('should resolve provided value', async () => { - // Write your test here + await expect(resolveValue(777)).resolves.toBe(777); }); }); describe('throwError', () => { test('should throw error with provided message', () => { - // Write your test here + expect(() => throwError('Custom error message')).toThrow('Custom error message'); }); test('should throw error with default message if message is not provided', () => { - // Write your test here + expect(() => throwError()).toThrow('Oops!'); }); }); describe('throwCustomError', () => { test('should throw custom error', () => { - // Write your test here + expect(() => throwCustomError()).toThrow(MyAwesomeError); }); }); describe('rejectCustomError', () => { test('should reject custom error', async () => { - // Write your test here + await expect(rejectCustomError()).rejects.toThrow(MyAwesomeError); }); -}); +}); \ No newline at end of file From 2a5d96f1c7f68a8ecb3b275e12e1d1996752c6c5 Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 21:25:05 +0300 Subject: [PATCH 06/10] feat: implement 04-test-class --- src/04-test-class/index.test.ts | 53 +++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/04-test-class/index.test.ts b/src/04-test-class/index.test.ts index 937490d82..2b9fa0343 100644 --- a/src/04-test-class/index.test.ts +++ b/src/04-test-class/index.test.ts @@ -1,44 +1,71 @@ -// Uncomment the code below and write your tests -// import { getBankAccount } from '.'; +import { describe, expect, jest, test } from '@jest/globals'; +import lodash from 'lodash'; +import { + getBankAccount + , InsufficientFundsError + , SynchronizationFailedError + , TransferFailedError +} from './index'; describe('BankAccount', () => { test('should create account with initial balance', () => { - // Write your test here + expect(getBankAccount(7351824).getBalance()).toBe(7351824); }); test('should throw InsufficientFundsError error when withdrawing more than balance', () => { - // Write your test here + expect(() => getBankAccount(4200000).withdraw(4200001)).toThrow(InsufficientFundsError); }); test('should throw error when transferring more than balance', () => { - // Write your test here + expect(() => getBankAccount(3500000).transfer(3500001, getBankAccount(2000000))).toThrow( + InsufficientFundsError, + ); }); test('should throw error when transferring to the same account', () => { - // Write your test here + const account = getBankAccount(5100000); + + expect(() => account.transfer(1000000, account)).toThrow(TransferFailedError); }); test('should deposit money', () => { - // Write your test here + expect(getBankAccount(2500000).deposit(1750000).getBalance()).toBe(4250000); }); test('should withdraw money', () => { - // Write your test here + expect(getBankAccount(9000000).withdraw(2750000).getBalance()).toBe(6250000); }); test('should transfer money', () => { - // Write your test here + const fromAccount = getBankAccount(8000000); + const toAccount = getBankAccount(1500000); + + fromAccount.transfer(3250000, toAccount); + + expect([fromAccount.getBalance(), toAccount.getBalance()]).toEqual([4750000, 4750000]); }); test('fetchBalance should return number in case if request did not failed', async () => { - // Write your tests here + jest.spyOn(lodash, 'random').mockReturnValueOnce(7420000).mockReturnValueOnce(1); + + await expect(getBankAccount(1000000).fetchBalance()).resolves.toBe(7420000); }); test('should set new balance if fetchBalance returned number', async () => { - // Write your tests here + const account = getBankAccount(3000000); + + jest.spyOn(account, 'fetchBalance').mockResolvedValue(8880000); + + await account.synchronizeBalance(); + + expect(account.getBalance()).toBe(8880000); }); test('should throw SynchronizationFailedError if fetchBalance returned null', async () => { - // Write your tests here + const account = getBankAccount(3000000); + + jest.spyOn(account, 'fetchBalance').mockResolvedValue(null); + + await expect(account.synchronizeBalance()).rejects.toThrow(SynchronizationFailedError); }); -}); +}); \ No newline at end of file From 16d7f2f6d6e7dbf37a5876aa511390fd3958bbfb Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sat, 18 Apr 2026 22:06:26 +0300 Subject: [PATCH 07/10] feat: implement 05-partial-mocking --- src/05-partial-mocking/index.test.ts | 31 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/05-partial-mocking/index.test.ts b/src/05-partial-mocking/index.test.ts index 9d8a66cbd..972a6fcad 100644 --- a/src/05-partial-mocking/index.test.ts +++ b/src/05-partial-mocking/index.test.ts @@ -1,8 +1,13 @@ -// Uncomment the code below and write your tests -// import { mockOne, mockTwo, mockThree, unmockedFunction } from './index'; +import { afterAll, describe, expect, jest, test } from '@jest/globals'; +import { mockOne, mockTwo, mockThree, unmockedFunction } from './index'; jest.mock('./index', () => { - // const originalModule = jest.requireActual('./index'); + // spread slower than Object.assign + return Object.assign({}, jest.requireActual('./index'), { + mockOne: jest.fn(), + mockTwo: jest.fn(), + mockThree: jest.fn(), + }); }); describe('partial mocking', () => { @@ -11,10 +16,24 @@ describe('partial mocking', () => { }); test('mockOne, mockTwo, mockThree should not log into console', () => { - // Write your test here + var consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => undefined); + + mockOne(); + mockTwo(); + mockThree(); + + expect(mockOne).toHaveBeenCalledTimes(1); + expect(mockTwo).toHaveBeenCalledTimes(1); + expect(mockThree).toHaveBeenCalledTimes(1); + expect(consoleLogSpy).not.toHaveBeenCalled(); }); test('unmockedFunction should log into console', () => { - // Write your test here + var consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => undefined); + + unmockedFunction(); + + expect(consoleLogSpy).toHaveBeenCalledTimes(1); + expect(consoleLogSpy).toHaveBeenCalledWith('I am not mocked'); }); -}); +}); \ No newline at end of file From 22b20c0faf8af6593fa802caadf93fd42dc44753 Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sun, 19 Apr 2026 01:35:49 +0300 Subject: [PATCH 08/10] feat: implement 06-mocking-node-api --- src/06-mocking-node-api/index.test.ts | 86 +++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/src/06-mocking-node-api/index.test.ts b/src/06-mocking-node-api/index.test.ts index 8dc3afd79..d0e7b4cd1 100644 --- a/src/06-mocking-node-api/index.test.ts +++ b/src/06-mocking-node-api/index.test.ts @@ -1,5 +1,21 @@ -// Uncomment the code below and write your tests -// import { readFileAsynchronously, doStuffByTimeout, doStuffByInterval } from '.'; +import { afterEach, beforeAll, afterAll, describe, expect, jest, test } from '@jest/globals'; +import { existsSync } from 'fs'; +import { readFile } from 'fs/promises'; +import { join } from 'path'; + +jest.mock('path', () => ({ + join: jest.fn(), +})); + +jest.mock('fs', () => ({ + existsSync: jest.fn(), +})); + +jest.mock('fs/promises', () => ({ + readFile: jest.fn(), +})); + +import { readFileAsynchronously, doStuffByTimeout, doStuffByInterval } from '.'; describe('doStuffByTimeout', () => { beforeAll(() => { @@ -11,11 +27,25 @@ describe('doStuffByTimeout', () => { }); test('should set timeout with provided callback and timeout', () => { - // Write your test here + const callback = jest.fn(); + const setTimeoutSpy = jest.spyOn(global, 'setTimeout'); + + doStuffByTimeout(callback, 1837); + + expect(setTimeoutSpy).toHaveBeenCalledTimes(1); + expect(setTimeoutSpy).toHaveBeenCalledWith(callback, 1837); }); test('should call callback only after timeout', () => { - // Write your test here + const callback = jest.fn(); + + doStuffByTimeout(callback, 2645); + + jest.advanceTimersByTime(2644); + expect(callback).not.toHaveBeenCalled(); + + jest.advanceTimersByTime(1); + expect(callback).toHaveBeenCalledTimes(1); }); }); @@ -29,24 +59,60 @@ describe('doStuffByInterval', () => { }); test('should set interval with provided callback and timeout', () => { - // Write your test here + const callback = jest.fn(); + const setIntervalSpy = jest.spyOn(global, 'setInterval'); + + doStuffByInterval(callback, 3719); + + expect(setIntervalSpy).toHaveBeenCalledTimes(1); + expect(setIntervalSpy).toHaveBeenCalledWith(callback, 3719); }); test('should call callback multiple times after multiple intervals', () => { - // Write your test here + const callback = jest.fn(); + + doStuffByInterval(callback, 1456); + + jest.advanceTimersByTime(1456 * 3); + + expect(callback).toHaveBeenCalledTimes(3); }); }); describe('readFileAsynchronously', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + test('should call join with pathToFile', async () => { - // Write your test here + const pathToFile = 'nested/file.txt'; + + (join as unknown as jest.Mock).mockReturnValue('/mocked/root/nested/file.txt'); + (existsSync as unknown as jest.Mock).mockReturnValue(false); + + await readFileAsynchronously(pathToFile); + + expect(join).toHaveBeenCalledTimes(1); + expect(join).toHaveBeenCalledWith(__dirname, pathToFile); }); test('should return null if file does not exist', async () => { - // Write your test here + (join as unknown as jest.Mock).mockReturnValue('/mocked/root/missing.txt'); + (existsSync as unknown as jest.Mock).mockReturnValue(false); + + await expect(readFileAsynchronously('missing.txt')).resolves.toBeNull(); + expect(readFile).not.toHaveBeenCalled(); }); test('should return file content if file exists', async () => { - // Write your test here + (join as unknown as jest.Mock).mockReturnValue('/mocked/root/existing.txt'); + (existsSync as unknown as jest.Mock).mockReturnValue(true); + (readFile as unknown as jest.Mock).mockImplementation(() => + Promise.resolve(Buffer.from('Mocked file content')), + ); + + await expect(readFileAsynchronously('existing.txt')).resolves.toBe('Mocked file content'); + expect(readFile).toHaveBeenCalledTimes(1); + expect(readFile).toHaveBeenCalledWith('/mocked/root/existing.txt'); }); -}); +}); \ No newline at end of file From d831d91dfb3d05a6db44dac2b3c0e36a76b751c6 Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sun, 19 Apr 2026 01:46:59 +0300 Subject: [PATCH 09/10] feat: implement 07-mocking-lib-api --- src/07-mocking-lib-api/index.test.ts | 41 +++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/07-mocking-lib-api/index.test.ts b/src/07-mocking-lib-api/index.test.ts index e1dd001ef..67c4f8c13 100644 --- a/src/07-mocking-lib-api/index.test.ts +++ b/src/07-mocking-lib-api/index.test.ts @@ -1,17 +1,44 @@ -// Uncomment the code below and write your tests -/* import axios from 'axios'; -import { throttledGetDataFromApi } from './index'; */ +import { beforeEach, describe, expect, jest, test } from '@jest/globals'; + +jest.mock('lodash', () => ({ + throttle: jest.fn((fn) => fn), +})); + +jest.mock('axios'); + +import axios from 'axios'; +import { throttledGetDataFromApi } from './index'; + +const mockedAxios = axios as jest.Mocked; +const getMock = jest.fn<(relativePath: string) => Promise<{ data: unknown }>>(); describe('throttledGetDataFromApi', () => { + beforeEach(() => { + mockedAxios.create.mockReturnValue({ get: getMock } as never); + }); + test('should create instance with provided base url', async () => { - // Write your test here + getMock.mockResolvedValue({ data: { ok: true } }); + + await throttledGetDataFromApi('/users'); + + expect(mockedAxios.create).toHaveBeenCalledWith({ + baseURL: 'https://jsonplaceholder.typicode.com', + }); }); test('should perform request to correct provided url', async () => { - // Write your test here + getMock.mockResolvedValue({ data: { ok: true } }); + + await throttledGetDataFromApi('/posts/7'); + + expect(getMock).toHaveBeenCalledWith('/posts/7'); }); test('should return response data', async () => { - // Write your test here + var responseData = { id: 713, title: 'Lorem ipsum' }; + getMock.mockResolvedValue({ data: responseData }); + + await expect(throttledGetDataFromApi('/posts/713')).resolves.toEqual(responseData); }); -}); +}); \ No newline at end of file From 5144ab5203d984080f93799a3d1ca097a6394e8e Mon Sep 17 00:00:00 2001 From: Oleksandr Parkhomenko <119164331+proff1991@users.noreply.github.com> Date: Sun, 19 Apr 2026 18:04:30 +0300 Subject: [PATCH 10/10] feat: implement 08-snapshot-testing modified: src/08-snapshot-testing/index.test.ts --- src/08-snapshot-testing/index.test.ts | 38 ++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/08-snapshot-testing/index.test.ts b/src/08-snapshot-testing/index.test.ts index 67c345706..e504c6a84 100644 --- a/src/08-snapshot-testing/index.test.ts +++ b/src/08-snapshot-testing/index.test.ts @@ -1,14 +1,38 @@ -// Uncomment the code below and write your tests -// import { generateLinkedList } from './index'; +import { describe, expect, test } from '@jest/globals'; +import { generateLinkedList } from './index'; describe('generateLinkedList', () => { - // Check match by expect(...).toStrictEqual(...) test('should generate linked list from values 1', () => { - // Write your test here + expect(generateLinkedList([173, 284, 395])).toStrictEqual({ + value: 173, + next: { + value: 284, + next: { + value: 395, + next: { + value: null, + next: null, + }, + }, + }, + }); }); - // Check match by comparison with snapshot test('should generate linked list from values 2', () => { - // Write your test here + expect(generateLinkedList([481, 592, 613])).toMatchInlineSnapshot(` + { + "next": { + "next": { + "next": { + "next": null, + "value": null, + }, + "value": 613, + }, + "value": 592, + }, + "value": 481, + } + `); }); -}); +}); \ No newline at end of file