From 0eff7852945eb7deb263dbe5a35ed40705c54569 Mon Sep 17 00:00:00 2001 From: Leela Prasad <47483946+leelaprasadv@users.noreply.github.com> Date: Sun, 1 Dec 2024 23:57:02 +0530 Subject: [PATCH] feat: testbeats config generation command --- .gitignore | 3 +- package-lock.json | 633 +++++++++++++++++++++++- package.json | 1 + src/cli.js | 43 +- src/commands/generate-config.command.js | 361 ++++++++++++++ src/index.js | 9 +- 6 files changed, 1021 insertions(+), 29 deletions(-) create mode 100644 src/commands/generate-config.command.js diff --git a/.gitignore b/.gitignore index ac5efc0..e1deca8 100644 --- a/.gitignore +++ b/.gitignore @@ -115,4 +115,5 @@ results # ignore test/override config files override-config*.json -.testbeats \ No newline at end of file +.testbeats +.testbeats.json \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7a61937..80d3eb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "2.1.6", "license": "ISC", "dependencies": { + "@inquirer/prompts": "^7.1.0", "async-retry": "^1.3.3", "dotenv": "^16.4.5", "form-data-lite": "^1.0.3", @@ -109,6 +110,257 @@ "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", "dev": true }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.2.tgz", + "integrity": "sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.1.0.tgz", + "integrity": "sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.2.tgz", + "integrity": "sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.0.2.tgz", + "integrity": "sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.2.tgz", + "integrity": "sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.2.tgz", + "integrity": "sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.2.tgz", + "integrity": "sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.2.tgz", + "integrity": "sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.2.tgz", + "integrity": "sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -309,6 +561,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "peer": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "dev": true, @@ -329,9 +590,22 @@ "node": ">=6" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -339,7 +613,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -607,6 +880,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "node_modules/charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -647,6 +925,14 @@ "dev": true, "license": "ISC" }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "engines": { + "node": ">= 12" + } + }, "node_modules/cliui": { "version": "7.0.4", "dev": true, @@ -659,7 +945,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -670,7 +955,6 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -832,7 +1116,6 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, "license": "MIT" }, "node_modules/end-of-stream": { @@ -871,6 +1154,19 @@ "node": ">=6" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-glob": { "version": "3.2.12", "dev": true, @@ -1163,6 +1459,17 @@ "node": ">= 6" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "dev": true, @@ -1280,7 +1587,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1733,6 +2039,14 @@ "node": ">= 6" } }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -1794,6 +2108,14 @@ "klona": "^2.0.4" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/p-is-promise": { "version": "3.0.0", "dev": true, @@ -2317,7 +2639,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -2401,7 +2722,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -2429,7 +2749,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2593,6 +2912,17 @@ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "dev": true, @@ -2648,6 +2978,23 @@ "node": "*" } }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "peer": true + }, "node_modules/universalify": { "version": "2.0.0", "dev": true, @@ -2811,6 +3158,18 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -2862,6 +3221,164 @@ "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", "dev": true }, + "@inquirer/checkbox": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.2.tgz", + "integrity": "sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + } + }, + "@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + } + }, + "@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "requires": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "dependencies": { + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "@inquirer/editor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.1.0.tgz", + "integrity": "sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "external-editor": "^3.1.0" + } + }, + "@inquirer/expand": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.2.tgz", + "integrity": "sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + } + }, + "@inquirer/figures": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==" + }, + "@inquirer/input": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.0.2.tgz", + "integrity": "sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + } + }, + "@inquirer/number": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.2.tgz", + "integrity": "sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + } + }, + "@inquirer/password": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.2.tgz", + "integrity": "sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2" + } + }, + "@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "requires": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + } + }, + "@inquirer/rawlist": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.2.tgz", + "integrity": "sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + } + }, + "@inquirer/search": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.2.tgz", + "integrity": "sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + } + }, + "@inquirer/select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.2.tgz", + "integrity": "sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==", + "requires": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + } + }, + "@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "requires": {} + }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2997,6 +3514,15 @@ "version": "2.0.4", "dev": true }, + "@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "peer": true, + "requires": { + "undici-types": "~6.20.0" + } + }, "agent-base": { "version": "6.0.2", "dev": true, @@ -3010,13 +3536,19 @@ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, "ansi-regex": { - "version": "5.0.1", - "dev": true + "version": "5.0.1" }, "ansi-styles": { "version": "4.3.0", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -3185,6 +3717,11 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -3209,6 +3746,11 @@ "version": "1.1.4", "dev": true }, + "cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==" + }, "cliui": { "version": "7.0.4", "dev": true, @@ -3220,14 +3762,12 @@ }, "color-convert": { "version": "2.0.1", - "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.4", - "dev": true + "version": "1.1.4" }, "combined-stream": { "version": "1.0.8", @@ -3329,8 +3869,7 @@ "dev": true }, "emoji-regex": { - "version": "8.0.0", - "dev": true + "version": "8.0.0" }, "end-of-stream": { "version": "1.4.4", @@ -3353,6 +3892,16 @@ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "dev": true }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "fast-glob": { "version": "3.2.12", "dev": true, @@ -3538,6 +4087,14 @@ "debug": "4" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.2.1", "dev": true @@ -3608,8 +4165,7 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true + "version": "3.0.0" }, "is-glob": { "version": "4.0.3", @@ -3902,6 +4458,11 @@ } } }, + "mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==" + }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -3942,6 +4503,11 @@ "klona": "^2.0.4" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, "p-is-promise": { "version": "3.0.0", "dev": true @@ -4281,8 +4847,7 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" }, "simple-concat": { "version": "1.0.1", @@ -4327,7 +4892,6 @@ }, "string-width": { "version": "4.2.3", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4347,7 +4911,6 @@ }, "strip-ansi": { "version": "6.0.1", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -4467,6 +5030,14 @@ } } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "2.0.0", "dev": true @@ -4503,6 +5074,17 @@ "safe-buffer": "^5.0.1" } }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "peer": true + }, "universalify": { "version": "2.0.0", "dev": true @@ -4611,6 +5193,11 @@ "yocto-queue": { "version": "0.1.0", "dev": true + }, + "yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==" } } } diff --git a/package.json b/package.json index e67e758..7bf75ac 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ }, "homepage": "https://testbeats.com", "dependencies": { + "@inquirer/prompts": "^7.1.0", "async-retry": "^1.3.3", "dotenv": "^16.4.5", "form-data-lite": "^1.0.3", diff --git a/src/cli.js b/src/cli.js index e43c37b..0da7ea1 100755 --- a/src/cli.js +++ b/src/cli.js @@ -2,16 +2,32 @@ require('dotenv').config(); const sade = require('sade'); +const { ExitPromptError } = require('@inquirer/prompts'); const prog = sade('testbeats'); const { PublishCommand } = require('./commands/publish.command'); +const { GenerateConfigCommand } = require('./commands/generate-config.command'); const logger = require('./utils/logger'); const pkg = require('../package.json'); +const banner = ` + _____ _ ___ _ +(_ _) ( )_ ( _'\\ ( )_ + | | __ ___ | ,_)| (_) ) __ _ _ | ,_) ___ + | | /'__'\\/',__)| | | _ <' /'__'\\ /'_' )| | /',__) + | |( ___/\\__, \\| |_ | (_) )( ___/( (_| || |_ \\__, \\ + (_)'\\____)(____/'\\__)(____/''\\____)'\\__,_)'\\__)(____/ + + v${pkg.version} + Config Generation [BETA] +` + prog .version(pkg.version) - .option('-c, --config', 'path to config file') .option('-l, --logLevel', 'Log Level', "INFO") + +prog.command('publish') + .option('-c, --config', 'path to config file') .option('--api-key', 'api key') .option('--project', 'project name') .option('--run', 'run name') @@ -27,9 +43,7 @@ prog .option('--xunit', 'xunit xml path') .option('--mstest', 'mstest xml path') .option('-ci-info', 'ci info extension') - .option('-chart-test-summary', 'chart test summary extension'); - -prog.command('publish') + .option('-chart-test-summary', 'chart test summary extension') .action(async (opts) => { try { logger.setLevel(opts.logLevel); @@ -41,4 +55,25 @@ prog.command('publish') } }); +prog.command('init') + .describe('Generate a TestBeats configuration file') + .example('init') + .action(async (opts) => { + console.log(banner) + try { + logger.setLevel(opts.logLevel); + logger.info(`🚧 Config generation is still in BETA mode, please report any issues at ${pkg.bugs.url}\n`); + const generate_command = new GenerateConfigCommand(); + await generate_command.execute(); + } catch (error) { + if (error.name === 'ExitPromptError') { + logger.info('😿 Configuration generation was canceled by the user.'); + } else { + logger.debug(error.stack) + throw new Error(`❌ Error in generating configuration file: ${error.message}`) + } + process.exit(1); + } + }); + prog.parse(process.argv); diff --git a/src/commands/generate-config.command.js b/src/commands/generate-config.command.js new file mode 100644 index 0000000..149fe23 --- /dev/null +++ b/src/commands/generate-config.command.js @@ -0,0 +1,361 @@ +const { input, confirm, checkbox } = require('@inquirer/prompts'); +const fs = require('fs/promises'); +const logger = require('../utils/logger'); + + +class GenerateConfigCommand { + /** + * TODO: [BETA / Experimental Mode] + * Generates initial TestBests configuration file + * + */ + constructor() { + this.answers = []; + this.config = [] + } + + async execute() { + this.answers = await this.#promptQuestions(); + this.config = this.#generateConfigObject(this.answers); + + // Write config to file + try { + await fs.writeFile(this.answers.configPath, JSON.stringify(this.config, null, 2)); + logger.info(`✅ Configuration file successfully generated: ${this.answers.configPath}`); + } catch (error) { + throw new Error(`Error: ${error.message}`) + } + } + + async #promptQuestions() { + // Prompt user input questions for the configuration + let targets = []; + let webhookEnvVars = []; + let title = ''; + let testResults = []; + const testBeatsConfig = {}; + const targetExtensions = {}; + const globalExtensions = []; + const extensionsList = [ + { name: 'Quick Chart Test Summary', value: 'quick-chart-test-summary' }, + { name: 'CI Information', value: 'ci-info' }, + { name: 'Hyperlinks', value: 'hyperlinks' }, + { name: 'Mentions', value: 'mentions' }, + { name: 'Report Portal Analysis', value: 'report-portal-analysis' }, + { name: 'Report Portal History', value: 'report-portal-history' }, + { name: 'Percy Analysis', value: 'percy-analysis' }, + { name: 'Metadata', value: 'metadata' }, + { name: 'AI Failure Summary', value: 'ai-failure-summary' }, + { name: 'Smart Analysis', value: 'smart-analysis' }, + { name: 'Error Clusters', value: 'error-clusters' } + ]; + + // Get initial answers + const configPath = await input({ + message: 'Enter path for configuration file :', + default: '.testbeats.json' + }); + + const includeResults = await confirm({ + message: 'Do you want to configure test results?', + default: true + }); + + if (includeResults) { + testResults = await checkbox({ + message: 'Select test result types to include:', + choices: [ + { name: 'Mocha', value: 'mocha' , checked: true}, + { name: 'JUnit', value: 'junit' }, + { name: 'TestNG', value: 'testng' }, + { name: 'Cucumber', value: 'cucumber' }, + { name: 'NUnit', value: 'nunit' }, + { name: 'xUnit', value: 'xunit' }, + { name: 'MSTest', value: 'mstest' } + ], + required: true + }); + } + + const includeTargets = await confirm({ + message: 'Do you want to configure notification targets (slack, teams, chat etc)?', + default: true + }); + + if (includeTargets) { + targets = await checkbox({ + message: 'Select notification targets:', + choices: [ + { name: 'Slack', value: 'slack' }, + { name: 'Microsoft Teams', value: 'teams' }, + { name: 'Google Chat', value: 'chat' } + ], + required: true + }); + + if (targets.length > 0) { + + title = await input({ + message: 'Enter notification title (optional):' + }); + + // For each target, ask about target-specific extensions + for (const target of targets) { + webhookEnvVars[target] = await input({ + message: `Enter environment variable name for ${target} webhook URL:`, + default: `${target.toUpperCase()}_WEBHOOK_URL` + }); + + const useExtensions = await confirm({ + message: `Do you want to configure extensions for ${target}?`, + default: true + }); + + if (useExtensions) { + targetExtensions[`${target}Extensions`] = true; + targetExtensions[`${target}ExtensionsList`] = await checkbox({ + message: `Select extensions for ${target}:`, + choices: extensionsList, + required: true + }); + + // Configure extension-specific inputs + for (const ext of targetExtensions[`${target}ExtensionsList`]) { + targetExtensions[`${target}${ext}Config`] = await this.#promptExtensionConfig(ext, target); + } + } + } + } + } + + const includeGlobalExtensions = await confirm({ + message: 'Do you want to configure global extensions?', + default: false + }); + + if (includeGlobalExtensions) { + const globalExtensionsSelected = await checkbox({ + message: 'Select global extensions to enable:', + choices: extensionsList + }); + // Configure extension-specific inputs + for (const ext of globalExtensionsSelected) { + const extDetails = await this.#promptExtensionConfig(ext, null); + globalExtensions.push(extDetails); + } + } + + // Handle result paths + const resultPaths = {}; + if (testResults.length > 0) { + for (const resultType of testResults) { + resultPaths[`${resultType}Path`] = await input({ + message: `Enter file path for ${resultType} results (.json, .xml etc):`, + default: "", + }); + } + } + + // TestBeats configuration + const includeTestBeats = await confirm({ + message: 'Do you want to configure TestBeats API key (optional)?', + default: false + }); + + if (includeTestBeats) { + const apiKey = await input({ + message: 'Enter environment variable name for API key (optional):', + default: '{TEST_RESULTS_API_KEY}' + }); + + const project = await input({ + message: 'Enter project name (optional):' + }); + + testBeatsConfig.push({ + api_key: apiKey, + project + }); + } + + // Combine all answers + return { + configPath, + ...testBeatsConfig, + includeResults, + testResults, + includeTargets, + targets, + webhookEnvVars, + title, + includeGlobalExtensions, + globalExtensions, + ...targetExtensions, + ...resultPaths + }; + } + + async #promptExtensionConfig(extension, target) { + const config = { + name: extension + }; + + switch (extension) { + case 'hyperlinks': + const links = []; + const addLink = await confirm({ + message: 'Do you want to add a hyperlink?', + default: true + }); + + while (addLink) { + links.push({ + text: await input({ message: 'Enter link text:' }), + url: await input({ message: 'Enter link URL:' }), + condition: await input({ + message: 'Enter condition (PASS, FAIL, or PASS_OR_FAIL):', + default: 'PASS_OR_FAIL' + }) + }); + + const addAnother = await confirm({ + message: 'Add another link?', + default: false + }); + if (!addAnother) break; + } + config.inputs = { links }; + break; + + case 'mentions': + const users = []; + const addUser = await confirm({ + message: 'Do you want to add user mentions?', + default: true + }); + + while (addUser) { + const user = {}; + user.name = await input({ message: 'Enter user name:' }); + + if (target === 'teams') { + user.teams_upn = await input({ message: 'Enter Teams UPN (user principal name):' }); + } else if (target === 'slack') { + user.slack_uid = await input({ message: 'Enter Slack user ID:' }); + } else if (target === 'chat') { + user.chat_uid = await input({ message: 'Enter Google Chat user ID:' }); + } + + users.push(user); + + const addAnother = await confirm({ + message: 'Add another user?', + default: false + }); + if (!addAnother) break; + } + config.inputs = { users }; + break; + + case 'metadata': + const data = []; + const addMetadata = await confirm({ + message: 'Do you want to add metadata?', + default: true + }); + + while (addMetadata) { + data.push({ + key: await input({ message: 'Enter metadata key:' }), + value: await input({ message: 'Enter metadata value:' }), + condition: await input({ + message: 'Enter condition (PASS, FAIL, or PASS_OR_FAIL):', + default: 'PASS_OR_FAIL' + }) + }); + + const addAnother = await confirm({ + message: 'Add another metadata item?', + default: false + }); + if (!addAnother) break; + } + config.inputs = { data }; + break; + + // Add default configuration for other extensions + default: + config.inputs = { + title: '', + separator: target === 'slack' ? false : true + }; + } + + return config; + } + + #generateConfigObject() { + const config = {}; + + // Add API key (required) + config.api_key = this.answers.apiKey; + + // Add optional fields only if they have values + if (this.answers.project?.trim()) { + config.project = this.answers.project.trim(); + } + + // Add test results if included + if (this.answers.includeResults && Array.isArray(this.answers.testResults) && this.answers.testResults.length > 0) { + // Check if result paths exist before mapping + const validResults = this.answers.testResults.filter(type => this.answers[`${type}Path`]); + if (validResults.length > 0) { + config.results = validResults.map(type => ({ + files: [this.answers[`${type}Path`]], + type + })); + } + } + + // Add global extensions if included + if (this.answers.includeGlobalExtensions && this.answers.globalExtensions?.length > 0) { + config.extensions = this.answers.globalExtensions.map(name => ({ name })); + } + + // Add targets if included + if (this.answers.includeTargets && this.answers.targets?.length > 0) { + config.targets = this.answers.targets.map(target => { + const targetConfig = { + name: target, + inputs: { + url: `{${this.answers.webhookEnvVars[target]}}`, + publish: 'test-summary' + } + }; + + if (this.answers.title?.trim()) { + targetConfig.inputs.title = this.answers.title.trim(); + } + + // Add target-specific extensions with their configurations + if (this.answers[`${target}Extensions`] && this.answers[`${target}ExtensionsList`]?.length > 0) { + targetConfig.extensions = this.answers[`${target}ExtensionsList`].map(ext => { + return this.answers[`${target}${ext}Config`]; + }); + } + + return targetConfig; + }); + } + + // Sort keys alphabetically + return Object.keys(config).sort() + .reduce((sortedConfig, key) => { + sortedConfig[key] = config[key]; + return sortedConfig; + }, {}); + } + +} + +module.exports = { GenerateConfigCommand }; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 17967c3..5bbb818 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,22 @@ const { PublishCommand } = require('./commands/publish.command'); +const { GenerateConfigCommand } = require('./commands/generate-config.command'); function publish(options) { const publish_command = new PublishCommand(options); return publish_command.publish(); } +function generateConfig() { + const generate_command = new GenerateConfigCommand(); + return generate_command.execute(); +} + function defineConfig(config) { - return config + return config; } module.exports = { publish, + generateConfig, defineConfig } \ No newline at end of file