From 4667a026cdde0758a09a4d88d72988d4f56a2332 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Wed, 8 Jul 2026 10:57:33 +0100 Subject: [PATCH 1/5] remove temp override rules and finish eslint migration --- eslint.config.mjs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index ed4870c808..0f6fb24fcf 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -22,19 +22,6 @@ export default [ ] }, - // TODO(eslint-v9-follow-up): the ESLint 8 -> 9 / neostandard rule-set change left a number - // of now-stale inline `eslint-disable` comments in the codebase (for n/no-process-exit, - // n/no-extraneous-import, n/no-unpublished-require, n/handle-callback-err, no-unused-vars, - // no-useless-return, no-template-curly-in-string, promise/no-callback-in-promise, - // vue/one-component-per-file, etc.). They surface as "Unused eslint-disable directive" - // warnings. Silencing the report here to keep this migration PR small; remove this block - // and delete the stale directives in the follow-up PR. - { - linterOptions: { - reportUnusedDisableDirectives: 'off' - } - }, - // extends: standard, plugin:import/recommended, plugin:promise/recommended, plugin:n/recommended // neostandard is the flat-config successor to eslint-config-standard and registers // (globally) the n and promise plugins plus @stylistic, subsuming the old promise/n @@ -156,12 +143,6 @@ export default [ 'vue/singleline-html-element-content-newline': 'off', 'vue/component-definition-name-casing': 'off', - // TODO(eslint-v9-follow-up): vue/no-required-prop-with-default is new in - // eslint-plugin-vue v10 and flags a required prop that also declares a default. - // Disabled to keep this migration PR small; fix the offending prop(s) and remove - // this in the follow-up PR. - 'vue/no-required-prop-with-default': 'off', - // plugin:promise 'promise/always-return': 'off', // common Vue.js pattern From 698a26b146a16486d69e7a512792f1aae1383534 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Wed, 8 Jul 2026 11:14:08 +0100 Subject: [PATCH 2/5] remove unused eslint-disable directives **forge code** Unused eslint-disable directive (no problems were reported from 'no-useless-return').eslint Unused eslint-disable directive (no problems were reported from 'n/no-unpublished-require').eslint Unused eslint-disable directive (no problems were reported from 'promise/no-callback-in-promise').eslint **vue files** Unused eslint-disable directive (no problems were reported from 'no-template-curly-in-string').eslint Unused eslint-disable directive (no problems were reported from 'vue/one-component-per-file').eslint Unused eslint-disable directive (no problems were reported from 'promise/no-nesting').eslint Unused eslint-disable directive (no problems were reported from 'n/no-extraneous-import').eslint **frontend test files** Unused eslint-disable directive (no problems were reported from 'n/no-process-exit').eslint Unused eslint-disable directive (no problems were reported from 'cypress/require-data-selectors').eslint **forge test files** Unused eslint-disable directive (no problems were reported from 'no-unused-vars').eslint Unused eslint-disable directive (no problems were reported from 'camelcase').eslint --- forge/caches/redis-cache.js | 2 +- forge/containers/stub/index.js | 2 +- .../20230824-01-add-ApplicationId-to-Devices.js | 2 -- .../20230919-01-add-action-to-pipeline-stage.js | 2 -- .../migrations/20240221-01-add-editor-state-to-Devices.js | 2 -- .../20240327-01-add-credentialSecret-to-snapshots.js | 2 -- .../migrations/20240503-01-ensure-all-ee-tables-exist.js | 1 - forge/ee/routes/catalogues/index.js | 2 +- forge/ee/routes/customHostnames/index.js | 2 +- forge/ee/routes/deviceEditor/index.js | 2 +- forge/ee/routes/gitops/index.js | 2 +- forge/ee/routes/ha/index.js | 2 +- forge/ee/routes/httpTokens/index.js | 8 ++++---- forge/ee/routes/protectedInstance/index.js | 2 +- forge/ee/routes/staticAssets/index.js | 2 +- forge/ee/routes/tables/index.js | 2 +- forge/ee/routes/teamBroker/3rdPartyBroker.js | 4 ++-- forge/ee/routes/teamBroker/index.js | 2 +- forge/ee/routes/teamBroker/schema.js | 4 ++-- forge/forge.js | 4 ++-- forge/routes/api/deviceSnapshots.js | 2 +- forge/routes/auth/index.js | 1 - forge/routes/index.js | 3 +-- frontend/src/components/audit-log/AuditLog.vue | 1 - frontend/src/composables/Hubspot.js | 2 +- .../pages/team/Devices/dialogs/TeamDeviceCreateDialog.vue | 4 ++-- frontend/src/pages/team/changeType.vue | 1 - frontend/src/tours/Tours.js | 2 -- test/e2e/frontend/cypress/tests-ee/admin/alerts.spec.js | 2 +- test/e2e/frontend/cypress/tests/devices/bulk.spec.js | 1 - test/e2e/frontend/test_environment_ee.js | 1 - test/e2e/frontend/test_environment_os.js | 1 - test/system/110-editor-login_spec.js | 2 +- test/system/201-nr-tools-plugin_spec.js | 2 +- test/unit/forge/caches/redis-cache_spec.js | 2 +- test/unit/forge/db/controllers/Project_spec.js | 2 +- test/unit/forge/db/models/Device_spec.js | 2 +- test/unit/forge/db/models/Project_spec.js | 2 +- test/unit/forge/ee/lib/billing/trialTask_spec.js | 2 +- .../forge/ee/routes/api/applicationDeviceGroups_spec.js | 2 +- test/unit/forge/ee/routes/api/application_spec.js | 2 +- test/unit/forge/ee/routes/catalogue/index_spec.js | 2 +- test/unit/forge/ee/routes/expert/index_spec.js | 2 +- test/unit/forge/ee/routes/ha/index_spec.js | 2 +- test/unit/forge/ee/routes/mcp/server_spec.js | 2 +- test/unit/forge/ee/routes/staticAssets/index_spec.js | 2 +- test/unit/forge/ee/routes/teamBroker/index_spec.js | 2 +- test/unit/forge/licensing/index_spec.js | 6 +++--- test/unit/forge/routes/api/application_spec.js | 2 +- test/unit/forge/routes/api/deviceSnapshots_spec.js | 2 +- test/unit/forge/routes/api/device_spec.js | 2 +- test/unit/forge/routes/api/projectSnapshots_spec.js | 2 +- test/unit/forge/routes/api/project_spec.js | 2 +- test/unit/forge/routes/api/snapshots_spec.js | 2 +- test/unit/forge/routes/api/teamDevices_spec.js | 2 +- test/unit/forge/routes/api/team_spec.js | 2 +- test/unit/forge/routes/auth/index_spec.js | 2 +- test/unit/forge/routes/auth/oauth_spec.js | 2 +- test/unit/forge/routes/logging/index_spec.js | 2 +- 59 files changed, 56 insertions(+), 74 deletions(-) diff --git a/forge/caches/redis-cache.js b/forge/caches/redis-cache.js index 40d60579d6..96eb00a1fc 100644 --- a/forge/caches/redis-cache.js +++ b/forge/caches/redis-cache.js @@ -20,7 +20,7 @@ async function initCache (options, app) { } } client = createClient(newOptions) - // eslint-disable-next-line n/handle-callback-err + client.on('error', (err) => { app.log.info(`Valkey Cache error ${err}`) }) diff --git a/forge/containers/stub/index.js b/forge/containers/stub/index.js index 0eb64c2e3c..47fec11667 100644 --- a/forge/containers/stub/index.js +++ b/forge/containers/stub/index.js @@ -11,7 +11,7 @@ */ const { normalize } = require('path') -const nrUtil = require('@node-red/util') // eslint-disable-line +const nrUtil = require('@node-red/util') const forgeUtils = require('../../db/utils') diff --git a/forge/db/migrations/20230824-01-add-ApplicationId-to-Devices.js b/forge/db/migrations/20230824-01-add-ApplicationId-to-Devices.js index ba30d07aae..2ceefc8648 100644 --- a/forge/db/migrations/20230824-01-add-ApplicationId-to-Devices.js +++ b/forge/db/migrations/20230824-01-add-ApplicationId-to-Devices.js @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ - /** * Add ProjectSnapshots table */ diff --git a/forge/db/migrations/20230919-01-add-action-to-pipeline-stage.js b/forge/db/migrations/20230919-01-add-action-to-pipeline-stage.js index e604bde32a..10f64b5d49 100644 --- a/forge/db/migrations/20230919-01-add-action-to-pipeline-stage.js +++ b/forge/db/migrations/20230919-01-add-action-to-pipeline-stage.js @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ - /** * Add ProjectSnapshots table */ diff --git a/forge/db/migrations/20240221-01-add-editor-state-to-Devices.js b/forge/db/migrations/20240221-01-add-editor-state-to-Devices.js index d0125f7858..4dd11142b8 100644 --- a/forge/db/migrations/20240221-01-add-editor-state-to-Devices.js +++ b/forge/db/migrations/20240221-01-add-editor-state-to-Devices.js @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ - /** * Add editorAffinity details to Devices table */ diff --git a/forge/db/migrations/20240327-01-add-credentialSecret-to-snapshots.js b/forge/db/migrations/20240327-01-add-credentialSecret-to-snapshots.js index 186a933195..31d42be8af 100644 --- a/forge/db/migrations/20240327-01-add-credentialSecret-to-snapshots.js +++ b/forge/db/migrations/20240327-01-add-credentialSecret-to-snapshots.js @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ - /** * Add credentialSecret to Snapshots table */ diff --git a/forge/db/migrations/20240503-01-ensure-all-ee-tables-exist.js b/forge/db/migrations/20240503-01-ensure-all-ee-tables-exist.js index d62e886f78..ac03726457 100644 --- a/forge/db/migrations/20240503-01-ensure-all-ee-tables-exist.js +++ b/forge/db/migrations/20240503-01-ensure-all-ee-tables-exist.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ /** * This migration ensures that all EE tables exist in the correct state. * This is only relevant for users running OSS version who installed <2.1.0. diff --git a/forge/ee/routes/catalogues/index.js b/forge/ee/routes/catalogues/index.js index d11b83d5c6..412a492517 100644 --- a/forge/ee/routes/catalogues/index.js +++ b/forge/ee/routes/catalogues/index.js @@ -17,7 +17,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('npm', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } if (!request.teamMembership && request.session.User) { diff --git a/forge/ee/routes/customHostnames/index.js b/forge/ee/routes/customHostnames/index.js index 98a03ae0c4..e8f0f5e45b 100644 --- a/forge/ee/routes/customHostnames/index.js +++ b/forge/ee/routes/customHostnames/index.js @@ -21,7 +21,7 @@ module.exports = async function (app) { await request.project.Team.ensureTeamTypeExists() if (!request.project.Team.getFeatureProperty('customHostnames', true)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.project.Team.id) diff --git a/forge/ee/routes/deviceEditor/index.js b/forge/ee/routes/deviceEditor/index.js index a2c5307ea6..923bc1ab7c 100644 --- a/forge/ee/routes/deviceEditor/index.js +++ b/forge/ee/routes/deviceEditor/index.js @@ -39,7 +39,7 @@ module.exports = async function (app) { // to return a redirect for this auth fail rather than an API error if (!request.routeOptions.config.allowAnonymous && !request.teamMembership && !request.session.User.admin) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.device.ApplicationId) { request.applicationId = app.db.models.Application.encodeHashid(request.device.ApplicationId) diff --git a/forge/ee/routes/gitops/index.js b/forge/ee/routes/gitops/index.js index 9e1d2fd85d..50b13ba6ab 100644 --- a/forge/ee/routes/gitops/index.js +++ b/forge/ee/routes/gitops/index.js @@ -13,7 +13,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('gitIntegration', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (!request.teamMembership) { request.teamMembership = await request.session.User.getTeamMembership(request.team.id) diff --git a/forge/ee/routes/ha/index.js b/forge/ee/routes/ha/index.js index 5027719808..b58e8714f1 100644 --- a/forge/ee/routes/ha/index.js +++ b/forge/ee/routes/ha/index.js @@ -18,7 +18,7 @@ module.exports = async function (app) { await request.project.Team.ensureTeamTypeExists() if (!request.project.Team.getFeatureProperty('ha', true)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.project.Team.id) diff --git a/forge/ee/routes/httpTokens/index.js b/forge/ee/routes/httpTokens/index.js index 469c53ce16..9b670babf8 100644 --- a/forge/ee/routes/httpTokens/index.js +++ b/forge/ee/routes/httpTokens/index.js @@ -18,18 +18,18 @@ module.exports = async function (app) { await request.project.Team.ensureTeamTypeExists() if (!request.project.Team.getFeatureProperty('teamHttpSecurity', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.project.Team.id) if (!request.teamMembership && !request.session.User.admin) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } else if (request.session.ownerId !== request.params.projectId) { // AccessToken being used - but not owned by this project reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } catch (err) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) @@ -49,7 +49,7 @@ module.exports = async function (app) { await request.device.Team.ensureTeamTypeExists() if (!request.device.Team.getFeatureProperty('teamHttpSecurity', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.device.Team.id) diff --git a/forge/ee/routes/protectedInstance/index.js b/forge/ee/routes/protectedInstance/index.js index 3a8c7ea938..9942e15b0e 100644 --- a/forge/ee/routes/protectedInstance/index.js +++ b/forge/ee/routes/protectedInstance/index.js @@ -17,7 +17,7 @@ module.exports = async function (app) { await request.project.Team.ensureTeamTypeExists() if (!request.project.Team.getFeatureProperty('protectedInstance', true)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.project.Team.id) diff --git a/forge/ee/routes/staticAssets/index.js b/forge/ee/routes/staticAssets/index.js index f57df251e4..1579afa57d 100644 --- a/forge/ee/routes/staticAssets/index.js +++ b/forge/ee/routes/staticAssets/index.js @@ -19,7 +19,7 @@ module.exports = async function (app) { await request.project.Team.ensureTeamTypeExists() if (!request.project.Team.getFeatureProperty('staticAssets', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found - not available on team' }) - return // eslint-disable-line no-useless-return + return } if (request.session.User) { request.teamMembership = await request.session.User.getTeamMembership(request.project.Team.id) diff --git a/forge/ee/routes/tables/index.js b/forge/ee/routes/tables/index.js index 851969d910..61a1837d9c 100644 --- a/forge/ee/routes/tables/index.js +++ b/forge/ee/routes/tables/index.js @@ -12,7 +12,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('tables', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found - not available on team' }) - return // eslint-disable-line no-useless-return + return } } if (!request.teamMembership && request.session?.User) { diff --git a/forge/ee/routes/teamBroker/3rdPartyBroker.js b/forge/ee/routes/teamBroker/3rdPartyBroker.js index ba2a821e37..953cde2ef9 100644 --- a/forge/ee/routes/teamBroker/3rdPartyBroker.js +++ b/forge/ee/routes/teamBroker/3rdPartyBroker.js @@ -26,7 +26,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('teamBroker', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } @@ -34,7 +34,7 @@ module.exports = async function (app) { request.broker = await app.db.models.BrokerCredentials.byId(request.params.brokerId) if (!request.broker) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } } diff --git a/forge/ee/routes/teamBroker/index.js b/forge/ee/routes/teamBroker/index.js index 4947642ee7..8b06c382eb 100644 --- a/forge/ee/routes/teamBroker/index.js +++ b/forge/ee/routes/teamBroker/index.js @@ -28,7 +28,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('teamBroker', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } } diff --git a/forge/ee/routes/teamBroker/schema.js b/forge/ee/routes/teamBroker/schema.js index e5de4fdc67..38bfa8ac85 100644 --- a/forge/ee/routes/teamBroker/schema.js +++ b/forge/ee/routes/teamBroker/schema.js @@ -26,7 +26,7 @@ module.exports = async function (app) { await request.team.ensureTeamTypeExists() if (!request.team.getFeatureProperty('teamBroker', false)) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } @@ -34,7 +34,7 @@ module.exports = async function (app) { request.broker = await app.db.models.BrokerCredentials.byId(request.params.brokerId) if (!request.broker) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } } diff --git a/forge/forge.js b/forge/forge.js index 3651eb332a..b8198a34fc 100644 --- a/forge/forge.js +++ b/forge/forge.js @@ -8,7 +8,7 @@ const fastify = require('fastify') const auditLog = require('./auditLog') const caches = require('./caches') const comms = require('./comms') -const config = require('./config') // eslint-disable-line n/no-unpublished-require +const config = require('./config') const containers = require('./containers') const db = require('./db') const ee = require('./ee') @@ -182,7 +182,7 @@ module.exports = async (options = {}) => { // Test Only. Permit access to app.routes - for evaluating routes in tests if (options.config?.test?.fastifyRoutes) { // since @fastify/routes is a dev dependency, we only load it when requested in test - server.register(require('@fastify/routes')) // eslint-disable-line n/no-unpublished-require + server.register(require('@fastify/routes')) } // Rate Limits: rate limiting for the server end points diff --git a/forge/routes/api/deviceSnapshots.js b/forge/routes/api/deviceSnapshots.js index 9a7f2b10c5..5677ba0fd4 100644 --- a/forge/routes/api/deviceSnapshots.js +++ b/forge/routes/api/deviceSnapshots.js @@ -25,7 +25,7 @@ module.exports = async function (app) { request.snapshot = await app.db.models.ProjectSnapshot.byId(request.params.snapshotId) if (!request.snapshot || request.snapshot.DeviceId !== request.device.id) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) - return // eslint-disable-line no-useless-return + return } } catch (err) { reply.code(404).send({ code: 'not_found', error: 'Not Found' }) diff --git a/forge/routes/auth/index.js b/forge/routes/auth/index.js index 2f1f0a9db3..27d43851fd 100644 --- a/forge/routes/auth/index.js +++ b/forge/routes/auth/index.js @@ -583,7 +583,6 @@ async function init (app, opts) { */ app.post('/account/verify', { preHandler: function (request, reply, done) { - // eslint-disable-next-line promise/no-callback-in-promise app.verifySession(request, reply).then(() => done()).catch(done) }, config: { diff --git a/forge/routes/index.js b/forge/routes/index.js index 4f9fb5a982..4679deae1f 100644 --- a/forge/routes/index.js +++ b/forge/routes/index.js @@ -24,7 +24,6 @@ module.exports = fp(async function (app, opts) { // Response Validation: dev only — surfaces schema/view drift as 500s. if (process.env.NODE_ENV === 'development') { - // eslint-disable-next-line n/no-unpublished-require -- dev-only, gated above const Ajv = require('ajv') const ajv = new Ajv({ coerceTypes: false, @@ -71,7 +70,7 @@ module.exports = fp(async function (app, opts) { } } }) - // eslint-disable-next-line n/no-unpublished-require -- dev-only, gated above + await app.register(require('@fastify/response-validation'), { ajv }) } diff --git a/frontend/src/components/audit-log/AuditLog.vue b/frontend/src/components/audit-log/AuditLog.vue index c00b4a939e..cd11bb0c39 100644 --- a/frontend/src/components/audit-log/AuditLog.vue +++ b/frontend/src/components/audit-log/AuditLog.vue @@ -24,7 +24,6 @@