diff --git a/.gitignore b/.gitignore index 530db921a751c03ed4845be0de44338fd51a3ba4..31458c846750a236e9c87882ecb0378805349113 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ Wiki/.idea ExerciseChecker/src/config/Version.ts +sonarlint.xml +sonarlint/ + ############################ MacOS # General .DS_Store diff --git a/ExerciseChecker/.gitlab-ci/04_stageCodeQuality.yml b/ExerciseChecker/.gitlab-ci/04_stageCodeQuality.yml index 48f2394902f9143be7eee5ca5706ffbd65f3355b..c10eae8504baed8bbb2688b9be5e6aef396bdd20 100644 --- a/ExerciseChecker/.gitlab-ci/04_stageCodeQuality.yml +++ b/ExerciseChecker/.gitlab-ci/04_stageCodeQuality.yml @@ -5,8 +5,28 @@ code_quality:lint: image: node:latest script: - cd "${PROJECT_FOLDER}" - + - npm install - npm run lint rules: - if: '$CI_COMMIT_TAG =~ "/^$/"' + + +code_quality:sonarqube: + stage: code_quality + tags: + - code_quality + image: + name: leadrien/isc-sonar-scanner-cli + entrypoint: [ "" ] + variables: + SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache + GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task + cache: + key: "${CI_JOB_NAME}" + paths: + - .sonar/cache + script: + - sonar-scanner + rules: + - if: '$CI_COMMIT_TAG =~ "/^$/"' diff --git a/ExerciseChecker/.idea/ExerciseChecker.iml b/ExerciseChecker/.idea/ExerciseChecker.iml index e0659eda202760c70a3fe561cc8815795a7fbe89..f798fb1dc4675041c5d5434873f5a101804a42d6 100644 --- a/ExerciseChecker/.idea/ExerciseChecker.iml +++ b/ExerciseChecker/.idea/ExerciseChecker.iml @@ -15,4 +15,7 @@ <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> </component> + <component name="SonarLintModuleSettings"> + <option name="uniqueId" value="39cd055e-87b7-4af4-82da-6d4c7c75ce23" /> + </component> </module> \ No newline at end of file diff --git a/ExerciseChecker/package-lock.json b/ExerciseChecker/package-lock.json index a46309f4872c72e2208182c4a39d0269676e88c2..0299647e7605c1ca0e88aaec392b5c994017463b 100644 --- a/ExerciseChecker/package-lock.json +++ b/ExerciseChecker/package-lock.json @@ -9,17 +9,20 @@ "version": "3.6.0", "license": "AGPLv3", "dependencies": { + "@gitbeaker/rest": "^39.34.3", "axios": "^1.6.5", "boxen": "^5.1.2", "chalk": "^4.1.2", "dotenv": "^16.3.1", "dotenv-expand": "^10.0.0", + "form-data": "^4.0.0", "fs-extra": "^11.2.0", "http-status-codes": "^2.3.0", "json5": "^2.2.3", "ora": "^5.4.1", "tar-stream": "^3.1.6", "winston": "^3.11.0", + "winston-transport": "^4.7.0", "yaml": "^2.3.4", "zod": "^3.22.4", "zod-validation-error": "^3.0.0" @@ -243,15 +246,54 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@gitbeaker/core": { + "version": "39.34.3", + "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-39.34.3.tgz", + "integrity": "sha512-/3qBXme2MjO38QU2F/MYGon9a4wHKrgtwNzdHHdjpbYJ2/wOGNgbEWSZcibcFkiWVgAjbPXdYqC5sY8hcwGO1w==", + "dependencies": { + "@gitbeaker/requester-utils": "^39.34.3", + "qs": "^6.11.2", + "xcase": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@gitbeaker/requester-utils": { + "version": "39.34.3", + "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-39.34.3.tgz", + "integrity": "sha512-nMnTkTo4UixHPwPYsYIjp8UdKrmSw3TjvRESexliAeNNq4/LVeyVUyRqBUa1ZI8MXt1nPPnPX3wh8s7rqlm7uA==", + "dependencies": { + "picomatch-browser": "^2.2.6", + "qs": "^6.11.2", + "rate-limiter-flexible": "^4.0.0", + "xcase": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@gitbeaker/rest": { + "version": "39.34.3", + "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-39.34.3.tgz", + "integrity": "sha512-SuceThS6WhJtqNNcKmW8j0yUU7aXA4k5a29OWcd6bn7peQ3MXlIpbfvLLRnmuUaYUuxHLnUzZhAfuxaNf4DVtQ==", + "dependencies": { + "@gitbeaker/core": "^39.34.3", + "@gitbeaker/requester-utils": "^39.34.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -313,32 +355,32 @@ "peer": true }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -351,9 +393,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz", - "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -771,6 +813,7 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.8.tgz", "integrity": "sha512-yx6KAqlt3TAHBduS2fMQtJDL2ufIHnDRArrJEOoTTuizxqmjLT+psGYOHpmMl3gvQpFJ11Hs76guUUktzAF9Bg==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "engines": { "node": ">=12.0.0" @@ -841,18 +884,18 @@ } }, "node_modules/@types/node": { - "version": "18.19.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.8.tgz", - "integrity": "sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg==", + "version": "18.19.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.21.tgz", + "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/tar-stream": { @@ -870,16 +913,16 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz", - "integrity": "sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.0", - "@typescript-eslint/type-utils": "6.19.0", - "@typescript-eslint/utils": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -905,15 +948,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz", - "integrity": "sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.19.0", - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/typescript-estree": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "engines": { @@ -933,13 +976,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz", - "integrity": "sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -950,13 +993,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz", - "integrity": "sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.19.0", - "@typescript-eslint/utils": "6.19.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -977,9 +1020,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz", - "integrity": "sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -990,13 +1033,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz", - "integrity": "sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1018,17 +1061,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz", - "integrity": "sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.0", - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -1043,12 +1086,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz", - "integrity": "sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1242,9 +1285,9 @@ } }, "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -1252,9 +1295,9 @@ } }, "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" }, "node_modules/balanced-match": { "version": "1.0.2", @@ -1262,6 +1305,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bare-events": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.1.tgz", + "integrity": "sha512-9GYPpsPFvrWBkelIhOhTWtkeZxVxZOdb3VnFTCzlOo3OjvmTvzLoZFUT8kNFACx0vJej6QPney1Cf9BvzCNE/A==", + "optional": true + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1365,6 +1414,24 @@ "node": ">=0.10.0" } }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1690,6 +1757,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1742,14 +1825,14 @@ } }, "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dotenv-expand": { @@ -1761,17 +1844,17 @@ } }, "node_modules/dotenv-vault": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/dotenv-vault/-/dotenv-vault-1.25.0.tgz", - "integrity": "sha512-+3isN+iq0E5VE+pfluBcNYb2qFf/Zu5q44Neh3Bazl82vk86xdUbI2z2cYHgJq5bMgRW1kUOaGWsgXjYlGUhng==", + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/dotenv-vault/-/dotenv-vault-1.26.1.tgz", + "integrity": "sha512-v+RK6LXpJQWhaelTT2s0b5FQB0qziRBuGCrAgAeDHtgkDEA0NqF7OXYXsrnKTuCPnwBg0FmNJr4lZebCpJnrFA==", "dev": true, "dependencies": { "@oclif/core": "^1", - "@oclif/plugin-help": "^5.2.11", - "@oclif/plugin-not-found": "^2.3.24", + "@oclif/plugin-help": "^5.2.15", + "@oclif/plugin-not-found": "^2.3.34", "@oclif/plugin-update": "^3.1.16", - "@oclif/plugin-warn-if-update-available": "^2.0.40", - "axios": "^0.27.2", + "@oclif/plugin-warn-if-update-available": "^2.0.46", + "axios": "^1.6.7", "chalk": "^4.1.2", "dotenv": "^16.3.1" }, @@ -1782,16 +1865,6 @@ "node": ">=16" } }, - "node_modules/dotenv-vault/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, "node_modules/ejs": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", @@ -1835,10 +1908,29 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -1857,17 +1949,17 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -2151,9 +2243,9 @@ } }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -2285,9 +2377,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, "peer": true }, @@ -2398,7 +2490,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2429,6 +2520,24 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -2538,6 +2647,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2566,11 +2686,43 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dependencies": { "function-bind": "^1.1.2" }, @@ -2654,9 +2806,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -3332,9 +3484,9 @@ } }, "node_modules/node-abi": { - "version": "3.54.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", - "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", + "version": "3.56.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", + "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", "dev": true, "dependencies": { "semver": "^7.3.5" @@ -3363,6 +3515,14 @@ } } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-treeify": { "version": "1.1.33", "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", @@ -3610,6 +3770,17 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/picomatch-browser": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/picomatch-browser/-/picomatch-browser-2.2.6.tgz", + "integrity": "sha512-0ypsOQt9D4e3hziV8O4elD9uN0z/jtUEfxVRtNaAAtXIyUx9m/SzlO020i8YNL2aL/E6blOvvHQcin6HZlFy/w==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pkg": { "version": "5.8.1", "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.8.1.tgz", @@ -3768,6 +3939,20 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3793,6 +3978,11 @@ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, + "node_modules/rate-limiter-flexible": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-4.0.1.tgz", + "integrity": "sha512-2/dGHpDFpeA0+755oUkW+EKyklqLS9lu0go9pDsbhqQjZcxfRyJ6LA4JI0+HAdZ2bemD/oOjUeZQB2lCZqXQfQ==" + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -4000,9 +4190,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4014,6 +4204,22 @@ "node": ">=10" } }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4035,6 +4241,23 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4178,12 +4401,15 @@ } }, "node_modules/streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { @@ -4296,9 +4522,9 @@ } }, "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", @@ -4377,12 +4603,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -4572,9 +4798,9 @@ } }, "node_modules/winston": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", - "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz", + "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", @@ -4586,16 +4812,16 @@ "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.5.0" + "winston-transport": "^4.7.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", @@ -4633,6 +4859,11 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xcase": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xcase/-/xcase-2.0.1.tgz", + "integrity": "sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -4649,9 +4880,12 @@ "dev": true }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } @@ -4714,9 +4948,9 @@ } }, "node_modules/zod-validation-error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.0.0.tgz", - "integrity": "sha512-x+agsJJG9rvC7axF0xqTEdZhJkLHyIZkdOAWDJSmwGPzxNHMHwtU6w2yDOAAP6yuSfTAUhAMJRBfhVGY64ySEQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.0.3.tgz", + "integrity": "sha512-cETTrcMq3Ze58vhdR0zD37uJm/694I6mAxcf/ei5bl89cC++fBNxrC2z8lkFze/8hVMPwrbtrwXHR2LB50fpHw==", "engines": { "node": ">=18.0.0" }, diff --git a/ExerciseChecker/package.json b/ExerciseChecker/package.json index 2331fbbc4014026023e80ff53c501ddcab998c42..233dc30319f284b19e01ff49c494932c21a1b6c4 100644 --- a/ExerciseChecker/package.json +++ b/ExerciseChecker/package.json @@ -29,17 +29,20 @@ "test" : "echo \"Error: no test specified\" && exit 1" }, "dependencies" : { + "@gitbeaker/rest" : "^39.34.3", "axios" : "^1.6.5", "boxen" : "^5.1.2", "chalk" : "^4.1.2", "dotenv" : "^16.3.1", "dotenv-expand" : "^10.0.0", + "form-data" : "^4.0.0", "fs-extra" : "^11.2.0", "http-status-codes" : "^2.3.0", "json5" : "^2.2.3", "ora" : "^5.4.1", "tar-stream" : "^3.1.6", "winston" : "^3.11.0", + "winston-transport" : "^4.7.0", "yaml" : "^2.3.4", "zod" : "^3.22.4", "zod-validation-error": "^3.0.0" diff --git a/ExerciseChecker/src/app.ts b/ExerciseChecker/src/app.ts index 2a519e885ef3ab66272ec4b9b4c6508c64d031f5..fd63ba82c031bcfb5f0e6ecdc3964f20e38e6add 100644 --- a/ExerciseChecker/src/app.ts +++ b/ExerciseChecker/src/app.ts @@ -30,150 +30,161 @@ import ClientsSharedExerciseHelper from './sharedByClients/helpers/Dojo import Icon from './shared/types/Icon'; -(async () => { - HttpManager.registerAxiosInterceptor(); - - console.log(Styles.APP_NAME(`${ Config.appName } (version {{VERSION}})`)); - - let exerciseAssignment: ExerciseAssignment | undefined; - let exerciseDockerCompose: ExerciseDockerCompose; - let exerciseResultsValidation: ExerciseResultsSanitizerAndValidator; - - let haveResultsVolume: boolean; - - - /* - //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 1: - - Read the dojo assignment file from the assignment repository - - Download immutables files (maybe throw or show an error if the files have been modified ?) - */ - { - console.log(Styles.INFO(`${ Icon.INFO }️Checking the exercise's assignment and his immutable files`)); - exerciseAssignment = await DojoBackendManager.getExerciseAssignment(); - if ( !exerciseAssignment ) { - console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the exercise's assignment`)); - process.exit(ExerciseCheckerError.EXERCISE_ASSIGNMENT_GET_ERROR); - } - - exerciseAssignment.immutable.forEach(immutableFile => { - const filePath = path.join(Config.folders.project, immutableFile.file_path); - fs.mkdirSync(path.dirname(filePath), { recursive: true }); - fs.writeFileSync(filePath, immutableFile.content, { encoding: 'base64' }); - }); +let exerciseAssignment: ExerciseAssignment | undefined; +let exerciseDockerCompose: ExerciseDockerCompose; +let exerciseResultsValidation: ExerciseResultsSanitizerAndValidator; + +let haveResultsVolume: boolean; + +/** + * Step 1: + * - Read the dojo assignment file from the assignment repository + * - Download immutables files (maybe throw or show an error if the files have been modified ?) + */ +async function downloadImmutablesFiles() { + console.log(Styles.INFO(`${ Icon.INFO }️ Checking the exercise's assignment and his immutable files`)); + exerciseAssignment = await DojoBackendManager.getExerciseAssignment(); + if ( !exerciseAssignment ) { + console.error(Styles.ERROR(`${ Icon.ERROR } Error while getting the exercise's assignment`)); + process.exit(ExerciseCheckerError.EXERCISE_ASSIGNMENT_GET_ERROR); + } - haveResultsVolume = exerciseAssignment.assignmentFile.result.volume !== undefined; + exerciseAssignment.immutable.forEach(immutableFile => { + const filePath = path.join(Config.folders.project, immutableFile.file_path); + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, immutableFile.content, { encoding: 'base64' }); + }); + + haveResultsVolume = exerciseAssignment.assignmentFile.result.volume !== undefined; +} + + +/** + * Step 2: + * - Get override of docker-compose file (for override the volume by a bind mount to the results folder shared between dind and the host) + * - Run docker-compose file + * - Get logs from linked services + */ +async function runDockerCompose() { + let composeFileOverride: string[] = []; + const composeOverridePath: string = path.join(Config.folders.project, 'docker-compose-override.yml'); + if ( haveResultsVolume ) { + const composeOverride = fs.readFileSync(path.join(__dirname, '../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', exerciseAssignment!.assignmentFile.result.volume!).replace('{{MOUNT_PATH}}', Config.folders.resultsExercise); + fs.writeFileSync(composeOverridePath, composeOverride); + + composeFileOverride = [ composeOverridePath ]; } + exerciseDockerCompose = new ExerciseDockerCompose(ClientsSharedConfig.dockerCompose.projectName, exerciseAssignment!.assignmentFile, Config.folders.project, composeFileOverride); - /* - //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 2: - - Get override of docker-compose file (for override the volume by a bind mount to the results folder shared between dind and the host) - - Run docker-compose file - - Get logs from linked services - */ - { - let composeFileOverride: string[] = []; - const composeOverridePath: string = path.join(Config.folders.project, 'docker-compose-override.yml'); - if ( haveResultsVolume ) { - const composeOverride = fs.readFileSync(path.join(__dirname, '../assets/docker-compose-override.yml'), 'utf8').replace('{{VOLUME_NAME}}', exerciseAssignment.assignmentFile.result.volume!).replace('{{MOUNT_PATH}}', Config.folders.resultsExercise); - fs.writeFileSync(composeOverridePath, composeOverride); - - composeFileOverride = [ composeOverridePath ]; - } - - exerciseDockerCompose = new ExerciseDockerCompose(ClientsSharedConfig.dockerCompose.projectName, exerciseAssignment.assignmentFile, Config.folders.project, composeFileOverride); - - try { - await new Promise<void>((resolve, reject) => { - exerciseDockerCompose.events.on('step', (_name: string, message: string) => { - console.log(Styles.INFO(`${ Icon.INFO } ${ message }`)); - }); - - exerciseDockerCompose.events.on('endStep', (_stepName: string, message: string, error: boolean) => { - if ( error ) { - console.error(Styles.ERROR(`${ Icon.ERROR } ${ message }`)); - } - }); - - exerciseDockerCompose.events.on('finished', (success: boolean) => { - success ? resolve() : reject(); - }); - - exerciseDockerCompose.run(); + try { + await new Promise<void>((resolve, reject) => { + exerciseDockerCompose.events.on('step', (_name: string, message: string) => { + console.log(Styles.INFO(`${ Icon.INFO } ${ message }`)); }); - } catch ( error ) { /* empty */ } - fs.rmSync(composeOverridePath, { force: true }); - fs.writeFileSync(path.join(Config.folders.resultsDojo, 'dockerComposeLogs.txt'), exerciseDockerCompose.allLogs); + exerciseDockerCompose.events.on('endStep', (_stepName: string, message: string, error: boolean) => { + if ( error ) { + console.error(Styles.ERROR(`${ Icon.ERROR } ${ message }`)); + } + }); - if ( !exerciseDockerCompose.success ) { - console.error(Styles.ERROR(`${ Icon.ERROR } Execution logs are available in artifacts`)); - process.exit(exerciseDockerCompose.exitCode); - } - } + exerciseDockerCompose.events.on('finished', (success: boolean) => { + success ? resolve() : reject(); + }); + exerciseDockerCompose.run(); + }); + } catch ( error ) { /* empty */ } - //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 3: Check content requirements and content size - { - exerciseResultsValidation = new ExerciseResultsSanitizerAndValidator(Config.folders.resultsDojo, Config.folders.resultsExercise, exerciseDockerCompose.exitCode); + fs.rmSync(composeOverridePath, { force: true }); + fs.writeFileSync(path.join(Config.folders.resultsDojo, 'dockerComposeLogs.txt'), exerciseDockerCompose.allLogs); - try { - await new Promise<void>((resolve) => { - exerciseResultsValidation.events.on('step', (_name: string, message: string) => { - console.log(Styles.INFO(`${ Icon.INFO } ${ message }`)); - }); + if ( !exerciseDockerCompose.success ) { + console.error(Styles.ERROR(`${ Icon.ERROR } Execution logs are available in artifacts`)); + process.exit(exerciseDockerCompose.exitCode); + } +} - exerciseResultsValidation.events.on('endStep', (_stepName: string, message: string, error: boolean) => { - if ( error ) { - console.error(Styles.ERROR(`${ Icon.ERROR } ${ message }`)); - } - }); - exerciseResultsValidation.events.on('finished', (success: boolean, exitCode: number) => { - if ( !success ) { - process.exit(exitCode); - } +/** + * Step 3: + * - Check content requirements and content size + */ +async function checkExecutionContent() { + exerciseResultsValidation = new ExerciseResultsSanitizerAndValidator(Config.folders.resultsDojo, Config.folders.resultsExercise, exerciseDockerCompose.exitCode); - resolve(); - }); + try { + await new Promise<void>(resolve => { + exerciseResultsValidation.events.on('step', (_name: string, message: string) => { + console.log(Styles.INFO(`${ Icon.INFO } ${ message }`)); + }); - exerciseResultsValidation.run(); + exerciseResultsValidation.events.on('endStep', (_stepName: string, message: string, error: boolean) => { + if ( error ) { + console.error(Styles.ERROR(`${ Icon.ERROR } ${ message }`)); + } }); - } catch ( error ) { /* empty */ } - } + exerciseResultsValidation.events.on('finished', (success: boolean, exitCode: number) => { + if ( !success ) { + process.exit(exitCode); + } - //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 4: Upload results - { - try { - console.log(Styles.INFO(`${ Icon.INFO } Uploading results to the dojo server`)); - const commit: Record<string, string> = {}; - Toolbox.getKeysWithPrefix(process.env, 'CI_COMMIT_').forEach(key => { - commit[Toolbox.snakeToCamel(key.replace('CI_COMMIT_', ''))] = process.env[key] as string; + resolve(); }); - const files = await RecursiveFilesStats.explore(Config.folders.resultsVolume, { - replacePathByRelativeOne: true, - liteStats : true - }); + exerciseResultsValidation.run(); + }); + } catch ( error ) { /* empty */ } +} + +/** + * Step 4: + * - Upload results + */ +async function uploadResults() { + try { + console.log(Styles.INFO(`${ Icon.INFO } Uploading results to the dojo server`)); + const commit: Record<string, string> = {}; + Toolbox.getKeysWithPrefix(process.env, 'CI_COMMIT_').forEach(key => { + commit[Toolbox.snakeToCamel(key.replace('CI_COMMIT_', ''))] = process.env[key] as string; + }); - await DojoBackendManager.sendResults(exerciseDockerCompose.exitCode, commit, exerciseResultsValidation.exerciseResults, files, await ArchiveHelper.getBase64(Config.folders.resultsVolume)); - } catch ( error ) { - console.error(Styles.ERROR(`${ Icon.ERROR } Error while uploading the results`)); - console.error(JSON.stringify(error)); - process.exit(ExerciseCheckerError.UPLOAD); - } + const files = await RecursiveFilesStats.explore(Config.folders.resultsVolume, { + replacePathByRelativeOne: true, + liteStats : true + }); + + await DojoBackendManager.sendResults(exerciseDockerCompose.exitCode, commit, exerciseResultsValidation.exerciseResults, files, await ArchiveHelper.getBase64(Config.folders.resultsVolume)); + } catch ( error ) { + console.error(Styles.ERROR(`${ Icon.ERROR } Error while uploading the results`)); + console.error(JSON.stringify(error)); + process.exit(ExerciseCheckerError.UPLOAD); } +} - /* - //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 5: - - Display results - - Exit with container exit code - */ - { - ClientsSharedExerciseHelper.displayExecutionResults(exerciseResultsValidation.exerciseResults, exerciseDockerCompose.exitCode, Styles, `\n\n${ Icon.INFO }️ More detailed logs and resources may be available in artifacts`); +/** + * Step 5: + * - Display results + * - Exit with container exit code + */ +async function displayResults() { + ClientsSharedExerciseHelper.displayExecutionResults(exerciseResultsValidation.exerciseResults, exerciseDockerCompose.exitCode, Styles, `\n\n${ Icon.INFO }️ More detailed logs and resources may be available in artifacts`); - process.exit(exerciseDockerCompose.exitCode); - } + process.exit(exerciseDockerCompose.exitCode); +} + + +(async () => { + HttpManager.registerAxiosInterceptor(); + + console.log(Styles.APP_NAME(`${ Config.appName } (version {{VERSION}})`)); + + await downloadImmutablesFiles(); + await runDockerCompose(); + await checkExecutionContent(); + await uploadResults(); + await displayResults(); })(); \ No newline at end of file diff --git a/ExerciseChecker/src/config/Config.ts b/ExerciseChecker/src/config/Config.ts index 42c446229456f1c92c316a4e7b27b54779f73c7a..db117f5636d7b8b952491fb337f373727fcaa0d2 100644 --- a/ExerciseChecker/src/config/Config.ts +++ b/ExerciseChecker/src/config/Config.ts @@ -20,7 +20,7 @@ class Config { }; constructor() { - this.appName = process.env.APP_NAME || ''; + this.appName = process.env.APP_NAME ?? ''; this.folders = { project : process.env.PROJECT_FOLDER?.convertWithEnvVars() ?? './', @@ -31,13 +31,13 @@ class Config { this.resetResultsVolume(); this.exercise = { - id : process.env.DOJO_EXERCISE_ID || '', - secret: process.env.DOJO_SECRET || '' + id : process.env.DOJO_EXERCISE_ID ?? '', + secret: process.env.DOJO_SECRET ?? '' }; this.dockerhub = { repositories: { - exerciseChecker: process.env.DOCKERHUB_EXERCISE_CHECKER_REPOSITORY || '' + exerciseChecker: process.env.DOCKERHUB_EXERCISE_CHECKER_REPOSITORY ?? '' } }; } diff --git a/ExerciseChecker/src/managers/DojoBackendManager.ts b/ExerciseChecker/src/managers/DojoBackendManager.ts index 102069ead041b6877029dad772edb7fb81a45211..76e339088656438412a22ff32aeac0730c3d3add 100644 --- a/ExerciseChecker/src/managers/DojoBackendManager.ts +++ b/ExerciseChecker/src/managers/DojoBackendManager.ts @@ -1,4 +1,3 @@ -import ClientsSharedConfig from '../sharedByClients/config/ClientsSharedConfig'; import axios from 'axios'; import DojoBackendResponse from '../shared/types/Dojo/DojoBackendResponse'; import ExerciseAssignment from '../sharedByClients/models/ExerciseAssignment'; @@ -6,23 +5,20 @@ import Config from '../config/Config'; import ExerciseResultsFile from '../shared/types/Dojo/ExerciseResultsFile'; import ApiRoute from '../sharedByClients/types/Dojo/ApiRoute'; import { IFileDirStat } from '../shared/helpers/recursiveFilesStats/RecursiveFilesStats'; +import DojoBackendHelper from '../sharedByClients/helpers/Dojo/DojoBackendHelper'; class DojoBackendManager { - public getApiUrl(route: ApiRoute): string { - return `${ ClientsSharedConfig.apiURL }${ route }`; - } - public async getExerciseAssignment(): Promise<ExerciseAssignment | undefined> { try { - return (await axios.get<DojoBackendResponse<ExerciseAssignment>>(this.getApiUrl(ApiRoute.EXERCISE_ASSIGNMENT).replace('{{id}}', Config.exercise.id))).data.data; + return (await axios.get<DojoBackendResponse<ExerciseAssignment>>(DojoBackendHelper.getApiUrl(ApiRoute.EXERCISE_ASSIGNMENT, { exerciseIdOrUrl: Config.exercise.id }))).data.data; } catch ( error ) { return undefined; } } public async sendResults(exitCode: number, commit: Record<string, string>, results: ExerciseResultsFile, files: Array<IFileDirStat>, archiveBase64: string): Promise<void> { - await axios.post(this.getApiUrl(ApiRoute.EXERCISE_RESULTS).replace('{{id}}', Config.exercise.id), { + await axios.post(DojoBackendHelper.getApiUrl(ApiRoute.EXERCISE_RESULTS, { exerciseIdOrUrl: Config.exercise.id }), { exitCode : exitCode, commit : JSON.stringify(commit), results : JSON.stringify(results), diff --git a/ExerciseChecker/src/managers/HttpManager.ts b/ExerciseChecker/src/managers/HttpManager.ts index 0276fb89605c897804afed8a59edce7e9a62c0f7..0f25bea7c601feac50c55e8f643a39d2ff97bc72 100644 --- a/ExerciseChecker/src/managers/HttpManager.ts +++ b/ExerciseChecker/src/managers/HttpManager.ts @@ -31,9 +31,9 @@ class HttpManager { } private registerRequestInterceptor() { - axios.interceptors.request.use((config) => { + axios.interceptors.request.use(config => { if ( config.data instanceof FormData ) { - config.headers = { ...config.headers, ...(config.data as FormData).getHeaders() } as AxiosRequestHeaders; + config.headers = { ...config.headers, ...config.data.getHeaders() } as AxiosRequestHeaders; } if ( config.url && (config.url.indexOf(ClientsSharedConfig.apiURL) !== -1) ) { @@ -54,9 +54,7 @@ class HttpManager { } private registerResponseInterceptor() { - axios.interceptors.response.use((response) => { - return response; - }, (error) => { + axios.interceptors.response.use(response => response, error => { if ( error.response ) { if ( error.response.status === StatusCodes.METHOD_NOT_ALLOWED && error.response.data ) { const data: DojoBackendResponse<void> = error.response.data; diff --git a/ExerciseChecker/src/shared b/ExerciseChecker/src/shared index 89f3579ca9009f793742170928d808ab4c35d931..75fedb26c47bb6f707725307a79a45a13e62496d 160000 --- a/ExerciseChecker/src/shared +++ b/ExerciseChecker/src/shared @@ -1 +1 @@ -Subproject commit 89f3579ca9009f793742170928d808ab4c35d931 +Subproject commit 75fedb26c47bb6f707725307a79a45a13e62496d diff --git a/ExerciseChecker/src/sharedByClients b/ExerciseChecker/src/sharedByClients index 098c6d20f6ed84240c086b979b56afd598fdfea4..c4efbcfb2a50e7108e101fb673e84f87fad8e246 160000 --- a/ExerciseChecker/src/sharedByClients +++ b/ExerciseChecker/src/sharedByClients @@ -1 +1 @@ -Subproject commit 098c6d20f6ed84240c086b979b56afd598fdfea4 +Subproject commit c4efbcfb2a50e7108e101fb673e84f87fad8e246 diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000000000000000000000000000000000000..14ae2bb967a9a70467d0d12778e1c02c499181dd --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,2 @@ +sonar.projectKey=DojoExerciseChecker +sonar.qualitygate.wait=true