feat: testing eslint9 (#13266)

* feat: testing eslint9

* fix: restore original functionality
This commit is contained in:
Barış Soner Uşaklı
2025-03-22 11:21:49 -04:00
committed by GitHub
parent 87b617e9bb
commit 6813664120
53 changed files with 116 additions and 122 deletions

View File

@@ -1,21 +0,0 @@
node_modules/
*.sublime-project
*.sublime-workspace
.project
.vagrant
.DS_Store
logs/
/public/templates
/public/uploads
/public/vendor
/public/src/modules/string.js
.idea/
.vscode/
*.ipr
*.iws
/coverage
/build
.eslintrc
test/files
*.min.js
install/docker/

View File

@@ -1,3 +0,0 @@
{
"extends": "nodebb"
}

62
eslint.config.cjs Normal file
View File

@@ -0,0 +1,62 @@
'use strict';
const serverConfig = require('eslint-config-nodebb');
const publicConfig = require('eslint-config-nodebb/public');
const { configs } = require('@eslint/js');
const globals = require('globals');
module.exports = [
{
ignores: [
'node_modules/',
'.project',
'.vagrant',
'.DS_Store',
'.tx',
'logs/',
'public/uploads/',
'public/vendor/',
'.idea/',
'.vscode/',
'*.ipr',
'*.iws',
'coverage/',
'build/',
'test/files/',
'*.min.js',
'install/docker/',
],
},
configs.recommended,
{
rules: {
'no-bitwise': 'warn',
'no-await-in-loop': 'warn',
}
},
// tests
{
files: ['test/**/*.js'],
languageOptions: {
ecmaVersion: 2020,
sourceType: 'commonjs',
globals: {
...globals.node,
...globals.browser,
it: 'readonly',
describe: 'readonly',
before: 'readonly',
beforeEach: 'readonly',
after: 'readonly',
afterEach: 'readonly',
},
},
rules: {
'no-unused-vars': 'off',
'no-prototype-builtins': 'off',
}
},
...publicConfig,
...serverConfig
];

View File

@@ -162,8 +162,8 @@
"@commitlint/cli": "19.8.0",
"@commitlint/config-angular": "19.8.0",
"coveralls": "3.1.1",
"eslint": "8.57.1",
"eslint-config-nodebb": "0.2.1",
"@eslint/js": "9.23.0",
"eslint-config-nodebb": "1.0.7",
"eslint-plugin-import": "2.31.0",
"grunt": "1.6.1",
"grunt-contrib-watch": "1.1.0",

View File

@@ -1,3 +0,0 @@
{
"extends": "nodebb/public"
}

View File

@@ -4,7 +4,6 @@ require('../app');
// scripts-admin.js is generated during build, it contains javascript files
// from plugins that add files to "acpScripts" block in plugin.json
// eslint-disable-next-line
require('../../scripts-admin');
app.onDomReady();

View File

@@ -23,7 +23,6 @@ Chart.register(
);
// eslint-disable-next-line import/prefer-default-export
export function init() {
setupCharts();

View File

@@ -64,7 +64,6 @@ $(window).on('action:ajaxify.start', function () {
usedTopicColors.length = 0;
});
// eslint-disable-next-line import/prefer-default-export
export function init() {
app.enterRoom('admin');

View File

@@ -21,7 +21,6 @@ Chart.register(
Filler
);
// eslint-disable-next-line import/prefer-default-export
export function init() {
categorySelector.init($('[component="category-selector"]'), {
onSelect: function (selectedCategory) {

View File

@@ -3,7 +3,6 @@ import { error } from '../../modules/alerts';
import * as categorySelector from '../../modules/categorySelector';
// eslint-disable-next-line import/prefer-default-export
export function init() {
categorySelector.init($('[component="category-selector"]'), {
onSelect: function (selectedCategory) {

View File

@@ -30,7 +30,6 @@ Chart.register(
let _current = null;
let isMobile = false;
// eslint-disable-next-line import/prefer-default-export
export function init({ set, dataset }) {
const canvas = document.getElementById('analytics-traffic');
const canvasCtx = canvas.getContext('2d');

View File

@@ -38,12 +38,13 @@ ajaxify.widgets = { render: render };
if (!pathname) {
({ pathname } = urlObj);
}
} catch (e) {
} catch (err) {
console.error(err);
return false;
}
const internalLink = utils.isInternalURI(urlObj, window.location, config.relative_path);
// eslint-disable-next-line no-script-url
const hrefEmpty = href => href === undefined || href === '' || href === 'javascript:;';
if (item instanceof Element) {
@@ -55,7 +56,6 @@ ajaxify.widgets = { render: render };
return null;
}
// eslint-disable-next-line no-script-url
if (hrefEmpty(urlObj.href) || urlObj.protocol === 'javascript:' || pathname === '#' || pathname === '') {
return null;
}
@@ -514,7 +514,6 @@ ajaxify.widgets = { render: render };
cache: false,
dataType: 'text',
success: function (script) {
// eslint-disable-next-line no-new-func
const renderFunction = new Function('module', script);
const moduleObj = { exports: {} };
renderFunction(moduleObj);

View File

@@ -4,7 +4,6 @@ require('./app');
// scripts-client.js is generated during build, it contains javascript files
// from plugins that add files to "scripts" block in plugin.json
// eslint-disable-next-line
require('../scripts-client');
app.onDomReady();

View File

@@ -26,7 +26,8 @@ define('forum/account/sessions', ['forum/account/header', 'components', 'api', '
window.location.href = config.relative_path + '/login?error=' + errorObj.title;
}
alerts.error(errorObj.title);
} catch (e) {
} catch (err) {
console.error(err);
alerts.error('[[error:invalid-data]]');
}
});

View File

@@ -132,6 +132,7 @@ define('forum/chats/manage', [
try {
data = await api.get(`/chats/${roomId}/users`, {});
} catch (err) {
console.error(err);
listEl.find('li').text(await translator.translate('[[error:invalid-data]]'));
}
}

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-redeclare */
'use strict';
const $ = require('jquery');

View File

@@ -1,5 +1,3 @@
/* eslint-disable import/first */
export * from 'ace-builds';
// only import the modes and theme we use
@@ -9,8 +7,7 @@ import 'ace-builds/src-noconflict/mode-html';
import 'ace-builds/src-noconflict/ext-searchbox';
import 'ace-builds/src-noconflict/theme-twilight';
/* eslint-disable import/no-webpack-loader-syntax */
/* eslint-disable import/no-unresolved */
import htmlWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-html';
import javascriptWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-javascript';
import cssWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-css';

View File

@@ -1,5 +1,3 @@
/* eslint-disable import/no-unresolved */
'use strict';
import { fire as fireHook } from 'hooks';

View File

@@ -222,6 +222,7 @@ define('iconSelect', ['benchpress', 'bootbox'], function (Benchpress, bootbox) {
{ id: 'android', label: 'Android (brands)', style: 'brands' },
{ id: 'address-book', label: 'Address Book (solid)', style: 'solid' },
];
iconSelect.init = function (el, onModified) {
onModified = onModified || function () { };
let selected = cleanFAClass(el[0].classList);
@@ -230,6 +231,7 @@ define('iconSelect', ['benchpress', 'bootbox'], function (Benchpress, bootbox) {
try {
$(`#icons .nbb-fa-icons ${selected.styles.length ? '.' + selected.styles.join('.') : ''}.${selected.icon}`).addClass('selected');
} catch (err) {
console.error(err);
selected = {
icon: '',
style: '',

View File

@@ -270,7 +270,8 @@ define('search', [
let term = data.term.replace(/^[ ?#]*/, '');
try {
term = encodeURIComponent(term);
} catch (e) {
} catch (err) {
console.error(err);
return alerts.error('[[error:invalid-search-term]]');
}
@@ -291,7 +292,8 @@ define('search', [
Search.getSearchPreferences = function () {
try {
return JSON.parse(storage.getItem('search-preferences') || '{}');
} catch (e) {
} catch (err) {
console.error(err);
return {};
}
};

View File

@@ -2,11 +2,10 @@
define('settings', ['hooks', 'alerts'], function (hooks, alerts) {
// eslint-disable-next-line prefer-const
let Settings;
let onReady = [];
let waitingJobs = 0;
// eslint-disable-next-line prefer-const
let helper;
/**
@@ -30,7 +29,6 @@ define('settings', ['hooks', 'alerts'], function (hooks, alerts) {
return null;
}
// eslint-disable-next-line prefer-const
helper = {
/**
@returns Object A deep clone of the given object.
@@ -326,12 +324,13 @@ define('settings', ['hooks', 'alerts'], function (hooks, alerts) {
use: function (settings) {
try {
settings._ = JSON.parse(settings._);
} catch (_error) {}
} catch (err) {
console.error(err);
}
Settings.cfg = settings;
},
};
// eslint-disable-next-line prefer-const
Settings = {
helper: helper,
plugins: {},
@@ -474,8 +473,8 @@ define('settings', ['hooks', 'alerts'], function (hooks, alerts) {
if (key && values.hasOwnProperty(key)) {
try {
values[key] = JSON.parse(values[key]);
} catch (e) {
// Leave the value as is
} catch (err) {
console.error(err);
}
}
});

View File

@@ -105,7 +105,8 @@ define('settings/array', function () {
separator = (function () {
try {
return $(separator);
} catch (_error) {
} catch (err) {
console.error(err);
return $(document.createTextNode(separator));
}
}());

View File

@@ -68,7 +68,8 @@ define('settings/object', function () {
separator = (function () {
try {
return $(separator);
} catch (_error) {
} catch (err) {
console.error(err);
return $(document.createTextNode(separator));
}
}());

View File

@@ -107,7 +107,8 @@ define('uploader', ['jquery-form'], function () {
if (typeof response === 'string') {
try {
return JSON.parse(response);
} catch (e) {
} catch (err) {
console.error(err);
return { error: '[[error:parse-error]]' };
}
}

View File

@@ -51,7 +51,9 @@ define('userFilter', ['api', 'hooks', 'slugify', 'benchpress'], function (api, h
try {
const userData = await api.get(`/api/user/${slugify(query)}`);
result.users.push(userData);
} catch (err) {}
} catch (err) {
console.error(err);
}
}
}
if (!result.users.length) {

View File

@@ -1,10 +1,8 @@
'use strict';
// eslint-disable-next-line no-redeclare
const io = require('socket.io-client');
// eslint-disable-next-line no-redeclare
const $ = require('jquery');
// eslint-disable-next-line import/no-unresolved
const { alert } = require('alerts');
app = window.app || {};

View File

@@ -272,7 +272,6 @@ const HTMLEntities = Object.freeze({
'diams;': 9830,
});
/* eslint-disable no-redeclare */
const utils = {
// https://github.com/substack/node-ent/blob/master/index.js
decodeHTMLEntities: function (html) {
@@ -467,7 +466,8 @@ const utils = {
try {
return new Date(parseInt(timestamp, 10)).toISOString();
} catch (e) {
} catch (err) {
console.error(err);
return timestamp;
}
},
@@ -631,7 +631,9 @@ const utils = {
try {
str = JSON.parse(str);
} catch (e) {}
} catch (err) {
console.error(err)
}
return str;
},

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-redeclare */
'use strict';

View File

@@ -37,7 +37,7 @@
if ($el.css('background-size') == "cover") {
var elementWidth = $el.innerWidth(),
elementHeight = $el.innerHeight(),
elementAspectRatio = elementWidth / elementHeight;
elementAspectRatio = elementWidth / elementHeight,
imageAspectRatio = image.width / image.height,
scale = 1;
@@ -182,18 +182,17 @@
}
$.fn.backgroundDraggable = function(options) {
var options = options;
var args = Array.prototype.slice.call(arguments, 1);
return this.each(function() {
var $this = $(this);
var plugin;
if (typeof options == 'undefined' || typeof options == 'object') {
options = $.extend({}, $.fn.backgroundDraggable.defaults, options);
var plugin = new Plugin(this, options);
plugin = new Plugin(this, options);
$this.data('dbg', plugin);
} else if (typeof options == 'string' && $this.data('dbg')) {
var plugin = $this.data('dbg');
plugin = $this.data('dbg');
Plugin.prototype[options].apply(plugin, args);
}
});
@@ -202,6 +201,6 @@
$.fn.backgroundDraggable.defaults = {
bound: true,
axis: undefined,
units: 'pixels'
units: 'pixels',
};
}(jQuery));

View File

@@ -1,5 +1,3 @@
/* eslint-disable import/order */
'use strict';
const fs = require('fs');

View File

@@ -21,8 +21,8 @@ eventsController.get = async function (req, res) {
}
// Limit by date
let from = req.query.start ? new Date(req.query.start) || undefined : undefined;
let to = req.query.end ? new Date(req.query.end) || undefined : new Date();
let from = req.query.start ? new Date(req.query.start) : undefined;
let to = req.query.end ? new Date(req.query.end) : new Date();
from = from && from.setUTCHours(0, 0, 0, 0); // setHours returns a unix timestamp (Number, not Date)
to = to && to.setUTCHours(23, 59, 59, 999); // setHours returns a unix timestamp (Number, not Date)

View File

@@ -106,8 +106,7 @@ events.log = async function (data) {
events.getEvents = async function (options) {
// backwards compatibility
if (arguments.length > 1) {
// eslint-disable-next-line prefer-rest-params
const args = Array.prototype.slice.call(arguments);
const args = [...arguments];
options = {
filter: args[0],
start: args[1],

View File

@@ -146,7 +146,6 @@ Upgrade.process = async function (files, skipCount) {
process.stdout.write(chalk.grey(' skipped\n'));
await db.sortedSetAdd('schemaLog', Date.now(), path.basename(file, '.js'));
// eslint-disable-next-line no-continue
continue;
}

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -76,7 +76,7 @@ module.exports = {
batch: 500,
withScores: true,
});
// eslint-disable-next-line no-await-in-loop
await db.deleteAll(`uid:${uid}:chat:room:${roomId}:mids`);
progress.incr(1);
}

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,5 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';
const db = require('../../database');

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-await-in-loop */
'use strict';

View File

@@ -4,6 +4,7 @@
const async = require('async');
const nconf = require('nconf');
const validator = require('validator');
const winston = require('winston');
const db = require('../database');
const meta = require('../meta');
@@ -88,7 +89,8 @@ module.exports = function (User) {
try {
groupsToJoin = JSON.parse(groupsToJoin);
} catch (e) {
} catch (err) {
winston.error(`[User.joinGroupsFromInvitation] ${err.stack}`);
return;
}

View File

@@ -45,7 +45,8 @@ utils.getSass = function () {
try {
const sass = require('sass-embedded');
return sass;
} catch (_err) {
} catch (err) {
console.error(err.message)
return require('sass');
}
};

View File

@@ -134,7 +134,7 @@ widgets.getWidgetDataForTemplates = async function (templates) {
try {
returnData[template][location] = parseWidgetData(templateWidgetData[location]);
} catch (err) {
winston.error(`can not parse widget data. template: ${template} location: ${location}`);
winston.error(`can not parse widget data. template: ${template} location: ${location}\n${err.stack}`);
returnData[template][location] = [];
}
} else {

View File

@@ -1,8 +0,0 @@
{
"env": {
"mocha": true
},
"rules": {
"no-unused-vars": "off"
}
}

View File

@@ -2,7 +2,6 @@
const nconf = require('nconf');
const assert = require('assert');
const async = require('async');
const db = require('../mocks/databasemock');
@@ -10,7 +9,6 @@ const user = require('../../src/user');
const groups = require('../../src/groups');
const request = require('../../src/request');
const socketUser = require('../../src/socket.io/user');
const adminUser = require('../../src/socket.io/admin/user');

View File

@@ -1,8 +1,6 @@
'use strict';
const assert = require('assert');
const nconf = require('nconf');
const util = require('util');
const db = require('../mocks/databasemock');
@@ -16,7 +14,7 @@ const utils = require('../../src/utils');
describe('email confirmation (library methods)', () => {
let uid;
async function dummyEmailerHook(data) {
async function dummyEmailerHook() {
// pretend to handle sending emails
}
@@ -159,7 +157,6 @@ describe('email confirmation (v3 api)', () => {
});
it('should have a pending validation', async () => {
const code = await db.get(`confirm:byUid:${userObj.uid}`);
assert.strictEqual(await user.email.isValidationPending(userObj.uid, 'test@example.org'), true);
});

View File

@@ -96,6 +96,7 @@ describe('Utility Methods', () => {
const email = 'sample@example.com';
assert(utils.isEmailValid(email), 'invalid email');
});
it('rejects empty address', () => {
const email = '';
assert.equal(utils.isEmailValid(email), false, 'accepted as valid email');
@@ -560,6 +561,7 @@ describe('Utility Methods', () => {
const shim = require('../src/translator');
const { Translator } = shim;
it('should translate in place', async () => {
const translator = Translator.create('en-GB');
const el = $(`<div><span id="search" title="[[global:search]]"></span><span id="text">[[global:home]]</span></div>`);