diff --git a/package-lock.json b/package-lock.json index d5ab63dd42b2da33332f54534f9966f7f1abcabc..d96f072047706163159ef826143b5ee939c4416d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,14 @@ "version": "1.0.0-BETA", "license": "EPL-2.0", "dependencies": { - "@babel/eslint-parser": "^7.17.0", - "@gitbeaker/node": "35.6.0", + "@gitbeaker/core": "^35.6.0", + "@gitbeaker/node": "github:autumnfound/gitbeaker#malowe/master/2483", "@octokit/plugin-retry": "^3.0.3", "@octokit/plugin-throttling": "^3.3.0", "@octokit/rest": "^18.0.3", - "axios": "^0.21.1", + "@types/node": "^17.0.32", + "@types/yargs": "^17.0.10", + "axios": "^0.21.4", "flat-cache": "^2.0.1", "nodemailer": "^6.5.0", "openid-client": "^3.15.6", @@ -25,18 +27,24 @@ "yargs": "^13.3.0" }, "devDependencies": { + "@babel/eslint-parser": "^7.17.0", + "@types/parse-link-header": "^2.0.0", + "@types/simple-oauth2": "^4.1.1", + "@types/uuid": "^8.3.4", "chai": "^4.2.0", "eslint": "^7.5.0", "eslint-config-strongloop": "^2.1.0", "faker": "^5.5.3", "mocha": "^7.0.1", - "sinon": "^10.0.0" + "sinon": "^10.0.0", + "typescript": "^4.6.4" } }, "node_modules/@ampproject/remapping": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.0" @@ -49,6 +57,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, "peer": true, "dependencies": { "@babel/highlight": "^7.16.7" @@ -61,6 +70,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "dev": true, "peer": true, "engines": { "node": ">=6.9.0" @@ -70,6 +80,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", + "dev": true, "peer": true, "dependencies": { "@ampproject/remapping": "^2.1.0", @@ -100,6 +111,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "peer": true, "bin": { "semver": "bin/semver.js" @@ -109,6 +121,7 @@ "version": "7.17.0", "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "dev": true, "dependencies": { "eslint-scope": "^5.1.1", "eslint-visitor-keys": "^2.1.0", @@ -126,6 +139,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, "engines": { "node": ">=10" } @@ -134,6 +148,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -142,6 +157,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.17.0", @@ -156,6 +172,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "dev": true, "peer": true, "dependencies": { "@babel/compat-data": "^7.17.7", @@ -174,6 +191,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "peer": true, "bin": { "semver": "bin/semver.js" @@ -183,6 +201,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.16.7" @@ -195,6 +214,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "dev": true, "peer": true, "dependencies": { "@babel/template": "^7.16.7", @@ -208,6 +228,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.16.7" @@ -220,6 +241,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.16.7" @@ -232,6 +254,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "dev": true, "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.16.7", @@ -251,6 +274,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.17.0" @@ -263,6 +287,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, "peer": true, "dependencies": { "@babel/types": "^7.16.7" @@ -275,6 +300,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -283,6 +309,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, "peer": true, "engines": { "node": ">=6.9.0" @@ -292,6 +319,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, "peer": true, "dependencies": { "@babel/template": "^7.16.7", @@ -306,6 +334,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", @@ -319,6 +348,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==", + "dev": true, "peer": true, "bin": { "parser": "bin/babel-parser.js" @@ -331,6 +361,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, "peer": true, "dependencies": { "@babel/code-frame": "^7.16.7", @@ -345,6 +376,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", + "dev": true, "peer": true, "dependencies": { "@babel/code-frame": "^7.16.7", @@ -366,6 +398,7 @@ "version": "7.17.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", @@ -387,6 +420,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -406,6 +440,7 @@ "version": "13.13.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -433,19 +468,11 @@ } }, "node_modules/@gitbeaker/node": { - "version": "35.6.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/node/-/node-35.6.0.tgz", - "integrity": "sha512-cJBxZdh8elrdLA8V4yEdISGinycESNaIO8JEIyAhemsovqv29XCJ40A9TBA4RlKNjkKVyVSN23BvcZimgqZSzA==", - "dependencies": { - "@gitbeaker/core": "^35.6.0", - "@gitbeaker/requester-utils": "^35.6.0", - "delay": "^5.0.0", - "got": "11.8.3", - "xcase": "^2.0.1" - }, - "engines": { - "node": ">=14.2.0" - } + "name": "gitbeaker", + "resolved": "git+ssh://git@github.com/autumnfound/gitbeaker.git#7192ef52f04c96100e0e38b6dfc327c609213b51", + "workspaces": [ + "packages/*" + ] }, "node_modules/@gitbeaker/requester-utils": { "version": "35.6.0", @@ -500,6 +527,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -512,12 +540,14 @@ "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true }, "node_modules/@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true, "peer": true, "engines": { "node": ">=6.0.0" @@ -527,12 +557,14 @@ "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true, "peer": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -706,17 +738,6 @@ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -752,28 +773,6 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, "node_modules/@types/got": { "version": "9.6.12", "resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.12.tgz", @@ -797,46 +796,52 @@ "node": ">= 0.12" } }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "node_modules/@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.32.tgz", + "integrity": "sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==" }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" - } + "node_modules/@types/parse-link-header": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-link-header/-/parse-link-header-2.0.0.tgz", + "integrity": "sha512-KbqcQLdRaawDOfXnwqr6nvhe1MV+Uv/Ww+ViSx7Ujgw9X5qCgObLP52B1ZSJqZD8FK1y/4o+bJQTUrZOynegcg==", + "dev": true + }, + "node_modules/@types/simple-oauth2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/simple-oauth2/-/simple-oauth2-4.1.1.tgz", + "integrity": "sha512-8jqhfUFb0FoCl2Od4czprB7ubM8/Fuo3tg+vQZ00zYtPcNLogGyDgm2DVfVvD3NYXK7AscKOXSaW33NHUWpNBg==", + "dev": true }, "node_modules/@types/tough-cookie": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -848,6 +853,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -868,6 +874,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -883,6 +890,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, "engines": { "node": ">=6" } @@ -891,6 +899,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -923,6 +932,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -940,6 +950,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1028,6 +1039,7 @@ "version": "4.20.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1053,31 +1065,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -1094,6 +1081,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { "node": ">=6" } @@ -1110,6 +1098,7 @@ "version": "1.0.30001327", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001327.tgz", "integrity": "sha512-1/Cg4jlD9qjZzhbzkzEaAC2JHsP0WrOc8Rd/3a3LuajGzGWR/hD7TVyvq99VqmTy99eVh8Zkmdq213OgvgXx7w==", + "dev": true, "funding": [ { "type": "opencollective", @@ -1144,6 +1133,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1310,18 +1300,6 @@ "node": ">= 0.8" } }, - "node_modules/compress-brotli": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", - "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", - "dependencies": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" - }, - "engines": { - "node": ">= 12" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1331,6 +1309,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, "peer": true, "dependencies": { "safe-buffer": "~5.1.1" @@ -1340,12 +1319,14 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, "peer": true }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1387,31 +1368,6 @@ "node": ">=0.10" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -1427,15 +1383,8 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/define-properties": { "version": "1.1.3", @@ -1449,17 +1398,6 @@ "node": ">= 0.4" } }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1496,6 +1434,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -1512,12 +1451,14 @@ "version": "1.4.106", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.106.tgz", "integrity": "sha512-ZYfpVLULm67K7CaaGP7DmjyeMY4naxsbTy+syVVxT6QHI1Ww8XbJjmr9fDckrhq44WzCrcC5kH3zGpdusxwwqg==", + "dev": true, "peer": true }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/enabled": { "version": "1.0.2", @@ -1539,6 +1480,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, "dependencies": { "ansi-colors": "^4.1.1" }, @@ -1624,6 +1566,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "peer": true, "engines": { "node": ">=6" @@ -1633,6 +1576,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -1641,6 +1585,7 @@ "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -1703,6 +1648,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -1715,6 +1661,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -1729,6 +1676,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, "engines": { "node": ">=4" } @@ -1737,6 +1685,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "dependencies": { "@babel/highlight": "^7.10.4" } @@ -1745,6 +1694,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1759,6 +1709,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1774,6 +1725,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1784,12 +1736,14 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "engines": { "node": ">=10" }, @@ -1801,6 +1755,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, "engines": { "node": ">=10" } @@ -1809,6 +1764,7 @@ "version": "13.13.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -1823,6 +1779,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1831,6 +1788,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -1842,6 +1800,7 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -1855,6 +1814,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -1867,6 +1827,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -1878,6 +1839,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -1886,6 +1848,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -1897,6 +1860,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -1905,6 +1869,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, "engines": { "node": ">=4.0" } @@ -1913,6 +1878,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1926,17 +1892,20 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "node_modules/fecha": { "version": "4.2.1", @@ -1947,6 +1916,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -1958,6 +1928,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -1969,12 +1940,14 @@ "node_modules/file-entry-cache/node_modules/flatted": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true }, "node_modules/file-entry-cache/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -2106,12 +2079,14 @@ "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "peer": true, "engines": { "node": ">=6.9.0" @@ -2197,6 +2172,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2208,35 +2184,12 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, "peer": true, "engines": { "node": ">=4" } }, - "node_modules/got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -2270,6 +2223,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, "engines": { "node": ">=4" } @@ -2314,22 +2268,11 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, "engines": { "node": ">= 4" } @@ -2338,6 +2281,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2353,6 +2297,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -2492,6 +2437,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2500,6 +2446,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -2508,6 +2455,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2646,7 +2594,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "node_modules/joi": { "version": "17.6.0", @@ -2677,12 +2626,14 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2695,6 +2646,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, "peer": true, "bin": { "jsesc": "bin/jsesc" @@ -2703,25 +2655,23 @@ "node": ">=4" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, "peer": true, "bin": { "json5": "lib/cli.js" @@ -2736,15 +2686,6 @@ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, - "node_modules/keyv": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", - "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", - "dependencies": { - "compress-brotli": "^1.3.6", - "json-buffer": "3.0.1" - } - }, "node_modules/kuler": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", @@ -2757,6 +2698,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -2796,12 +2738,14 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true }, "node_modules/log-symbols": { "version": "3.0.0", @@ -3059,7 +3003,8 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "node_modules/nise": { "version": "4.1.0", @@ -3116,6 +3061,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true, "peer": true }, "node_modules/nodemailer": { @@ -3135,17 +3081,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/object-hash": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", @@ -3387,6 +3322,7 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -3474,6 +3410,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -3509,6 +3446,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -3535,6 +3473,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, "peer": true }, "node_modules/picomatch": { @@ -3553,6 +3492,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -3569,6 +3509,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -3586,6 +3527,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, "engines": { "node": ">=6" } @@ -3621,17 +3563,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -3661,6 +3592,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, "engines": { "node": ">=8" }, @@ -3680,6 +3612,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3689,27 +3622,15 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "engines": { "node": ">=4" } }, - "node_modules/responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dependencies": { - "lowercase-keys": "^2.0.0" - } - }, "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -3752,6 +3673,7 @@ "version": "7.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "dev": true, "dependencies": { "lru-cache": "^7.4.0" }, @@ -3766,6 +3688,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz", "integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==", + "dev": true, "engines": { "node": ">=12" } @@ -3779,6 +3702,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3790,6 +3714,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -3878,6 +3803,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -3894,6 +3820,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3908,6 +3835,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -3918,12 +3846,14 @@ "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -3940,7 +3870,8 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "node_modules/stack-trace": { "version": "0.0.10", @@ -3970,6 +3901,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4009,6 +3941,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4020,6 +3953,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "engines": { "node": ">=8" }, @@ -4031,6 +3965,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -4042,6 +3977,7 @@ "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -4057,6 +3993,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -4071,7 +4008,8 @@ "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/text-hex": { "version": "1.0.0", @@ -4081,12 +4019,14 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, "peer": true, "engines": { "node": ">=4" @@ -4126,6 +4066,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -4146,6 +4087,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -4153,6 +4095,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -4177,6 +4132,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -4208,7 +4164,8 @@ "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "node_modules/webidl-conversions": { "version": "3.0.1", @@ -4228,6 +4185,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -4347,6 +4305,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -4539,6 +4498,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, "peer": true, "requires": { "@jridgewell/trace-mapping": "^0.3.0" @@ -4548,6 +4508,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, "peer": true, "requires": { "@babel/highlight": "^7.16.7" @@ -4557,12 +4518,14 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "dev": true, "peer": true }, "@babel/core": { "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.9.tgz", "integrity": "sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw==", + "dev": true, "peer": true, "requires": { "@ampproject/remapping": "^2.1.0", @@ -4586,6 +4549,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "peer": true } } @@ -4594,6 +4558,7 @@ "version": "7.17.0", "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "dev": true, "requires": { "eslint-scope": "^5.1.1", "eslint-visitor-keys": "^2.1.0", @@ -4603,12 +4568,14 @@ "eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -4616,6 +4583,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.9.tgz", "integrity": "sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.17.0", @@ -4627,6 +4595,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "dev": true, "peer": true, "requires": { "@babel/compat-data": "^7.17.7", @@ -4639,6 +4608,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "peer": true } } @@ -4647,6 +4617,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.16.7" @@ -4656,6 +4627,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "dev": true, "peer": true, "requires": { "@babel/template": "^7.16.7", @@ -4666,6 +4638,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.16.7" @@ -4675,6 +4648,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.16.7" @@ -4684,6 +4658,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "dev": true, "peer": true, "requires": { "@babel/helper-environment-visitor": "^7.16.7", @@ -4700,6 +4675,7 @@ "version": "7.17.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.17.0" @@ -4709,6 +4685,7 @@ "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, "peer": true, "requires": { "@babel/types": "^7.16.7" @@ -4717,18 +4694,21 @@ "@babel/helper-validator-identifier": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, "peer": true }, "@babel/helpers": { "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, "peer": true, "requires": { "@babel/template": "^7.16.7", @@ -4740,6 +4720,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", @@ -4750,12 +4731,14 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz", "integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==", + "dev": true, "peer": true }, "@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, "peer": true, "requires": { "@babel/code-frame": "^7.16.7", @@ -4767,6 +4750,7 @@ "version": "7.17.9", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.9.tgz", "integrity": "sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==", + "dev": true, "peer": true, "requires": { "@babel/code-frame": "^7.16.7", @@ -4785,6 +4769,7 @@ "version": "7.17.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, "peer": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -4800,6 +4785,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -4816,6 +4802,7 @@ "version": "13.13.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "dev": true, "requires": { "type-fest": "^0.20.2" } @@ -4836,16 +4823,8 @@ } }, "@gitbeaker/node": { - "version": "35.6.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/node/-/node-35.6.0.tgz", - "integrity": "sha512-cJBxZdh8elrdLA8V4yEdISGinycESNaIO8JEIyAhemsovqv29XCJ40A9TBA4RlKNjkKVyVSN23BvcZimgqZSzA==", - "requires": { - "@gitbeaker/core": "^35.6.0", - "@gitbeaker/requester-utils": "^35.6.0", - "delay": "^5.0.0", - "got": "11.8.3", - "xcase": "^2.0.1" - } + "version": "git+ssh://git@github.com/autumnfound/gitbeaker.git#7192ef52f04c96100e0e38b6dfc327c609213b51", + "from": "@gitbeaker/node@github:autumnfound/gitbeaker#malowe/master/2483" }, "@gitbeaker/requester-utils": { "version": "35.6.0", @@ -4897,6 +4876,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -4906,24 +4886,28 @@ "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true }, "@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true, "peer": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true, "peer": true }, "@jridgewell/trace-mapping": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, "peer": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", @@ -5083,11 +5067,6 @@ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" - }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -5123,25 +5102,6 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, "@types/got": { "version": "9.6.12", "resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.12.tgz", @@ -5164,51 +5124,58 @@ } } }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "requires": { - "@types/node": "*" - } - }, "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.32.tgz", + "integrity": "sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw==" }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } + "@types/parse-link-header": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-link-header/-/parse-link-header-2.0.0.tgz", + "integrity": "sha512-KbqcQLdRaawDOfXnwqr6nvhe1MV+Uv/Ww+ViSx7Ujgw9X5qCgObLP52B1ZSJqZD8FK1y/4o+bJQTUrZOynegcg==", + "dev": true + }, + "@types/simple-oauth2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/simple-oauth2/-/simple-oauth2-4.1.1.tgz", + "integrity": "sha512-8jqhfUFb0FoCl2Od4czprB7ubM8/Fuo3tg+vQZ00zYtPcNLogGyDgm2DVfVvD3NYXK7AscKOXSaW33NHUWpNBg==", + "dev": true }, "@types/tough-cookie": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "requires": {} }, "aggregate-error": { @@ -5224,6 +5191,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5234,12 +5202,14 @@ "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, "ansi-styles": { "version": "3.2.1", @@ -5263,6 +5233,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -5276,7 +5247,8 @@ "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true }, "async": { "version": "2.6.3", @@ -5353,6 +5325,7 @@ "version": "4.20.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "dev": true, "peer": true, "requires": { "caniuse-lite": "^1.0.30001317", @@ -5362,25 +5335,6 @@ "picocolors": "^1.0.0" } }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -5393,7 +5347,8 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, "camelcase": { "version": "5.3.1", @@ -5404,6 +5359,7 @@ "version": "1.0.30001327", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001327.tgz", "integrity": "sha512-1/Cg4jlD9qjZzhbzkzEaAC2JHsP0WrOc8Rd/3a3LuajGzGWR/hD7TVyvq99VqmTy99eVh8Zkmdq213OgvgXx7w==", + "dev": true, "peer": true }, "chai": { @@ -5425,6 +5381,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5564,15 +5521,6 @@ "delayed-stream": "~1.0.0" } }, - "compress-brotli": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", - "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", - "requires": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5582,6 +5530,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, "peer": true, "requires": { "safe-buffer": "~5.1.1" @@ -5591,6 +5540,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, "peer": true } } @@ -5599,6 +5549,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5623,21 +5574,6 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - } - } - }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -5650,12 +5586,8 @@ "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "define-properties": { "version": "1.1.3", @@ -5666,11 +5598,6 @@ "object-keys": "^1.0.12" } }, - "delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5701,6 +5628,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "requires": { "esutils": "^2.0.2" } @@ -5714,12 +5642,14 @@ "version": "1.4.106", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.106.tgz", "integrity": "sha512-ZYfpVLULm67K7CaaGP7DmjyeMY4naxsbTy+syVVxT6QHI1Ww8XbJjmr9fDckrhq44WzCrcC5kH3zGpdusxwwqg==", + "dev": true, "peer": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "enabled": { "version": "1.0.2", @@ -5741,6 +5671,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, "requires": { "ansi-colors": "^4.1.1" } @@ -5807,17 +5738,20 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "peer": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -5865,6 +5799,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -5873,6 +5808,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -5881,6 +5817,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5890,6 +5827,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -5897,22 +5835,26 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true }, "globals": { "version": "13.13.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "dev": true, "requires": { "type-fest": "^0.20.2" } @@ -5920,12 +5862,14 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -5942,6 +5886,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -5951,6 +5896,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -5958,12 +5904,14 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, "requires": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -5973,12 +5921,14 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, "requires": { "estraverse": "^5.1.0" }, @@ -5986,7 +5936,8 @@ "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true } } }, @@ -5994,6 +5945,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "requires": { "estraverse": "^5.2.0" }, @@ -6001,19 +5953,22 @@ "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "faker": { "version": "5.5.3", @@ -6024,17 +5979,20 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "fecha": { "version": "4.2.1", @@ -6045,6 +6003,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "requires": { "flat-cache": "^3.0.4" }, @@ -6053,6 +6012,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -6061,12 +6021,14 @@ "flatted": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -6154,12 +6116,14 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "peer": true }, "get-caller-file": { @@ -6218,6 +6182,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -6226,26 +6191,9 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, "peer": true }, - "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -6269,7 +6217,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "has-symbols": { "version": "1.0.3", @@ -6296,24 +6245,17 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6322,7 +6264,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "indent-string": { "version": "4.0.0", @@ -6411,17 +6354,20 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -6512,7 +6458,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "joi": { "version": "17.6.0", @@ -6537,12 +6484,14 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -6552,27 +6501,26 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, "peer": true }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, "peer": true }, "just-extend": { @@ -6581,15 +6529,6 @@ "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, - "keyv": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", - "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", - "requires": { - "compress-brotli": "^1.3.6", - "json-buffer": "3.0.1" - } - }, "kuler": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", @@ -6602,6 +6541,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6635,12 +6575,14 @@ "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true }, "log-symbols": { "version": "3.0.0", @@ -6840,7 +6782,8 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "nise": { "version": "4.1.0", @@ -6885,6 +6828,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true, "peer": true }, "nodemailer": { @@ -6898,11 +6842,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" - }, "object-hash": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", @@ -7093,6 +7032,7 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -7150,6 +7090,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "requires": { "callsites": "^3.0.0" } @@ -7175,7 +7116,8 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, "path-to-regexp": { "version": "1.8.0", @@ -7196,6 +7138,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, "peer": true }, "picomatch": { @@ -7207,7 +7150,8 @@ "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true }, "prepend-http": { "version": "2.0.0", @@ -7217,7 +7161,8 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "pump": { "version": "3.0.0", @@ -7231,7 +7176,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "qs": { "version": "6.10.3", @@ -7252,11 +7198,6 @@ "strict-uri-encode": "^2.0.0" } }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -7279,7 +7220,8 @@ "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true }, "require-directory": { "version": "2.1.1", @@ -7289,30 +7231,19 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "requires": { - "lowercase-keys": "^2.0.0" - } + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true }, "rimraf": { "version": "2.6.3", @@ -7336,6 +7267,7 @@ "version": "7.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.6.tgz", "integrity": "sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==", + "dev": true, "requires": { "lru-cache": "^7.4.0" }, @@ -7343,7 +7275,8 @@ "lru-cache": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.8.1.tgz", - "integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==" + "integrity": "sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg==", + "dev": true } } }, @@ -7356,6 +7289,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -7363,7 +7297,8 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true }, "side-channel": { "version": "1.0.4", @@ -7435,6 +7370,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -7445,6 +7381,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -7453,6 +7390,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -7460,7 +7398,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, @@ -7468,6 +7407,7 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, "peer": true }, "split-on-first": { @@ -7478,7 +7418,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "stack-trace": { "version": "0.0.10", @@ -7502,6 +7443,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7532,6 +7474,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -7539,12 +7482,14 @@ "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -7553,6 +7498,7 @@ "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, "requires": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -7565,6 +7511,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7575,7 +7522,8 @@ "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true } } }, @@ -7587,12 +7535,14 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, "peer": true }, "to-readable-stream": { @@ -7623,6 +7573,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "requires": { "prelude-ls": "^1.2.1" } @@ -7636,7 +7587,14 @@ "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typescript": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true }, "unbox-primitive": { "version": "1.0.1", @@ -7659,6 +7617,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -7684,7 +7643,8 @@ "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "webidl-conversions": { "version": "3.0.1", @@ -7704,6 +7664,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -7797,7 +7758,8 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true }, "wrap-ansi": { "version": "5.1.0", diff --git a/package.json b/package.json index 028f0752b1aeb53f549086b5b183bec235ad3b6c..c844ae5a81a8e93acc85ded8f48fee2544c7cdee 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,13 @@ }, "homepage": "https://github.com/eclipsefdn/eclipsefdn-github-sync#readme", "dependencies": { - "@gitbeaker/node": "35.6.0", + "@gitbeaker/core": "^35.6.0", + "@gitbeaker/node": "github:autumnfound/gitbeaker#malowe/master/2483", "@octokit/plugin-retry": "^3.0.3", "@octokit/plugin-throttling": "^3.3.0", "@octokit/rest": "^18.0.3", + "@types/node": "^17.0.32", + "@types/yargs": "^17.0.10", "axios": "^0.21.4", "flat-cache": "^2.0.1", "nodemailer": "^6.5.0", @@ -36,11 +39,15 @@ }, "devDependencies": { "@babel/eslint-parser": "^7.17.0", + "@types/parse-link-header": "^2.0.0", + "@types/simple-oauth2": "^4.1.1", + "@types/uuid": "^8.3.4", "chai": "^4.2.0", "eslint": "^7.5.0", "eslint-config-strongloop": "^2.1.0", "faker": "^5.5.3", "mocha": "^7.0.1", - "sinon": "^10.0.0" + "sinon": "^10.0.0", + "typescript": "^4.6.4" } } diff --git a/src/EclipseAPI.js b/src/EclipseAPI.js index 114f1f2fa508cf1e413e0daf6ea75ce2082b318b..695738bae3da991f9ff7804ef471af237fb87a44 100644 --- a/src/EclipseAPI.js +++ b/src/EclipseAPI.js @@ -183,7 +183,7 @@ module.exports = class EclipseAPI { }, }) .then(result => result.data) - .catch(err => this.#logger.error(err)); + .catch(err => this.#logger.error(`${err}`)); } async eclipseBots() { @@ -192,7 +192,7 @@ module.exports = class EclipseAPI { } var botsRaw = await axios.get('https://api.eclipse.org/bots') .then(result => result.data) - .catch(err => this.#logger.error(err)); + .catch(err => this.#logger.error(`${err}`)); if (botsRaw === undefined || botsRaw.length <= 0) { this.#logger.error('Could not retrieve bots from API'); process.exit(EXIT_ERROR_STATE); diff --git a/src/GitWrapper.js b/src/GitWrapper.js index edc75e4a8891fcec46460c2c8617853d128e619a..3711228b4cf6b1daf9e17de111292fe6c34e2159 100644 --- a/src/GitWrapper.js +++ b/src/GitWrapper.js @@ -993,5 +993,5 @@ function logError(err, root) { log.error(`${err.errors[i].message}`); } } - log.error(err); + log.error(`${err}`); } diff --git a/src/GitlabSync.js b/src/GitlabSync.js index 12e59fbd797c1fe9b741a33d0d5908012dab1902..f506791d436d2ccda90a0dba2c98b21bb26106cf 100644 --- a/src/GitlabSync.js +++ b/src/GitlabSync.js @@ -6,16 +6,19 @@ var argv = require('yargs') alias: 'dryrun', description: 'Runs script as dry run, not writing any changes to API', boolean: true, + default: false, }) .option('D', { alias: 'devMode', description: 'Runs script in dev mode, which returns API data that does not impact production organizations/teams.', boolean: true, + default: false, }) .option('V', { alias: 'verbose', description: 'Sets the script to run in verbose mode', boolean: true, + default: false, }) .option('H', { alias: 'host', @@ -39,529 +42,21 @@ var argv = require('yargs') .alias('h', 'help') .version('0.1') .alias('v', 'version') - .epilog('Copyright 2019 Eclipse Foundation inc.') - .argv; - -const ADMIN_PERMISSIONS_LEVEL = 50; - -const uuid = require('uuid'); -const { SecretReader, getBaseConfig } = require('./SecretReader.js'); - -const { Gitlab } = require('@gitbeaker/node'); -const EclipseAPI = require('./EclipseAPI.js'); - -const { getLogger } = require('./logger.js'); -let logger = getLogger(argv.V ? 'debug' : 'info', 'main'); - -var api; -var eApi; -var bots; - -var namedGroups = {}; -var namedProjects = {}; -var namedUsers = {}; -var gMems = {}; - -_prepareSecret(); - -/** - * Retrieves secret API token from system, and then starts the script via _init - * - * @returns - */ -function _prepareSecret() { - // retrieve the secret API token - var accessToken, eclipseToken; - // retrieve the secret API file root if set - var settings = getBaseConfig(); - if (argv.s !== undefined) { - settings.root = argv.s; - } - var reader = new SecretReader(settings); - var data = reader.readSecret('access-token'); - if (data !== null) { - accessToken = data.trim(); - // retrieve the Eclipse API token (needed for emails) - data = reader.readSecret('eclipse-oauth-config'); - if (data !== null) { - eclipseToken = data.trim(); - run(accessToken, eclipseToken); - } else { - logger.error('Could not find the Eclipse OAuth config, exiting'); - } - } else { - logger.error('Could not find the GitLab access token, exiting'); - } -} - -async function run(secret, eclipseToken) { - api = new Gitlab({ - host: argv.H, - token: secret, - }); - eApi = new EclipseAPI(JSON.parse(eclipseToken)); - eApi.testMode = argv.D; - - // get raw project data and post process to add additional context - var data = await eApi.eclipseAPI(); - data = eApi.postprocessEclipseData(data, 'gitlab_repos'); - - // get the bots for the projects - var rawBots = await eApi.eclipseBots(); - bots = eApi.processBots(rawBots, 'gitlab.eclipse.org'); - - // get all current groups for the instance - var groups = await api.Groups.all(); - var projects = await api.Projects.all(); - var users = await api.Users.all(); - - // map the groups/projects/users to their name - for (var groupIdx in groups) { - namedGroups[sanitizeGroupName(groups[groupIdx].path)] = groups[groupIdx]; - } - for (var projectIdx in projects) { - namedProjects[getCompositeProjectKey(projects[projectIdx].name, projects[projectIdx].namespace.id)] = projects[projectIdx]; - } - for (var userIdx in users) { - namedUsers[users[userIdx].username] = users[userIdx]; - } - - // fetch org group from results, create if missing - logger.info('Starting sync'); - var g = await getGroup('Eclipse', 'eclipse', undefined); - if (g === undefined) { - if (argv.d) { - logger.error('Unable to start sync of GitLab content. Base Eclipse group could not be found and dryrun is set'); - } else { - logger.error('Unable to start sync of GitLab content. Base Eclipse group could not be created'); - } - return; - } - - for (projectIdx in data) { - var project = data[projectIdx]; - if (argv.P !== undefined && project.short_project_id !== argv.P) { - logger.info(`Project target set ('${argv.P}'). Skipping non-matching project ID ${project.short_project_id}`); - continue; - } - logger.info(`Processing '${project.short_project_id}'`); - // fetch project group from results, create if missing - var projGroup = await getGroup(project.name, project.short_project_id, g); - if (projGroup === undefined) { - if (argv.d) { - logger.warn(`Unable to continue processing project with ID '${project.short_project_id}'.` - + ' Group does not exist and dryrun has been set.'); - } else { - logger.error(`Unable to continue processing project with ID '${project.short_project_id}'.` - + ' Group does not exist and could not be created.'); - } - continue; - } - - // get the list of users to be added for current project - var userList = getUserList(project); - // for each user, get their gitlab user and add to the project group - var usernames = Object.keys(userList); - for (var usernameIdx in usernames) { - var uname = usernames[usernameIdx]; - var user = await getUser(uname, userList[uname].url); - if (user === undefined) { - logger.verbose(`Could not retrieve user for UID '${uname}', skipping`); - continue; - } - - await addUserToGroup(user, projGroup, userList[uname].access_level); - } - - // remove users that don't match the expected users - await removeAdditionalUsers(userList, projGroup, project.short_project_id); - - // for each of the repos in the Eclipse project, ensure there is a GL - // project - for (var repoIdx in project.gitlab_repos) { - var extRepo = project.gitlab_repos[repoIdx]; - if (extRepo === undefined || extRepo.repo === undefined || extRepo.org === undefined) { - continue; - } - if (argv.V) { - logger.debug(`Processing repo '${extRepo.url}'`); - } - // retrieving current project - var p = await getProject(extRepo.repo, projGroup); - if (p !== undefined) { - await cleanUpProjectUsers(p, project.short_project_id); - } - } - } -} - -async function removeAdditionalUsers(expectedUsers, group, projectID) { - if (argv.V) { - logger.debug(`GitlabSync:removeAdditionalUsers(expectedUsers = ${expectedUsers}, group = ${group}, projectID = ${projectID})`); - } - // get the current list of users for the group - var members = await getGroupMembers(group); - if (members === undefined) { - logger.warn(`Could not find any group members for ID ${group.id}'. Skipping user removal check`); - return; - } - - // check that each of the users in the group match whats expected - var expectedUsernames = Object.keys(expectedUsers); - for (var memberIdx in members) { - var member = members[memberIdx]; - // check access and ensure user isn't an owner - logger.verbose(`Checking user '${member.username}' access to group '${group.name}'`); - if (member.access_level !== ADMIN_PERMISSIONS_LEVEL && expectedUsernames.indexOf(member.username) === -1 - && !isBot(member.username, projectID)) { - if (argv.d) { - logger.info(`Dryrun flag active, would have removed user '${member.username}' from group '${group.name}'`); - continue; - } - logger.info(`Removing user '${member.username}' from group '${group.name}'`); - try { - await api.GroupMembers.remove(group.id, member.id); - } catch (err) { - if (argv.V) { - logger.error(err); - } - logger.warn(`Error while removing user '${member.username}' from group '${group.name}'`); - } - } - } -} - -async function cleanUpProjectUsers(project, projectID) { - if (argv.V) { - logger.debug(`GitlabSync:cleanUpProjectUsers(project = ${project.id})`); - } - var projectMembers = await api.ProjectMembers.all(project.id, { includeInherited: false }); - for (var idx in projectMembers) { - let member = projectMembers[idx]; - // skip bot user or admin users - if (isBot(member.username, projectID) || member.access_level === ADMIN_PERMISSIONS_LEVEL) { - continue; - } - if (argv.d) { - logger.debug(`Dryrun flag active, would have removed user '${member.username}' from project '${project.name}'(${project.id})`); - continue; - } - logger.info(`Removing user '${member.username}' from project '${project.name}'(${project.id})`); - try { - await api.ProjectMembers.remove(project.id, member.id); - } catch (err) { - if (argv.V) { - logger.error(err); - } - logger.error(`Error while removing user '${member.username}' from project '${project.name}'(${project.id})`); - } - } -} - -function isBot(uname, projectID) { - var botList = bots[projectID]; - // check if the current user is in the current key-values list - return botList !== undefined && botList.indexOf(uname) !== -1; -} - - -/** API FUNCTIONS */ - - -async function addUserToGroup(user, group, perms) { - if (argv.V) { - logger.debug(`GitlabSync:addUserToGroup(user = ${user}, group = ${group}, perms = ${perms})`); - } - // get the members for the current group - var members = await getGroupMembers(group); - if (members === undefined) { - logger.warn(`Could not find any references to group with ID ${group.id}`); - return; - } - - // check if user is already present - for (var memberIdx in members) { - if (members[memberIdx].username === user.username) { - logger.verbose(`User '${user.username}' is already a member of ${group.name}`); - if (members[memberIdx].access_level !== perms) { - // skip if dryrun - if (argv.d) { - logger.info(`Dryrun flag active, would have updated user '${members[memberIdx].username}' in group '${group.name}'`); - return; - } - - // modify user, catching errors - logger.info(`Fixing permission level for user '${user.username}' in group '${group.name}'`); - try { - var updatedMember = await api.GroupMembers.edit(group.id, user.id, perms); - // update inner array - members[memberIdx] = updatedMember; - gMems[group.id] = members; - } catch (err) { - if (argv.V) { - logger.error(err); - } - logger.warn(`Error while fixing permission level for user '${user.username}' in group '${group.name}'`); - return; - } - } - // return a copy of the updated user - return JSON.parse(JSON.stringify(members[memberIdx])); - } - } - // check if dry run before updating - if (argv.d) { - logger.info(`Dryrun flag active, would have added user '${user.username}' to group '${group.name}' with access level '${perms}'`); - return; - } - - logger.info(`Adding '${user.username}' to '${group.name}' group`); - try { - // add member to group, track, and return a copy - var newMember = await api.GroupMembers.add(group.id, user.id, perms); - members.push(newMember); - gMems[group.id] = members; - - // return a copy - return JSON.parse(JSON.stringify(newMember)); - } catch (err) { - if (argv.V) { - logger.error(err); - } - logger.warn(`Error while adding '${user.username}' to '${group.name}' group`); - } -} - -async function getProject(name, parent) { - if (argv.V) { - logger.debug(`GitlabSync:getProject(name = ${name}, parent = ${parent})`); - } - if (name.trim() === '.github') { - logger.warn("Skipping project with name '.github'. No current equivalent to default repository in GitLab."); - return; - } - - var p = namedProjects[getCompositeProjectKey(name, parent.id)]; - if (p === undefined) { - logger.verbose(`Creating new project with name '${name}'`); - // create the request options for the new user - var opts = { - path: name, - visibility: 'public', - }; - if (parent !== undefined) { - opts.namespace_id = parent.id; - } - // check if dry run before creating new project - if (argv.d) { - logger.info(`Dryrun flag active, would have created new project '${name}' with options ${JSON.stringify(opts)}`); - return; - } - - // create the new project, and track it - if (argv.V) { - logger.debug(`Creating project with options: ${JSON.stringify(opts)}`); - } - try { - p = await api.Projects.create(opts); - } catch (err) { - if (argv.V) { - logger.error(err); - } - } - if (p === null || p instanceof Array) { - logger.warn(`Error while creating project '${name}'`); - return undefined; - } - if (argv.V) { - logger.debug(`Created project: ${JSON.stringify(p)}`); - } - // set it back - namedProjects[getCompositeProjectKey(name, parent.id)] = p; - } - return p; -} - -async function getGroup(name, path, parent, visibility = 'public') { - if (argv.V) { - logger.debug(`GitlabSync:getGroup(name = ${name}, path = ${path}, parent = ${parent}, visibility = ${visibility})`); - } - var g = namedGroups[sanitizeGroupName(path)]; - if (g === undefined) { - logger.verbose(`Creating new group with name '${name}'`); - var opts = { - project_creation_level: 'maintainer', - visibility: visibility, - request_access_enabled: false, - }; - if (parent !== undefined && parent.id !== undefined) { - opts.parent_id = parent.id; - } - // check if dry run before creating group - if (argv.d) { - logger.info(`Dryrun flag active, would have created new group '${name}' with options ${JSON.stringify(opts)}`); - return; - } - - // if verbose is set display user opts - if (argv.V) { - logger.debug(`Creating group with options: ${JSON.stringify(opts)}`); - } - try { - g = await api.Groups.create(name, sanitizeGroupName(path), opts); - } catch (err) { - if (argv.V) { - logger.error(err); - } - } - if (g === null || g instanceof Array) { - logger.warn(`Error while creating group '${name}'`); - return undefined; - } - if (argv.V) { - logger.debug(`Created group: ${JSON.stringify(g)}`); - } - // set it back - namedGroups[sanitizeGroupName(path)] = g; - } - return g; -} - -async function getUser(uname, url) { - if (argv.V) { - logger.debug(`GitlabSync:getUser(uname = ${uname}, url = ${url})`); - } - if (url === undefined || url === '') { - logger.error(`Cannot fetch user information for user '${uname}' with no set URL`); - return; - } - - var u = namedUsers[uname]; - if (u === undefined) { - if (argv.d) { - logger.info(`Dryrun is enabled. Would have created user ${uname} but was skipped`); - return; - } - - // retrieve user data - var data = await eApi.eclipseUser(uname); - if (data === undefined) { - logger.error(`Cannot create linked user account for '${uname}', no external data found`); - return; - } - logger.verbose(`Creating new user with name '${uname}'`); - var opts = { - username: uname, - password: uuid.v4(), - force_random_password: true, - name: `${data.first_name} ${data.last_name}`, - email: data.mail, - extern_uid: data.uid, - provider: argv.p, - skip_confirmation: true, - }; - // check if dry run before creating new user - if (argv.d) { - logger.info(`Dryrun flag active, would have created new user '${uname}' with options ${JSON.stringify(opts)}`); - return; - } - - // if verbose, display information being used to generate user - if (argv.V) { - // copy the object and redact the password for security - var optLog = JSON.parse(JSON.stringify(opts)); - optLog.password = 'redacted'; - logger.debug(`Creating user with options: ${JSON.stringify(optLog)}`); - } - try { - u = await api.Users.create(opts); - } catch (err) { - if (argv.V) { - logger.error(err); - } - } - if (u === null) { - logger.warn(`Error while creating user '${uname}'`); - return undefined; - } - // set it back - namedUsers[uname] = u; - } - return u; -} - -async function getGroupMembers(group) { - if (argv.V) { - logger.debug(`GitlabSync:getGroupMembers(group = ${group})`); - } - var members = gMems[group.id]; - if (members === undefined) { - try { - members = await api.GroupMembers.all(group.id); - } catch (err) { - if (argv.V) { - logger.error(err); - } - } - if (members === null) { - logger.warn(`Unable to find group members for group with ID '${group.id}'`); - return; - } - gMems[group.id] = members; - } - return members; -} - - -/** HELPERS */ - - -function getUserList(project) { - if (argv.V) { - logger.debug(`GitlabSync:getUserList(project = ${JSON.stringify(project)})`); - } - var l = {}; - // add the contributors with reporter access - for (var contributorIdx in project.contributors) { - l[project.contributors[contributorIdx].username] = { - url: project.contributors[contributorIdx].url, - access_level: 20, - }; - } - // add the committers with developer access - for (var committerIdx in project.committers) { - l[project.committers[committerIdx].username] = { - url: project.committers[committerIdx].url, - access_level: 30, - }; - } - // add the project leads not yet tracked with reporter access - for (var plIdx in project.project_leads) { - l[project.project_leads[plIdx].username] = { - url: project.project_leads[plIdx].url, - access_level: 40, - }; - } - // add the bots with developer access - var botList = bots[project.project_id]; - for (var botIdx in botList) { - l[botList[botIdx]] = { - access_level: 30, - }; - } - return l; -} - -function sanitizeGroupName(pid) { - if (argv.V) { - logger.debug(`GitlabSync:sanitizeGroupName(pid = ${pid})`); - } - if (pid !== undefined) { - return pid.toLowerCase().replace(/[^\s\da-zA-Z-.]/g, '-'); - } - return ''; -} - -function getCompositeProjectKey(projectName, parentId) { - return projectName + ':' + parentId; + .epilog('Copyright 2019 Eclipse Foundation inc.').argv; + +import { GitlabSyncRunner } from './gl/GitlabSyncRunner'; + +const runner = new GitlabSyncRunner({ + devMode: argv.D, + host: argv.host, + dryRun: argv.dryRun, + provider: argv.provider, + verbose: argv.verbose, + project: argv.project, + secretLocation: argv.secretLocation, +}); +run(); + +async function run() { + await runner.run(); } diff --git a/src/SecretReader.js b/src/SecretReader.js index 5dc08a756b2da596f6908a7bebe40165191d197c..6bb7579f0f0c237b17aa7e6cd43c9d1929169075 100644 --- a/src/SecretReader.js +++ b/src/SecretReader.js @@ -66,7 +66,7 @@ class SecretReader { try { var data = fs.readFileSync(filepath, { encoding: encoding }); if (data !== undefined && (data = data.trim()) !== '') { - return data; + return data.toString(); } } catch (err) { if (err.code === 'ENOENT') { diff --git a/src/eclipse/EclipseAPI.ts b/src/eclipse/EclipseAPI.ts new file mode 100644 index 0000000000000000000000000000000000000000..908398e5430ecf9c02ee02fefa1e2ae0f19e4b9f --- /dev/null +++ b/src/eclipse/EclipseAPI.ts @@ -0,0 +1,288 @@ +import axios, { AxiosRequestConfig } from 'axios'; +import parse from 'parse-link-header'; +import { AccessToken, ClientCredentials } from 'simple-oauth2'; +import { Logger } from 'winston'; +import { BotDefinition, EclipseProject, Repo, EclipseUser } from '../interfaces/EclipseApi'; +import { getLogger } from '../helpers/logger'; + +const HOUR_IN_SECONDS = 3600; +const EXIT_ERROR_STATE = 1; + +/** + * Root config used for interacting with the Eclipse API. OAuth is + */ +export interface EclipseApiConfig { + oauth: EclipseApiOAuthConfig; + verbose?: boolean; + testMode?: boolean; +} + +/** + * Configuration interface for oauth/security binding. + */ +export interface EclipseApiOAuthConfig { + client_secret: string; + client_id: string; + endpoint: string; + redirect: string; + scope: string; + timeout?: number; +} + +export class EclipseAPI { + config: EclipseApiConfig; + client?: ClientCredentials; + accessToken: AccessToken | null = null; + logger: Logger; + + constructor(config: EclipseApiConfig) { + this.config = config; + // generate creds if auth is set + if (this.config.oauth !== null) { + this.client = new ClientCredentials({ + client: { + id: this.config.oauth.client_id, + secret: this.config.oauth.client_secret, + }, + auth: { + tokenHost: this.config.oauth.endpoint, + tokenPath: '/oauth2/token', + authorizePath: '/oauth2/authorize', + }, + }); + } + this.logger = getLogger('info', 'EclipseAPI'); + } + + /** + * Retrieves Eclipse projects with the given query string parameters, with an option to paginate and return all results. + * + * @param queryStringParams optional query string to use when querying projects + * @param paginate Optional, false if only 1 page should be queried, true otherwise. + * @returns promise to return either a page or all pages of eclipse projects given a query string. + */ + async eclipseAPI(queryStringParams = '', paginate = true): Promise<EclipseProject[]> { + if (this.config.verbose) { + this.logger.debug(`EclipseAPI:eclipseAPI(queryStringParams = ${queryStringParams}, paginate = ${paginate})`); + } + // if test mode is enabled, return data that doesn't impact production + if (this.config.testMode) { + return testProjects; + } + + let hasMore = true; + let result = []; + let data = []; + // add timestamp to url to avoid browser caching + var url = 'https://projects.eclipse.org/api/projects' + queryStringParams; + // loop through all available users, and add them to a list to be returned + do { + this.logger.silly('Loading next page...'); + // get the current page of results, incrementing page count after call + result = await axios + .get(url) + .then(r => { + // return the data to the user + let links = parse(r.headers.link); + // check if we should continue processing + if (links === null || links!.self.url === links!.last.url) { + hasMore = false; + } else { + url = links!.next.url; + } + return r.data; + }) + .catch(err => { + this.logger.error(`Error while retrieving results from Eclipse Projects API (${url}): ${err}`); + }); + + // collect the results + if (result != null && result.length > 0) { + for (var i = 0; i < result.length; i++) { + data.push(result[i]); + } + } + } while (hasMore && paginate); + return data; + } + + /** + * Retrieves an eclipse foundation user using the given username, returning null if the user cannot be found. + * + * @param username the username to retrieve data for + * @returns the Eclipse Foundation user account data, enhanced with sensitive information if oauth is configured. Returns null if user cannot be found. + */ + async eclipseUser(username: string): Promise<EclipseUser | null> { + if (this.config.verbose) { + this.logger.debug(`EclipseAPI:eclipseUser(username = ${username})`); + } + + return await axios + .get('https://api.eclipse.org/account/profile/' + username, await this.getAuthenticationHeaders()) + .then(result => result.data) + .catch(err => { + this.logger.error(`${err}`); + return null; + }); + } + + async eclipseBots(): Promise<BotDefinition[]> { + if (this.config.verbose) { + this.logger.debug('EclipseAPI:eclipseBots()'); + } + var botsRaw = await axios + .get('https://api.eclipse.org/bots') + .then(result => result.data) + .catch(err => this.logger.error(`${err}`)); + if (botsRaw === undefined || botsRaw.length <= 0) { + this.logger.error('Could not retrieve bots from API'); + process.exit(EXIT_ERROR_STATE); + } + return botsRaw; + } + + /** + * Maps bot users by listing bots per project. + * + * @param botsRaw the raw bot definition list to convert to a project bot mapping. + * @param site the site targeted for bots to limit results + * @returns a mapping of project to configured bot usernames. + */ + processBots(botsRaw: BotDefinition[], site: string = 'github.com'): Record<string, string[]> { + if (this.config.verbose) { + this.logger.debug(`EclipseAPI:processBots(botsRaw = ${JSON.stringify(botsRaw)}, site = ${site})`); + } + let rgx = new RegExp(`^${site}.*`); + var botMap: Record<string, string[]> = {}; + for (var botIdx in botsRaw) { + let bot = botsRaw[botIdx]; + // get the list of bots for project if already created + var projBots = botMap[bot.projectId]; + if (projBots === undefined) { + projBots = []; + } + // get usernames for site + sub resource bots + let botKeys = Object.keys(bot); + for (let idx in botKeys) { + let key = botKeys[idx]; + // if there is a match (either direct or sub resource match) push the bot name to the list + let match = key.match(rgx); + if (match) { + projBots.push(bot[key].username); + } + } + // dont add empty arrays to output + if (projBots.length === 0) { + continue; + } + botMap[bot.projectId] = projBots; + } + return botMap; + } + + /** + * If OAuth has been configured, then retrieves access token and sets into request config to use for calls to Eclipse API endpoints. + * This call is needed to be able to retrieve sensitive user profile information. + * + * @returns request configs including authentication headers if auth is configured, or empty config otherwise. + */ + async getAuthenticationHeaders(): Promise<AxiosRequestConfig> { + let token = await this._getAccessToken(); + if (token === null) { + this.logger.info('Authentication token cannot be retrieved, information returned mey be limited'); + return {}; + } else { + return { + headers: { + Authorization: `Bearer ${token}`, + }, + }; + } + } + + /** + * Retrieves an oauth token and caches it internally to authenticate requests to the Eclipse API. This by default caches + * for an hour to reduce turn around on the authentication API. + * + * @returns the access token if found, otherwise null. + */ + async _getAccessToken(): Promise<string | null> { + // check that we have auth configs and that current token is expired before attempting retrieval + if ( + this.config.oauth !== null && + this.client !== null && + (this.accessToken === null || this.accessToken!.expired(this.config.oauth.timeout ?? HOUR_IN_SECONDS)) + ) { + // wrap retrieval in try-catch to give more information to the logs on error. + try { + this.accessToken = await this.client!.getToken({ + scope: this.config.oauth.scope, + }); + } catch (error) { + this.logger.error(`${error}`); + process.exit(EXIT_ERROR_STATE); + } + return this.accessToken.token.access_token; + } + return null; + } +} + +const testProjects: EclipseProject[] = [ + { + project_id: 'spider.pig', + url: '', + website_repo: [], + website_url: '', + short_project_id: 'spider.pig', + name: 'Spider pig does what a spider pig does', + summary: 'Can he fly? No, hes a pig. Look out, here comes the spider pig', + logo: '', + tags: ['simpsons', 'doh', 'spider pig'], + gerrit_repos: [ + { + url: 'https://github.com/eclipsefdn-webdev/spider-pig', + }, + ], + github_repos: [ + { + url: 'https://github.com/eclipsefdn-webdev/spider-pig', + }, + ], + gitlab_repos: [ + { + url: 'https://gitlab.eclipse.org/eclipsefdn/webdev/gitlab-testing', + }, + ], + contributors: [], + committers: [ + { + username: 'malowe', + url: 'https://api.eclipse.org/account/profile/malowe', + }, + { + username: 'epoirier', + url: 'https://api.eclipse.org/account/profile/epoirier', + }, + ], + project_leads: [ + { + username: 'malowe', + url: 'https://api.eclipse.org/account/profile/malowe', + }, + { + username: 'cguindon', + url: 'https://api.eclipse.org/account/profile/cguindon', + }, + ], + working_groups: [ + { + name: 'Cloud Development Tools', + id: 'cloud-development-tools', + }, + ], + spec_project_working_group: [], + state: 'Regular', + releases: [], + }, +]; diff --git a/src/gl/AxiosRequester.ts b/src/gl/AxiosRequester.ts new file mode 100644 index 0000000000000000000000000000000000000000..ccff72bacf5235af5d92811a4fd2dbf58f9e94f6 --- /dev/null +++ b/src/gl/AxiosRequester.ts @@ -0,0 +1,21 @@ +import {RequesterType} from '@gitbeaker/requester-utils'; +import axios from 'axios'; + +export class AxiosRequester implements RequesterType { + get(endpoint: string, options?: Record<string, unknown>): Promise<any> { + throw new Error('Method not implemented.'); + } + post(endpoint: string, options?: Record<string, unknown>): Promise<any> { + throw new Error('Method not implemented.'); + } + put(endpoint: string, options?: Record<string, unknown>): Promise<any> { + throw new Error('Method not implemented.'); + } + delete(endpoint: string, options?: Record<string, unknown>): Promise<any> { + throw new Error('Method not implemented.'); + } + stream?(endpoint: string, options?: Record<string, unknown>): NodeJS.ReadableStream { + throw new Error('Method not implemented.'); + } + +} \ No newline at end of file diff --git a/src/gl/GitlabSync.ts b/src/gl/GitlabSync.ts new file mode 100644 index 0000000000000000000000000000000000000000..9596a57205745d726c9fbcfb20de28e2f5aee5db --- /dev/null +++ b/src/gl/GitlabSync.ts @@ -0,0 +1,68 @@ +// set up yargs command line parsing + +import { GitlabSyncRunner } from './GitlabSyncRunner'; +import yargs from 'yargs'; +let args = yargs(process.argv) + .usage('Usage: $0 [options]') + .example('$0', '') + .option('d', { + alias: 'dryrun', + description: 'Runs script as dry run, not writing any changes to API', + boolean: true, + default: false, + }) + .option('D', { + alias: 'devMode', + description: 'Runs script in dev mode, which returns API data that does not impact production organizations/teams.', + boolean: true, + default: false, + }) + .option('V', { + alias: 'verbose', + description: 'Sets the script to run in verbose mode', + boolean: true, + default: false, + }) + .option('H', { + alias: 'host', + description: 'GitLab host base URL', + default: 'http://gitlab.eclipse.org/', + string: true, + }) + .option('p', { + alias: 'provider', + description: 'The OAuth provider name set in GitLab', + default: 'oauth2_generic', + string: true, + }) + .option('P', { + alias: 'project', + description: 'The short project ID of the target for the current sync run', + string: true, + }) + .option('s', { + alias: 'secretLocation', + description: 'The location of the access-token file containing an API access token', + string: true, + }) + .help('h') + .alias('h', 'help') + .version('0.1') + .alias('v', 'version') + .epilog('Copyright 2019 Eclipse Foundation inc.').argv; + +const runner = +run(); + +async function run() { + const argv = await args; + await new GitlabSyncRunner({ + devMode: argv.D, + host: argv.H, + dryRun: argv.d, + provider: argv.p, + verbose: argv.V, + project: argv.P, + secretLocation: argv.s, + }).run(); +} diff --git a/src/gl/GitlabSyncRunner.ts b/src/gl/GitlabSyncRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..558f5d57395f536a7b09735eaec8c9ffb9285b1f --- /dev/null +++ b/src/gl/GitlabSyncRunner.ts @@ -0,0 +1,714 @@ +import { Logger } from 'winston'; +import { AccessLevel, GroupSchema, MemberSchema, ProjectSchema, UserSchema } from '@gitbeaker/core/dist/types/types'; +import { v4 } from 'uuid'; +import { EclipseAPI, EclipseApiConfig } from '../eclipse/EclipseAPI'; +import { getLogger } from '../helpers/logger'; +import { SecretReader, getBaseConfig } from '../helpers/SecretReader'; +import { EclipseProject, EclipseUser } from '../interfaces/EclipseApi'; +import { Resources } from '@gitbeaker/core/dist/types'; + +// used to make use of default requested based on Got rather than recreating our own +import {Gitlab} from '@gitbeaker/core'; + +const ADMIN_PERMISSIONS_LEVEL = 50; + +/** + * Represents the nested group cache that can represent the relationships between groups and to simplify child lookups. + */ +interface GroupCache { + _self: GroupSchema | null; + projectTargets: string[]; + children: Record<string, GroupCache>; +} + +interface EclipseUserAccess { + url: string; + accessLevel: AccessLevel; +} + +interface GitlabSyncRunnerConfig { + host: string; + provider: string; + secretLocation?: string; + project?: string; + verbose: boolean; + devMode: boolean; + dryRun: boolean; +} + +export class GitlabSyncRunner { + // internal state + accessToken: string = ''; + eclipseToken: string = ''; + config: GitlabSyncRunnerConfig; + logger: Logger; + + // api access + api: Resources.Gitlab; + eApi: EclipseAPI; + bots: Record<string, string[]> = {}; + + // caches to optimize calling + namedProjects: Record<string, ProjectSchema> = {}; + namedUsers: Record<string, UserSchema> = {}; + groupCache: GroupCache = { + _self: null, + children: {}, + projectTargets: [], + }; + eclipseProjectCache: Record<string, EclipseProject> = {}; + gMems: Record<number, MemberSchema[]> = {}; + + constructor( + config: GitlabSyncRunnerConfig = { + host: 'http://gitlab.eclipse.org/', + provider: 'oauth2_generic', + verbose: false, + devMode: false, + dryRun: false, + } + ) { + this.config = config; + this.logger = getLogger(this.config.verbose ? 'debug' : 'info', 'main'); + this._prepareSecret(); + + // create API instances + this.api = new Gitlab({ + host: this.config.host, + token: this.accessToken, + requesterFn: + }); + let eclipseAPIConfig: EclipseApiConfig = JSON.parse(this.eclipseToken); + eclipseAPIConfig.testMode = this.config.devMode; + eclipseAPIConfig.verbose = this.config.verbose; + this.eApi = new EclipseAPI(eclipseAPIConfig); + } + + _prepareSecret() { + // retrieve the secret API file root if set + var settings = getBaseConfig(); + if (this.config.secretLocation !== undefined) { + settings.root = this.config.secretLocation; + } + var reader = new SecretReader(settings); + var data = reader.readSecret('access-token'); + if (data !== null) { + this.accessToken = data.trim(); + // retrieve the Eclipse API token (needed for emails) + data = reader.readSecret('eclipse-oauth-config'); + if (data !== null) { + this.eclipseToken = data.trim(); + } else { + this.logger.error('Could not find the Eclipse OAuth config, exiting'); + process.exit(1); + } + } else { + this.logger.error('Could not find the GitLab access token, exiting'); + process.exit(1); + } + } + + async run() { + // prepopulate caches to optimally retrieve info used in sync ops + await this.prepareCaches(); + + // fetch org group from results, create if missing + this.logger.info('Starting sync'); + var g = await this.getGroup('eclipse'); + if (g === undefined) { + if (this.config.dryRun) { + this.logger.error('Unable to start sync of GitLab content. Base Eclipse group could not be found and dryrun is set'); + } else { + this.logger.error('Unable to start sync of GitLab content. Base Eclipse group could not be created'); + } + return; + } + + for (let projectIdx in this.eclipseProjectCache) { + var project = this.eclipseProjectCache[projectIdx]; + if (this.config.project !== undefined && project.short_project_id !== this.config.project) { + this.logger.info(`Project target set ('${this.config.project}'). Skipping non-matching project ID ${project.short_project_id}`); + continue; + } + this.logger.info(`Processing '${project.short_project_id}'`); + + // get the list of users to be added for current project + var userList = this.getUserList(project); + // for each user, get their gitlab user and add to the project group + var usernames = Object.keys(userList); + + // fetch group namespaces indicated by the project + for (let idx in project.gitlab_repos) { + let [host, namespace] = this.splitNamespaceUrl(project.gitlab_repos[idx].url); + // make sure namespace URL is valid + if (host === null || namespace === null) { + continue; + } + // check if hosts are the same ignoring case, skipping if they are different + if (host.localeCompare(this.config.host, undefined, { sensitivity: 'base' }) !== 0) { + continue; + } + + // check group cache to ensure well formed. + let namespaceGroup = this.getCachedGroup(namespace); + if (namespaceGroup === null || namespaceGroup._self === null) { + continue; + } + // update the group to add the users for the current project + for (var usernameIdx in usernames) { + var uname = usernames[usernameIdx]; + var user = await this.getUser(uname, userList[uname].url); + if (user === null) { + this.logger.verbose(`Could not retrieve user for UID '${uname}', skipping`); + continue; + } + + await this.addUserToGroup(user, namespaceGroup._self!, userList[uname].accessLevel); + // if not tracked, track current project for group for post-sync cleanup + if (namespaceGroup.projectTargets.indexOf(project.short_project_id) !== -1) { + namespaceGroup.projectTargets.push(project.short_project_id); + } + } + } + } + this.cleanupGroups(); + } + + /** + * Generates the caches needed for running the Gitlab sync process. + */ + async prepareCaches() { + // get raw project data and post process to add additional context + let data = await this.eApi.eclipseAPI(); + + // get the bots for the projects + let rawBots = await this.eApi.eclipseBots(); + this.bots = this.eApi.processBots(rawBots, 'gitlab.eclipse.org'); + + // get all current groups for the instance + var groups = await this.api.Groups.all(); + var projects = await this.api.Projects.all(); + var users = await this.api.Users.all(); + + // generates the nested cache + this.generateGroupsCache(groups); + // maps path + parent to create unique tokens to match projects + for (var projectIdx in projects) { + this.namedProjects[this.getCompositeProjectKey(projects[projectIdx].name, projects[projectIdx].namespace.id)] = projects[projectIdx]; + } + // map the users to their usernames for easy lookups + for (var userIdx in users) { + this.namedUsers[users[userIdx].username] = users[userIdx]; + } + for (let projectIdx in data) { + let p = data[projectIdx]; + this.eclipseProjectCache[p.short_project_id] = p; + } + } + + /** + * Iterate through each group, checking self and ancestor project users and comparing against the current groups users to ensure that there are no + * additional users added with permissions. + */ + cleanupGroups(currentLevel: GroupCache = this.groupCache, collectedProjects: string[] = []) { + let self = currentLevel._self; + if (self === null) { + this.logger.error('Error encountered during group cleanup process, ending early'); + return; + } + // collect and deduplicate project IDs + let projects = [...Array.from(new Set([...currentLevel.projectTargets, ...collectedProjects]))]; + // build the user mapping to pass to cleanup + let projectUsers: Record<string, EclipseUser> = {}; + for (let pidx in projects) { + projectUsers = Object.assign(projectUsers, this.getUserList(this.eclipseProjectCache[projects[pidx]])); + } + // TODO we need to be able to pass multiple projects + this.removeAdditionalUsers(projectUsers, self, ...projects); + // for each of the children, pass the collected projects forward and process + for (let cidx in currentLevel.children) { + this.cleanupGroups(currentLevel.children[cidx], projects); + } + } + + async removeAdditionalUsers(expectedUsers: Record<string, EclipseUser>, group: GroupSchema, ...projectIDs: string[]) { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:removeAdditionalUsers(expectedUsers = ${expectedUsers}, group = ${group}, projectIDs = ${projectIDs})`); + } + // get the current list of users for the group + var members = await this.getGroupMembers(group); + if (members === null) { + this.logger.warn(`Could not find any group members for ID ${group.id}'. Skipping user removal check`); + return; + } + + // check that each of the users in the group match whats expected + var expectedUsernames = Object.keys(expectedUsers); + members!.forEach(async member => { + // check access and ensure user isn't an owner + this.logger.verbose(`Checking user '${member.username}' access to group '${group.name}'`); + if ( + member.access_level !== ADMIN_PERMISSIONS_LEVEL && + expectedUsernames.indexOf(member.username) === -1 && + !this.isBot(member.username, projectIDs) + ) { + if (this.config.dryRun) { + this.logger.info(`Dryrun flag active, would have removed user '${member.username}' from group '${group.name}'`); + return; + } + this.logger.info(`Removing user '${member.username}' from group '${group.name}'`); + try { + await this.api.GroupMembers.remove(group.id, member.id); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + this.logger.warn(`Error while removing user '${member.username}' from group '${group.name}'`); + } + } + }); + } + + async cleanUpProjectUsers(project: ProjectSchema, projectID: string) { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:cleanUpProjectUsers(project = ${project.id})`); + } + var projectMembers = await this.api.ProjectMembers.all(project.id, { includeInherited: false }); + for (var idx in projectMembers) { + let member = projectMembers[idx]; + // skip bot user or admin users + if (this.isBot(member.username, [projectID]) || member.access_level === ADMIN_PERMISSIONS_LEVEL) { + continue; + } + if (this.config.dryRun) { + this.logger.debug(`Dryrun flag active, would have removed user '${member.username}' from project '${project.name}'(${project.id})`); + continue; + } + this.logger.info(`Removing user '${member.username}' from project '${project.name}'(${project.id})`); + try { + await this.api.ProjectMembers.remove(project.id, member.id); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + this.logger.error(`Error while removing user '${member.username}' from project '${project.name}'(${project.id})`); + } + } + } + + async addUserToGroup(user: UserSchema, group: GroupSchema, perms: AccessLevel): Promise<MemberSchema | null> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:addUserToGroup(user = ${user}, group = ${group}, perms = ${perms})`); + } + // get the members for the current group + var members = await this.getGroupMembers(group); + if (members === null) { + this.logger.warn(`Could not find any references to group with ID ${group.id}`); + return null; + } + + // check if user is already present + members!.forEach(async (member, idx) => { + if (member.username === user.username) { + this.logger.verbose(`User '${user.username}' is already a member of ${group.name}`); + if (member.access_level !== perms) { + // skip if dryrun + if (this.config.dryRun) { + this.logger.info(`Dryrun flag active, would have updated user '${member.username}' in group '${group.name}'`); + return null; + } + + // modify user, catching errors + this.logger.info(`Fixing permission level for user '${user.username}' in group '${group.name}'`); + try { + var updatedMember = await this.api.GroupMembers.edit(group.id, user.id, perms); + // update inner array + members![idx] = updatedMember; + this.gMems[group.id] = members!; + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + this.logger.warn(`Error while fixing permission level for user '${user.username}' in group '${group.name}'`); + return null; + } + } + // return a copy of the updated user + return members![idx]; + } + }); + // check if dry run before updating + if (this.config.dryRun) { + this.logger.info( + `Dryrun flag active, would have added user '${user.username}' to group '${group.name}' with access level '${perms}'` + ); + return null; + } + + this.logger.info(`Adding '${user.username}' to '${group.name}' group`); + try { + // add member to group, track, and return a copy + var newMember = await this.api.GroupMembers.add(group.id, user.id, perms); + members.push(newMember); + this.gMems[group.id] = members; + + // return a copy + return newMember; + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + this.logger.warn(`Error while adding '${user.username}' to '${group.name}' group`); + } + return null; + } + + async getProject(name: string, parent: GroupSchema): Promise<ProjectSchema | null> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getProject(name = ${name}, parent = ${parent})`); + } + if (name.trim() === '.github') { + this.logger.warn("Skipping project with name '.github'. No current equivalent to default repository in GitLab."); + return null; + } + + var p = this.namedProjects[this.getCompositeProjectKey(name, parent.id)]; + if (p === undefined) { + this.logger.verbose(`Creating new project with name '${name}'`); + // create the request options for the new user, any needed for addition of random properties after + let opts; + if (parent !== undefined) { + opts = { + path: name, + visibility: 'public', + namespace_id: parent.id, + }; + } else { + opts = { + path: name, + visibility: 'public', + }; + } + // check if dry run before creating new project + if (this.config.dryRun) { + this.logger.info(`Dryrun flag active, would have created new project '${name}' with options ${JSON.stringify(opts)}`); + return null; + } + + // create the new project, and track it + if (this.config.verbose) { + this.logger.debug(`Creating project with options: ${JSON.stringify(opts)}`); + } + try { + p = await this.api.Projects.create(opts); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + } + if (p === null || p instanceof Array) { + this.logger.warn(`Error while creating project '${name}'`); + return null; + } + if (this.config.verbose) { + this.logger.debug(`Created project: ${JSON.stringify(p)}`); + } + // set it back + this.namedProjects[this.getCompositeProjectKey(name, parent.id)] = p; + } + return p; + } + + async getGroup(namespace: string, visibility: string = 'public'): Promise<GroupSchema | null> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getGroup(namespace = ${namespace}, visibility = ${visibility})`); + } + let g: GroupSchema | null = null; + let cachedGroup = this.getCachedGroup(namespace); + if (cachedGroup === null) { + let parentNamespace = namespace.substring(0, namespace.lastIndexOf('/')); + let parent = this.getCachedGroup(parentNamespace); + if (parent === null || parent._self === null) { + this.logger.error(`Could not find the parent of group to fetch (${parentNamespace}), cannot fetch group ${namespace}`); + return null; + } + let groupName = namespace.substring(namespace.lastIndexOf('/'), namespace.length - 1); + this.logger.verbose(`Creating new group with name '${groupName}'`); + var opts = { + project_creation_level: 'maintainer', + visibility: visibility, + request_access_enabled: false, + parent_id: parent._self.id, + }; + // check if dry run before creating group + if (this.config.dryRun) { + this.logger.info(`Dryrun flag active, would have created new group '${groupName}' with options ${JSON.stringify(opts)}`); + return null; + } + + // if verbose is set display user opts + if (this.config.verbose) { + this.logger.debug(`Creating group with options: ${JSON.stringify(opts)}`); + } + try { + g = await this.api.Groups.create(groupName, this.sanitizeGroupName(groupName), opts); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + } + if (g === null || g instanceof Array) { + this.logger.warn(`Error while creating group '${groupName}'`); + return null; + } + if (this.config.verbose) { + this.logger.debug(`Created group: ${JSON.stringify(g)}`); + } + // set it back + this.addGroup(g); + } + return g; + } + + async getUser(uname: string, url: string): Promise<UserSchema | null> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getUser(uname = ${uname}, url = ${url})`); + } + if (url === undefined || url === '') { + this.logger.error(`Cannot fetch user information for user '${uname}' with no set URL`); + return null; + } + + var u = this.namedUsers[uname]; + if (u === undefined) { + if (this.config.dryRun) { + this.logger.info(`Dryrun is enabled. Would have created user ${uname} but was skipped`); + return null; + } + + // retrieve user data + var data = await this.eApi.eclipseUser(uname); + if (data === null) { + this.logger.error(`Cannot create linked user account for '${uname}', no external data found`); + return null; + } + this.logger.verbose(`Creating new user with name '${uname}'`); + var opts = { + username: uname, + password: v4(), + force_random_password: true, + name: `${data!.first_name} ${data!.last_name}`, + email: data!.mail, + extern_uid: data!.uid, + provider: this.config.provider, + skip_confirmation: true, + }; + // check if dry run before creating new user + if (this.config.dryRun) { + this.logger.info(`Dryrun flag active, would have created new user '${uname}' with options ${JSON.stringify(opts)}`); + return null; + } + + // if verbose, display information being used to generate user + if (this.config.verbose) { + // copy the object and redact the password for security + var optLog = JSON.parse(JSON.stringify(opts)); + optLog.password = 'redacted'; + this.logger.debug(`Creating user with options: ${JSON.stringify(optLog)}`); + } + try { + u = await this.api.Users.create(opts); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + } + if (u === null) { + this.logger.warn(`Error while creating user '${uname}'`); + return null; + } + // set it back + this.namedUsers[uname] = u; + } + return u; + } + + async getGroupMembers(group: GroupSchema): Promise<MemberSchema[] | null> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getGroupMembers(group = ${group})`); + } + var members = this.gMems[group.id]; + if (members === undefined) { + try { + members = await this.api.GroupMembers.all(group.id, { includeInherited: false }); + } catch (err) { + if (this.config.verbose) { + this.logger.error(`${err}`); + } + } + if (members === null) { + this.logger.warn(`Unable to find group members for group with ID '${group.id}'`); + return null; + } + this.gMems[group.id] = members; + } + return members; + } + + /** HELPERS */ + + generateGroupsCache(rawGroups: GroupSchema[]): void { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:generateGroupsCache(projects = count->${rawGroups.length})`); + } + // create initial cache container + this.groupCache = { + _self: null, + projectTargets: [], + children: {}, + }; + + // iterate through groups and insert into the nested cache + for (let i = 0; i < rawGroups.length; i++) { + this.addGroup(rawGroups[i], this.groupCache); + } + } + + getCachedGroup(namespace: string): GroupCache | null { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getCachedGroup(${namespace})`); + } + return this.tunnelAndRetrieve(namespace.split('/'), this.groupCache); + } + + addGroup(g: GroupSchema, parent: GroupCache = this.groupCache): GroupCache | null { + // type the namespace as it is a raw type, make sure its the type we expect + if (typeof g.path_with_namespace !== 'string') { + this.logger.error(`Could not cast namespace to string: ${g.path_with_namespace}`); + // TODO this should short circuit as not having groups is a non-starter + return null; + } + let namespace = g.path_with_namespace as string; + // split into group namespace paths (eclipse/sample/group.path into ['eclipse','sample','group.path']) + let namespaceParts = namespace.split('/'); + return this.tunnelAndInsert(namespaceParts, g, this.groupCache); + } + + tunnelAndInsert(namespaceParts: string[], g: GroupSchema, parent: GroupCache): GroupCache { + let child = parent.children[namespaceParts[0]]; + if (child === undefined) { + child = { + _self: null, + projectTargets: [], + children: {}, + }; + parent.children[namespaceParts[0]] = child; + } + // check if we should continue tunneling or insert and finish processing + if (namespaceParts.length > 1) { + return this.tunnelAndInsert(namespaceParts.slice(1, namespaceParts.length - 1), g, child); + } else { + child._self = g; + return child; + } + } + + tunnelAndRetrieve(namespaceParts: string[], parent: GroupCache): GroupCache | null { + let child = parent.children[namespaceParts[0]]; + if (child === undefined) { + return null; + } + // check if we should continue tunneling or insert and finish processing + if (namespaceParts.length > 1) { + return this.tunnelAndRetrieve(namespaceParts.slice(1, namespaceParts.length - 1), child); + } else { + return child; + } + } + + getUserList(project: EclipseProject): Record<string, EclipseUserAccess> { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:getUserList(project = ${JSON.stringify(project)})`); + } + var l: Record<string, EclipseUserAccess> = {}; + // add the contributors with reporter access + project.contributors.forEach(v => { + l[v.username] = { + url: v.url, + accessLevel: 20, + }; + }); + // add the committers with developer access + project.committers.forEach(v => { + l[v.username] = { + url: v.url, + accessLevel: 30, + }; + }); + // add the project leads not yet tracked with reporter access + project.project_leads.forEach(v => { + l[v.username] = { + url: v.url, + accessLevel: 40, + }; + }); + // add the bots with developer access + var botList = this.bots[project.project_id]; + if (botList !== undefined && botList.length === 0) { + botList.forEach(v => { + l[v] = { + url: '', + accessLevel: 30, + }; + }); + } + return l; + } + + sanitizeGroupName(pid: string): string { + if (this.config.verbose) { + this.logger.debug(`GitlabSync:sanitizeGroupName(pid = ${pid})`); + } + if (pid !== undefined) { + return pid.toLowerCase().replace(/[^\s\da-zA-Z-.]/g, '-'); + } + return ''; + } + + getCompositeProjectKey(projectName: string, parentId: number): string { + return projectName + ':' + parentId; + } + + /** + * Uses TS URL type to ingest a namespace URL and return the host and namespace for use downstream + * + * @param rawUrl the raw namespace URL to check and split. + * @returns the host first, and the path of the url second which should be the namespace. + */ + splitNamespaceUrl(rawUrl: string): [string | null, string | null] { + try { + let url = new URL(rawUrl); + return [url.host, url.pathname.substring(1, url.pathname.length - 1)]; + } catch (e) { + // cast and message with error + let message = ''; + if (typeof e === 'string') { + message = e.toUpperCase(); + } else if (e instanceof Error) { + message = e.message; + } + this.logger.error(`Could not convert URL (${rawUrl}) to namespace: ${message}`); + } + return [null, null]; + } + isBot(uname: string, projectIDs: string[]): boolean { + for (let pidx in projectIDs) { + var botList = this.bots[projectIDs[pidx]]; + // check if the current user is in the current key-values list + if (botList !== undefined && botList.indexOf(uname) !== -1) { + return true; + } + } + return false; + } +} diff --git a/src/helpers/SecretReader.ts b/src/helpers/SecretReader.ts new file mode 100644 index 0000000000000000000000000000000000000000..8739c50464217b1aae9b7272be1450895ff79f80 --- /dev/null +++ b/src/helpers/SecretReader.ts @@ -0,0 +1,88 @@ +/** *************************************************************** + Copyright (C) 2022 Eclipse Foundation, Inc. + + This program and the accompanying materials are made + available under the terms of the Eclipse Public License 2.0 + which is available at https://www.eclipse.org/legal/epl-2.0/ + + Contributors: + Martin Lowe <martin.lowe@eclipse-foundation.org> + + SPDX-License-Identifier: EPL-2.0 +******************************************************************/ + +import { getLogger, isNodeErr } from './logger'; +import fs from 'fs'; +import { Logger } from 'winston'; + +const DEFAULT_FILE_ENCODING: string = 'utf-8'; +const DEFAULT_SECRET_LOCATION: string = '/run/secrets/'; + +export interface SecretReaderConfig { + root?: string; + encoding?: string; +} + +/** + * Contains functionality for reading secret files in and returning them + * to the user. This defaults to the location used in Kubernetes containers + * for secrets. This can be configured by passing an object with updated values. + * + * Multiple secrets can be read using the same reader assuming that they are + * in the same directory. Additional secrets would need to be read in using a + * new reader in such a case. + */ +export class SecretReader { + verbose: boolean = false; + logger: Logger; + config: SecretReaderConfig; + + constructor(config: SecretReaderConfig) { + // set internally and modify for defaults + this.config = config; + // set defaults if value is missing + this.config.root = this.config.root ?? DEFAULT_SECRET_LOCATION; + this.config.encoding = this.config.encoding ?? DEFAULT_FILE_ENCODING; + // throws if there is no access + fs.accessSync(this.config.root, fs.constants.R_OK); + this.logger = getLogger('info', 'SecretReader'); + } + + readSecret(name: string, encoding: string = this.config.encoding ?? DEFAULT_FILE_ENCODING): string | null { + if (this.verbose === true) { + this.logger.debug(`SecretReader:readSecret(name = ${name}, encoding = ${encoding})`); + } + var filepath = `${this.config.root}/${name}`; + try { + var data = fs.readFileSync(filepath, { encoding: encoding as BufferEncoding }); + let out: string; + if (data !== undefined && (out = data.trim()) !== '') { + return out; + } + } catch (e) { + // cast and message with error + if (isNodeErr(e)) { + if (e.code === 'ENOENT') { + this.logger.error(`File at path ${filepath} does not exist`); + } else if (e.code === 'EACCES') { + this.logger.error(`File at path ${filepath} cannot be read`); + } else { + this.logger.error('An unknown error occurred while reading the secret'); + } + } else if (typeof e === 'string') { + this.logger.error('An unknown error occurred while reading the secret'); + } + } + return null; + } +} + +/** + * Get modifiable deep copy of the base configuration for this class. + */ +export function getBaseConfig(): SecretReaderConfig { + return { + root: DEFAULT_SECRET_LOCATION, + encoding: DEFAULT_FILE_ENCODING, + }; +} diff --git a/src/helpers/logger.ts b/src/helpers/logger.ts new file mode 100644 index 0000000000000000000000000000000000000000..39856a72992b2467b6996d036153d313ab925b8e --- /dev/null +++ b/src/helpers/logger.ts @@ -0,0 +1,42 @@ +/** ************************************************************** + Copyright (C) 2021 Eclipse Foundation, Inc. + + This program and the accompanying materials are made + available under the terms of the Eclipse Public License 2.0 + which is available at https://www.eclipse.org/legal/epl-2.0/ + + Contributors: + Martin Lowe <martin.lowe@eclipse-foundation.org> + + SPDX-License-Identifier: EPL-2.0 +******************************************************************/ +// import winston for logging implementation +import { createLogger, format, Logger, transports } from 'winston'; + +/** +Exports central implementation of logging to be used across JS. This way logging can be consistent across the logs easily w/o repitition. + +Example of this format: + +2021-01-25T15:55:29 [main] INFO Generating teams for eclipsefdn-webdev/spider-pig +2021-01-25T15:55:30 [SecretReader] ERROR An unknown error occurred while reading the secret + */ +export function getLogger(level: string, name = 'main') { + let logger = createLogger({ + level: level, + format: format.combine( + format.timestamp({ + format: 'YYYY-MM-DDTHH:mm:ss', + }), + format.printf(info => { + return `${info.timestamp} [${name}] ${info.level.toUpperCase()} ${info.message}`; + })), + transports: [ + new transports.Console({ level: level }), + ], + }); + return logger; +} +export function isNodeErr(error: unknown): error is NodeJS.ErrnoException { + return error instanceof Error; +} diff --git a/src/interfaces/EclipseApi.ts b/src/interfaces/EclipseApi.ts new file mode 100644 index 0000000000000000000000000000000000000000..e005abea71f3552175b317a0dd6442d50b080e76 --- /dev/null +++ b/src/interfaces/EclipseApi.ts @@ -0,0 +1,100 @@ +// +// PROJECTS API +// + +export interface Repo { + url: string; + // post-processing fields + repo?: string; + org?: string; +} + +export interface UserRef { + username: string; + full_name?: string; + url: string; +} + +export interface Release { + name: string; + url: string; +} +export interface WorkingGroup { + name: string; + id: string; +} + +export interface EclipseProject { + project_id: string; + short_project_id: string; + name: string; + summary: string; + url: string; + website_url: string; + website_repo: string[]; + logo: string; + tags: string[]; + github_repos: Repo[]; + gitlab_repos: Repo[]; + gerrit_repos: Repo[]; + contributors: UserRef[]; + committers: UserRef[]; + project_leads: UserRef[]; + working_groups: WorkingGroup[]; + spec_project_working_group: WorkingGroup | Array<any>; + state: string; + releases: Release[]; + // post processing storage fields + pp_repos?: string[]; + pp_orgs?: string[]; +} + +// +// ECLIPSE ACCOUNT +// + +export interface EclipseUser { + uid: string; + name: string; + mail: string; + picture: string; + eca: { + signed: boolean; + can_contribute_spec_project: boolean; + }; + is_committer: boolean; + friends: { + friend_id: string; + }; + first_name: string; + last_name: string; + full_name: string; + github_handle: string; + twitter_handle: string; + org: string; + org_id: number; + job_title: string; + website: string; + country: { + code: string; + name: string; + }; + bio: string; +} + +// +// BOTS API +// + +export interface BotInstance { + username: string; + email: string; +} + +export interface BotProperties { + id: number; + projectId: string; + username: string; + email: string; +} +export type BotDefinition = BotProperties & Record<string, BotInstance>; diff --git a/src/logger.js b/src/logger.js index 9c53a2778dba94828ccfc11dcaec672ea3eca558..ce1fc849c0a89c4b2737630153cb237190ffcf5a 100644 --- a/src/logger.js +++ b/src/logger.js @@ -11,7 +11,7 @@ SPDX-License-Identifier: EPL-2.0 ******************************************************************/ // import winston for logging implementation -const { createLogger, format, transports } = require('winston'); +import { createLogger, format, transports } from 'winston'; /** Exports central implementation of logging to be used across JS. This way logging can be consistent across the logs easily w/o repitition. @@ -21,7 +21,7 @@ Example of this format: 2021-01-25T15:55:29 [main] INFO Generating teams for eclipsefdn-webdev/spider-pig 2021-01-25T15:55:30 [SecretReader] ERROR An unknown error occurred while reading the secret */ -module.exports.getLogger = function(level, name = 'main') { +export function getLogger(level, name = 'main') { let logger = createLogger({ level: level, format: format.combine( @@ -36,4 +36,4 @@ module.exports.getLogger = function(level, name = 'main') { ], }); return logger; -}; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..45480bf8b2a2e474d24e758c85faac35bc6bcb01 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "esModuleInterop": true, + "sourceMap": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts" + ] +} \ No newline at end of file