This run took 445 seconds.
From 5553f56705ce0372db341d390aa23c416228f008 Mon Sep 17 00:00:00 2001 From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org> Date: Sun, 30 Jun 2024 16:28:02 +0000 Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.28.2 Change-Id: I2c0a7a8e8785b0bb779534eb8d3ad8c5659b7503 --- app.js | 10 +- lib/article.creation.morelike.js | 4 +- lib/article.creation.translation.js | 6 +- lib/description.js | 15 +- package-lock.json | 598 +++++++++++------- package.json | 2 +- routes/article.creation.morelike.js | 6 +- test/features/app/app.js | 18 +- test/features/app/spec.js | 16 +- test/features/v1/article.creation.morelike.js | 6 +- test/lib/caption.js | 4 +- test/lib/suggested-edits-common.js | 18 +- test/utils/server.js | 12 +- 13 files changed, 403 insertions(+), 312 deletions(-) diff --git a/app.js b/app.js index 6eac1c1..2e61fe4 100644 --- a/app.js +++ b/app.js @@ -68,9 +68,7 @@ function initApp(options) { 'user-agent', 'x-request-id' ]; } - app.conf.log_header_whitelist = new RegExp(`^(?:${ app.conf.log_header_whitelist.map((item) => { - return item.trim(); - }).join('|') })$`, 'i'); + app.conf.log_header_whitelist = new RegExp(`^(?:${ app.conf.log_header_whitelist.map((item) => item.trim()).join('|') })$`, 'i'); // set up the request templates for the APIs apiUtil.setupApiTemplates(app); @@ -151,8 +149,7 @@ function initApp(options) { function loadRoutes(app, dir) { // recursively load routes from .js files under routes/ - return fs.readdirAsync(dir).map((fname) => { - return BBPromise.try(() => { + return fs.readdirAsync(dir).map((fname) => BBPromise.try(() => { const resolvedPath = path.resolve(dir, fname); const isDirectory = fs.statSync(resolvedPath).isDirectory(); if (isDirectory) { @@ -185,8 +182,7 @@ function loadRoutes(app, dir) { sUtil.wrapRouteHandlers(route, app); // all good, use that route app.use(route.path, route.router); - }); - }).then(() => { + })).then(() => { // catch errors sUtil.setErrorHandler(app); // route loading is now complete, return the app object diff --git a/lib/article.creation.morelike.js b/lib/article.creation.morelike.js index 87c5d9c..d0d0a79 100644 --- a/lib/article.creation.morelike.js +++ b/lib/article.creation.morelike.js @@ -340,9 +340,7 @@ function getArticleNormalizedRanksFromDb(app, wikidataIds, targetLanguage) { const retry = app.conf.mysql_conn.retry || 2; const retryDelay = app.conf.mysql_conn.retry_delay || 1000; - wikidataIds = wikidataIds.map((x) => { - return parseInt(x.replace('Q', ''), 10); - }); + wikidataIds = wikidataIds.map((x) => parseInt(x.replace('Q', ''), 10)); return new BBPromise((resolve, reject) => { _getArticleNormalizedRanksFromMySQL( diff --git a/lib/article.creation.translation.js b/lib/article.creation.translation.js index ae9e21c..9e53b81 100644 --- a/lib/article.creation.translation.js +++ b/lib/article.creation.translation.js @@ -126,11 +126,7 @@ function recommend(app, source, target, projectDomain, seed) { candidates = getArticlesByPageviews(app, source, target, projectDomain); } return candidates - .then((candidates) => { - return candidates.sort((a, b) => { - return b.sitelink_count - a.sitelink_count; - }); - }); + .then((candidates) => candidates.sort((a, b) => b.sitelink_count - a.sitelink_count)); } module.exports = { diff --git a/lib/description.js b/lib/description.js index 2ac31e4..c03b184 100644 --- a/lib/description.js +++ b/lib/description.js @@ -74,13 +74,11 @@ function wikibaseItemHasSiteLink(page, dbName) { * @return {!Object} filtered pages */ function filterPages(pages) { - return pages.filter(page => { - return hasPageProps(page) && + return pages.filter(page => hasPageProps(page) && !isDisambiguationPage(page) && hasWikibaseItem(page) && !hasDescription(page) && - !isPageProtected(page); - } + !isPageProtected(page) ); } @@ -178,16 +176,13 @@ function buildResponse( return []; } wikiPages.forEach((page) => { - const wikidataPage = wikidataPages.find(p => - p.title === page.pageprops.wikibase_item); + const wikidataPage = wikidataPages.find(p => p.title === page.pageprops.wikibase_item); page.wikibase_item = entities[page.pageprops.wikibase_item]; page.wikibase_item.protection = wikidataPage.protection; delete page.pageprops; }); - return wikiPages.filter((page) => { - return !isWikibaseItemPageProtected(page) && - isValidResult(page, targetLang, targetWikiLang, sourceLang, sourceWikiLang); - }); + return wikiPages.filter((page) => !isWikibaseItemPageProtected(page) && + isValidResult(page, targetLang, targetWikiLang, sourceLang, sourceWikiLang)); } /** diff --git a/package-lock.json b/package-lock.json index 16fc0a6..81e4dfc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ }, "devDependencies": { "ajv": "^6.9.1", - "eslint-config-wikimedia": "0.27.0", + "eslint-config-wikimedia": "0.28.2", "extend": "^3.0.2", "mocha": "^6.0.1", "mocha-lcov-reporter": "^1.3.0", @@ -200,9 +200,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -387,11 +387,14 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" @@ -678,6 +681,22 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -690,23 +709,17 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -714,12 +727,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -727,21 +740,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -753,10 +767,19 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -770,6 +793,21 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -777,64 +815,38 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "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" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -860,9 +872,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1270,12 +1282,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1320,9 +1332,9 @@ } }, "node_modules/browserslist-config-wikimedia": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz", - "integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.7.0.tgz", + "integrity": "sha512-CTa0lv78dXKEgrYsOLCkqO+9UUS3CV9MWEOYHcymgEvx4mYxB80sCoKRCR7wW2SOMNxjaP9hohrZripjnKuRTA==", "dev": true }, "node_modules/buffer-from": { @@ -1343,15 +1355,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", @@ -1801,9 +1804,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js-compat": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", - "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -2072,6 +2075,19 @@ "node": ">= 0.8" } }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2276,9 +2292,9 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "dependencies": { "semver": "^7.5.4" @@ -2291,28 +2307,28 @@ } }, "node_modules/eslint-config-wikimedia": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz", - "integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", + "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", "dev": true, "dependencies": { - "browserslist-config-wikimedia": "^0.6.1", + "browserslist-config-wikimedia": "^0.7.0", "eslint": "^8.57.0", "eslint-plugin-compat": "^4.2.0", "eslint-plugin-es-x": "^7.6.0", - "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-jsdoc": "48.2.1", - "eslint-plugin-json-es": "^1.5.7", - "eslint-plugin-mediawiki": "^0.6.0", - "eslint-plugin-mocha": "^10.4.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-no-jquery": "^2.7.0", + "eslint-plugin-jest": "^28.5.0", + "eslint-plugin-jsdoc": "48.2.5", + "eslint-plugin-json-es": "^1.6.0", + "eslint-plugin-mediawiki": "^0.7.0", + "eslint-plugin-mocha": "^10.4.3", + "eslint-plugin-n": "^17.7.0", + "eslint-plugin-no-jquery": "^3.0.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", - "eslint-plugin-unicorn": "^51.0.1", - "eslint-plugin-vue": "^9.23.0", + "eslint-plugin-unicorn": "^53.0.0", + "eslint-plugin-vue": "^9.26.0", "eslint-plugin-wdio": "^8.24.12", - "eslint-plugin-yml": "^1.13.2" + "eslint-plugin-yml": "^1.14.0" } }, "node_modules/eslint-plugin-compat": { @@ -2337,39 +2353,40 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", - "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.7.0.tgz", + "integrity": "sha512-aP3qj8BwiEDPttxQkZdI221DLKq9sI/qHolE2YSQL1/9+xk7dTV+tB1Fz8/IaCA+lnLA1bDEnvaS2LKs0k2Uig==", "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.0" + "eslint-compat-utils": "^0.5.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, "peerDependencies": { "eslint": ">=8" } }, "node_modules/eslint-plugin-jest": { - "version": "27.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", - "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0", - "eslint": "^7.0.0 || ^8.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, "peerDependenciesMeta": { @@ -2382,19 +2399,19 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz", - "integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==", + "version": "48.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.5.tgz", + "integrity": "sha512-ZeTfKV474W1N9niWfawpwsXGu+ZoMXu4417eBROX31d7ZuOk8zyG66SO77DpJ2+A9Wa2scw/jRqBPnnQo7VbcQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.42.0", + "@es-joy/jsdoccomment": "~0.43.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", + "semver": "^7.6.1", "spdx-expression-parse": "^4.0.0" }, "engines": { @@ -2405,9 +2422,9 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2438,9 +2455,9 @@ } }, "node_modules/eslint-plugin-json-es": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.7.tgz", - "integrity": "sha512-ehBHcCcJo4iViYx6vp3T+SmwzLIlVDzZNoVxN/txZIiPwDQ26mnYaN5iJ3imqN4l1b8z6rbxEH2kB9XDGxeU/w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.6.0.tgz", + "integrity": "sha512-xVn6hufGQH1Aa+yqOhQ43Cq28GuitTcMpQh+uaUh27U2qnVLBrvkN+2xQSnv6zpdLEPS35JCNhq4kvhR+PQCgw==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0", @@ -2451,9 +2468,9 @@ } }, "node_modules/eslint-plugin-mediawiki": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz", - "integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.7.0.tgz", + "integrity": "sha512-1Y2nsFDPp96xOZCB5ivZAgqYe9i6w2u64VoCIaAzPyZnd/2h8VQR3CtD+u4Yk/KrpbKq9AAJjrs5LS8VAz6KOA==", "dev": true, "dependencies": { "eslint-plugin-vue": "^9.23.0", @@ -2464,9 +2481,9 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz", - "integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.3.tgz", + "integrity": "sha512-emc4TVjq5Ht0/upR+psftuz6IBG5q279p+1dSRDeHf+NS9aaerBi3lXKo1SEzwC29hFIW21gO89CEWSvRsi8IQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -2481,40 +2498,73 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.9.0.tgz", + "integrity": "sha512-CPSaXDXdrT4nsrOrO4mT4VB6FMUkoySRkHWuuJJHVqsIEjIeZgMY1H7AzSwPbDScikBmLN82KeM1u7ixV7PzGg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", + "enhanced-resolve": "^5.17.0", "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", + "globals": "^15.0.0", "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", + "minimatch": "^9.0.0", "semver": "^7.5.3" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.7.0.tgz", + "integrity": "sha512-ivatRXWwKC6ImcdKO7dOwXuXR5XFrdwo45qFwD7D0qOkEPzzJdLXC3BHceBdyrPOD3p1suPaWi4Y4NMm2D++AQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/eslint-plugin-no-jquery": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", - "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", + "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", "dev": true, "peerDependencies": { - "eslint": ">=2.3.0" + "eslint": ">=8.0.0" } }, "node_modules/eslint-plugin-qunit": { @@ -2540,17 +2590,17 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "51.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", - "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "version": "53.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-53.0.0.tgz", + "integrity": "sha512-kuTcNo9IwwUCfyHGwQFOK/HjJAYzbODHN3wP0PgqbW+jbXqpNWxNVpVhj2tO9SixBwuAdmal8rVcWKBxwFnGuw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "@eslint-community/eslint-utils": "^4.4.0", - "@eslint/eslintrc": "^2.1.4", + "@eslint/eslintrc": "^3.0.2", "ci-info": "^4.0.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.34.0", + "core-js-compat": "^3.37.0", "esquery": "^1.5.0", "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", @@ -2559,11 +2609,11 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.27", "regjsparser": "^0.10.0", - "semver": "^7.5.4", + "semver": "^7.6.1", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=16" + "node": ">=18.18" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" @@ -2572,6 +2622,105 @@ "eslint": ">=8.56.0" } }, + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint-plugin-unicorn/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -2584,10 +2733,16 @@ "node": ">=6" } }, + "node_modules/eslint-plugin-unicorn/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/eslint-plugin-vue": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz", - "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==", + "version": "9.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz", + "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -3048,9 +3203,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3374,9 +3529,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -4768,17 +4923,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -4841,12 +4985,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6046,9 +6190,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -7154,12 +7298,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -7810,6 +7951,15 @@ "node": ">=4" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "4.4.19", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", @@ -8057,25 +8207,16 @@ "node": ">=0.8" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, "engines": { - "node": ">= 6" + "node": ">=16" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "typescript": ">=4.2.0" } }, "node_modules/tunnel-agent": { @@ -8211,9 +8352,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "peer": true, "bin": { @@ -8349,9 +8490,9 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -8373,9 +8514,9 @@ } }, "node_modules/vue-eslint-parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -8616,11 +8757,6 @@ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/yaml": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", diff --git a/package.json b/package.json index a940615..533669c 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "devDependencies": { "ajv": "^6.9.1", - "eslint-config-wikimedia": "0.27.0", + "eslint-config-wikimedia": "0.28.2", "extend": "^3.0.2", "mocha": "^6.0.1", "mocha-lcov-reporter": "^1.3.0", diff --git a/routes/article.creation.morelike.js b/routes/article.creation.morelike.js index aea403f..1abc1d8 100644 --- a/routes/article.creation.morelike.js +++ b/routes/article.creation.morelike.js @@ -85,13 +85,11 @@ router.get('/:seed', (req, res) => { app, ids, language ).then((results) => { res.json(results); - }).catch((error) => { - return BBPromise.reject(new util.HTTPError({ + }).catch((error) => BBPromise.reject(new util.HTTPError({ status: 503, message: 'Cannot retrieve normalized ranks from' + ' the database. Please try again later.' - })); - }); + }))); } }); }); diff --git a/test/features/app/app.js b/test/features/app/app.js index 0ac8f00..7e3d3e5 100644 --- a/test/features/app/app.js +++ b/test/features/app/app.js @@ -17,14 +17,12 @@ describe('express app', function () { before(() => server.start()); - it('should get robots.txt', () => { - return preq.get({ + it('should get robots.txt', () => preq.get({ uri: `${ server.config.uri }robots.txt` }).then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.disallow, '/'); - }); - }); + })); it('should set CORS headers', () => { if (server.config.service.conf.cors === false) { @@ -59,8 +57,7 @@ describe('express app', function () { }); }); - it('should get static content gzipped', () => { - return preq.get({ + it('should get static content gzipped', () => preq.get({ uri: `${ server.config.uri }static/index.html`, headers: { 'accept-encoding': 'gzip, deflate' @@ -70,11 +67,9 @@ describe('express app', function () { // if there is no content-length, the reponse was gzipped assert.deepEqual(res.headers['content-length'], undefined, 'Did not expect the content-length header!'); - }); - }); + })); - it('should get static content uncompressed', () => { - return preq.get({ + it('should get static content uncompressed', () => preq.get({ uri: `${ server.config.uri }static/index.html`, headers: { 'accept-encoding': '' @@ -83,6 +78,5 @@ describe('express app', function () { const contentEncoding = res.headers['content-encoding']; assert.deepEqual(res.status, 200); assert.deepEqual(contentEncoding, undefined, 'Did not expect gzipped contents!'); - }); - }); + })); }); diff --git a/test/features/app/spec.js b/test/features/app/spec.js index 60b500d..84ca636 100644 --- a/test/features/app/spec.js +++ b/test/features/app/spec.js @@ -240,19 +240,15 @@ describe('Swagger spec', function () { this.timeout(20000); - before(() => { - return server.start(); - }); + before(() => server.start()); - it('get the spec', () => { - return preq.get(`${ server.config.uri }?spec`) + it('get the spec', () => preq.get(`${ server.config.uri }?spec`) .then((res) => { assert.status(200); assert.contentType(res, 'application/json'); assert.notDeepEqual(res.body, undefined, 'No body received!'); spec = res.body; - }); - }); + })); it('spec validation', () => { if (spec['x-default-params']) { @@ -282,14 +278,12 @@ describe('Swagger spec', function () { describe('routes', () => { constructTests(spec.paths, defParams).forEach((testCase) => { - it(testCase.title, () => { - return preq(testCase.request) + it(testCase.title, () => preq(testCase.request) .then((res) => { validateTestResponse(testCase, res); }, (err) => { validateTestResponse(testCase, err); - }); - }); + })); }); }); diff --git a/test/features/v1/article.creation.morelike.js b/test/features/v1/article.creation.morelike.js index c280826..dab1388 100644 --- a/test/features/v1/article.creation.morelike.js +++ b/test/features/v1/article.creation.morelike.js @@ -29,8 +29,7 @@ before(() => server.start()); describe('article.creation.morelike', function () { this.timeout(20000); - it('should return recommendations for good article title', () => { - return preq.get( + it('should return recommendations for good article title', () => preq.get( `${ server.config.uri }uz.wikipedia.org/v1/article/creation/morelike/Palov` ).then((res) => { assert.status(res, 200); @@ -43,6 +42,5 @@ describe('article.creation.morelike', function () { { wikidata_id: 'Q127418', normalized_rank: 0.891431 } ] ); - }); - }); + })); }); diff --git a/test/lib/caption.js b/test/lib/caption.js index 39392d1..1378664 100644 --- a/test/lib/caption.js +++ b/test/lib/caption.js @@ -190,9 +190,7 @@ describe('lib:caption', () => { } }; - const cond = (image, targetLang, sourceLang) => { - return image.structured.captions[sourceLang] && !image.structured.captions[targetLang]; - }; + const cond = (image, targetLang, sourceLang) => image.structured.captions[sourceLang] && !image.structured.captions[targetLang]; const makeResults = lib.__get__('makeResults'); diff --git a/test/lib/suggested-edits-common.js b/test/lib/suggested-edits-common.js index e8b36f1..e92c212 100644 --- a/test/lib/suggested-edits-common.js +++ b/test/lib/suggested-edits-common.js @@ -57,23 +57,17 @@ describe('lib:suggested-edits-common', () => { describe('getWikiLangForLangCode', () => { - it('translates language variants to base wiki language codes', () => { - return lib.getWikiLangForLangCode(app, req, 'zh-hans').then((res) => { + it('translates language variants to base wiki language codes', () => lib.getWikiLangForLangCode(app, req, 'zh-hans').then((res) => { assert.deepEqual(res, 'zh'); - }); - }); + })); - it('passed through other inputs', () => { - return lib.getWikiLangForLangCode(app, req, 'foo').then((res) => { + it('passed through other inputs', () => lib.getWikiLangForLangCode(app, req, 'foo').then((res) => { assert.deepEqual(res, 'foo'); - }); - }); + })); - it('handles undefined', () => { - return lib.getWikiLangForLangCode(app, req, undefined).then((res) => { + it('handles undefined', () => lib.getWikiLangForLangCode(app, req, undefined).then((res) => { assert.deepEqual(res, undefined); - }); - }); + })); }); diff --git a/test/utils/server.js b/test/utils/server.js index 70099e1..44cb649 100644 --- a/test/utils/server.js +++ b/test/utils/server.js @@ -29,9 +29,7 @@ config.conf.logging = { // make a deep copy of it for later reference const origConfig = extend(true, {}, config); -module.exports.stop = () => { - return BBPromise.resolve(); -}; +module.exports.stop = () => BBPromise.resolve(); let options = null; const runner = new ServiceRunner(); @@ -50,13 +48,9 @@ function start(_options) { .then((serviceReturns) => { module.exports.stop = () => { console.log('stopping test server'); - serviceReturns.forEach(servers => - servers.forEach(server => - server.shutdown())); + serviceReturns.forEach(servers => servers.forEach(server => server.shutdown())); return runner.stop().then(() => { - module.exports.stop = () => { - return BBPromise.resolve(); - }; + module.exports.stop = () => BBPromise.resolve(); }); }; return true; -- 2.39.2
$ date --- stdout --- Sun Jun 30 16:20:40 UTC 2024 --- end --- $ git clone file:///srv/git/mediawiki-services-recommendation-api.git repo --depth=1 -b master --- stderr --- Cloning into 'repo'... --- stdout --- --- end --- $ git config user.name libraryupgrader --- stdout --- --- end --- $ git config user.email tools.libraryupgrader@tools.wmflabs.org --- stdout --- --- end --- $ git submodule update --init --- stdout --- --- end --- $ grr init --- stdout --- Installed commit-msg hook. --- end --- $ git show-ref refs/heads/master --- stdout --- 89967d28df149b294c4024ac790c5890156b3b55 refs/heads/master --- end --- $ /usr/bin/npm audit --json --- stdout --- { "auditReportVersion": 2, "vulnerabilities": { "ajv": { "name": "ajv", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097685, "name": "ajv", "dependency": "ajv", "title": "Prototype Pollution in Ajv", "url": "https://github.com/advisories/GHSA-v88g-cgmw-v5xw", "severity": "moderate", "cwe": [ "CWE-915", "CWE-1321" ], "cvss": { "score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L" }, "range": "<6.12.3" } ], "effects": [ "ajv-keywords", "eslint", "table" ], "range": "<6.12.3", "nodes": [ "node_modules/rewire/node_modules/ajv", "node_modules/table/node_modules/ajv" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "ajv-keywords": { "name": "ajv-keywords", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [], "range": "2.1.1", "nodes": [ "node_modules/table/node_modules/ajv-keywords" ], "fixAvailable": true }, "braces": { "name": "braces", "severity": "high", "isDirect": false, "via": [ { "source": 1097496, "name": "braces", "dependency": "braces", "title": "Uncontrolled resource consumption in braces", "url": "https://github.com/advisories/GHSA-grv7-fg5c-xmjg", "severity": "high", "cwe": [ "CWE-1050" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": "<3.0.3" } ], "effects": [], "range": "<3.0.3", "nodes": [ "node_modules/braces" ], "fixAvailable": true }, "debug": { "name": "debug", "severity": "low", "isDirect": false, "via": [ { "source": 1096793, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": [ "CWE-400" ], "cvss": { "score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": ">=3.2.0 <3.2.7" } ], "effects": [ "mocha" ], "range": "3.2.0 - 3.2.6", "nodes": [ "node_modules/mocha/node_modules/debug" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "eslint": { "name": "eslint", "severity": "moderate", "isDirect": false, "via": [ "ajv", "table" ], "effects": [ "rewire" ], "range": "2.5.0 - 2.5.2 || 4.2.0 - 5.0.0-rc.0", "nodes": [ "node_modules/rewire/node_modules/eslint" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "flat": { "name": "flat", "severity": "critical", "isDirect": false, "via": [ { "source": 1089152, "name": "flat", "dependency": "flat", "title": "flat vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm", "severity": "critical", "cwe": [ "CWE-1321" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<5.0.1" } ], "effects": [ "yargs-unparser" ], "range": "<5.0.1", "nodes": [ "node_modules/flat" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "limitation": { "name": "limitation", "severity": "moderate", "isDirect": false, "via": [ "wikimedia-kad-fork" ], "effects": [ "service-runner" ], "range": ">=0.2.3", "nodes": [ "node_modules/limitation" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "minimatch": { "name": "minimatch", "severity": "high", "isDirect": false, "via": [ { "source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": [ "CWE-400", "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": "<3.0.5" } ], "effects": [ "mocha" ], "range": "<3.0.5", "nodes": [ "node_modules/mocha/node_modules/minimatch" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "mocha": { "name": "mocha", "severity": "critical", "isDirect": true, "via": [ "debug", "minimatch", "yargs-unparser" ], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": [ "node_modules/mocha" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "ms": { "name": "ms", "severity": "moderate", "isDirect": false, "via": [ { "source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": [ "CWE-1333" ], "cvss": { "score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": "<2.0.0" } ], "effects": [ "wikimedia-kad-fork" ], "range": "<2.0.0", "nodes": [ "node_modules/wikimedia-kad-fork/node_modules/ms" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "preq": { "name": "preq", "severity": "high", "isDirect": true, "via": [ "request", "requestretry" ], "effects": [], "range": "*", "nodes": [ "node_modules/preq" ], "fixAvailable": false }, "request": { "name": "request", "severity": "moderate", "isDirect": false, "via": [ { "source": 1096727, "name": "request", "dependency": "request", "title": "Server-Side Request Forgery in Request", "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N" }, "range": "<=2.88.2" }, "tough-cookie" ], "effects": [ "preq", "requestretry" ], "range": "*", "nodes": [ "node_modules/request" ], "fixAvailable": false }, "requestretry": { "name": "requestretry", "severity": "high", "isDirect": false, "via": [ { "source": 1090420, "name": "requestretry", "dependency": "requestretry", "title": "Cookie exposure in requestretry", "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45", "severity": "high", "cwe": [ "CWE-200" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" }, "range": "<7.0.0" }, "request" ], "effects": [ "preq" ], "range": "*", "nodes": [ "node_modules/requestretry" ], "fixAvailable": false }, "rewire": { "name": "rewire", "severity": "moderate", "isDirect": true, "via": [ "eslint" ], "effects": [], "range": "4.0.0 - 4.0.1", "nodes": [ "node_modules/rewire" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "service-runner": { "name": "service-runner", "severity": "moderate", "isDirect": true, "via": [ "limitation", "tar" ], "effects": [], "range": ">=3.0.0", "nodes": [ "node_modules/service-runner" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "swagger-ui": { "name": "swagger-ui", "severity": "critical", "isDirect": true, "via": [ { "source": 1085691, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Reverse Tabnapping in swagger-ui", "url": "https://github.com/advisories/GHSA-x9p2-fxq6-2m5f", "severity": "moderate", "cwe": [ "CWE-1022" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<3.18.0" }, { "source": 1086900, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-388g-jwpg-x6j4", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N" }, "range": "<3.0.13" }, { "source": 1088760, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Spoofing attack in swagger-ui", "url": "https://github.com/advisories/GHSA-cr3q-pqgq-m8c2", "severity": "moderate", "cwe": [ "CWE-20" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<4.1.3" }, { "source": 1088813, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-site scripting in Swagger-UI", "url": "https://github.com/advisories/GHSA-c427-hjc3-wrfw", "severity": "critical", "cwe": [ "CWE-79", "CWE-352" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<3.23.11" }, { "source": 1092161, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Server side request forgery in SwaggerUI", "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 0, "vectorString": null }, "range": "<4.1.3" }, { "source": 1094217, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-4f9m-pxwh-68hg", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<3.20.9" } ], "effects": [], "range": "<=4.1.2", "nodes": [ "node_modules/swagger-ui" ], "fixAvailable": false }, "table": { "name": "table", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [ "eslint" ], "range": "3.7.10 - 4.0.2", "nodes": [ "node_modules/table" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "tar": { "name": "tar", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097493, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": [ "CWE-400" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H" }, "range": "<6.2.1" } ], "effects": [ "service-runner" ], "range": "<6.2.1", "nodes": [ "node_modules/tar" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "tough-cookie": { "name": "tough-cookie", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097682, "name": "tough-cookie", "dependency": "tough-cookie", "title": "tough-cookie Prototype Pollution vulnerability", "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3", "severity": "moderate", "cwe": [ "CWE-1321" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<4.1.3" } ], "effects": [ "request" ], "range": "<4.1.3", "nodes": [ "node_modules/tough-cookie" ], "fixAvailable": false }, "wikimedia-kad-fork": { "name": "wikimedia-kad-fork", "severity": "moderate", "isDirect": false, "via": [ "ms" ], "effects": [ "limitation" ], "range": "*", "nodes": [ "node_modules/wikimedia-kad-fork" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "yargs-unparser": { "name": "yargs-unparser", "severity": "critical", "isDirect": false, "via": [ "flat" ], "effects": [ "mocha" ], "range": "<=1.6.3", "nodes": [ "node_modules/yargs-unparser" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } } }, "metadata": { "vulnerabilities": { "info": 0, "low": 1, "moderate": 12, "high": 4, "critical": 4, "total": 21 }, "dependencies": { "prod": 205, "dev": 578, "optional": 9, "peer": 1, "peerOptional": 0, "total": 791 } } } --- end --- Upgrading n:eslint-config-wikimedia from 0.27.0 -> 0.28.2 $ /usr/bin/npm install --- stderr --- npm WARN skipping integrity check for git dependency ssh://git@github.com/wikimedia/swagger-ui.git npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained. npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated mkdirp@0.5.4: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained. npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor. npm WARN deprecated debug@3.2.6: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated sinon@7.5.0: 16.1.1 --- stdout --- added 801 packages, and audited 802 packages in 1m 113 packages are looking for funding run `npm fund` for details 20 vulnerabilities (1 low, 12 moderate, 3 high, 4 critical) To address issues that do not require attention, run: npm audit fix To address all issues possible (including breaking changes), run: npm audit fix --force Some issues need review, and may require choosing a different dependency. Run `npm audit` for details. --- end --- $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- $ ./node_modules/.bin/eslint . --fix --- stdout --- /src/repo/app.js 20:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 71:37 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp 145:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 147:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 159:31 warning Found non-literal argument in require security/detect-non-literal-require 196:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 197:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 235:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types /src/repo/config.dev.yaml 22:1 warning Empty mapping values are forbidden yml/no-empty-mapping-value 93:9 warning Empty mapping values are forbidden yml/no-empty-mapping-value /src/repo/config.yaml 22:1 warning Empty mapping values are forbidden yml/no-empty-mapping-value 93:9 warning Empty mapping values are forbidden yml/no-empty-mapping-value /src/repo/lib/api-util.js 81:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 128:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/lib/article.creation.morelike.js 1:11 warning 'setTimeout' is already defined as a built-in global variable no-redeclare /src/repo/lib/article.creation.translation.js 129:12 warning 'candidates' is already declared in the upper scope on line 122 column 9 no-shadow /src/repo/lib/util.js 109:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 155:1 warning The type 'bool' is undefined jsdoc/no-undefined-types 165:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 260:1 warning The type 'Router' is undefined jsdoc/no-undefined-types 280:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/routes/article.creation.morelike.js 75:32 warning 'ids' is already declared in the upper scope on line 66 column 24 no-shadow /src/repo/routes/article.creation.translation.js 14:25 warning Unsafe Regular Expression security/detect-unsafe-regex /src/repo/spec.yaml 234:1 warning This line has a length of 115. Maximum allowed is 100 max-len 307:1 warning This line has a length of 120. Maximum allowed is 100 max-len /src/repo/test/features/app/app.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare /src/repo/test/features/app/spec.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare 24:30 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename 178:14 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp /src/repo/test/lib/caption.js 193:1 warning This line has a length of 136. Maximum allowed is 100 max-len /src/repo/test/utils/logStream.js 41:13 warning 'end' is already declared in the upper scope on line 31 column 14 no-shadow 49:18 warning 'get' is already declared in the upper scope on line 34 column 14 no-shadow ✖ 38 problems (0 errors, 38 warnings) --- end --- $ ./node_modules/.bin/eslint . -f json --- stdout --- [{"filePath":"/src/repo/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/app.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'bluebird' is undefined.","line":20,"column":1,"nodeType":"Block","endLine":20,"endColumn":1},{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":71,"column":37,"nodeType":"NewExpression","endLine":71,"endColumn":133},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":145,"column":1,"nodeType":"Block","endLine":145,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'bluebird' is undefined.","line":147,"column":1,"nodeType":"Block","endLine":147,"endColumn":1},{"ruleId":"security/detect-non-literal-require","severity":1,"message":"Found non-literal argument in require","line":159,"column":31,"nodeType":"CallExpression","endLine":159,"endColumn":61},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":196,"column":1,"nodeType":"Block","endLine":196,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'bluebird' is undefined.","line":197,"column":1,"nodeType":"Block","endLine":197,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'bluebird' is undefined.","line":235,"column":1,"nodeType":"Block","endLine":235,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":8,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst http = require('http');\nconst BBPromise = require('bluebird');\nconst express = require('express');\nconst compression = require('compression');\nconst bodyParser = require('body-parser');\nconst fs = BBPromise.promisifyAll(require('fs'));\nconst sUtil = require('./lib/util');\nconst apiUtil = require('./lib/api-util');\nconst packageInfo = require('./package.json');\nconst yaml = require('js-yaml');\nconst addShutdown = require('http-shutdown');\nconst path = require('path');\n\n/**\n * Creates an express app and initialises it\n *\n * @param {Object} options the options to initialise the app with\n * @return {bluebird} the promise resolving to the app object\n */\nfunction initApp(options) {\n\n // the main application object\n const app = express();\n\n // get the options and make them available in the app\n app.logger = options.logger; // the logging device\n app.metrics = options.metrics; // the metrics\n app.conf = options.config; // this app's config options\n app.info = packageInfo; // this app's package info\n\n // ensure some sane defaults\n if (!app.conf.port) {\n app.conf.port = 8888;\n }\n if (!app.conf.interface) {\n app.conf.interface = '0.0.0.0';\n }\n if (app.conf.compression_level === undefined) {\n app.conf.compression_level = 3;\n }\n if (app.conf.cors === undefined) {\n app.conf.cors = '*';\n }\n if (app.conf.csp === undefined) {\n app.conf.csp = \"default-src 'self'; object-src 'none'; media-src *; img-src *; style-src *; frame-ancestors 'self'\";\n }\n\n // set outgoing proxy\n if (app.conf.proxy) {\n process.env.HTTP_PROXY = app.conf.proxy;\n // if there is a list of domains which should\n // not be proxied, set it\n if (app.conf.no_proxy_list) {\n if (Array.isArray(app.conf.no_proxy_list)) {\n process.env.NO_PROXY = app.conf.no_proxy_list.join(',');\n } else {\n process.env.NO_PROXY = app.conf.no_proxy_list;\n }\n }\n }\n\n // set up header whitelisting for logging\n if (!app.conf.log_header_whitelist) {\n app.conf.log_header_whitelist = [\n 'cache-control', 'content-type', 'content-length', 'if-match',\n 'user-agent', 'x-request-id'\n ];\n }\n app.conf.log_header_whitelist = new RegExp(`^(?:${ app.conf.log_header_whitelist.map((item) => item.trim()).join('|') })$`, 'i');\n\n // set up the request templates for the APIs\n apiUtil.setupApiTemplates(app);\n // set up query templates\n apiUtil.setupQueryTemplates(app);\n\n // set up the spec\n if (!app.conf.spec) {\n app.conf.spec = `${ __dirname }/spec.yaml`;\n }\n if (app.conf.spec.constructor !== Object) {\n try {\n app.conf.spec = yaml.safeLoad(fs.readFileSync(app.conf.spec));\n } catch (e) {\n app.logger.log('warn/spec', `Could not load the spec: ${ e }`);\n app.conf.spec = {};\n }\n }\n if (!app.conf.spec.swagger) {\n app.conf.spec.swagger = '2.0';\n }\n if (!app.conf.spec.info) {\n app.conf.spec.info = {\n version: app.info.version,\n title: app.info.name,\n description: app.info.description\n };\n }\n app.conf.spec.info.version = app.info.version;\n if (!app.conf.spec.paths) {\n app.conf.spec.paths = {};\n }\n\n // set the CORS and CSP headers\n app.all('*', (req, res, next) => {\n if (app.conf.cors !== false) {\n res.header('access-control-allow-origin', app.conf.cors);\n res.header('access-control-allow-headers', 'accept, x-requested-with, content-type');\n res.header('access-control-expose-headers', 'etag');\n }\n if (app.conf.csp !== false) {\n res.header('x-xss-protection', '1; mode=block');\n res.header('x-content-type-options', 'nosniff');\n res.header('x-frame-options', 'SAMEORIGIN');\n res.header('content-security-policy', app.conf.csp);\n res.header('x-content-security-policy', app.conf.csp);\n res.header('x-webkit-csp', app.conf.csp);\n }\n sUtil.initAndLogRequest(req, app);\n next();\n });\n\n // set up the user agent header string to use for requests\n app.conf.user_agent = app.conf.user_agent || app.info.name;\n\n // disable the X-Powered-By header\n app.set('x-powered-by', false);\n // disable the ETag header - users should provide them!\n app.set('etag', false);\n // enable compression\n app.use(compression({ level: app.conf.compression_level }));\n // use the JSON body parser\n app.use(bodyParser.json());\n // use the application/x-www-form-urlencoded parser\n app.use(bodyParser.urlencoded({ extended: true }));\n\n return BBPromise.resolve(app);\n\n}\n\n/**\n * Loads all routes declared in routes/ into the app\n *\n * @param {Application} app the application object to load routes into\n * @param {string} dir\n * @return {bluebird} a promise resolving to the app object\n */\nfunction loadRoutes(app, dir) {\n\n // recursively load routes from .js files under routes/\n return fs.readdirAsync(dir).map((fname) => BBPromise.try(() => {\n const resolvedPath = path.resolve(dir, fname);\n const isDirectory = fs.statSync(resolvedPath).isDirectory();\n if (isDirectory) {\n loadRoutes(app, resolvedPath);\n } else if (/\\.js$/.test(fname)) {\n // import the route file\n const route = require(`${ dir }/${ fname }`);\n return route(app);\n }\n }).then((route) => {\n if (route === undefined) {\n return undefined;\n }\n // check that the route exports the object we need\n if (route.constructor !== Object || !route.path || !route.router ||\n !(route.api_version || route.skip_domain)) {\n throw new TypeError(`routes/${ fname } does not export the correct object!`);\n }\n // normalise the path to be used as the mount point\n if (route.path[0] !== '/') {\n route.path = `/${ route.path }`;\n }\n if (route.path[route.path.length - 1] !== '/') {\n route.path = `${ route.path }/`;\n }\n if (!route.skip_domain) {\n route.path = `/:domain/v${ route.api_version }${ route.path }`;\n }\n // wrap the route handlers with Promise.try() blocks\n sUtil.wrapRouteHandlers(route, app);\n // all good, use that route\n app.use(route.path, route.router);\n })).then(() => {\n // catch errors\n sUtil.setErrorHandler(app);\n // route loading is now complete, return the app object\n return BBPromise.resolve(app);\n });\n}\n\n/**\n * Creates and start the service's web server\n *\n * @param {Application} app the app object to use in the service\n * @return {bluebird} a promise creating the web server\n */\nfunction createServer(app) {\n\n // return a promise which creates an HTTP server,\n // attaches the app to it, and starts accepting\n // incoming client requests\n let server;\n return new BBPromise((resolve) => {\n server = http.createServer(app).listen(\n app.conf.port,\n app.conf.interface,\n resolve\n );\n server = addShutdown(server);\n }).then(() => {\n app.logger.log('info',\n `Worker ${ process.pid } listening on ${ app.conf.interface || '*' }:${ app.conf.port }`);\n\n // Don't delay incomplete packets for 40ms (Linux default) on\n // pipelined HTTP sockets. We write in large chunks or buffers, so\n // lack of coalescing should not be an issue here.\n server.on('connection', (socket) => {\n socket.setNoDelay(true);\n });\n\n return server;\n });\n\n}\n\n/**\n * The service's entry point. It takes over the configuration\n * options and the logger- and metrics-reporting objects from\n * service-runner and starts an HTTP server, attaching the application\n * object to it.\n *\n * @param {Object} options\n * @return {bluebird}\n */\nmodule.exports = function (options) {\n\n return initApp(options)\n .then(app => loadRoutes(app, `${ __dirname }/routes`))\n .then((app) => {\n // serve static files from static/\n app.use('/static', express.static(`${ __dirname }/static`));\n return app;\n }).then(createServer);\n\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.dev.yaml","messages":[{"ruleId":"yml/no-empty-mapping-value","severity":1,"message":"Empty mapping values are forbidden.","line":22,"column":1,"nodeType":"YAMLPair","messageId":"unexpectedEmpty","endLine":22,"endColumn":9},{"ruleId":"yml/no-empty-mapping-value","severity":1,"message":"Empty mapping values are forbidden.","line":93,"column":9,"nodeType":"YAMLPair","messageId":"unexpectedEmpty","endLine":93,"endColumn":14}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"# Number of worker processes to spawn.\n# Set to 0 to run everything in a single process without clustering.\n# Use 'ncpu' to run as many workers as there are CPU units\nnum_workers: 0\n\n# Log error messages and gracefully restart a worker if v8 reports that it\n# uses more heap (note: not RSS) than this many mb.\nworker_heap_limit_mb: 250\n\n# Logger info\nlogging:\n level: trace\n streams:\n - type: stdout # log to stdout\n named_levels: true # emit log level name instead of index. e.g. INFO vs 30\n# # Use gelf-stream -> logstash\n# - type: gelf\n# host: logstash1003.eqiad.wmnet\n# port: 12201\n\n# Statsd metrics reporter\nmetrics:\n# type: log\n# host: localhost\n# port: 8125\n\nservices:\n - name: recommendation-api\n # a relative path or the name of an npm package, if different from name\n module: ./app.js\n # optionally, a version constraint of the npm package\n # version: ^0.4.0\n # per-service config\n conf:\n port: 6927\n # interface: localhost # uncomment to only listen on localhost\n # more per-service config settings\n # the location of the spec, defaults to spec.yaml if not specified\n # spec: ./spec.template.yaml\n # allow cross-domain requests to the API (default '*')\n cors: \"*\"\n # to disable use:\n # cors: false\n # to restrict to a particular domain, use:\n # cors: restricted.domain.org\n # content for the CSP headers\n # csp: false # uncomment this line to disable sending them\n # URL of the outbound proxy to use (complete with protocol)\n # proxy: http://my.proxy.org:8080\n # the list of domains for which not to use the proxy defined above\n # no_proxy_list:\n # - domain1.com\n # - domain2.org\n # the list of incoming request headers that can be logged; if left empty,\n # the following headers are allowed: cache-control, content-length,\n # content-type, if-match, user-agent, x-request-id\n # log_header_whitelist:\n # - cache-control\n # - content-length\n # - content-type\n # - if-match\n # - user-agent\n # - x-request-id\n # the user agent to use when issuing requests\n # user_agent: service-template-node\n # the template used for contacting the MW API\n mwapi_req:\n method: post\n uri: https://{{domain}}/w/api.php\n headers:\n user-agent: \"{{user-agent}}\"\n body: \"{{ default(request.query, {}) }}\"\n # the template used for contacting RESTBase\n restbase_req:\n method: \"{{request.method}}\"\n uri: https://{{domain}}/api/rest_v1/{+path}\n query: \"{{ default(request.query, {}) }}\"\n headers: \"{{request.headers}}\"\n body: \"{{request.body}}\"\n wdqsapi_req:\n method: post\n uri: \"https://query.wikidata.org/sparql\"\n headers:\n user-agent: \"{{user-agent}}\"\n body:\n format: json\n query: \"{{request.query}}\"\n mysql_conn:\n limit: 2\n host: localhost:3306\n name: recommendationapi\n user: root\n pass:\n # If a connection to MySQL fails, how many times to retry?\n retry: 2\n # retry delay (in ms) before connecting to MySQL\n retry_delay: 1000\n mysql_tables:\n language: language\n normalized_rank: normalized_rank\n wikidata_domain: www.wikidata.org\n article:\n # key is the target language, values are source languages\n translation_models:\n uz:\n - ru\n description_allowed_domains:\n - www.wikidata.org\n - test.wikidata.org\n - wikidata.beta.wmflabs.org\n caption_allowed_domains:\n - commons.wikimedia.org\n - test-commons.wikimedia.org\n - commons.wikimedia.beta.wmflabs.org\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.yaml","messages":[{"ruleId":"yml/no-empty-mapping-value","severity":1,"message":"Empty mapping values are forbidden.","line":22,"column":1,"nodeType":"YAMLPair","messageId":"unexpectedEmpty","endLine":22,"endColumn":9},{"ruleId":"yml/no-empty-mapping-value","severity":1,"message":"Empty mapping values are forbidden.","line":93,"column":9,"nodeType":"YAMLPair","messageId":"unexpectedEmpty","endLine":93,"endColumn":14}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"# Number of worker processes to spawn.\n# Set to 0 to run everything in a single process without clustering.\n# Use 'ncpu' to run as many workers as there are CPU units\nnum_workers: 0\n\n# Log error messages and gracefully restart a worker if v8 reports that it\n# uses more heap (note: not RSS) than this many mb.\nworker_heap_limit_mb: 250\n\n# Logger info\nlogging:\n level: trace\n streams:\n - type: stdout # log to stdout\n named_levels: true # emit log level name instead of index. e.g. INFO vs 30\n# # Use gelf-stream -> logstash\n# - type: gelf\n# host: logstash1003.eqiad.wmnet\n# port: 12201\n\n# Statsd metrics reporter\nmetrics:\n# type: log\n# host: localhost\n# port: 8125\n\nservices:\n - name: recommendation-api\n # a relative path or the name of an npm package, if different from name\n module: ./app.js\n # optionally, a version constraint of the npm package\n # version: ^0.4.0\n # per-service config\n conf:\n port: 6927\n # interface: localhost # uncomment to only listen on localhost\n # more per-service config settings\n # the location of the spec, defaults to spec.yaml if not specified\n # spec: ./spec.template.yaml\n # allow cross-domain requests to the API (default '*')\n cors: \"*\"\n # to disable use:\n # cors: false\n # to restrict to a particular domain, use:\n # cors: restricted.domain.org\n # content for the CSP headers\n # csp: false # uncomment this line to disable sending them\n # URL of the outbound proxy to use (complete with protocol)\n # proxy: http://my.proxy.org:8080\n # the list of domains for which not to use the proxy defined above\n # no_proxy_list:\n # - domain1.com\n # - domain2.org\n # the list of incoming request headers that can be logged; if left empty,\n # the following headers are allowed: cache-control, content-length,\n # content-type, if-match, user-agent, x-request-id\n # log_header_whitelist:\n # - cache-control\n # - content-length\n # - content-type\n # - if-match\n # - user-agent\n # - x-request-id\n # the user agent to use when issuing requests\n # user_agent: service-template-node\n # the template used for contacting the MW API\n mwapi_req:\n method: post\n uri: https://{{domain}}/w/api.php\n headers:\n user-agent: \"{{user-agent}}\"\n body: \"{{ default(request.query, {}) }}\"\n # the template used for contacting RESTBase\n restbase_req:\n method: \"{{request.method}}\"\n uri: https://{{domain}}/api/rest_v1/{+path}\n query: \"{{ default(request.query, {}) }}\"\n headers: \"{{request.headers}}\"\n body: \"{{request.body}}\"\n wdqsapi_req:\n method: post\n uri: \"https://query.wikidata.org/sparql\"\n headers:\n user-agent: \"{{user-agent}}\"\n body:\n format: json\n query: \"{{request.query}}\"\n mysql_conn:\n limit: 2\n host: localhost:3306\n name: recommendationapi\n user: root\n pass:\n # If a connection to MySQL fails, how many times to retry?\n retry: 2\n # retry delay (in ms) before connecting to MySQL\n retry_delay: 1000\n mysql_tables:\n language: language\n normalized_rank: normalized_rank\n wikidata_domain: www.wikidata.org\n article:\n # key is the target language, values are source languages\n translation_models:\n uz:\n - ru\n description_allowed_domains:\n - www.wikidata.org\n - test.wikidata.org\n - wikidata.beta.wmflabs.org\n caption_allowed_domains:\n - commons.wikimedia.org\n - test-commons.wikimedia.org\n - commons.wikimedia.beta.wmflabs.org\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/api-util.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":81,"column":1,"nodeType":"Block","endLine":81,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":128,"column":1,"nodeType":"Block","endLine":128,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst preq = require('preq');\nconst sUtil = require('./util');\nconst Template = require('swagger-router').Template;\nconst HTTPError = sUtil.HTTPError;\n\n/**\n * Calls the MW API with the supplied query as its body\n *\n * @param {!Object} app the application object\n * @param {string} domain the domain to issue the request to\n * @param {?Object} query an object with all the query parameters for the MW API\n * @return {!Promise} a promise resolving as the response object from the MW API\n */\nfunction mwApiGet(app, domain, query) {\n\n query = Object.assign({\n format: 'json',\n formatversion: 2\n }, query);\n\n const request = app.mwapi_tpl.expand({\n request: {\n params: { domain },\n headers: { 'user-agent': app.conf.user_agent },\n query\n }\n });\n\n return preq(request).then((response) => {\n if (response.status < 200 || response.status > 399) {\n // there was an error when calling the upstream service, propagate that\n throw new HTTPError({\n status: response.status,\n type: 'api_error',\n title: 'MW API error',\n detail: response.body\n });\n }\n return response;\n });\n\n}\n\n/**\n * Calls the REST API with the supplied domain, path and request parameters\n *\n * @param {!Object} app the application object\n * @param {string} domain the domain to issue the request for\n * @param {!string} path the REST API path to contact without the leading slash\n * @param {?Object} [restReq={}] the object containing the REST request details\n * @param {?string} [restReq.method=get] the request method\n * @param {?Object} [restReq.query={}] the query string to send, if any\n * @param {?Object} [restReq.headers={}] the request headers to send\n * @param {?Object} [restReq.body=null] the body of the request, if any\n * @return {!Promise} a promise resolving as the response object from the REST API\n */\nfunction restApiGet(app, domain, path, restReq) {\n\n restReq = restReq || {};\n path = path[0] === '/' ? path.slice(1) : path;\n\n const request = app.restbase_tpl.expand({\n request: {\n method: restReq.method,\n params: { domain, path },\n query: restReq.query,\n headers: Object.assign({ 'user-agent': app.conf.user_agent }, restReq.headers),\n body: restReq.body\n }\n });\n\n return preq(request);\n\n}\n\n/**\n * Sets up the request templates for MW and RESTBase API requests\n *\n * @param {!Application} app the application object\n */\nfunction setupApiTemplates(app) {\n\n // set up the MW API request template\n if (!app.conf.mwapi_req) {\n app.conf.mwapi_req = {\n uri: 'http://{{domain}}/w/api.php',\n headers: {\n 'user-agent': '{{user-agent}}'\n },\n body: '{{ default(request.query, {}) }}'\n };\n }\n app.mwapi_tpl = new Template(app.conf.mwapi_req);\n\n // set up the RESTBase request template\n if (!app.conf.restbase_req) {\n app.conf.restbase_req = {\n method: '{{request.method}}',\n uri: 'http://{{domain}}/api/rest_v1/{+path}',\n query: '{{ default(request.query, {}) }}',\n headers: '{{request.headers}}',\n body: '{{request.body}}'\n };\n }\n app.restbase_tpl = new Template(app.conf.restbase_req);\n\n if (!app.conf.wdqsapi_req) {\n app.conf.wdqsapi_req = {\n method: 'post',\n uri: 'https://query.wikidata.org/sparql',\n headers: {\n 'user-agent': '{{user-agent}}'\n },\n body: {\n format: 'json',\n query: '{{request.query}}'\n }\n };\n }\n app.wdqsapi_tpl = new Template(app.conf.wdqsapi_req);\n}\n\n/**\n * Sets up templates for queries used in multiple places\n *\n * @param {!Application} app the application object\n */\nfunction setupQueryTemplates(app) {\n app.queryTemplates = app.queryTemplates || {};\n\n app.queryTemplates.seed = new Template({\n parameters: {\n format: 'json',\n action: 'query',\n prop: 'pageprops',\n ppprop: 'wikibase_item',\n generator: 'search',\n gsrlimit: 500,\n gsrsearch: 'morelike:{{params.seed}}',\n gsrprop: ''\n }\n });\n}\n\nmodule.exports = {\n mwApiGet,\n restApiGet,\n setupApiTemplates,\n setupQueryTemplates\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/article.creation.morelike.js","messages":[{"ruleId":"no-redeclare","severity":1,"message":"'setTimeout' is already defined as a built-in global variable.","line":1,"column":11,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":21}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* global setTimeout */\n\n'use strict';\n\nconst BBPromise = require('bluebird');\nconst aUtils = require('./api-util');\n\n/**\n * Return article's Wikidata ID from MW API\n *\n * @param {Object} app\n * @param {string} domain\n * @param {string} articleTitle\n * @return {Promise} promise that resolves with article's Wikidata ID or `null`\n */\nfunction getWikidataId(app, domain, articleTitle) {\n const parameters = {\n format: 'json',\n formatversion: 2,\n action: 'query',\n prop: 'pageprops',\n ppprop: 'wikibase_item',\n titles: articleTitle\n };\n\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Getting article\\'s Wikidata ID from MW API.',\n articleTitle\n });\n\n return aUtils.mwApiGet(app, domain, parameters).then(\n (response) => {\n if (!response.body || !response.body.query ||\n !response.body.query.pages ||\n !response.body.query.pages[0].pageprops ||\n !response.body.query.pages[0].pageprops.wikibase_item) {\n app.logger.log('debug/article.creation.morelike', {\n msg: 'No article Wikidta ID retrieved.'\n });\n return null;\n }\n\n const id = response.body.query.pages[0].pageprops.wikibase_item;\n\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Article Wikidata ID retrieved.',\n id\n });\n return id;\n }\n );\n}\n\n/**\n * For a Wikidata item return article names from Wikidata's MW API in\n * given languages.\n *\n * @param {Object} app\n * @param {string} wikidataId\n * @param {string[]} languages\n * @return {Promise} promise that resolves with article's names or `null`\n */\nfunction getArticleNames(app, wikidataId, languages) {\n const domain = app.conf.wikidata_domain;\n const parameters = {\n format: 'json',\n formatversion: 2,\n action: 'wbgetentities',\n ids: wikidataId,\n props: 'sitelinks',\n sitefilter: languages.map(x => `${ x }wiki`).join('|')\n };\n\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Getting article titles from the MW API.',\n wikidataId,\n languages\n });\n\n return aUtils.mwApiGet(app, domain, parameters).then(\n (response) => {\n if (!response.body || !response.body.entities ||\n !response.body.entities[wikidataId] ||\n !response.body.entities[wikidataId].sitelinks) {\n app.logger.log('debug/article.creation.morelike', {\n msg: 'No article names from Wikidta retrieved.',\n wikidataId,\n languages\n });\n return null;\n }\n\n const sitelinks = response.body.entities[wikidataId].sitelinks;\n const articleNames = {};\n\n languages.forEach((lang) => {\n const wiki = sitelinks[`${ lang }wiki`];\n if (wiki && wiki.title) {\n if (lang in articleNames) {\n articleNames[lang].push(wiki.title);\n } else {\n articleNames[lang] = [wiki.title];\n }\n }\n });\n\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Article names from Wikidata retrieved.',\n articleNames\n });\n\n return articleNames;\n }\n );\n}\n\n/**\n * Get similar articles to articleNames using MediaWiki morelike API\n *\n * @param {Object} app\n * @param {string} language Wiki language\n * @param {string} projectDomain\n * @param {string} wikidataId\n * @param {string[]} articleNames\n * @return {Promise} promise that resolves with the list of wikidata IDs\n */\nfunction getMorelike(app, language, projectDomain, wikidataId, articleNames) {\n const domain = `${ language }.${ projectDomain }`;\n const seedQuery = app.queryTemplates.seed.expand({\n params: {\n seed: articleNames.join('|')\n }\n });\n\n return aUtils.mwApiGet(app, domain, seedQuery.parameters).then(\n (response) => {\n if (!response.body || !response.body.query ||\n !response.body.query.pages) {\n app.logger.log('debug/article.creation.morelike', {\n msg: 'No article Wikidta ID retrieved.'\n });\n return [];\n }\n\n const pages = response.body.query.pages;\n const similarIds = [];\n for (const id in pages) {\n if (id) {\n const pageprops = pages[id].pageprops;\n if (pageprops && pageprops.wikibase_item) {\n similarIds.push(pageprops.wikibase_item);\n }\n }\n }\n return similarIds;\n });\n}\n\n/**\n * Get Wikidata item IDs similar to wikidataId using morelike API for languages\n *\n * @param {Object} app\n * @param {string} projectDomain\n * @param {string} wikidataId\n * @param {string[]} languages\n * @return {Promise} promise that resolves with the list of similar Wikidata IDs\n */\nfunction getSimilarArticles(app, projectDomain, wikidataId, languages) {\n return getArticleNames(app, wikidataId, languages)\n .then((articleNames) => {\n const requests = [];\n for (const language in articleNames) {\n if (language) {\n requests.push(getMorelike(\n app, language, projectDomain, wikidataId,\n articleNames[language]));\n }\n }\n\n return Promise.all(requests)\n .then((morelikeItems) => {\n const wikidataIds = [];\n morelikeItems.forEach((item) => {\n wikidataIds.push(...item);\n });\n return Array.from(new Set(wikidataIds));\n });\n });\n}\n\n/**\n * Return filtered Wikidata item IDs that don't have a sitelink to the\n * wiki indicated by language.\n *\n * @param {Object} app\n * @param {string} projectDomain\n * @param {string[]} wikidataIds\n * @param {string} language\n * @return {Promise} promise that resolves with the list of Wikidata IDs\n */\nfunction getMissingArticles(app, projectDomain, wikidataIds, language) {\n const domain = app.conf.wikidata_domain;\n const wiki = `${ language }wiki`;\n // hard-limit set by the API on the number of IDs we can pass to the API\n const idLimit = 50;\n const parameters = {\n format: 'json',\n formatversion: 2,\n action: 'wbgetentities',\n props: 'sitelinks',\n sitefilter: wiki\n };\n\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Getting article titles from the MW API.',\n wikidataIds,\n language\n });\n\n // Split Wikidata IDs in to chunks and make separate requests so\n // that we don't hit the API limit.\n const requests = [];\n const requestCount = Math.ceil(wikidataIds.length / idLimit);\n for (let i = 0; i < requestCount; i++) {\n const start = i * idLimit;\n const end = start + idLimit;\n const ids = wikidataIds.slice(start, end);\n parameters.ids = ids.join('|');\n requests.push(\n aUtils.mwApiGet(app, domain, parameters)\n );\n }\n return Promise.all(requests)\n .then((responses) => {\n const results = [];\n responses.forEach((response) => {\n const entities = response.body.entities;\n for (const id in entities) {\n if (!entities[id].sitelinks ||\n !entities[id].sitelinks[wiki]) {\n results.push(id);\n }\n }\n });\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Retrieved missing articles.',\n results\n });\n return results;\n })\n .catch((error) => {\n app.logger.log('error/article.creation.morelike', {\n msg: 'Could not retrieve missing articles.',\n error\n });\n return null;\n });\n}\n\n/**\n * Internal function for getting normalized ranks from MySQL\n *\n * In case of MySQL failure, the function is called recursively until no\n * more retries are left.\n *\n * @param {Object} app\n * @param {string[]} wikidataIds\n * @param {string} targetLanguage language used as the target language\n * in recommendation predictions\n * @param {number} retry number of times to retry MySQL query in case of failure\n * @param {number} retryDelay delay in ms before retrying MySQL connection\n * @param {Function} reject callback\n * @param {Function} resolve callback\n */\nfunction _getArticleNormalizedRanksFromMySQL(\n app, wikidataIds, targetLanguage, retry, retryDelay, reject, resolve) {\n const langTable = app.conf.mysql_tables.language;\n const normalizedRankTable = app.conf.mysql_tables.normalized_rank;\n\n app.mysqlPool.query(\n `SELECT max_vals.wikidata_id, rank_table.normalized_rank,\n source.code as source_language from (SELECT wikidata_id, max(normalized_rank) as normalized_rank\n FROM ?? INNER JOIN ?? as target ON ??=target.id\n WHERE wikidata_id in (?)\n AND target.code=? GROUP BY wikidata_id\n ORDER BY max(normalized_rank) DESC) as max_vals\n LEFT JOIN ?? as rank_table\n ON max_vals.wikidata_id=rank_table.wikidata_id AND\n max_vals.normalized_rank=rank_table.normalized_rank\n INNER JOIN ?? as source ON\n rank_table.source_id=source.id LIMIT 10`,\n [normalizedRankTable, langTable,\n `${ normalizedRankTable }.target_id`, wikidataIds,\n targetLanguage, normalizedRankTable, langTable],\n (error, results, _) => {\n if (error) {\n app.logger.log('error/article.creation.morelike', error);\n if (retry > 0) {\n app.logger.log(\n 'debug/article.creation.morelike',\n {\n msg: 'Retrying MySQL query.',\n retry,\n retryDelay\n });\n setTimeout(_getArticleNormalizedRanksFromMySQL, retryDelay,\n app, wikidataIds, targetLanguage, --retry,\n retryDelay, reject, resolve);\n } else {\n reject(error);\n }\n return;\n }\n\n if (results && results.length) {\n app.logger.log('debug/article.creation.morelike', {\n msg: 'Articles retrieved from DB.',\n count: results.length\n });\n }\n results = results.map((x) => {\n x.wikidata_id = `Q${ x.wikidata_id }`;\n return x;\n });\n resolve(results);\n });\n}\n\n/**\n * Get recommendation normalized ranks for Wikidata IDs\n *\n * @param {Object} app\n * @param {string[]} wikidataIds\n * @param {string} targetLanguage language used as the target language\n * in recommendation predictions\n * @return {Promise} promise that resolves with Wikidata IDs and their\n * recommendation normalized ranks\n */\nfunction getArticleNormalizedRanksFromDb(app, wikidataIds, targetLanguage) {\n const retry = app.conf.mysql_conn.retry || 2;\n const retryDelay = app.conf.mysql_conn.retry_delay || 1000;\n\n wikidataIds = wikidataIds.map((x) => parseInt(x.replace('Q', ''), 10));\n\n return new BBPromise((resolve, reject) => {\n _getArticleNormalizedRanksFromMySQL(\n app, wikidataIds, targetLanguage, retry, retryDelay,\n reject, resolve);\n });\n}\n\nmodule.exports = {\n getWikidataId,\n getSimilarArticles,\n getMissingArticles,\n getArticleNormalizedRanksFromDb\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/article.creation.translation.js","messages":[{"ruleId":"no-shadow","severity":1,"message":"'candidates' is already declared in the upper scope on line 122 column 9.","line":129,"column":12,"nodeType":"Identifier","messageId":"noShadow","endLine":129,"endColumn":22}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst aUtils = require('./api-util');\nconst util = require('./util');\n\n/**\n * Gets articles from the mw api\n *\n * @param {Object} app the application object\n * @param {string} domain the domain to query\n * @param {Object} params the query parameters\n * @return {Promise.<Object>} the resulting map of wikidata id to article title\n */\nfunction getArticles(app, domain, params) {\n return aUtils.mwApiGet(app, domain, params)\n .then((response) => {\n if (Object.prototype.hasOwnProperty.call(response.body, 'error')) {\n throw new util.HTTPError({\n status: 500,\n type: 'internal_server_error',\n title: 'MediaWiki API error',\n detail: JSON.stringify(response.body)\n });\n }\n if (!Object.prototype.hasOwnProperty.call(response.body, 'query')) {\n throw new util.HTTPError({\n status: 404,\n type: 'not_found',\n title: 'no results found',\n detail: JSON.stringify(response.body)\n });\n }\n return Object.keys(response.body.query.pages)\n .reduce((accumulator, currentKey) => {\n const current = response.body.query.pages[currentKey];\n if (current.ns !== 0) {\n return accumulator;\n }\n if (!current.pageprops || !current.pageprops.wikibase_item) {\n return accumulator;\n }\n if (current.title.includes(':') ||\n current.title.includes('List') === 0) {\n return accumulator;\n }\n if ('langlinks' in current || 'disambiguation' in current.pageprops) {\n return accumulator;\n } else {\n accumulator.push({\n wikidata_id: current.pageprops.wikibase_item,\n title: current.title,\n sitelink_count: current.langlinkscount ? current.langlinkscount + 1 : 1\n });\n return accumulator;\n }\n }, []);\n });\n}\n\n/**\n * Gets articles most closely related to seed\n *\n * @param {Object} app the application object\n * @param {string} source the source language code\n * @param {string} target the target language code\n * @param {string} projectDomain the project domain\n * @param {string} seed the seed to search by\n * @return {Promise.<Object>}\n */\nfunction getArticlesBySeed(app, source, target, projectDomain, seed) {\n const domain = `${ source }.${ projectDomain }`;\n const parameters = {\n format: 'json',\n action: 'query',\n prop: 'pageprops|langlinks|langlinkscount',\n ppprop: 'wikibase_item|disambiguation',\n lllang: target,\n lllimit: 500,\n generator: 'search',\n gsrlimit: 500,\n gsrsearch: `morelike:${ seed }`\n };\n\n return getArticles(app, domain, parameters);\n}\n\n/**\n * Gets the most popular articles in source wikipedia\n *\n * @param {Object} app the application object\n * @param {string} source the source language code\n * @param {string} target the target language code\n * @param {string} projectDomain the project domain\n * @return {Promise.<Object>}\n */\nfunction getArticlesByPageviews(app, source, target, projectDomain) {\n const domain = `${ source }.${ projectDomain }`;\n const parameters = {\n format: 'json',\n action: 'query',\n prop: 'pageprops|langlinks|langlinkscount',\n ppprop: 'wikibase_item|disambiguation',\n generator: 'mostviewed',\n lllang: target,\n lllimit: 500,\n gpvimlimit: 500\n };\n return getArticles(app, domain, parameters);\n}\n\n/**\n * Recommends articles in source to translate to target\n *\n * @param {Object} app the application object\n * @param {string} source the source language code\n * @param {string} target the target language code\n * @param {string} projectDomain the project domain\n * @param {string} [seed=null] the seed to search by, if any\n * @return {Promise.<Object[]>}\n */\nfunction recommend(app, source, target, projectDomain, seed) {\n let candidates;\n if (seed) {\n candidates = getArticlesBySeed(app, source, target, projectDomain, seed);\n } else {\n candidates = getArticlesByPageviews(app, source, target, projectDomain);\n }\n return candidates\n .then((candidates) => candidates.sort((a, b) => b.sitelink_count - a.sitelink_count));\n}\n\nmodule.exports = {\n recommend\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/caption.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/description.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/suggested-edits-common.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/swagger-ui.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/util.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":109,"column":1,"nodeType":"Block","endLine":109,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'bool' is undefined.","line":155,"column":1,"nodeType":"Block","endLine":155,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":165,"column":1,"nodeType":"Block","endLine":165,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Router' is undefined.","line":260,"column":1,"nodeType":"Block","endLine":260,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Application' is undefined.","line":280,"column":1,"nodeType":"Block","endLine":280,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst BBPromise = require('bluebird');\nconst express = require('express');\nconst uuid = require('cassandra-uuid');\nconst bunyan = require('bunyan');\n\n/**\n * Error instance wrapping HTTP error responses\n */\nclass HTTPError extends Error {\n\n constructor(response) {\n super();\n Error.captureStackTrace(this, HTTPError);\n\n if (response.constructor !== Object) {\n // just assume this is just the error message\n response = {\n status: 500,\n type: 'internal_error',\n title: 'InternalError',\n detail: response\n };\n }\n\n this.name = this.constructor.name;\n this.message = `${ response.status }`;\n if (response.type) {\n this.message += `: ${ response.type }`;\n }\n\n Object.assign(this, response);\n }\n}\n\n/**\n * Generates an object suitable for logging out of a request object\n *\n * @param {!Request} req the request\n * @param {?RegExp} whitelistRE the RegExp used to filter headers\n * @return {!Object} an object containing the key components of the request\n */\nfunction reqForLog(req, whitelistRE) {\n\n const ret = {\n url: req.originalUrl,\n headers: {},\n method: req.method,\n params: req.params,\n query: req.query,\n body: req.body,\n remoteAddress: req.connection.remoteAddress,\n remotePort: req.connection.remotePort\n };\n\n if (req.headers && whitelistRE) {\n Object.keys(req.headers).forEach((hdr) => {\n if (whitelistRE.test(hdr)) {\n ret.headers[hdr] = req.headers[hdr];\n }\n });\n }\n\n return ret;\n\n}\n\n/**\n * Serialises an error object in a form suitable for logging.\n *\n * @param {!Error} err error to serialise\n * @return {!Object} the serialised version of the error\n */\nfunction errForLog(err) {\n\n const ret = bunyan.stdSerializers.err(err);\n ret.status = err.status;\n ret.type = err.type;\n ret.detail = err.detail;\n\n // log the stack trace only for 500 errors\n if (Number.parseInt(ret.status, 10) !== 500) {\n ret.stack = undefined;\n }\n\n return ret;\n\n}\n\n/**\n * Generates a unique request ID.\n *\n * @return {!string} the generated request ID\n */\nfunction generateRequestId() {\n\n return uuid.TimeUuid.now().toString();\n\n}\n\n/**\n * Wraps all of the given router's handler functions with\n * promised try blocks so as to allow catching all errors,\n * regardless of whether a handler returns/uses promises\n * or not.\n *\n * @param {!Object} route the object containing the router and path to bind it to\n * @param {!Application} app the application object\n */\nfunction wrapRouteHandlers(route, app) {\n\n route.router.stack.forEach((routerLayer) => {\n const path = (route.path + routerLayer.route.path.slice(1))\n .replace(/\\/:/g, '/--')\n .replace(/^\\//, '')\n .replace(/[/?]+$/, '');\n routerLayer.route.stack.forEach((layer) => {\n const origHandler = layer.handle;\n layer.handle = function (req, res, next) {\n const startTime = Date.now();\n BBPromise.try(() => origHandler(req, res, next))\n .catch(next)\n .finally(() => {\n let statusCode = parseInt(res.statusCode, 10) || 500;\n if (statusCode < 100 || statusCode > 599) {\n statusCode = 500;\n }\n app.metrics.makeMetric({\n type: 'Histogram',\n name: 'router',\n prometheus: {\n name: 'recommendation_api_router_request_duration_seconds',\n help: 'request duration handled by router',\n buckets: [0.01, 0.05, 0.1, 0.5, 1, 5]\n },\n labels: {\n names: ['path', 'method', 'status'],\n omitLabelNames: true\n }\n }).endTiming(startTime, [path || 'root', req.method, statusCode]);\n });\n };\n });\n });\n\n}\n\n/**\n * Heuristically determine whether the request is a health check, i.e.\n * initiated by service-checker-swagger. Useful for handling MW API\n * errors differently when it's under stress.\n *\n * @param {!Request} req\n * @return {bool}\n */\nfunction isHealthCheck(req) {\n const userAgent = req.headers['user-agent'];\n return userAgent && userAgent.startsWith('ServiceChecker-WMF');\n}\n\n/**\n * Generates an error handler for the given applications and installs it.\n *\n * @param {!Application} app the application object to add the handler to\n */\nfunction setErrorHandler(app) {\n\n app.use((err, req, res, next) => {\n let errObj;\n // ensure this is an HTTPError object\n if (err.constructor === HTTPError) {\n errObj = err;\n } else if (err instanceof Error) {\n // is this an HTTPError defined elsewhere? (preq)\n if (err.constructor.name === 'HTTPError') {\n const o = { status: err.status };\n if (err.body && err.body.constructor === Object) {\n Object.keys(err.body).forEach((key) => {\n o[key] = err.body[key];\n });\n } else {\n o.detail = err.body;\n }\n o.message = err.message;\n errObj = new HTTPError(o);\n } else {\n // this is a standard error, convert it\n errObj = new HTTPError({\n status: 500,\n type: 'internal_error',\n title: err.name,\n detail: err.message,\n stack: err.stack\n });\n }\n } else if (err.constructor === Object) {\n // this is a regular object, suppose it's a response\n errObj = new HTTPError(err);\n } else {\n // just assume this is just the error message\n errObj = new HTTPError({\n status: 500,\n type: 'internal_error',\n title: 'InternalError',\n detail: err\n });\n }\n // ensure some important error fields are present\n if (!errObj.status) {\n errObj.status = 500;\n }\n if (!errObj.type) {\n errObj.type = 'internal_error';\n }\n // add the offending URI and method as well\n if (!errObj.method) {\n errObj.method = req.method;\n }\n if (!errObj.uri) {\n errObj.uri = req.url;\n }\n // some set 'message' or 'description' instead of 'detail'\n errObj.detail = errObj.detail || errObj.message || errObj.description || '';\n // adjust the log level based on the status code\n let level = 'error';\n if (Number.parseInt(errObj.status, 10) < 400) {\n level = 'trace';\n } else if (Number.parseInt(errObj.status, 10) < 500) {\n level = 'info';\n }\n // log the error\n const component = (errObj.component ? errObj.component : errObj.status);\n (req.logger || app.logger).log(`${ level }/${ component }`, errForLog(errObj));\n // Reduce false alarms to SRE stemming from health check\n // requests. These kinds of '500+' errors may happen when the\n // MediaWiki API is under load and fails to return a success.\n // See https://phabricator.wikimedia.org/T247732#6099579\n if (isHealthCheck(req) && err.healthCheckStatus) {\n errObj.status = err.healthCheckStatus;\n }\n // let through only non-sensitive info\n const respBody = {\n status: errObj.status,\n type: errObj.type,\n title: errObj.title,\n detail: errObj.detail,\n method: errObj.method,\n uri: errObj.uri\n };\n res.status(errObj.status).json(respBody);\n });\n\n}\n\n/**\n * Creates a new router with some default options.\n *\n * @param {?Object} [opts] additional options to pass to express.Router()\n * @return {!Router} a new router object\n */\nfunction createRouter(opts) {\n\n const options = {\n mergeParams: true\n };\n\n if (opts && opts.constructor === Object) {\n Object.assign(options, opts);\n }\n\n return new express.Router(options);\n\n}\n\n/**\n * Adds logger to the request and logs it.\n *\n * @param {!*} req request object\n * @param {!Application} app application object\n */\nfunction initAndLogRequest(req, app) {\n req.headers = req.headers || {};\n req.headers['x-request-id'] = req.headers['x-request-id'] || generateRequestId();\n req.logger = app.logger.child({\n request_id: req.headers['x-request-id'],\n request: reqForLog(req, app.conf.log_header_whitelist)\n });\n req.logger.log('trace/req', { msg: 'incoming request' });\n}\n\nmodule.exports = {\n HTTPError,\n initAndLogRequest,\n wrapRouteHandlers,\n setErrorHandler,\n router: createRouter\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/article.creation.morelike.js","messages":[{"ruleId":"no-shadow","severity":1,"message":"'ids' is already declared in the upper scope on line 66 column 24.","line":75,"column":32,"nodeType":"Identifier","messageId":"noShadow","endLine":75,"endColumn":35}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst BBPromise = require('bluebird');\nconst mysql = require('mysql');\nconst util = require('../lib/util');\nconst aUtil = require('../lib/article.creation.morelike');\n\nconst router = util.router();\nlet app;\n\nfunction mwApiFailure(e) {\n app.logger.log('error/article.creation.morelike', { e });\n return BBPromise.reject(new util.HTTPError({\n status: 503,\n healthCheckStatus: 404, // extra flag to reduce false alarms\n message: 'The MediaWiki API failed. Please try again later.'\n }));\n}\n\n/**\n * GET /{seed}\n * Gets missing articles (from the current wiki) similar to seed.\n *\n * Similar articles are retrieved using a CirrusSearch morelike query.\n * Articles are prioritized using translation recommendations\n * predictions.\n */\nrouter.get('/:seed', (req, res) => {\n const domain = req.params.domain;\n const domainParts = domain.split('.');\n const language = domainParts[0]; // e.g. en\n const projectDomain = domainParts.splice(1).join('.');\n\n let sourceLanguages = [];\n let availableModels = [];\n\n if (app.conf.article && app.conf.article.translation_models) {\n sourceLanguages = app.conf.article.translation_models[language] || [];\n availableModels = Object.keys(app.conf.article.translation_models);\n }\n\n if (!sourceLanguages.length) {\n app.logger.log('error/article.creation.morelike',\n `Article translation model for \"${ language }\" doesn't exist.`);\n\n const errorObject = new util.HTTPError({\n status: 501,\n message: `'morelike' article recommendations are not enabled on\n this Wikipedia. Currently enabled on:\n ${ availableModels.join(', ') || 'none' }.`\n });\n return BBPromise.reject(errorObject);\n }\n\n return aUtil.getWikidataId(app, domain, req.params.seed)\n .catch(mwApiFailure)\n .then((id) => {\n if (!id) {\n return BBPromise.reject(new util.HTTPError({\n status: 404,\n message: 'No such article found.'\n }));\n }\n return aUtil.getSimilarArticles(app, projectDomain, id, sourceLanguages)\n .catch(mwApiFailure)\n .then((ids) => {\n if (!ids.length) {\n return BBPromise.reject(new util.HTTPError({\n status: 404,\n message: 'No similar articles to seed found.'\n }));\n }\n return aUtil.getMissingArticles(app, projectDomain, ids, language)\n .catch(mwApiFailure)\n .then((ids) => {\n if (ids === null) {\n return mwApiFailure();\n } else if (!ids.length) {\n return BBPromise.reject(new util.HTTPError({\n status: 404,\n message: 'All similar articles have been created.'\n }));\n } else {\n return aUtil.getArticleNormalizedRanksFromDb(\n app, ids, language\n ).then((results) => {\n res.json(results);\n }).catch((error) => BBPromise.reject(new util.HTTPError({\n status: 503,\n message: 'Cannot retrieve normalized ranks from' +\n ' the database. Please try again later.'\n })));\n }\n });\n });\n });\n});\n\nmodule.exports = function (appObj) {\n app = appObj;\n\n const mysqlConf = app.conf.mysql_conn;\n const hostPort = mysqlConf.host.split(':');\n app.mysqlPool = mysql.createPool({\n connectionLimit: mysqlConf.limit,\n host: hostPort[0],\n port: hostPort[1] || 3306,\n user: mysqlConf.user,\n password: mysqlConf.pass,\n database: mysqlConf.name\n });\n\n return {\n path: '/article/creation/morelike',\n api_version: 1,\n router\n };\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/article.creation.translation.js","messages":[{"ruleId":"security/detect-unsafe-regex","severity":1,"message":"Unsafe Regular Expression","line":14,"column":25,"nodeType":"Literal","endLine":14,"endColumn":51}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst util = require('../lib/util');\nconst tUtil = require('../lib/article.creation.translation');\n\nconst router = util.router();\nlet app;\n\n/**\n * Regular expression used for validating the source parameter\n *\n * @type {RegExp}\n */\nconst sourceValidator = /^[a-zA-Z]+(-[a-zA-Z]+)*$/;\n\nfunction recommend(req, res, source, target, projectDomain, seed) {\n if (!sourceValidator.test(source)) {\n throw new util.HTTPError({\n status: 400,\n type: 'bad_request',\n title: 'Bad request',\n detail: 'source parameter was invalid'\n });\n }\n\n let count = 24;\n if (req.query && req.query.count) {\n count = parseInt(req.query.count, 10);\n if (isNaN(count) || count < 1 || count > 500) {\n throw new util.HTTPError({\n status: 400,\n type: 'bad_request',\n title: 'Bad request',\n detail: 'count parameter was invalid'\n });\n }\n }\n\n return tUtil.recommend(app, source, target, projectDomain, seed)\n .then((result) => {\n result = result.slice(0, count);\n res.json({\n count: result.length,\n items: result\n });\n });\n}\n\n/**\n * GET /{source}/{seed}\n * Gets the articles existing in source but missing in domain based on seed.\n */\nrouter.get('/:source/:seed?', (req, res) => {\n const domainParts = req.params.domain.split('.');\n const target = domainParts[0];\n const projectDomain = domainParts.splice(1).join('.');\n return recommend(req, res, req.params.source, target,\n projectDomain, req.params.seed);\n});\n\nmodule.exports = function (appObj) {\n\n app = appObj;\n\n return {\n path: '/article/creation/translation',\n api_version: 1,\n router\n };\n\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/caption.addition.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/caption.translation.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/description.addition.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/description.translation.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/routes/root.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/server.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/spec.yaml","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 115. Maximum allowed is 100.","line":234,"column":1,"nodeType":"Program","messageId":"max","endLine":234,"endColumn":116},{"ruleId":"max-len","severity":1,"message":"This line has a length of 120. Maximum allowed is 100.","line":307,"column":1,"nodeType":"Program","messageId":"max","endLine":307,"endColumn":121}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"swagger: \"2.0\"\ninfo:\n termsOfService: https://wikimediafoundation.org/wiki/Terms_of_Use\n contact:\n name: the Wikimedia Research team\n url: https://www.mediawiki.org/wiki/Wikimedia_Research\n license:\n name: Apache2\n url: http://www.apache.org/licenses/LICENSE-2.0\npaths:\n # from routes/root.js\n /robots.txt:\n get:\n tags:\n - Root\n - Robots\n description: Gets robots.txt\n x-amples:\n - title: robots.txt check\n request: {}\n response:\n status: 200\n headers:\n user-agent: \"*\"\n disallow: /\n /:\n get:\n tags:\n - Root\n description: The root service end-point\n produces:\n - application/json\n x-amples:\n - title: root with no query params\n request: {}\n response:\n status: 404\n - title: spec from root\n request:\n query:\n spec: true\n response:\n status: 200\n - title: doc from root\n request:\n query:\n doc: true\n response:\n status: 200\n - title: root with wrong query param\n request:\n query:\n fooo: true\n response:\n status: 404\n # from routes/article.creation.translation.js\n /{domain}/v1/article/creation/translation/{source}{/seed}:\n get:\n tags:\n - Recommend\n summary: Recommend missing articles\n description: |\n Recommends articles to be translated from the source\n to the domain language.\n Stability: [unstable](https://www.mediawiki.org/wiki/API_versioning#Unstable)\n produces:\n - applicaiton/json\n parameters:\n - name: source\n in: path\n description: The source language code\n type: string\n required: true\n - name: domain\n in: path\n description: The target domain\n type: string\n required: true\n - name: seed\n in: path\n description: The article to use as a search seed\n type: string\n required: false\n - name: count\n in: query\n description: The max number of articles to return\n type: int\n required: false\n default: 24\n x-amples:\n # # TODO: Find a stable source of pageview data (T233381)\n # - title: article.creation.translation - normal source and target\n # request:\n # params:\n # source: it\n # domain: de.wikipedia.org\n # response:\n # status: 200\n # headers:\n # content-type: application/json\n - title: article.creation.translation - normal source and target with seed\n request:\n params:\n source: en\n domain: de.wikipedia.org\n seed: Apple\n response:\n status: 200\n headers:\n content-type: application/json\n # # TODO: Find a solution for this case\n # - title: article.creation.translation - bad source\n # request:\n # params:\n # source: qqq\n # domain: de.wikipedia.org\n # response:\n # status: 504\n # headers:\n # content-type: application/json\n - title: article.creation.translation - bad seed\n request:\n params:\n source: en\n domain: de.wikipedia.org\n seed: thishsouldnotreturnanyresultsfromthesearchapi\n response:\n status: 404\n headers:\n content-type: application/json\n - title: article.creation.translation - invalid count\n request:\n params:\n source: en\n domain: de.wikipedia.org\n query:\n count: -123\n response:\n status: 400\n - title: article.creation.translation - incorrectly formatted source\n request:\n params:\n source: en-\n domain: de.wikipedia.org\n response:\n status: 400\n /{domain}/v1/article/creation/morelike/{seed}:\n get:\n tags:\n - Recommendation\n summary: Recommend missing articles\n description: |\n Recommends articles similar to the seed article but are missing\n from the domain language Wikipedia.\n\n Stability: [unstable](https://www.mediawiki.org/wiki/API_versioning#Unstable)\n produces:\n - application/json\n - application/problem+json\n parameters:\n - name: seed\n in: path\n description: The article title used to search similar but missing articles\n type: string\n required: true\n x-amples:\n - title: article.creation.morelike - good article title\n # Disabling for now because the test environment may not have\n # access to MySQL. See feature tests for a replacement.\n skip-locally: true\n request:\n params:\n seed: Palov\n domain: uz.wikipedia.org\n response:\n status: 200\n headers:\n content-type: application/json\n - title: article.creation.morelike - bad article title\n request:\n params:\n seed: Palov-missing\n domain: uz.wikipedia.org\n response:\n status: 404\n headers:\n content-type: application/json\n - title: article.creation.morelike - missing models\n request:\n params:\n seed: Palov\n domain: blah.wikipedia.org\n response:\n status: 501\n headers:\n content-type: application/json\n\n /{domain}/v1/caption/addition/{target}:\n get:\n tags:\n - Recommendation\n summary: Recommend files missing a caption (label) in the target language\n produces:\n - application/json\n - application/problem+json\n parameters:\n - name: target\n in: path\n description: The target wiki language code for suggestions\n type: string\n required: true\n x-amples:\n - title: Caption addition suggestions\n request:\n params:\n domain: commons.wikimedia.org\n target: zh\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n - pageid: /.+/\n ns: 6\n title: /.+/\n mime: /image.*/\n structured:\n captions: /.+/\n\n /{domain}/v1/caption/translation/from/{source}/to/{target}:\n get:\n tags:\n - Recommendation\n summary: Recommend files with a caption (label) in the source language but missing one in the target language\n produces:\n - application/json\n - application/problem+json\n parameters:\n - name: source\n in: path\n description: The source wiki language code for suggestions\n type: string\n required: true\n - name: target\n in: path\n description: The target wiki language code for suggestions\n type: string\n required: true\n x-amples:\n - title: Caption translation suggestions\n request:\n params:\n domain: commons.wikimedia.org\n source: en\n target: zh\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n - pageid: /.+/\n ns: 6\n title: /.+/\n mime: /image.*/\n structured:\n captions: /.+/\n\n /{domain}/v1/description/addition/{target}:\n get:\n tags:\n - Recommendation\n summary: Recommend Wikibase items missing a description in the target language\n produces:\n - application/json\n - application/problem+json\n parameters:\n - name: target\n in: path\n description: The target wiki language code for suggestions\n type: string\n required: true\n x-amples:\n - title: Description addition suggestions\n request:\n params:\n domain: www.wikidata.org\n target: zh\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n - pageid: /.+/\n ns: 0\n title: /.+/\n wikibase_item:\n type: item\n id: /.+/\n labels: /.+/\n descriptions: /.+/\n sitelinks: /.+/\n\n /{domain}/v1/description/translation/from/{source}/to/{target}:\n get:\n tags:\n - Recommendation\n summary: Recommend Wikibase items with a description in the source language but missing one in the target language\n produces:\n - application/json\n - application/problem+json\n parameters:\n - name: source\n in: path\n description: The source wiki language code for suggestions\n type: string\n required: true\n - name: target\n in: path\n description: The target wiki language code for suggestions\n type: string\n required: true\n x-amples:\n - title: Description translation suggestions\n request:\n params:\n domain: www.wikidata.org\n source: en\n target: zh\n response:\n status: 200\n headers:\n content-type: application/json\n body:\n - pageid: /.+/\n ns: 0\n title: /.+/\n wikibase_item:\n type: item\n id: /.+/\n labels: /.+/\n descriptions: /.+/\n sitelinks: /.+/\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/targets.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/app/app.js","messages":[{"ruleId":"no-redeclare","severity":1,"message":"'describe' is already defined as a built-in global variable.","line":1,"column":11,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":19},{"ruleId":"no-redeclare","severity":1,"message":"'it' is already defined as a built-in global variable.","line":1,"column":21,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":23},{"ruleId":"no-redeclare","severity":1,"message":"'before' is already defined as a built-in global variable.","line":1,"column":25,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":31},{"ruleId":"no-redeclare","severity":1,"message":"'after' is already defined as a built-in global variable.","line":1,"column":33,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":38}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* global describe, it, before, after */\n\n'use strict';\n\nconst preq = require('preq');\nconst assert = require('../../utils/assert.js');\nconst server = require('../../utils/server.js');\n\nif (!server.stopHookAdded) {\n server.stopHookAdded = true;\n after(() => server.stop());\n}\n\ndescribe('express app', function () {\n\n this.timeout(20000);\n\n before(() => server.start());\n\n it('should get robots.txt', () => preq.get({\n uri: `${ server.config.uri }robots.txt`\n }).then((res) => {\n assert.deepEqual(res.status, 200);\n assert.deepEqual(res.headers.disallow, '/');\n }));\n\n it('should set CORS headers', () => {\n if (server.config.service.conf.cors === false) {\n return true;\n }\n return preq.get({\n uri: `${ server.config.uri }robots.txt`\n }).then((res) => {\n assert.deepEqual(res.status, 200);\n assert.deepEqual(res.headers['access-control-allow-origin'], '*');\n assert.deepEqual(!!res.headers['access-control-allow-headers'], true);\n assert.deepEqual(!!res.headers['access-control-expose-headers'], true);\n });\n });\n\n it('should set CSP headers', () => {\n if (server.config.service.conf.csp === false) {\n return true;\n }\n return preq.get({\n uri: `${ server.config.uri }robots.txt`\n }).then((res) => {\n assert.deepEqual(res.status, 200);\n assert.deepEqual(res.headers['x-xss-protection'], '1; mode=block');\n assert.deepEqual(res.headers['x-content-type-options'], 'nosniff');\n assert.deepEqual(res.headers['x-frame-options'], 'SAMEORIGIN');\n\n assert.deepEqual(res.headers['content-security-policy'], 'default-src \\'self\\'; object-src \\'none\\'; media-src *; img-src *; style-src *; frame-ancestors \\'self\\'');\n assert.deepEqual(res.headers['x-content-security-policy'], 'default-src \\'self\\'; object-src \\'none\\'; media-src *; img-src *; style-src *; frame-ancestors \\'self\\'');\n assert.deepEqual(res.headers['x-webkit-csp'], 'default-src \\'self\\'; object-src \\'none\\'; media-src *; img-src *; style-src *; frame-ancestors \\'self\\'');\n\n });\n });\n\n it('should get static content gzipped', () => preq.get({\n uri: `${ server.config.uri }static/index.html`,\n headers: {\n 'accept-encoding': 'gzip, deflate'\n }\n }).then((res) => {\n assert.deepEqual(res.status, 200);\n // if there is no content-length, the reponse was gzipped\n assert.deepEqual(res.headers['content-length'], undefined,\n 'Did not expect the content-length header!');\n }));\n\n it('should get static content uncompressed', () => preq.get({\n uri: `${ server.config.uri }static/index.html`,\n headers: {\n 'accept-encoding': ''\n }\n }).then((res) => {\n const contentEncoding = res.headers['content-encoding'];\n assert.deepEqual(res.status, 200);\n assert.deepEqual(contentEncoding, undefined, 'Did not expect gzipped contents!');\n }));\n});\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/app/spec.js","messages":[{"ruleId":"no-redeclare","severity":1,"message":"'describe' is already defined as a built-in global variable.","line":1,"column":11,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":19},{"ruleId":"no-redeclare","severity":1,"message":"'it' is already defined as a built-in global variable.","line":1,"column":21,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":23},{"ruleId":"no-redeclare","severity":1,"message":"'before' is already defined as a built-in global variable.","line":1,"column":25,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":31},{"ruleId":"no-redeclare","severity":1,"message":"'after' is already defined as a built-in global variable.","line":1,"column":33,"nodeType":"Block","messageId":"redeclaredAsBuiltin","endLine":1,"endColumn":38},{"ruleId":"security/detect-non-literal-fs-filename","severity":1,"message":"Found readFileSync from package \"fs\" with non literal argument at index 0","line":24,"column":30,"nodeType":"CallExpression","endLine":24,"endColumn":55},{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":178,"column":14,"nodeType":"NewExpression","endLine":178,"endColumn":47}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* global describe, it, before, after */\n\n'use strict';\n\nconst preq = require('preq');\nconst assert = require('../../utils/assert.js');\nconst server = require('../../utils/server.js');\nconst URI = require('swagger-router').URI;\nconst yaml = require('js-yaml');\nconst fs = require('fs');\n\nif (!server.stopHookAdded) {\n server.stopHookAdded = true;\n after(() => server.stop());\n}\n\nfunction staticSpecLoad() {\n\n let spec;\n const myService = server.config.conf.services[server.config.conf.services.length - 1].conf;\n const specPath = `${ __dirname }/../../../${ myService.spec ? myService.spec : 'spec.yaml' }`;\n\n try {\n spec = yaml.safeLoad(fs.readFileSync(specPath));\n } catch (e) {\n // this error will be detected later, so ignore it\n spec = { paths: {}, 'x-default-params': {} };\n }\n\n return spec;\n\n}\n\nfunction validateExamples(pathStr, defParams, mSpec) {\n\n const uri = new URI(pathStr, {}, true);\n\n if (!mSpec) {\n try {\n uri.expand(defParams);\n return true;\n } catch (e) {\n throw new Error(`Missing parameter for route ${ pathStr } : ${ e.message }`);\n }\n }\n\n if (!Array.isArray(mSpec)) {\n throw new Error(`Route ${ pathStr } : x-amples must be an array!`);\n }\n\n mSpec.forEach((ex, idx) => {\n if (!ex.title) {\n throw new Error(`Route ${ pathStr }, example ${ idx }: title missing!`);\n }\n ex.request = ex.request || {};\n try {\n uri.expand(Object.assign({}, defParams, ex.request.params || {}));\n } catch (e) {\n throw new Error(\n `Route ${ pathStr }, example ${ idx } (${ ex.title }): missing parameter: ${ e.message }`\n );\n }\n });\n\n return true;\n\n}\n\nfunction constructTestCase(title, path, method, request, response) {\n\n return {\n title,\n request: {\n uri: server.config.uri + (path[0] === '/' ? path.slice(1) : path),\n method,\n headers: request.headers || {},\n query: request.query,\n body: request.body,\n followRedirect: false\n },\n response: {\n status: response.status || 200,\n headers: response.headers || {},\n body: response.body\n }\n };\n\n}\n\nfunction constructTests(paths, defParams) {\n\n const ret = [];\n\n Object.keys(paths).forEach((pathStr) => {\n Object.keys(paths[pathStr]).forEach((method) => {\n const p = paths[pathStr][method];\n if ({}.hasOwnProperty.call(p, 'x-monitor') && !p['x-monitor']) {\n return;\n }\n const uri = new URI(pathStr, {}, true);\n if (!p['x-amples']) {\n ret.push(constructTestCase(\n pathStr,\n uri.toString({ params: defParams }),\n method,\n {},\n {}\n ));\n return;\n }\n p['x-amples'].forEach((ex) => {\n ex.request = ex.request || {};\n if (!ex['skip-locally']) {\n ret.push(constructTestCase(\n ex.title,\n uri.toString({\n params: Object.assign(\n {},\n defParams,\n ex.request.params || {}\n )\n }),\n method,\n ex.request,\n ex.response || {}\n ));\n }\n });\n });\n });\n\n return ret;\n\n}\n\nfunction cmp(result, expected, errMsg) {\n\n if (expected === null || expected === undefined) {\n // nothing to expect, so we can return\n return true;\n }\n if (result === null || result === undefined) {\n result = '';\n }\n\n if (expected.constructor === Object) {\n Object.keys(expected).forEach((key) => {\n const val = expected[key];\n assert.deepEqual({}.hasOwnProperty.call(result, key), true,\n `Body field ${ key } not found in response!`);\n cmp(result[key], val, `${ key } body field mismatch!`);\n });\n return true;\n } else if (expected.constructor === Array) {\n if (result.constructor !== Array) {\n assert.deepEqual(result, expected, errMsg);\n return true;\n }\n // only one item in expected - compare them all\n if (expected.length === 1 && result.length > 1) {\n result.forEach((item) => {\n cmp(item, expected[0], errMsg);\n });\n return true;\n }\n // more than one item expected, check them one by one\n if (expected.length !== result.length) {\n assert.deepEqual(result, expected, errMsg);\n return true;\n }\n expected.forEach((item, idx) => {\n cmp(result[idx], item, errMsg);\n });\n return true;\n }\n\n if (expected.length > 1 && expected[0] === '/' && expected[expected.length - 1] === '/') {\n if ((new RegExp(expected.slice(1, -1))).test(result)) {\n return true;\n }\n } else if (expected.length === 0 && result.length === 0) {\n return true;\n } else if (result === expected || result.startsWith(expected)) {\n return true;\n }\n\n assert.deepEqual(result, expected, errMsg);\n return true;\n\n}\n\nfunction validateTestResponse(testCase, res) {\n\n const expRes = testCase.response;\n\n // check the status\n assert.status(res, expRes.status);\n // check the headers\n Object.keys(expRes.headers).forEach((key) => {\n const val = expRes.headers[key];\n assert.deepEqual({}.hasOwnProperty.call(res.headers, key), true,\n `Header ${ key } not found in response!`);\n cmp(res.headers[key], val, `${ key } header mismatch!`);\n });\n // check the body\n if (!expRes.body) {\n return true;\n }\n res.body = res.body || '';\n if (Buffer.isBuffer(res.body)) {\n res.body = res.body.toString();\n }\n if (expRes.body.constructor !== res.body.constructor) {\n if (expRes.body.constructor === String) {\n res.body = JSON.stringify(res.body);\n } else {\n res.body = JSON.parse(res.body);\n }\n }\n // check that the body type is the same\n if (expRes.body.constructor !== res.body.constructor) {\n throw new Error(\n `Expected body type ${ expRes.body.constructor } but got ${ res.body.constructor }`\n );\n }\n\n // compare the bodies\n cmp(res.body, expRes.body, 'Body mismatch!');\n\n return true;\n\n}\n\ndescribe('Swagger spec', function () {\n\n // the variable holding the spec\n let spec = staticSpecLoad();\n // default params, if given\n let defParams = spec['x-default-params'] || {};\n\n this.timeout(20000);\n\n before(() => server.start());\n\n it('get the spec', () => preq.get(`${ server.config.uri }?spec`)\n .then((res) => {\n assert.status(200);\n assert.contentType(res, 'application/json');\n assert.notDeepEqual(res.body, undefined, 'No body received!');\n spec = res.body;\n }));\n\n it('spec validation', () => {\n if (spec['x-default-params']) {\n defParams = spec['x-default-params'];\n }\n // check the high-level attributes\n ['info', 'swagger', 'paths'].forEach((prop) => {\n assert.deepEqual(!!spec[prop], true, `No ${ prop } field present!`);\n });\n // no paths - no love\n assert.deepEqual(!!Object.keys(spec.paths), true, 'No paths given in the spec!');\n // now check each path\n Object.keys(spec.paths).forEach((pathStr) => {\n assert.deepEqual(!!pathStr, true, 'A path cannot have a length of zero!');\n const path = spec.paths[pathStr];\n assert.deepEqual(!!Object.keys(path), true, `No methods defined for path: ${ pathStr }`);\n Object.keys(path).forEach((method) => {\n const mSpec = path[method];\n if ({}.hasOwnProperty.call(mSpec, 'x-monitor') && !mSpec['x-monitor']) {\n return;\n }\n validateExamples(pathStr, defParams, mSpec['x-amples']);\n });\n });\n });\n\n describe('routes', () => {\n\n constructTests(spec.paths, defParams).forEach((testCase) => {\n it(testCase.title, () => preq(testCase.request)\n .then((res) => {\n validateTestResponse(testCase, res);\n }, (err) => {\n validateTestResponse(testCase, err);\n }));\n });\n\n });\n});\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/features/v1/article.creation.morelike.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lib/article.creation.morelike.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lib/caption.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 136. Maximum allowed is 100.","line":193,"column":1,"nodeType":"Program","messageId":"max","endLine":193,"endColumn":137}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst rewire = require('rewire');\nconst lib = rewire('../../lib/caption');\nconst assert = require('../utils/assert');\n\ndescribe('lib:caption', () => {\n\n describe('convertGlobalUsagePageIdsToInts', () => {\n const convertGlobalUsagePageIdsToInts = lib.__get__('convertGlobalUsagePageIdsToInts');\n\n it('converts page ID string to int', () => {\n const image = {\n pageid: 1,\n ns: 6,\n title: 'File:Foo.jpg',\n mime: 'image/jpeg',\n structured: { captions: {} },\n globalusage: [{\n title: 'Foo',\n wiki: 'en.wikipedia.org',\n pageid: '5'\n }]\n };\n convertGlobalUsagePageIdsToInts(image);\n assert.deepEqual(image.globalusage[0].pageid, 5);\n });\n });\n\n describe('consolidateImageData', () => {\n const consolidateImageData = lib.__get__('consolidateImageData');\n\n it('consolidates entity data to expected items', () => {\n const images = { 1: {}, 2: {}, 3: {} };\n const entities = {\n M1: { labels: { en: { value: 'en' } } },\n M2: { labels: { es: { value: 'es' } } },\n M3: { labels: { de: { value: 'de' } } }\n };\n consolidateImageData(images, entities);\n assert.deepEqual(images['1'].structured.captions.en, 'en');\n assert.deepEqual(images['2'].structured.captions.es, 'es');\n assert.deepEqual(images['3'].structured.captions.de, 'de');\n });\n\n it('handles undefined entities object', () => {\n assert.doesNotThrow(consolidateImageData, {}, undefined);\n });\n\n });\n\n describe('filterPages', () => {\n const filterPages = lib.__get__('filterPages');\n\n it('filters non-image MIME types', () => {\n const pages = {\n 1: { imageinfo: [ { mime: 'audio/ogg' } ] },\n 2: { imageinfo: [ { mime: 'image/jpeg' } ] },\n 3: { imageinfo: [ { mime: 'text/html' } ] },\n 4: {\n imageinfo: [ { mime: 'image/jpeg' } ],\n protection: [ { type: 'edit', level: 'sysop' } ]\n }\n };\n const result = filterPages(pages);\n assert.deepEqual(Object.keys(result).length, 1);\n assert.ok(result['2']);\n });\n\n it('handles undefined pages object', () => {\n assert.doesNotThrow(filterPages, undefined);\n });\n\n });\n\n describe('makeResult', () => {\n\n const image = {\n pageid: 1,\n ns: 6,\n title: 'File:Foo',\n structured: {\n captions: {\n en: 'Foo',\n pt: 'Bar'\n }\n },\n imageinfo: [{\n mime: 'image/jpeg'\n }],\n globalusage: [{\n title: 'Bar',\n wiki: 'pt.wikipedia.org',\n pageid: 3\n }]\n };\n\n const expected = {\n pageid: 1,\n ns: 6,\n title: 'File:Foo',\n mime: 'image/jpeg',\n structured: {\n captions: {\n en: 'Foo',\n pt: 'Bar'\n }\n },\n globalusage: {\n pt: [{\n title: 'Bar',\n wiki: 'pt.wikipedia.org',\n pageid: 3\n }]\n }\n };\n\n const makeResult = lib.__get__('makeResult');\n\n it('result is structured as expected', () => {\n assert.deepEqual(makeResult(image, 'pt', 'en'), expected);\n });\n\n });\n\n describe('makeResults', () => {\n\n const images = {\n 1: {\n pageid: 1,\n ns: 6,\n title: 'File:Foo',\n imageinfo: [{\n mime: 'image/jpeg'\n }],\n globalusage: [{\n title: 'Bar',\n wiki: 'pt.wikipedia.org',\n pageid: 3\n }]\n },\n 2: {\n pageid: 2,\n ns: 6,\n title: 'File:Bar',\n imageinfo: [{\n mime: 'image/jpeg'\n }],\n globalusage: [{\n title: 'Foo',\n wiki: 'pt.wikipedia.org',\n pageid: 4\n }]\n },\n 3: {\n pageid: 3,\n ns: 6,\n title: 'File:Baz',\n imageinfo: [{\n mime: 'image/jpeg'\n }],\n globalusage: [{\n title: 'Baz',\n wiki: 'pt.wikipedia.org',\n pageid: 5\n }]\n }\n };\n\n const entities = {\n M1: {\n labels: {\n en: {\n value: 'Foo'\n },\n pt: {\n value: 'Bar'\n }\n }\n },\n M2: {\n labels: {}\n },\n M3: {\n labels: {\n en: {\n value: 'Baz'\n }\n }\n }\n };\n\n const cond = (image, targetLang, sourceLang) => image.structured.captions[sourceLang] && !image.structured.captions[targetLang];\n\n const makeResults = lib.__get__('makeResults');\n\n it('makes results as expected', () => {\n const result = makeResults(images, entities, cond, 'pt', 'en');\n const expected = [{\n pageid: 3,\n ns: 6,\n title: 'File:Baz',\n mime: 'image/jpeg',\n structured: {\n captions: {\n en: 'Baz'\n }\n },\n globalusage: {\n pt: [{\n title: 'Baz',\n wiki: 'pt.wikipedia.org',\n pageid: 5\n }]\n }\n }];\n assert.deepEqual(result, expected);\n });\n });\n\n});\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lib/description.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/lib/suggested-edits-common.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/assert.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/logStream.js","messages":[{"ruleId":"no-shadow","severity":1,"message":"'end' is already declared in the upper scope on line 31 column 14.","line":41,"column":13,"nodeType":"Identifier","messageId":"noShadow","endLine":41,"endColumn":16},{"ruleId":"no-shadow","severity":1,"message":"'get' is already declared in the upper scope on line 34 column 14.","line":49,"column":18,"nodeType":"Identifier","messageId":"noShadow","endLine":49,"endColumn":21}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst bunyan = require('bunyan');\n\nfunction logStream(logStdout) {\n\n const log = [];\n const parrot = bunyan.createLogger({\n name: 'test-logger',\n level: 'warn'\n });\n\n function write(chunk, encoding, callback) {\n try {\n const entry = JSON.parse(chunk);\n const levelMatch = /^(\\w+)/.exec(entry.levelPath);\n if (logStdout && levelMatch) {\n const level = levelMatch[1];\n if (parrot[level]) {\n parrot[level](entry);\n }\n }\n } catch (e) {\n console.error('something went wrong trying to parrot a log entry', e, chunk);\n }\n\n log.push(chunk);\n }\n\n // to implement the stream writer interface\n function end(chunk, encoding, callback) {\n }\n\n function get() {\n return log;\n }\n\n function slice() {\n\n const begin = log.length;\n let end = null;\n\n function halt() {\n if (end === null) {\n end = log.length;\n }\n }\n\n function get() {\n return log.slice(begin, end);\n }\n\n /* Disable eslint object-shorthand until Node 4 support is dropped */\n\n return {\n halt: halt,\n get: get\n };\n\n }\n\n return {\n write: write,\n end: end,\n slice: slice,\n get: get\n };\n}\n\nmodule.exports = logStream;\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/server.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}] --- end --- $ /usr/bin/npm ci --- stderr --- npm WARN skipping integrity check for git dependency ssh://git@github.com/wikimedia/swagger-ui.git npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained. npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated mkdirp@0.5.4: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained. npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor. npm WARN deprecated debug@3.2.6: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated sinon@7.5.0: 16.1.1 --- stdout --- added 801 packages, and audited 802 packages in 2m 113 packages are looking for funding run `npm fund` for details 20 vulnerabilities (1 low, 12 moderate, 3 high, 4 critical) To address issues that do not require attention, run: npm audit fix To address all issues possible (including breaking changes), run: npm audit fix --force Some issues need review, and may require choosing a different dependency. Run `npm audit` for details. --- end --- $ /usr/bin/npm test --- stdout --- > recommendation-api@0.7.0 test > PREQ_CONNECT_TIMEOUT=15 mocha && npm run lint starting test server express app ✓ should get robots.txt ✓ should set CORS headers ✓ should set CSP headers ✓ should get static content gzipped ✓ should get static content uncompressed Swagger spec ✓ get the spec ✓ spec validation routes ✓ robots.txt check ✓ root with no query params ✓ spec from root ✓ doc from root ✓ root with wrong query param ✓ article.creation.translation - normal source and target with seed (1503ms) ✓ article.creation.translation - bad seed (110ms) ✓ article.creation.translation - invalid count ✓ article.creation.translation - incorrectly formatted source ✓ article.creation.morelike - bad article title (58ms) ✓ article.creation.morelike - missing models (121ms) ✓ Caption addition suggestions (1271ms) ✓ Caption translation suggestions (1230ms) ✓ Description addition suggestions (1287ms) ✓ Description translation suggestions (2009ms) article.creation.morelike ✓ should return recommendations for good article title (2750ms) Get missing articles ✓ correctly filters out existing articles lib:caption convertGlobalUsagePageIdsToInts ✓ converts page ID string to int consolidateImageData ✓ consolidates entity data to expected items ✓ handles undefined entities object filterPages ✓ filters non-image MIME types ✓ handles undefined pages object makeResult ✓ result is structured as expected makeResults ✓ makes results as expected lib:description wikiLangToDBName ✓ appends "wiki" ✓ converts hyphens to underscores ✓ converts be-tarask to be_x_oldwiki buildResponse ✓ gracefully handles undefined inputs ✓ gracefully handles empty inputs lib:suggested-edits-common checkRequestDomain ✓ allows allowed domains ✓ disallows disallowed domains ✓ handles undefined getWikiLangForLangCode ✓ translates language variants to base wiki language codes ✓ passed through other inputs ✓ handles undefined stopping test server 42 passing (11s) > recommendation-api@0.7.0 lint > node_modules/.bin/eslint --ext .js . /src/repo/app.js 20:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 71:37 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp 145:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 147:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 159:31 warning Found non-literal argument in require security/detect-non-literal-require 196:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 197:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 235:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types /src/repo/lib/api-util.js 81:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 128:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/lib/article.creation.morelike.js 1:11 warning 'setTimeout' is already defined as a built-in global variable no-redeclare /src/repo/lib/article.creation.translation.js 129:12 warning 'candidates' is already declared in the upper scope on line 122 column 9 no-shadow /src/repo/lib/util.js 109:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 155:1 warning The type 'bool' is undefined jsdoc/no-undefined-types 165:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 260:1 warning The type 'Router' is undefined jsdoc/no-undefined-types 280:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/routes/article.creation.morelike.js 75:32 warning 'ids' is already declared in the upper scope on line 66 column 24 no-shadow /src/repo/routes/article.creation.translation.js 14:25 warning Unsafe Regular Expression security/detect-unsafe-regex /src/repo/test/features/app/app.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare /src/repo/test/features/app/spec.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare 24:30 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename 178:14 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp /src/repo/test/lib/caption.js 193:1 warning This line has a length of 136. Maximum allowed is 100 max-len /src/repo/test/utils/logStream.js 41:13 warning 'end' is already declared in the upper scope on line 31 column 14 no-shadow 49:18 warning 'get' is already declared in the upper scope on line 34 column 14 no-shadow ✖ 32 problems (0 errors, 32 warnings) --- end --- $ /usr/bin/npm audit --json --- stdout --- { "auditReportVersion": 2, "vulnerabilities": { "ajv": { "name": "ajv", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097685, "name": "ajv", "dependency": "ajv", "title": "Prototype Pollution in Ajv", "url": "https://github.com/advisories/GHSA-v88g-cgmw-v5xw", "severity": "moderate", "cwe": [ "CWE-915", "CWE-1321" ], "cvss": { "score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L" }, "range": "<6.12.3" } ], "effects": [ "ajv-keywords", "eslint", "table" ], "range": "<6.12.3", "nodes": [ "node_modules/rewire/node_modules/ajv", "node_modules/table/node_modules/ajv" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "ajv-keywords": { "name": "ajv-keywords", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [], "range": "2.1.1", "nodes": [ "node_modules/table/node_modules/ajv-keywords" ], "fixAvailable": true }, "debug": { "name": "debug", "severity": "low", "isDirect": false, "via": [ { "source": 1096793, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": [ "CWE-400" ], "cvss": { "score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": ">=3.2.0 <3.2.7" } ], "effects": [ "mocha" ], "range": "3.2.0 - 3.2.6", "nodes": [ "node_modules/mocha/node_modules/debug" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "eslint": { "name": "eslint", "severity": "moderate", "isDirect": false, "via": [ "ajv", "table" ], "effects": [ "rewire" ], "range": "2.5.0 - 2.5.2 || 4.2.0 - 5.0.0-rc.0", "nodes": [ "node_modules/rewire/node_modules/eslint" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "flat": { "name": "flat", "severity": "critical", "isDirect": false, "via": [ { "source": 1089152, "name": "flat", "dependency": "flat", "title": "flat vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm", "severity": "critical", "cwe": [ "CWE-1321" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<5.0.1" } ], "effects": [ "yargs-unparser" ], "range": "<5.0.1", "nodes": [ "node_modules/flat" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "limitation": { "name": "limitation", "severity": "moderate", "isDirect": false, "via": [ "wikimedia-kad-fork" ], "effects": [ "service-runner" ], "range": ">=0.2.3", "nodes": [ "node_modules/limitation" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "minimatch": { "name": "minimatch", "severity": "high", "isDirect": false, "via": [ { "source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": [ "CWE-400", "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": "<3.0.5" } ], "effects": [ "mocha" ], "range": "<3.0.5", "nodes": [ "node_modules/mocha/node_modules/minimatch" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "mocha": { "name": "mocha", "severity": "critical", "isDirect": true, "via": [ "debug", "minimatch", "yargs-unparser" ], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": [ "node_modules/mocha" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "ms": { "name": "ms", "severity": "moderate", "isDirect": false, "via": [ { "source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": [ "CWE-1333" ], "cvss": { "score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": "<2.0.0" } ], "effects": [ "wikimedia-kad-fork" ], "range": "<2.0.0", "nodes": [ "node_modules/wikimedia-kad-fork/node_modules/ms" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "preq": { "name": "preq", "severity": "high", "isDirect": true, "via": [ "request", "requestretry" ], "effects": [], "range": "*", "nodes": [ "node_modules/preq" ], "fixAvailable": false }, "request": { "name": "request", "severity": "moderate", "isDirect": false, "via": [ { "source": 1096727, "name": "request", "dependency": "request", "title": "Server-Side Request Forgery in Request", "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N" }, "range": "<=2.88.2" }, "tough-cookie" ], "effects": [ "preq", "requestretry" ], "range": "*", "nodes": [ "node_modules/request" ], "fixAvailable": false }, "requestretry": { "name": "requestretry", "severity": "high", "isDirect": false, "via": [ { "source": 1090420, "name": "requestretry", "dependency": "requestretry", "title": "Cookie exposure in requestretry", "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45", "severity": "high", "cwe": [ "CWE-200" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" }, "range": "<7.0.0" }, "request" ], "effects": [ "preq" ], "range": "*", "nodes": [ "node_modules/requestretry" ], "fixAvailable": false }, "rewire": { "name": "rewire", "severity": "moderate", "isDirect": true, "via": [ "eslint" ], "effects": [], "range": "4.0.0 - 4.0.1", "nodes": [ "node_modules/rewire" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "service-runner": { "name": "service-runner", "severity": "moderate", "isDirect": true, "via": [ "limitation", "tar" ], "effects": [], "range": ">=3.0.0", "nodes": [ "node_modules/service-runner" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "swagger-ui": { "name": "swagger-ui", "severity": "critical", "isDirect": true, "via": [ { "source": 1085691, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Reverse Tabnapping in swagger-ui", "url": "https://github.com/advisories/GHSA-x9p2-fxq6-2m5f", "severity": "moderate", "cwe": [ "CWE-1022" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<3.18.0" }, { "source": 1086900, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-388g-jwpg-x6j4", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N" }, "range": "<3.0.13" }, { "source": 1088760, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Spoofing attack in swagger-ui", "url": "https://github.com/advisories/GHSA-cr3q-pqgq-m8c2", "severity": "moderate", "cwe": [ "CWE-20" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<4.1.3" }, { "source": 1088813, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-site scripting in Swagger-UI", "url": "https://github.com/advisories/GHSA-c427-hjc3-wrfw", "severity": "critical", "cwe": [ "CWE-79", "CWE-352" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<3.23.11" }, { "source": 1092161, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Server side request forgery in SwaggerUI", "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 0, "vectorString": null }, "range": "<4.1.3" }, { "source": 1094217, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-4f9m-pxwh-68hg", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<3.20.9" } ], "effects": [], "range": "<=4.1.2", "nodes": [ "node_modules/swagger-ui" ], "fixAvailable": false }, "table": { "name": "table", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [ "eslint" ], "range": "3.7.10 - 4.0.2", "nodes": [ "node_modules/table" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "tar": { "name": "tar", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097493, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": [ "CWE-400" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H" }, "range": "<6.2.1" } ], "effects": [ "service-runner" ], "range": "<6.2.1", "nodes": [ "node_modules/tar" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "tough-cookie": { "name": "tough-cookie", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097682, "name": "tough-cookie", "dependency": "tough-cookie", "title": "tough-cookie Prototype Pollution vulnerability", "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3", "severity": "moderate", "cwe": [ "CWE-1321" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<4.1.3" } ], "effects": [ "request" ], "range": "<4.1.3", "nodes": [ "node_modules/tough-cookie" ], "fixAvailable": false }, "wikimedia-kad-fork": { "name": "wikimedia-kad-fork", "severity": "moderate", "isDirect": false, "via": [ "ms" ], "effects": [ "limitation" ], "range": "*", "nodes": [ "node_modules/wikimedia-kad-fork" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "yargs-unparser": { "name": "yargs-unparser", "severity": "critical", "isDirect": false, "via": [ "flat" ], "effects": [ "mocha" ], "range": "<=1.6.3", "nodes": [ "node_modules/yargs-unparser" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } } }, "metadata": { "vulnerabilities": { "info": 0, "low": 1, "moderate": 12, "high": 3, "critical": 4, "total": 20 }, "dependencies": { "prod": 203, "dev": 590, "optional": 9, "peer": 1, "peerOptional": 0, "total": 801 } } } --- end --- Attempting to npm audit fix $ /usr/bin/npm audit fix --dry-run --only=dev --json --- stderr --- npm WARN invalid config only="dev" set in command line options npm WARN invalid config Must be one of: null, prod, production --- stdout --- { "added": 0, "removed": 0, "changed": 0, "audited": 802, "funding": 113, "audit": { "auditReportVersion": 2, "vulnerabilities": { "ajv": { "name": "ajv", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097685, "name": "ajv", "dependency": "ajv", "title": "Prototype Pollution in Ajv", "url": "https://github.com/advisories/GHSA-v88g-cgmw-v5xw", "severity": "moderate", "cwe": [ "CWE-915", "CWE-1321" ], "cvss": { "score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L" }, "range": "<6.12.3" } ], "effects": [ "ajv-keywords", "eslint", "table" ], "range": "<6.12.3", "nodes": [ "node_modules/rewire/node_modules/ajv", "node_modules/table/node_modules/ajv" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "ajv-keywords": { "name": "ajv-keywords", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [], "range": "2.1.1", "nodes": [ "node_modules/table/node_modules/ajv-keywords" ], "fixAvailable": true }, "debug": { "name": "debug", "severity": "low", "isDirect": false, "via": [ { "source": 1096793, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": [ "CWE-400" ], "cvss": { "score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": ">=3.2.0 <3.2.7" } ], "effects": [ "mocha" ], "range": "3.2.0 - 3.2.6", "nodes": [ "node_modules/mocha/node_modules/debug" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "eslint": { "name": "eslint", "severity": "moderate", "isDirect": false, "via": [ "ajv", "table" ], "effects": [ "rewire" ], "range": "2.5.0 - 2.5.2 || 4.2.0 - 5.0.0-rc.0", "nodes": [ "node_modules/rewire/node_modules/eslint" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "flat": { "name": "flat", "severity": "critical", "isDirect": false, "via": [ { "source": 1089152, "name": "flat", "dependency": "flat", "title": "flat vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm", "severity": "critical", "cwe": [ "CWE-1321" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<5.0.1" } ], "effects": [ "yargs-unparser" ], "range": "<5.0.1", "nodes": [ "node_modules/flat" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "limitation": { "name": "limitation", "severity": "moderate", "isDirect": false, "via": [ "wikimedia-kad-fork" ], "effects": [ "service-runner" ], "range": ">=0.2.3", "nodes": [ "node_modules/limitation" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "minimatch": { "name": "minimatch", "severity": "high", "isDirect": false, "via": [ { "source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": [ "CWE-400", "CWE-1333" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" }, "range": "<3.0.5" } ], "effects": [ "mocha" ], "range": "<3.0.5", "nodes": [ "node_modules/mocha/node_modules/minimatch" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "mocha": { "name": "mocha", "severity": "critical", "isDirect": true, "via": [ "debug", "minimatch", "yargs-unparser" ], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": [ "node_modules/mocha" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } }, "ms": { "name": "ms", "severity": "moderate", "isDirect": false, "via": [ { "source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": [ "CWE-1333" ], "cvss": { "score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L" }, "range": "<2.0.0" } ], "effects": [ "wikimedia-kad-fork" ], "range": "<2.0.0", "nodes": [ "node_modules/wikimedia-kad-fork/node_modules/ms" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "preq": { "name": "preq", "severity": "high", "isDirect": true, "via": [ "request", "requestretry" ], "effects": [], "range": "*", "nodes": [ "node_modules/preq" ], "fixAvailable": false }, "request": { "name": "request", "severity": "moderate", "isDirect": false, "via": [ { "source": 1096727, "name": "request", "dependency": "request", "title": "Server-Side Request Forgery in Request", "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N" }, "range": "<=2.88.2" }, "tough-cookie" ], "effects": [ "preq", "requestretry" ], "range": "*", "nodes": [ "node_modules/request" ], "fixAvailable": false }, "requestretry": { "name": "requestretry", "severity": "high", "isDirect": false, "via": [ { "source": 1090420, "name": "requestretry", "dependency": "requestretry", "title": "Cookie exposure in requestretry", "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45", "severity": "high", "cwe": [ "CWE-200" ], "cvss": { "score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" }, "range": "<7.0.0" }, "request" ], "effects": [ "preq" ], "range": "*", "nodes": [ "node_modules/requestretry" ], "fixAvailable": false }, "rewire": { "name": "rewire", "severity": "moderate", "isDirect": true, "via": [ "eslint" ], "effects": [], "range": "4.0.0 - 4.0.1", "nodes": [ "node_modules/rewire" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "service-runner": { "name": "service-runner", "severity": "moderate", "isDirect": true, "via": [ "limitation", "tar" ], "effects": [], "range": ">=3.0.0", "nodes": [ "node_modules/service-runner" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "swagger-ui": { "name": "swagger-ui", "severity": "critical", "isDirect": true, "via": [ { "source": 1085691, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Reverse Tabnapping in swagger-ui", "url": "https://github.com/advisories/GHSA-x9p2-fxq6-2m5f", "severity": "moderate", "cwe": [ "CWE-1022" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<3.18.0" }, { "source": 1086900, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-388g-jwpg-x6j4", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N" }, "range": "<3.0.13" }, { "source": 1088760, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Spoofing attack in swagger-ui", "url": "https://github.com/advisories/GHSA-cr3q-pqgq-m8c2", "severity": "moderate", "cwe": [ "CWE-20" ], "cvss": { "score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N" }, "range": "<4.1.3" }, { "source": 1088813, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-site scripting in Swagger-UI", "url": "https://github.com/advisories/GHSA-c427-hjc3-wrfw", "severity": "critical", "cwe": [ "CWE-79", "CWE-352" ], "cvss": { "score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "range": "<3.23.11" }, { "source": 1092161, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Server side request forgery in SwaggerUI", "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx", "severity": "moderate", "cwe": [ "CWE-918" ], "cvss": { "score": 0, "vectorString": null }, "range": "<4.1.3" }, { "source": 1094217, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-4f9m-pxwh-68hg", "severity": "moderate", "cwe": [ "CWE-79" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<3.20.9" } ], "effects": [], "range": "<=4.1.2", "nodes": [ "node_modules/swagger-ui" ], "fixAvailable": false }, "table": { "name": "table", "severity": "moderate", "isDirect": false, "via": [ "ajv" ], "effects": [ "eslint" ], "range": "3.7.10 - 4.0.2", "nodes": [ "node_modules/table" ], "fixAvailable": { "name": "rewire", "version": "7.0.0", "isSemVerMajor": true } }, "tar": { "name": "tar", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097493, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": [ "CWE-400" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H" }, "range": "<6.2.1" } ], "effects": [ "service-runner" ], "range": "<6.2.1", "nodes": [ "node_modules/tar" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "tough-cookie": { "name": "tough-cookie", "severity": "moderate", "isDirect": false, "via": [ { "source": 1097682, "name": "tough-cookie", "dependency": "tough-cookie", "title": "tough-cookie Prototype Pollution vulnerability", "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3", "severity": "moderate", "cwe": [ "CWE-1321" ], "cvss": { "score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" }, "range": "<4.1.3" } ], "effects": [ "request" ], "range": "<4.1.3", "nodes": [ "node_modules/tough-cookie" ], "fixAvailable": false }, "wikimedia-kad-fork": { "name": "wikimedia-kad-fork", "severity": "moderate", "isDirect": false, "via": [ "ms" ], "effects": [ "limitation" ], "range": "*", "nodes": [ "node_modules/wikimedia-kad-fork" ], "fixAvailable": { "name": "service-runner", "version": "5.0.0", "isSemVerMajor": true } }, "yargs-unparser": { "name": "yargs-unparser", "severity": "critical", "isDirect": false, "via": [ "flat" ], "effects": [ "mocha" ], "range": "<=1.6.3", "nodes": [ "node_modules/yargs-unparser" ], "fixAvailable": { "name": "mocha", "version": "10.5.2", "isSemVerMajor": true } } }, "metadata": { "vulnerabilities": { "info": 0, "low": 1, "moderate": 12, "high": 3, "critical": 4, "total": 20 }, "dependencies": { "prod": 203, "dev": 590, "optional": 9, "peer": 1, "peerOptional": 0, "total": 801 } } } } --- end --- {"added": 0, "removed": 0, "changed": 0, "audited": 802, "funding": 113, "audit": {"auditReportVersion": 2, "vulnerabilities": {"ajv": {"name": "ajv", "severity": "moderate", "isDirect": false, "via": [{"source": 1097685, "name": "ajv", "dependency": "ajv", "title": "Prototype Pollution in Ajv", "url": "https://github.com/advisories/GHSA-v88g-cgmw-v5xw", "severity": "moderate", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<6.12.3"}], "effects": ["ajv-keywords", "eslint", "table"], "range": "<6.12.3", "nodes": ["node_modules/rewire/node_modules/ajv", "node_modules/table/node_modules/ajv"], "fixAvailable": {"name": "rewire", "version": "7.0.0", "isSemVerMajor": true}}, "ajv-keywords": {"name": "ajv-keywords", "severity": "moderate", "isDirect": false, "via": ["ajv"], "effects": [], "range": "2.1.1", "nodes": ["node_modules/table/node_modules/ajv-keywords"], "fixAvailable": true}, "debug": {"name": "debug", "severity": "low", "isDirect": false, "via": [{"source": 1096793, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": ["CWE-400"], "cvss": {"score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": ">=3.2.0 <3.2.7"}], "effects": ["mocha"], "range": "3.2.0 - 3.2.6", "nodes": ["node_modules/mocha/node_modules/debug"], "fixAvailable": {"name": "mocha", "version": "10.5.2", "isSemVerMajor": true}}, "eslint": {"name": "eslint", "severity": "moderate", "isDirect": false, "via": ["ajv", "table"], "effects": ["rewire"], "range": "2.5.0 - 2.5.2 || 4.2.0 - 5.0.0-rc.0", "nodes": ["node_modules/rewire/node_modules/eslint"], "fixAvailable": {"name": "rewire", "version": "7.0.0", "isSemVerMajor": true}}, "flat": {"name": "flat", "severity": "critical", "isDirect": false, "via": [{"source": 1089152, "name": "flat", "dependency": "flat", "title": "flat vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<5.0.1"}], "effects": ["yargs-unparser"], "range": "<5.0.1", "nodes": ["node_modules/flat"], "fixAvailable": {"name": "mocha", "version": "10.5.2", "isSemVerMajor": true}}, "limitation": {"name": "limitation", "severity": "moderate", "isDirect": false, "via": ["wikimedia-kad-fork"], "effects": ["service-runner"], "range": ">=0.2.3", "nodes": ["node_modules/limitation"], "fixAvailable": {"name": "service-runner", "version": "5.0.0", "isSemVerMajor": true}}, "minimatch": {"name": "minimatch", "severity": "high", "isDirect": false, "via": [{"source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": ["CWE-400", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": "<3.0.5"}], "effects": ["mocha"], "range": "<3.0.5", "nodes": ["node_modules/mocha/node_modules/minimatch"], "fixAvailable": {"name": "mocha", "version": "10.5.2", "isSemVerMajor": true}}, "mocha": {"name": "mocha", "severity": "critical", "isDirect": true, "via": ["debug", "minimatch", "yargs-unparser"], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": ["node_modules/mocha"], "fixAvailable": {"name": "mocha", "version": "10.5.2", "isSemVerMajor": true}}, "ms": {"name": "ms", "severity": "moderate", "isDirect": false, "via": [{"source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<2.0.0"}], "effects": ["wikimedia-kad-fork"], "range": "<2.0.0", "nodes": ["node_modules/wikimedia-kad-fork/node_modules/ms"], "fixAvailable": {"name": "service-runner", "version": "5.0.0", "isSemVerMajor": true}}, "preq": {"name": "preq", "severity": "high", "isDirect": true, "via": ["request", "requestretry"], "effects": [], "range": "*", "nodes": ["node_modules/preq"], "fixAvailable": false}, "request": {"name": "request", "severity": "moderate", "isDirect": false, "via": [{"source": 1096727, "name": "request", "dependency": "request", "title": "Server-Side Request Forgery in Request", "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6", "severity": "moderate", "cwe": ["CWE-918"], "cvss": {"score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"}, "range": "<=2.88.2"}, "tough-cookie"], "effects": ["preq", "requestretry"], "range": "*", "nodes": ["node_modules/request"], "fixAvailable": false}, "requestretry": {"name": "requestretry", "severity": "high", "isDirect": false, "via": [{"source": 1090420, "name": "requestretry", "dependency": "requestretry", "title": "Cookie exposure in requestretry", "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45", "severity": "high", "cwe": ["CWE-200"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"}, "range": "<7.0.0"}, "request"], "effects": ["preq"], "range": "*", "nodes": ["node_modules/requestretry"], "fixAvailable": false}, "rewire": {"name": "rewire", "severity": "moderate", "isDirect": true, "via": ["eslint"], "effects": [], "range": "4.0.0 - 4.0.1", "nodes": ["node_modules/rewire"], "fixAvailable": {"name": "rewire", "version": "7.0.0", "isSemVerMajor": true}}, "service-runner": {"name": "service-runner", "severity": "moderate", "isDirect": true, "via": ["limitation", "tar"], "effects": [], "range": ">=3.0.0", "nodes": ["node_modules/service-runner"], "fixAvailable": {"name": "service-runner", "version": "5.0.0", "isSemVerMajor": true}}, "swagger-ui": {"name": "swagger-ui", "severity": "critical", "isDirect": true, "via": [{"source": 1085691, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Reverse Tabnapping in swagger-ui", "url": "https://github.com/advisories/GHSA-x9p2-fxq6-2m5f", "severity": "moderate", "cwe": ["CWE-1022"], "cvss": {"score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N"}, "range": "<3.18.0"}, {"source": 1086900, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-388g-jwpg-x6j4", "severity": "moderate", "cwe": ["CWE-79"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N"}, "range": "<3.0.13"}, {"source": 1088760, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Spoofing attack in swagger-ui", "url": "https://github.com/advisories/GHSA-cr3q-pqgq-m8c2", "severity": "moderate", "cwe": ["CWE-20"], "cvss": {"score": 4.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N"}, "range": "<4.1.3"}, {"source": 1088813, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-site scripting in Swagger-UI", "url": "https://github.com/advisories/GHSA-c427-hjc3-wrfw", "severity": "critical", "cwe": ["CWE-79", "CWE-352"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<3.23.11"}, {"source": 1092161, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Server side request forgery in SwaggerUI", "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx", "severity": "moderate", "cwe": ["CWE-918"], "cvss": {"score": 0, "vectorString": null}, "range": "<4.1.3"}, {"source": 1094217, "name": "swagger-ui", "dependency": "swagger-ui", "title": "Cross-Site Scripting in swagger-ui", "url": "https://github.com/advisories/GHSA-4f9m-pxwh-68hg", "severity": "moderate", "cwe": ["CWE-79"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"}, "range": "<3.20.9"}], "effects": [], "range": "<=4.1.2", "nodes": ["node_modules/swagger-ui"], "fixAvailable": false}, "table": {"name": "table", "severity": "moderate", "isDirect": false, "via": ["ajv"], "effects": ["eslint"], "range": "3.7.10 - 4.0.2", "nodes": ["node_modules/table"], "fixAvailable": {"name": "rewire", "version": "7.0.0", "isSemVerMajor": true}}, "tar": {"name": "tar", "severity": "moderate", "isDirect": false, "via": [{"source": 1097493, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": ["CWE-400"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"}, "range": "<6.2.1"}], "effects": ["service-runner"], "range": "<6.2.1", "nodes": ["node_modules/tar"], "fixAvailable": {"name": "service-runner", "version": "5.0.0", "isSemVerMajor": true}}, "tough-cookie": {"name": "tough-cookie", "severity": "moderate", "isDirect": false, "via": [{"source": 1097682, "name": "tough-cookie", "dependency": "tough-cookie", "title": "tough-cookie Prototype Pollution vulnerability", "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"}, "range": "<4.1.3"}], "effects": ["request"], "range": "<4.1.3", "nodes": ["node_modules/tough-cookie"], "fixAvailable": false}, "wikimedia-kad-fork": {"name": "wikimedia-kad-fork", "severity": "moderate", "isDirect": false, "via": ["ms"], "effects": ["limitation"], "range": "*", "nodes": ["node_modules/wikimedia-kad-fork"], "fixAvailable": {"name": "service-runner", "version": "5.0.0", "isSemVerMajor": true}}, "yargs-unparser": {"name": "yargs-unparser", "severity": "critical", "isDirect": false, "via": ["flat"], "effects": ["mocha"], "range": "<=1.6.3", "nodes": ["node_modules/yargs-unparser"], "fixAvailable": {"name": "mocha", "version": "10.5.2", "isSemVerMajor": true}}}, "metadata": {"vulnerabilities": {"info": 0, "low": 1, "moderate": 12, "high": 3, "critical": 4, "total": 20}, "dependencies": {"prod": 203, "dev": 590, "optional": 9, "peer": 1, "peerOptional": 0, "total": 801}}}} $ /usr/bin/npm audit fix --only=dev --- stderr --- npm WARN invalid config only="dev" set in command line options npm WARN invalid config Must be one of: null, prod, production --- stdout --- up to date, audited 802 packages in 4s 113 packages are looking for funding run `npm fund` for details # npm audit report ajv <6.12.3 Severity: moderate Prototype Pollution in Ajv - https://github.com/advisories/GHSA-v88g-cgmw-v5xw fix available via `npm audit fix --force` Will install rewire@7.0.0, which is a breaking change node_modules/rewire/node_modules/ajv node_modules/table/node_modules/ajv ajv-keywords 2.1.1 Depends on vulnerable versions of ajv node_modules/table/node_modules/ajv-keywords eslint 2.5.0 - 2.5.2 || 4.2.0 - 5.0.0-rc.0 Depends on vulnerable versions of ajv Depends on vulnerable versions of table node_modules/rewire/node_modules/eslint rewire 4.0.0 - 4.0.1 Depends on vulnerable versions of eslint node_modules/rewire table 3.7.10 - 4.0.2 Depends on vulnerable versions of ajv node_modules/table debug 3.2.0 - 3.2.6 Regular Expression Denial of Service in debug - https://github.com/advisories/GHSA-gxpj-cx7g-858c fix available via `npm audit fix --force` Will install mocha@10.5.2, which is a breaking change node_modules/mocha/node_modules/debug mocha 5.1.0 - 9.2.1 Depends on vulnerable versions of debug Depends on vulnerable versions of minimatch Depends on vulnerable versions of yargs-unparser node_modules/mocha flat <5.0.1 Severity: critical flat vulnerable to Prototype Pollution - https://github.com/advisories/GHSA-2j2x-2gpw-g8fm fix available via `npm audit fix --force` Will install mocha@10.5.2, which is a breaking change node_modules/flat yargs-unparser <=1.6.3 Depends on vulnerable versions of flat node_modules/yargs-unparser minimatch <3.0.5 Severity: high minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3 fix available via `npm audit fix --force` Will install mocha@10.5.2, which is a breaking change node_modules/mocha/node_modules/minimatch ms <2.0.0 Severity: moderate Vercel ms Inefficient Regular Expression Complexity vulnerability - https://github.com/advisories/GHSA-w9mr-4mfr-499f fix available via `npm audit fix --force` Will install service-runner@5.0.0, which is a breaking change node_modules/wikimedia-kad-fork/node_modules/ms wikimedia-kad-fork * Depends on vulnerable versions of ms node_modules/wikimedia-kad-fork limitation >=0.2.3 Depends on vulnerable versions of wikimedia-kad-fork node_modules/limitation service-runner >=3.0.0 Depends on vulnerable versions of limitation Depends on vulnerable versions of tar node_modules/service-runner request * Severity: moderate Server-Side Request Forgery in Request - https://github.com/advisories/GHSA-p8p7-x288-28g6 Depends on vulnerable versions of tough-cookie No fix available node_modules/request preq * Depends on vulnerable versions of request Depends on vulnerable versions of requestretry node_modules/preq requestretry * Depends on vulnerable versions of request node_modules/requestretry swagger-ui <=4.1.2 Severity: critical Reverse Tabnapping in swagger-ui - https://github.com/advisories/GHSA-x9p2-fxq6-2m5f Cross-Site Scripting in swagger-ui - https://github.com/advisories/GHSA-388g-jwpg-x6j4 Spoofing attack in swagger-ui - https://github.com/advisories/GHSA-cr3q-pqgq-m8c2 Cross-site scripting in Swagger-UI - https://github.com/advisories/GHSA-c427-hjc3-wrfw Server side request forgery in SwaggerUI - https://github.com/advisories/GHSA-qrmm-w75w-3wpx Cross-Site Scripting in swagger-ui - https://github.com/advisories/GHSA-4f9m-pxwh-68hg No fix available node_modules/swagger-ui tar <6.2.1 Severity: moderate Denial of service while parsing a tar file due to lack of folders count validation - https://github.com/advisories/GHSA-f5x3-32g6-xq36 fix available via `npm audit fix --force` Will install service-runner@5.0.0, which is a breaking change node_modules/tar tough-cookie <4.1.3 Severity: moderate tough-cookie Prototype Pollution vulnerability - https://github.com/advisories/GHSA-72xf-g2v4-qvf3 No fix available node_modules/tough-cookie 20 vulnerabilities (1 low, 12 moderate, 3 high, 4 critical) To address issues that do not require attention, run: npm audit fix To address all issues possible (including breaking changes), run: npm audit fix --force Some issues need review, and may require choosing a different dependency. --- end --- $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- Verifying that tests still pass $ /usr/bin/npm ci --- stderr --- npm WARN skipping integrity check for git dependency ssh://git@github.com/wikimedia/swagger-ui.git npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained. npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated mkdirp@0.5.4: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained. npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor. npm WARN deprecated debug@3.2.6: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated sinon@7.5.0: 16.1.1 --- stdout --- added 801 packages, and audited 802 packages in 3m 113 packages are looking for funding run `npm fund` for details 20 vulnerabilities (1 low, 12 moderate, 3 high, 4 critical) To address issues that do not require attention, run: npm audit fix To address all issues possible (including breaking changes), run: npm audit fix --force Some issues need review, and may require choosing a different dependency. Run `npm audit` for details. --- end --- $ /usr/bin/npm test --- stdout --- > recommendation-api@0.7.0 test > PREQ_CONNECT_TIMEOUT=15 mocha && npm run lint starting test server express app ✓ should get robots.txt ✓ should set CORS headers ✓ should set CSP headers ✓ should get static content gzipped ✓ should get static content uncompressed Swagger spec ✓ get the spec ✓ spec validation routes ✓ robots.txt check ✓ root with no query params ✓ spec from root ✓ doc from root ✓ root with wrong query param ✓ article.creation.translation - normal source and target with seed (637ms) ✓ article.creation.translation - bad seed (138ms) ✓ article.creation.translation - invalid count ✓ article.creation.translation - incorrectly formatted source ✓ article.creation.morelike - bad article title (59ms) ✓ article.creation.morelike - missing models (122ms) ✓ Caption addition suggestions (1485ms) ✓ Caption translation suggestions (1312ms) ✓ Description addition suggestions (924ms) ✓ Description translation suggestions (642ms) article.creation.morelike ✓ should return recommendations for good article title (1229ms) Get missing articles ✓ correctly filters out existing articles lib:caption convertGlobalUsagePageIdsToInts ✓ converts page ID string to int consolidateImageData ✓ consolidates entity data to expected items ✓ handles undefined entities object filterPages ✓ filters non-image MIME types ✓ handles undefined pages object makeResult ✓ result is structured as expected makeResults ✓ makes results as expected lib:description wikiLangToDBName ✓ appends "wiki" ✓ converts hyphens to underscores ✓ converts be-tarask to be_x_oldwiki buildResponse ✓ gracefully handles undefined inputs ✓ gracefully handles empty inputs lib:suggested-edits-common checkRequestDomain ✓ allows allowed domains ✓ disallows disallowed domains ✓ handles undefined getWikiLangForLangCode ✓ translates language variants to base wiki language codes ✓ passed through other inputs ✓ handles undefined stopping test server 42 passing (7s) > recommendation-api@0.7.0 lint > node_modules/.bin/eslint --ext .js . /src/repo/app.js 20:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 71:37 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp 145:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 147:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 159:31 warning Found non-literal argument in require security/detect-non-literal-require 196:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 197:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types 235:1 warning The type 'bluebird' is undefined jsdoc/no-undefined-types /src/repo/lib/api-util.js 81:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 128:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/lib/article.creation.morelike.js 1:11 warning 'setTimeout' is already defined as a built-in global variable no-redeclare /src/repo/lib/article.creation.translation.js 129:12 warning 'candidates' is already declared in the upper scope on line 122 column 9 no-shadow /src/repo/lib/util.js 109:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 155:1 warning The type 'bool' is undefined jsdoc/no-undefined-types 165:1 warning The type 'Application' is undefined jsdoc/no-undefined-types 260:1 warning The type 'Router' is undefined jsdoc/no-undefined-types 280:1 warning The type 'Application' is undefined jsdoc/no-undefined-types /src/repo/routes/article.creation.morelike.js 75:32 warning 'ids' is already declared in the upper scope on line 66 column 24 no-shadow /src/repo/routes/article.creation.translation.js 14:25 warning Unsafe Regular Expression security/detect-unsafe-regex /src/repo/test/features/app/app.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare /src/repo/test/features/app/spec.js 1:11 warning 'describe' is already defined as a built-in global variable no-redeclare 1:21 warning 'it' is already defined as a built-in global variable no-redeclare 1:25 warning 'before' is already defined as a built-in global variable no-redeclare 1:33 warning 'after' is already defined as a built-in global variable no-redeclare 24:30 warning Found readFileSync from package "fs" with non literal argument at index 0 security/detect-non-literal-fs-filename 178:14 warning Found non-literal argument to RegExp Constructor security/detect-non-literal-regexp /src/repo/test/lib/caption.js 193:1 warning This line has a length of 136. Maximum allowed is 100 max-len /src/repo/test/utils/logStream.js 41:13 warning 'end' is already declared in the upper scope on line 31 column 14 no-shadow 49:18 warning 'get' is already declared in the upper scope on line 34 column 14 no-shadow ✖ 32 problems (0 errors, 32 warnings) --- end --- {} $ package-lock-lint package-lock.json --- stdout --- Checking package-lock.json --- end --- build: Updating eslint-config-wikimedia to 0.28.2 $ git add . --- stdout --- --- end --- $ git commit -F /tmp/tmp9wc_6bdk --- stdout --- [master 5553f56] build: Updating eslint-config-wikimedia to 0.28.2 13 files changed, 403 insertions(+), 312 deletions(-) --- end --- $ git format-patch HEAD~1 --stdout --- stdout --- From 5553f56705ce0372db341d390aa23c416228f008 Mon Sep 17 00:00:00 2001 From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org> Date: Sun, 30 Jun 2024 16:28:02 +0000 Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.28.2 Change-Id: I2c0a7a8e8785b0bb779534eb8d3ad8c5659b7503 --- app.js | 10 +- lib/article.creation.morelike.js | 4 +- lib/article.creation.translation.js | 6 +- lib/description.js | 15 +- package-lock.json | 598 +++++++++++------- package.json | 2 +- routes/article.creation.morelike.js | 6 +- test/features/app/app.js | 18 +- test/features/app/spec.js | 16 +- test/features/v1/article.creation.morelike.js | 6 +- test/lib/caption.js | 4 +- test/lib/suggested-edits-common.js | 18 +- test/utils/server.js | 12 +- 13 files changed, 403 insertions(+), 312 deletions(-) diff --git a/app.js b/app.js index 6eac1c1..2e61fe4 100644 --- a/app.js +++ b/app.js @@ -68,9 +68,7 @@ function initApp(options) { 'user-agent', 'x-request-id' ]; } - app.conf.log_header_whitelist = new RegExp(`^(?:${ app.conf.log_header_whitelist.map((item) => { - return item.trim(); - }).join('|') })$`, 'i'); + app.conf.log_header_whitelist = new RegExp(`^(?:${ app.conf.log_header_whitelist.map((item) => item.trim()).join('|') })$`, 'i'); // set up the request templates for the APIs apiUtil.setupApiTemplates(app); @@ -151,8 +149,7 @@ function initApp(options) { function loadRoutes(app, dir) { // recursively load routes from .js files under routes/ - return fs.readdirAsync(dir).map((fname) => { - return BBPromise.try(() => { + return fs.readdirAsync(dir).map((fname) => BBPromise.try(() => { const resolvedPath = path.resolve(dir, fname); const isDirectory = fs.statSync(resolvedPath).isDirectory(); if (isDirectory) { @@ -185,8 +182,7 @@ function loadRoutes(app, dir) { sUtil.wrapRouteHandlers(route, app); // all good, use that route app.use(route.path, route.router); - }); - }).then(() => { + })).then(() => { // catch errors sUtil.setErrorHandler(app); // route loading is now complete, return the app object diff --git a/lib/article.creation.morelike.js b/lib/article.creation.morelike.js index 87c5d9c..d0d0a79 100644 --- a/lib/article.creation.morelike.js +++ b/lib/article.creation.morelike.js @@ -340,9 +340,7 @@ function getArticleNormalizedRanksFromDb(app, wikidataIds, targetLanguage) { const retry = app.conf.mysql_conn.retry || 2; const retryDelay = app.conf.mysql_conn.retry_delay || 1000; - wikidataIds = wikidataIds.map((x) => { - return parseInt(x.replace('Q', ''), 10); - }); + wikidataIds = wikidataIds.map((x) => parseInt(x.replace('Q', ''), 10)); return new BBPromise((resolve, reject) => { _getArticleNormalizedRanksFromMySQL( diff --git a/lib/article.creation.translation.js b/lib/article.creation.translation.js index ae9e21c..9e53b81 100644 --- a/lib/article.creation.translation.js +++ b/lib/article.creation.translation.js @@ -126,11 +126,7 @@ function recommend(app, source, target, projectDomain, seed) { candidates = getArticlesByPageviews(app, source, target, projectDomain); } return candidates - .then((candidates) => { - return candidates.sort((a, b) => { - return b.sitelink_count - a.sitelink_count; - }); - }); + .then((candidates) => candidates.sort((a, b) => b.sitelink_count - a.sitelink_count)); } module.exports = { diff --git a/lib/description.js b/lib/description.js index 2ac31e4..c03b184 100644 --- a/lib/description.js +++ b/lib/description.js @@ -74,13 +74,11 @@ function wikibaseItemHasSiteLink(page, dbName) { * @return {!Object} filtered pages */ function filterPages(pages) { - return pages.filter(page => { - return hasPageProps(page) && + return pages.filter(page => hasPageProps(page) && !isDisambiguationPage(page) && hasWikibaseItem(page) && !hasDescription(page) && - !isPageProtected(page); - } + !isPageProtected(page) ); } @@ -178,16 +176,13 @@ function buildResponse( return []; } wikiPages.forEach((page) => { - const wikidataPage = wikidataPages.find(p => - p.title === page.pageprops.wikibase_item); + const wikidataPage = wikidataPages.find(p => p.title === page.pageprops.wikibase_item); page.wikibase_item = entities[page.pageprops.wikibase_item]; page.wikibase_item.protection = wikidataPage.protection; delete page.pageprops; }); - return wikiPages.filter((page) => { - return !isWikibaseItemPageProtected(page) && - isValidResult(page, targetLang, targetWikiLang, sourceLang, sourceWikiLang); - }); + return wikiPages.filter((page) => !isWikibaseItemPageProtected(page) && + isValidResult(page, targetLang, targetWikiLang, sourceLang, sourceWikiLang)); } /** diff --git a/package-lock.json b/package-lock.json index 16fc0a6..81e4dfc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ }, "devDependencies": { "ajv": "^6.9.1", - "eslint-config-wikimedia": "0.27.0", + "eslint-config-wikimedia": "0.28.2", "extend": "^3.0.2", "mocha": "^6.0.1", "mocha-lcov-reporter": "^1.3.0", @@ -200,9 +200,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -387,11 +387,14 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" @@ -678,6 +681,22 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -690,23 +709,17 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -714,12 +727,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -727,21 +740,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -753,10 +767,19 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -770,6 +793,21 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -777,64 +815,38 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "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" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "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" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -860,9 +872,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1270,12 +1282,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1320,9 +1332,9 @@ } }, "node_modules/browserslist-config-wikimedia": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz", - "integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.7.0.tgz", + "integrity": "sha512-CTa0lv78dXKEgrYsOLCkqO+9UUS3CV9MWEOYHcymgEvx4mYxB80sCoKRCR7wW2SOMNxjaP9hohrZripjnKuRTA==", "dev": true }, "node_modules/buffer-from": { @@ -1343,15 +1355,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", @@ -1801,9 +1804,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js-compat": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", - "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -2072,6 +2075,19 @@ "node": ">= 0.8" } }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2276,9 +2292,9 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "dependencies": { "semver": "^7.5.4" @@ -2291,28 +2307,28 @@ } }, "node_modules/eslint-config-wikimedia": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz", - "integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz", + "integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==", "dev": true, "dependencies": { - "browserslist-config-wikimedia": "^0.6.1", + "browserslist-config-wikimedia": "^0.7.0", "eslint": "^8.57.0", "eslint-plugin-compat": "^4.2.0", "eslint-plugin-es-x": "^7.6.0", - "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-jsdoc": "48.2.1", - "eslint-plugin-json-es": "^1.5.7", - "eslint-plugin-mediawiki": "^0.6.0", - "eslint-plugin-mocha": "^10.4.1", - "eslint-plugin-n": "^16.6.2", - "eslint-plugin-no-jquery": "^2.7.0", + "eslint-plugin-jest": "^28.5.0", + "eslint-plugin-jsdoc": "48.2.5", + "eslint-plugin-json-es": "^1.6.0", + "eslint-plugin-mediawiki": "^0.7.0", + "eslint-plugin-mocha": "^10.4.3", + "eslint-plugin-n": "^17.7.0", + "eslint-plugin-no-jquery": "^3.0.1", "eslint-plugin-qunit": "^8.1.1", "eslint-plugin-security": "^1.7.1", - "eslint-plugin-unicorn": "^51.0.1", - "eslint-plugin-vue": "^9.23.0", + "eslint-plugin-unicorn": "^53.0.0", + "eslint-plugin-vue": "^9.26.0", "eslint-plugin-wdio": "^8.24.12", - "eslint-plugin-yml": "^1.13.2" + "eslint-plugin-yml": "^1.14.0" } }, "node_modules/eslint-plugin-compat": { @@ -2337,39 +2353,40 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", - "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.7.0.tgz", + "integrity": "sha512-aP3qj8BwiEDPttxQkZdI221DLKq9sI/qHolE2YSQL1/9+xk7dTV+tB1Fz8/IaCA+lnLA1bDEnvaS2LKs0k2Uig==", "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.0" + "eslint-compat-utils": "^0.5.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, "peerDependencies": { "eslint": ">=8" } }, "node_modules/eslint-plugin-jest": { - "version": "27.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", - "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0", - "eslint": "^7.0.0 || ^8.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, "peerDependenciesMeta": { @@ -2382,19 +2399,19 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz", - "integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==", + "version": "48.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.5.tgz", + "integrity": "sha512-ZeTfKV474W1N9niWfawpwsXGu+ZoMXu4417eBROX31d7ZuOk8zyG66SO77DpJ2+A9Wa2scw/jRqBPnnQo7VbcQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.42.0", + "@es-joy/jsdoccomment": "~0.43.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", + "semver": "^7.6.1", "spdx-expression-parse": "^4.0.0" }, "engines": { @@ -2405,9 +2422,9 @@ } }, "node_modules/eslint-plugin-jsdoc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2438,9 +2455,9 @@ } }, "node_modules/eslint-plugin-json-es": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.7.tgz", - "integrity": "sha512-ehBHcCcJo4iViYx6vp3T+SmwzLIlVDzZNoVxN/txZIiPwDQ26mnYaN5iJ3imqN4l1b8z6rbxEH2kB9XDGxeU/w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.6.0.tgz", + "integrity": "sha512-xVn6hufGQH1Aa+yqOhQ43Cq28GuitTcMpQh+uaUh27U2qnVLBrvkN+2xQSnv6zpdLEPS35JCNhq4kvhR+PQCgw==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0", @@ -2451,9 +2468,9 @@ } }, "node_modules/eslint-plugin-mediawiki": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz", - "integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.7.0.tgz", + "integrity": "sha512-1Y2nsFDPp96xOZCB5ivZAgqYe9i6w2u64VoCIaAzPyZnd/2h8VQR3CtD+u4Yk/KrpbKq9AAJjrs5LS8VAz6KOA==", "dev": true, "dependencies": { "eslint-plugin-vue": "^9.23.0", @@ -2464,9 +2481,9 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz", - "integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.3.tgz", + "integrity": "sha512-emc4TVjq5Ht0/upR+psftuz6IBG5q279p+1dSRDeHf+NS9aaerBi3lXKo1SEzwC29hFIW21gO89CEWSvRsi8IQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -2481,40 +2498,73 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.9.0.tgz", + "integrity": "sha512-CPSaXDXdrT4nsrOrO4mT4VB6FMUkoySRkHWuuJJHVqsIEjIeZgMY1H7AzSwPbDScikBmLN82KeM1u7ixV7PzGg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", + "enhanced-resolve": "^5.17.0", "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", + "globals": "^15.0.0", "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", + "minimatch": "^9.0.0", "semver": "^7.5.3" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.7.0.tgz", + "integrity": "sha512-ivatRXWwKC6ImcdKO7dOwXuXR5XFrdwo45qFwD7D0qOkEPzzJdLXC3BHceBdyrPOD3p1suPaWi4Y4NMm2D++AQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/eslint-plugin-no-jquery": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", - "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz", + "integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==", "dev": true, "peerDependencies": { - "eslint": ">=2.3.0" + "eslint": ">=8.0.0" } }, "node_modules/eslint-plugin-qunit": { @@ -2540,17 +2590,17 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "51.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", - "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "version": "53.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-53.0.0.tgz", + "integrity": "sha512-kuTcNo9IwwUCfyHGwQFOK/HjJAYzbODHN3wP0PgqbW+jbXqpNWxNVpVhj2tO9SixBwuAdmal8rVcWKBxwFnGuw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "@eslint-community/eslint-utils": "^4.4.0", - "@eslint/eslintrc": "^2.1.4", + "@eslint/eslintrc": "^3.0.2", "ci-info": "^4.0.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.34.0", + "core-js-compat": "^3.37.0", "esquery": "^1.5.0", "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", @@ -2559,11 +2609,11 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.27", "regjsparser": "^0.10.0", - "semver": "^7.5.4", + "semver": "^7.6.1", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=16" + "node": ">=18.18" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" @@ -2572,6 +2622,105 @@ "eslint": ">=8.56.0" } }, + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint-plugin-unicorn/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -2584,10 +2733,16 @@ "node": ">=6" } }, + "node_modules/eslint-plugin-unicorn/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/eslint-plugin-vue": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz", - "integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==", + "version": "9.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz", + "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -3048,9 +3203,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3374,9 +3529,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -4768,17 +4923,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -4841,12 +4985,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6046,9 +6190,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -7154,12 +7298,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -7810,6 +7951,15 @@ "node": ">=4" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "4.4.19", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", @@ -8057,25 +8207,16 @@ "node": ">=0.8" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, "engines": { - "node": ">= 6" + "node": ">=16" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "typescript": ">=4.2.0" } }, "node_modules/tunnel-agent": { @@ -8211,9 +8352,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "peer": true, "bin": { @@ -8349,9 +8490,9 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -8373,9 +8514,9 @@ } }, "node_modules/vue-eslint-parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -8616,11 +8757,6 @@ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/yaml": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", diff --git a/package.json b/package.json index a940615..533669c 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "devDependencies": { "ajv": "^6.9.1", - "eslint-config-wikimedia": "0.27.0", + "eslint-config-wikimedia": "0.28.2", "extend": "^3.0.2", "mocha": "^6.0.1", "mocha-lcov-reporter": "^1.3.0", diff --git a/routes/article.creation.morelike.js b/routes/article.creation.morelike.js index aea403f..1abc1d8 100644 --- a/routes/article.creation.morelike.js +++ b/routes/article.creation.morelike.js @@ -85,13 +85,11 @@ router.get('/:seed', (req, res) => { app, ids, language ).then((results) => { res.json(results); - }).catch((error) => { - return BBPromise.reject(new util.HTTPError({ + }).catch((error) => BBPromise.reject(new util.HTTPError({ status: 503, message: 'Cannot retrieve normalized ranks from' + ' the database. Please try again later.' - })); - }); + }))); } }); }); diff --git a/test/features/app/app.js b/test/features/app/app.js index 0ac8f00..7e3d3e5 100644 --- a/test/features/app/app.js +++ b/test/features/app/app.js @@ -17,14 +17,12 @@ describe('express app', function () { before(() => server.start()); - it('should get robots.txt', () => { - return preq.get({ + it('should get robots.txt', () => preq.get({ uri: `${ server.config.uri }robots.txt` }).then((res) => { assert.deepEqual(res.status, 200); assert.deepEqual(res.headers.disallow, '/'); - }); - }); + })); it('should set CORS headers', () => { if (server.config.service.conf.cors === false) { @@ -59,8 +57,7 @@ describe('express app', function () { }); }); - it('should get static content gzipped', () => { - return preq.get({ + it('should get static content gzipped', () => preq.get({ uri: `${ server.config.uri }static/index.html`, headers: { 'accept-encoding': 'gzip, deflate' @@ -70,11 +67,9 @@ describe('express app', function () { // if there is no content-length, the reponse was gzipped assert.deepEqual(res.headers['content-length'], undefined, 'Did not expect the content-length header!'); - }); - }); + })); - it('should get static content uncompressed', () => { - return preq.get({ + it('should get static content uncompressed', () => preq.get({ uri: `${ server.config.uri }static/index.html`, headers: { 'accept-encoding': '' @@ -83,6 +78,5 @@ describe('express app', function () { const contentEncoding = res.headers['content-encoding']; assert.deepEqual(res.status, 200); assert.deepEqual(contentEncoding, undefined, 'Did not expect gzipped contents!'); - }); - }); + })); }); diff --git a/test/features/app/spec.js b/test/features/app/spec.js index 60b500d..84ca636 100644 --- a/test/features/app/spec.js +++ b/test/features/app/spec.js @@ -240,19 +240,15 @@ describe('Swagger spec', function () { this.timeout(20000); - before(() => { - return server.start(); - }); + before(() => server.start()); - it('get the spec', () => { - return preq.get(`${ server.config.uri }?spec`) + it('get the spec', () => preq.get(`${ server.config.uri }?spec`) .then((res) => { assert.status(200); assert.contentType(res, 'application/json'); assert.notDeepEqual(res.body, undefined, 'No body received!'); spec = res.body; - }); - }); + })); it('spec validation', () => { if (spec['x-default-params']) { @@ -282,14 +278,12 @@ describe('Swagger spec', function () { describe('routes', () => { constructTests(spec.paths, defParams).forEach((testCase) => { - it(testCase.title, () => { - return preq(testCase.request) + it(testCase.title, () => preq(testCase.request) .then((res) => { validateTestResponse(testCase, res); }, (err) => { validateTestResponse(testCase, err); - }); - }); + })); }); }); diff --git a/test/features/v1/article.creation.morelike.js b/test/features/v1/article.creation.morelike.js index c280826..dab1388 100644 --- a/test/features/v1/article.creation.morelike.js +++ b/test/features/v1/article.creation.morelike.js @@ -29,8 +29,7 @@ before(() => server.start()); describe('article.creation.morelike', function () { this.timeout(20000); - it('should return recommendations for good article title', () => { - return preq.get( + it('should return recommendations for good article title', () => preq.get( `${ server.config.uri }uz.wikipedia.org/v1/article/creation/morelike/Palov` ).then((res) => { assert.status(res, 200); @@ -43,6 +42,5 @@ describe('article.creation.morelike', function () { { wikidata_id: 'Q127418', normalized_rank: 0.891431 } ] ); - }); - }); + })); }); diff --git a/test/lib/caption.js b/test/lib/caption.js index 39392d1..1378664 100644 --- a/test/lib/caption.js +++ b/test/lib/caption.js @@ -190,9 +190,7 @@ describe('lib:caption', () => { } }; - const cond = (image, targetLang, sourceLang) => { - return image.structured.captions[sourceLang] && !image.structured.captions[targetLang]; - }; + const cond = (image, targetLang, sourceLang) => image.structured.captions[sourceLang] && !image.structured.captions[targetLang]; const makeResults = lib.__get__('makeResults'); diff --git a/test/lib/suggested-edits-common.js b/test/lib/suggested-edits-common.js index e8b36f1..e92c212 100644 --- a/test/lib/suggested-edits-common.js +++ b/test/lib/suggested-edits-common.js @@ -57,23 +57,17 @@ describe('lib:suggested-edits-common', () => { describe('getWikiLangForLangCode', () => { - it('translates language variants to base wiki language codes', () => { - return lib.getWikiLangForLangCode(app, req, 'zh-hans').then((res) => { + it('translates language variants to base wiki language codes', () => lib.getWikiLangForLangCode(app, req, 'zh-hans').then((res) => { assert.deepEqual(res, 'zh'); - }); - }); + })); - it('passed through other inputs', () => { - return lib.getWikiLangForLangCode(app, req, 'foo').then((res) => { + it('passed through other inputs', () => lib.getWikiLangForLangCode(app, req, 'foo').then((res) => { assert.deepEqual(res, 'foo'); - }); - }); + })); - it('handles undefined', () => { - return lib.getWikiLangForLangCode(app, req, undefined).then((res) => { + it('handles undefined', () => lib.getWikiLangForLangCode(app, req, undefined).then((res) => { assert.deepEqual(res, undefined); - }); - }); + })); }); diff --git a/test/utils/server.js b/test/utils/server.js index 70099e1..44cb649 100644 --- a/test/utils/server.js +++ b/test/utils/server.js @@ -29,9 +29,7 @@ config.conf.logging = { // make a deep copy of it for later reference const origConfig = extend(true, {}, config); -module.exports.stop = () => { - return BBPromise.resolve(); -}; +module.exports.stop = () => BBPromise.resolve(); let options = null; const runner = new ServiceRunner(); @@ -50,13 +48,9 @@ function start(_options) { .then((serviceReturns) => { module.exports.stop = () => { console.log('stopping test server'); - serviceReturns.forEach(servers => - servers.forEach(server => - server.shutdown())); + serviceReturns.forEach(servers => servers.forEach(server => server.shutdown())); return runner.stop().then(() => { - module.exports.stop = () => { - return BBPromise.resolve(); - }; + module.exports.stop = () => BBPromise.resolve(); }); }; return true; -- 2.39.2 --- end ---