diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 534dd275b..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "env": { - "node": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 11 - }, - "extends": "google", - "rules": { - "arrow-parens": ["error", - "as-needed" - ], - "max-len": ["error", { - "code": 120, - "ignoreComments": true - }], - "require-jsdoc": ["error", { - "require": { - "FunctionDeclaration": true, - "MethodDefinition": false, - "ClassDeclaration": false, - "ArrowFunctionExpression": false, - "FunctionExpression": false - } - }] - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..bbfcd6e4b --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,38 @@ +import js from "@eslint/js"; +import globals from "globals"; +import conf from "eslint-config-google"; +import jsdoc from 'eslint-plugin-jsdoc'; + +export default [ + js.configs.recommended, + jsdoc.configs['flat/recommended'], + { + languageOptions: { + ecmaVersion: 2022, + sourceType: "script", + globals: { + ...globals.node, + ...globals.mocha, + } + }, + rules: { + ...conf.rules, + 'arrow-parens': ['error', 'as-needed'], + 'max-len': ['error', { + code: 120, + ignoreComments: true, + }], + 'jsdoc/require-jsdoc': ['error', { + require: { + FunctionDeclaration: true, + MethodDefinition: false, + ClassDeclaration: false, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }], + 'valid-jsdoc': 'off', + 'require-jsdoc': 'off', + } + }, +]; diff --git a/lib/app.js b/lib/app.js index fd3dc21fd..f812d0b62 100644 --- a/lib/app.js +++ b/lib/app.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const hasher = require('object-hash'); const path = require('path'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); const utils = require('./utils'); @@ -153,7 +154,7 @@ module.exports = class App { // do stuff with them later this.warnings = []; this.id = hasher(`${this.name}-${this.root}`); - }; + } /* * @TODO, add compose data to the add @@ -227,7 +228,7 @@ module.exports = class App { */ .then(() => this.events.emit('post-destroy')) .then(() => this.log.info('destroyed app.')); - }; + } /** * Initializes the app @@ -308,7 +309,7 @@ module.exports = class App { * @property {App} app The app instance. */ .then(() => this.events.emit('ready', this)); - }; + } /** * Rebuilds an app. @@ -358,14 +359,14 @@ module.exports = class App { */ .then(() => this.events.emit('post-rebuild')) .then(() => this.log.info('rebuilt app.')); - }; + } /* * @TODO */ reset() { this.initialized = false; - }; + } /** * Stops and then starts an app. @@ -388,7 +389,7 @@ module.exports = class App { return this.stop() .then(() => this.start()) .then(() => this.log.info('restarted app.')); - }; + } /** * Starts an app. @@ -434,7 +435,7 @@ module.exports = class App { */ .then(() => this.events.emit('post-start')) .then(() => this.log.info('started app.')); - }; + } /** * Stops an app. @@ -473,7 +474,7 @@ module.exports = class App { */ .then(() => this.events.emit('post-stop')) .then(() => this.log.info('stopped app.')); - }; + } /** * Soft removes the apps services but maintains persistent data like app volumes. @@ -521,14 +522,14 @@ module.exports = class App { */ .then(() => this.events.emit('post-uninstall')) .then(() => this.log.info('uninstalled app.')); - }; + } getServiceContainerId(service) { return `${this.project}-${service}-1`; - }; + } getServiceFromContainerId(id) { const regex = new RegExp(`${this.project}-(.*)-1`); return id.replace(regex, '$1'); - }; + } }; diff --git a/lib/art.js b/lib/art.js index 3667f35d8..fec9c00d6 100644 --- a/lib/art.js +++ b/lib/art.js @@ -103,7 +103,7 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => { '', ].join(os.EOL); case 'pre': - return chalk.cyan(`Let\'s get this party started! Starting app ${italicize(name)}...`); + return chalk.cyan(`Let's get this party started! Starting app ${italicize(name)}...`); case 'post': return [ '', @@ -113,7 +113,7 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => { 'Here are some vitals:', '', ].join(os.EOL); - case 'report': + case 'report': { const message = [ '', chalk.yellow('Warning!'), @@ -132,6 +132,7 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => { message.push('Here are some vitals:'); message.push(''); return message.join(os.EOL); + } } }; @@ -141,7 +142,7 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => { exports.appStop = ({name, phase = 'pre'} = {}) => { switch (phase) { case 'pre': - return chalk.cyan(`This party\'s over :( Stopping app ${italicize(name)}`); + return chalk.cyan(`This party's over :( Stopping app ${italicize(name)}`); case 'post': return chalk.red(`App ${italicize(name)} has been stopped!`); } diff --git a/lib/cache.js b/lib/cache.js index 6676ef294..6ae22cff1 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -28,7 +28,7 @@ module.exports = class Cache extends NodeCache { this.cacheDir = cacheDir; // Ensure the cache dir exists mkdirSync(this.cacheDir, {recursive: true}); - }; + } /** * Sets an item in the cache @@ -53,6 +53,7 @@ module.exports = class Cache extends NodeCache { set(key, data, {persist = false, ttl = 0} = {}) { // Unsafe cache key patterns const patterns = { + // eslint-disable-next-line no-control-regex controlRe: /[\x00-\x1f\x80-\x9f]/g, // NOSONAR illegalRe: /[/?<>\\*|":]/g, // NOSONAR reservedRe: /^\.+$/, @@ -75,7 +76,7 @@ module.exports = class Cache extends NodeCache { if (persist) { writeFileSync(join(this.cacheDir, key), data); } - }; + } /** * Gets an item in the cache @@ -100,11 +101,11 @@ module.exports = class Cache extends NodeCache { try { this.log.debug('Trying to retrieve from file cache with key %s', key); return readFileSync(join(this.cacheDir, key)); - } catch (e) { + } catch { this.log.debug('File cache miss with key %s', key); } } - }; + } /** * Manually remove an item from the cache. @@ -124,8 +125,8 @@ module.exports = class Cache extends NodeCache { // Also remove file if applicable try { unlinkSync(join(this.cacheDir, key)); - } catch (e) { + } catch { this.log.debug('No file cache with key %s', key); } - }; + } }; diff --git a/lib/cli.js b/lib/cli.js index ff88e70bb..a44a0867b 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -43,26 +43,24 @@ module.exports = class Cli { this.prefix = prefix; this.logLevel = logLevel; this.userConfRoot = userConfRoot; - }; + } /** * Returns a parsed array of CLI arguments and options - * * @since 3.0.0 * @alias lando.cli.argv - * @return {Object} Yarg parsed options + * @returns {object} Yarg parsed options * @example * const argv = lando.cli.argv(); * @todo make this static and then fix all call sites */ argv() { return require('yargs').help(false).version(false).argv; - }; + } /** * Checks to see if lando is running with sudo. If it is it * will exit the process with a stern warning - * * @since 3.0.0 * @alias lando.cli.checkPerms * @example @@ -70,7 +68,7 @@ module.exports = class Cli { */ checkPerms() { /* Do nothing */ - }; + } /* * Toggle the secret toggle @@ -78,7 +76,7 @@ module.exports = class Cli { clearTaskCaches() { if (fs.existsSync(process.landoTaskCacheFile)) fs.unlinkSync(process.landoTaskCacheFile); if (fs.existsSync(process.landoAppTaskCacheFile)) fs.unlinkSync(process.landoAppTaskCacheFile); - }; + } /* * Confirm question @@ -95,16 +93,15 @@ module.exports = class Cli { message: message, }, }; - }; + } /** * Returns a config object with some good default settings for bootstrapping * lando as a command line interface - * * @since 3.5.0 * @alias lando.cli.defaultConfig - * @param {Object} [appConfig={}] Optional raw landofile - * @return {Object} Config that can be used in a Lando CLI bootstrap + * @param {object} [appConfig] Optional raw landofile + * @returns {object} Config that can be used in a Lando CLI bootstrap * @example * const config = lando.cli.defaultConfig(); * // Kick off our bootstrap @@ -144,40 +141,38 @@ module.exports = class Cli { userAgent: `Lando/${version}`, version, }; - }; + } /* * Format data */ formatData(data, {path = '', format = 'default', filter = []} = {}, opts = {}) { return formatters.formatData(data, {path, format, filter}, opts); - }; + } /* * FormatOptios */ formatOptions(omit = []) { return formatters.formatOptions(omit); - }; + } - // eslint-disable-next-line valid-jsdoc /** * Cli wrapper for error handler - * * @since 3.0.0 * @alias lando.cli.handleError * @param {Error} error The error * @param {import('./error')} handler The error handler function * @param {number} verbose [verbose=this.argv().verbose] The verbosity level - * @param {Object} lando The Lando object - * @return {Promise} + * @param {object} lando The Lando object + * @returns {Promise} */ handleError(error, handler, verbose = this.argv().verbose, lando = {}) { // Set the verbosity error.verbose = verbose; // Report error if user has error reporting on return handler.handle(error).then(code => process.exit(code)); - }; + } /* * Init @@ -227,30 +222,33 @@ module.exports = class Cli { /** * Returns some cli "art" - * * @since 3.0.0 * @alias lando.cli.makeArt - * @param {String} [func='start'] The art func you want to call - * @param {Object} [opts] Func options - * @return {String} Usually a printable string + * @param {string} [func] The art func you want to call + * @param {object} [opts] Func options + * @returns {string} Usually a printable string */ makeArt(func, opts) { return require('./art')[func](opts); - }; + } /** * Parses a lando task object into something that can be used by the [yargs](http://yargs.js.org/docs/) CLI. * * A lando task object is an abstraction on top of yargs that also contains some * metadata about how to interactively ask questions on both a CLI and GUI. - * * @since 3.5.0 * @alias lando.cli.parseToYargs * @see [yargs docs](http://yargs.js.org/docs/) * @see [inquirer docs](https://github.com/sboudrias/Inquirer.js) - * @param {Object} task A Lando task object (@see add for definition) - * @param {Object} [config={}] The landofile - * @return {Object} A yargs command object + * @param {object} task A Lando task object (@see add for definition) + * @param task.command + * @param task.describe + * @param task.options + * @param task.run + * @param task.level + * @param {object} [config] The landofile + * @returns {object} A yargs command object * @example * // Add a task to the yargs CLI * yargs.command(lando.tasks.parseToYargs(task)); @@ -293,10 +291,9 @@ module.exports = class Cli { * are run * * You will want to replace CMD with the actual task name eg `task-start-answers`. - * * @since 3.0.0 * @event task_CMD_answers - * @property {Object} answers argv and inquirer questions + * @property {object} answers argv and inquirer questions */ .then(() => lando.events.emit('cli-answers', data, argv._[0])) .then(() => lando.events.emit(`cli-${argv._[0]}-answers`, data, argv._[0])) @@ -309,10 +306,9 @@ module.exports = class Cli { * Event that allows final altering of answers before the task runs * * You will want to replace CMD with the actual task name eg `task-start-run`. - * * @since 3.0.0 * @event task_CMD_run - * @property {Object} answers object + * @property {object} answers object */ .then(answers => lando.events.emit('cli-run', _.merge(data.options, answers), argv._[0])) .then(() => lando.events.emit(`cli-${argv._[0]}-run`, data, argv._[0])) @@ -336,7 +332,7 @@ module.exports = class Cli { // Return our yarg command return {command, describe, builder: formatters.sortOptions(options), handler}; - }; + } /* * Run the CLI @@ -355,7 +351,7 @@ module.exports = class Cli { // Initialize this.init(yargs, tasks, config, userConfig); - }; + } /* * Toggle a toggle diff --git a/lib/config.js b/lib/config.js index 7d08f6119..bc8ef0ec6 100644 --- a/lib/config.js +++ b/lib/config.js @@ -94,7 +94,7 @@ const normalizePlugins = (plugins = [], baseDir = __dirname) => _(plugins) exports.tryConvertJson = value => { try { return JSON.parse(value); - } catch (error) { + } catch { return value; } }; diff --git a/lib/daemon.js b/lib/daemon.js index 4f32ab9ed..bfaf1e20c 100644 --- a/lib/daemon.js +++ b/lib/daemon.js @@ -5,6 +5,7 @@ const Cache = require('./cache'); const env = require('./env'); const Events = require('./events'); const Log = require('./logger'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); const Shell = require('./shell'); @@ -26,7 +27,7 @@ module.exports = class LandoDaemon { this.docker = docker; this.events = events; this.log = log; - }; + } /* * Tries to active the docker engine/daemon. @@ -53,7 +54,7 @@ module.exports = class LandoDaemon { * @event post_engine_up */ .then(() => this.events.emit('post-engine-up')); - }; + } down() { /* @@ -82,7 +83,7 @@ module.exports = class LandoDaemon { */ isUp() { return Promise.resolve(true); - }; + } /* * Helper to get the versions of the things we need @@ -97,7 +98,7 @@ module.exports = class LandoDaemon { let dockerData; try { dockerData = JSON.parse(data[0].stdout); - } catch (e) { + } catch { dockerData = {}; console.error(data[0].stdout); } @@ -112,5 +113,5 @@ module.exports = class LandoDaemon { compose: data[1].stdout.trim(), }; }); - }; + } }; diff --git a/lib/docker.js b/lib/docker.js index b6fd5d36e..df8cc14d8 100644 --- a/lib/docker.js +++ b/lib/docker.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const Dockerode = require('dockerode'); const fs = require('fs'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); const utils = require('./utils'); @@ -27,7 +28,7 @@ module.exports = class Landerode extends Dockerode { opts.Promise = promise; super(opts); this.id = id; - }; + } /* * Creates a network @@ -38,14 +39,14 @@ module.exports = class Landerode extends Dockerode { .catch(err => { throw new Error(err, 'Error creating network.'); }); - }; + } /* * Inspects a container. */ scan(cid) { return containerOpt(this.getContainer(cid), 'inspect', 'Error inspecting container: %j'); - }; + } /* * Return true if the container is running otherwise false. @@ -65,7 +66,7 @@ module.exports = class Landerode extends Dockerode { // Otherwise throw else throw err; }); - }; + } /* * Returns a list of Lando containers @@ -105,7 +106,7 @@ module.exports = class Landerode extends Dockerode { return containers; } }); - }; + } /* * Remove a container. @@ -113,12 +114,12 @@ module.exports = class Landerode extends Dockerode { */ remove(cid, opts = {v: true, force: false}) { return containerOpt(this.getContainer(cid), 'remove', 'Error removing container: %j', opts); - }; + } /* * Do a docker stop */ stop(cid, opts = {}) { return containerOpt(this.getContainer(cid), 'stop', 'Error stopping container: %j', opts); - }; + } }; diff --git a/lib/env.js b/lib/env.js index f9212f841..43f06508e 100644 --- a/lib/env.js +++ b/lib/env.js @@ -16,7 +16,7 @@ const findFileInPath = (file, paths) => { if (stat?.isFile()) { return normalize(fullname); } - } catch (err) { + } catch { // Ignore - mockfs does not respect throwIfNoEntry } } diff --git a/lib/events.js b/lib/events.js index 6da530b68..9eabb2480 100644 --- a/lib/events.js +++ b/lib/events.js @@ -3,6 +3,7 @@ // Modules. const {EventEmitter} = require('events'); const Log = require('./logger'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); /** @@ -25,7 +26,7 @@ class AsyncEvents extends EventEmitter { // Set things this.log = log; this._listeners = []; - }; + } /** * Our overridden event on method. @@ -62,7 +63,7 @@ class AsyncEvents extends EventEmitter { this.log.silly('loading event %s priority %s', name, priority); // Call original on method. return super.on(name, fn); - }; + } /** * Reimplements event emit method. @@ -104,8 +105,8 @@ class AsyncEvents extends EventEmitter { // Return true if event had listeners just like the original emit function. .return(!!fns.length); - }; -}; + } +} // Set our maxListeners to something more reasonable for lando AsyncEvents.prototype.setMaxListeners(128); diff --git a/lib/formatters.js b/lib/formatters.js index c9e06edc5..8c69edb8b 100644 --- a/lib/formatters.js +++ b/lib/formatters.js @@ -40,8 +40,7 @@ exports.formatData = (data, {path = '', format = 'default', filter = []} = {}, o switch (format) { case 'json': return JSON.stringify(data); - break; - case 'table': + case 'table': { const Table = require('./table'); if (!_.isArray(data)) { const table = new Table(data, opts); @@ -52,7 +51,7 @@ exports.formatData = (data, {path = '', format = 'default', filter = []} = {}, o .map(table => table.toString()) .thru(data => data.join(os.EOL)) .value(); - break; + } default: return util.inspect(data, { colors: process.stdout.isTTY, diff --git a/lib/promise.js b/lib/promise.js index eba3e0fc9..5d2197e77 100644 --- a/lib/promise.js +++ b/lib/promise.js @@ -16,6 +16,7 @@ * @see http://bluebirdjs.com/docs/api-reference.html * @see https://github.com/petkaantonov/bluebird/issues/1397 */ +// eslint-disable-next-line no-redeclare const Promise = require('bluebird'); // Use long stack traces. @@ -58,6 +59,7 @@ Promise.retry = retry; * Promise.retry(someFunction, {max: 25, backoff: 1000}); * */ +// eslint-disable-next-line no-extend-native Promise.prototype.retry = retry; // Export the promise object diff --git a/lib/router.js b/lib/router.js index fc28305dd..7752f41b3 100644 --- a/lib/router.js +++ b/lib/router.js @@ -2,6 +2,7 @@ // Modules const _ = require('lodash'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); const utils = require('./utils'); diff --git a/lib/scan.js b/lib/scan.js index a142da887..3c0eea986 100644 --- a/lib/scan.js +++ b/lib/scan.js @@ -5,6 +5,7 @@ const _ = require('lodash'); const http = require('http'); const https = require('https'); const Log = require('./logger'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); /* diff --git a/lib/shell.js b/lib/shell.js index bf9e76bc8..23b3c9234 100644 --- a/lib/shell.js +++ b/lib/shell.js @@ -7,6 +7,7 @@ const Log = require('./logger'); const _shell = require('shelljs'); const path = require('path'); const parse = require('yargs-parser'); +// eslint-disable-next-line no-redeclare const Promise = require('./promise'); const {PassThrough} = require('stream'); @@ -71,7 +72,7 @@ module.exports = class Shell { this.running = []; this.stdout = new PassThrough(); this.stderr = new PassThrough(); - }; + } /** * Gets running processes. @@ -82,7 +83,7 @@ module.exports = class Shell { */ get() { return this.running; - }; + } /** * Runs a command. @@ -158,7 +159,7 @@ module.exports = class Shell { const msg = `${cmd} failed with exit code ${code}\n:${stderr}`; return (code !== 0) ? Promise.reject(new Error(msg)) : Promise.resolve(stdout); }); - }; + } /** * Returns the path of a specific command or binary. @@ -174,7 +175,7 @@ module.exports = class Shell { */ which(cmd) { return _shell.which(cmd); - }; + } }; module.exports.exec = exec; diff --git a/package-lock.json b/package-lock.json index a0dae2b43..41fd92cef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,13 +32,16 @@ "lando": "bin/lando.js" }, "devDependencies": { + "@eslint/js": "^9.39.2", "@yao-pkg/pkg": "^6.11.0", "chai": "^4.5.0", "chai-as-promised": "^7.1.2", "chai-events": "^0.0.3", "command-line-test": "^1.0.10", - "eslint": "^8.57.0", + "eslint": "^9.39.2", "eslint-config-google": "^0.14.0", + "eslint-plugin-jsdoc": "^61.5.0", + "globals": "^16.5.0", "leia-parser": "^0.4.0", "mocha": "^11.7.5", "mock-fs": "^5.2.0", @@ -346,6 +349,33 @@ "kuler": "^2.0.0" } }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.76.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.76.0.tgz", + "integrity": "sha512-g+RihtzFgGTx2WYCuTHbdOXJeAlGnROws0TeALx9ow/ZmOROOZkVg5wp/B44n0WJgI4SQFP1eWM2iRPlU2Y14w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.8", + "@typescript-eslint/types": "^8.46.0", + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~6.10.0" + }, + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@es-joy/resolve.exports": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@es-joy/resolve.exports/-/resolve.exports-1.2.0.tgz", + "integrity": "sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -375,38 +405,119 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/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, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@grpc/grpc-js": { @@ -574,20 +685,28 @@ "node": ">=12" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -604,13 +723,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", @@ -1005,6 +1130,19 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, + "node_modules/@sindresorhus/base62": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/base62/-/base62-1.0.0.tgz", + "integrity": "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -1064,6 +1202,20 @@ "text-hex": "1.0.x" } }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "25.0.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", @@ -1079,12 +1231,19 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "node_modules/@typescript-eslint/types": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.1.tgz", + "integrity": "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, "node_modules/@yao-pkg/pkg": { "version": "6.11.0", @@ -1247,6 +1406,16 @@ "dev": true, "license": "MIT" }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1975,6 +2144,16 @@ "node": ">=20" } }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2231,19 +2410,6 @@ "node": ">=6" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dot/-/dot-1.1.3.tgz", @@ -2431,61 +2597,64 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-google": { @@ -2501,10 +2670,39 @@ "eslint": ">=5.16.0" } }, + "node_modules/eslint-plugin-jsdoc": { + "version": "61.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-61.5.0.tgz", + "integrity": "sha512-PR81eOGq4S7diVnV9xzFSBE4CDENRQGP0Lckkek8AdHtbj+6Bm0cItwlFnxsLFriJHspiE3mpu8U20eODyToIg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.76.0", + "@es-joy/resolve.exports": "1.2.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.4.3", + "escape-string-regexp": "^4.0.0", + "espree": "^10.4.0", + "esquery": "^1.6.0", + "html-entities": "^2.6.0", + "object-deep-merge": "^2.0.0", + "parse-imports-exports": "^0.2.4", + "semver": "^7.7.3", + "spdx-expression-parse": "^4.0.0", + "to-valid-identifier": "^1.0.0" + }, + "engines": { + "node": ">=20.11.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2512,7 +2710,7 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2531,19 +2729,45 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2773,16 +2997,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -2843,57 +3067,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "keyv": "^4.5.4" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { @@ -3232,16 +3416,13 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3266,13 +3447,6 @@ "devOptional": true, "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3381,6 +3555,23 @@ "he": "bin/he" } }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3869,6 +4060,16 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.10.0.tgz", + "integrity": "sha512-+LexoTRyYui5iOhJGn13N9ZazL23nAHGkXsa1p/C8yeq79WRfLBag6ZZ0FQG2aRoc9yfo59JT9EYCQonOkHKkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -5327,6 +5528,13 @@ "node": ">=6" } }, + "node_modules/object-deep-merge": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-2.0.0.tgz", + "integrity": "sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==", + "dev": true, + "license": "MIT" + }, "node_modules/object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", @@ -5667,6 +5875,23 @@ "node": ">= 0.4.0" } }, + "node_modules/parse-imports-exports": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", + "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-statements": "1.0.11" + } + }, + "node_modules/parse-statements": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", + "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6105,6 +6330,19 @@ "dev": true, "license": "ISC" }, + "node_modules/reserved-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz", + "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", @@ -6505,6 +6743,31 @@ "dev": true, "license": "ISC" }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/split-ca": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", @@ -6854,13 +7117,6 @@ "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "license": "MIT" }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -6890,6 +7146,23 @@ "node": ">=8.0" } }, + "node_modules/to-valid-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-valid-identifier/-/to-valid-identifier-1.0.0.tgz", + "integrity": "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/base62": "^1.0.0", + "reserved-identifiers": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -6961,19 +7234,6 @@ "node": ">=4" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", diff --git a/package.json b/package.json index b2d957d0c..221546090 100644 --- a/package.json +++ b/package.json @@ -119,13 +119,16 @@ "yargs": "^16.1.0" }, "devDependencies": { + "@eslint/js": "^9.39.2", "@yao-pkg/pkg": "^6.11.0", "chai": "^4.5.0", "chai-as-promised": "^7.1.2", "chai-events": "^0.0.3", "command-line-test": "^1.0.10", - "eslint": "^8.57.0", + "eslint": "^9.39.2", "eslint-config-google": "^0.14.0", + "eslint-plugin-jsdoc": "^61.5.0", + "globals": "^16.5.0", "leia-parser": "^0.4.0", "mocha": "^11.7.5", "mock-fs": "^5.2.0", diff --git a/plugins/lando-proxy/lib/utils.js b/plugins/lando-proxy/lib/utils.js index c7efbee72..63dc6f3ed 100644 --- a/plugins/lando-proxy/lib/utils.js +++ b/plugins/lando-proxy/lib/utils.js @@ -5,6 +5,7 @@ const {Socket} = require('net'); const _ = require('lodash'); const hasher = require('object-hash'); const url = require('url'); +// eslint-disable-next-line no-redeclare const Promise = require('../../../lib/promise'); /* @@ -169,7 +170,7 @@ exports.parseRoutes = (service, urls = [], sslReady, labels = {}) => { // Add in any path stripping middleware we need it if (rule.pathname.length > 1) { rule.middlewares.push({name: 'stripprefix', key: 'stripprefix.prefixes', value: rule.pathname}); - }; + } // Ensure we prefix all middleware with the ruleid rule.middlewares = _(rule.middlewares) .map(middleware => _.merge({}, middleware, {name: `${rule.id}-${middleware.name}`})) diff --git a/plugins/lando-tooling/lib/utils.js b/plugins/lando-tooling/lib/utils.js index a06ea5824..47ab85d6c 100644 --- a/plugins/lando-tooling/lib/utils.js +++ b/plugins/lando-tooling/lib/utils.js @@ -2,6 +2,7 @@ // Modules const _ = require('lodash'); +// eslint-disable-next-line no-redeclare const escape = require('./../../../lib/utils').shellEscape; const getUser = require('./../../../lib/utils').getUser; const getCliEnvironment = require('./../../../lib/utils').getCliEnvironment; diff --git a/test/docker.spec.js b/test/docker.spec.js index d91db3aef..6e8a581b6 100644 --- a/test/docker.spec.js +++ b/test/docker.spec.js @@ -15,6 +15,7 @@ const sinon = require('sinon'); const Landerode = require('./../lib/docker'); const landerode = new Landerode(); const Dockerode = require('dockerode'); +// eslint-disable-next-line no-redeclare const Promise = require('./../lib/promise'); const _ = require('lodash'); diff --git a/test/promise.spec.js b/test/promise.spec.js index 6db5a6f0b..da90a2783 100644 --- a/test/promise.spec.js +++ b/test/promise.spec.js @@ -11,6 +11,7 @@ const sinon = require('sinon'); chai.use(require('chai-as-promised')); chai.should(); +// eslint-disable-next-line no-redeclare const Promise = require('../lib/promise'); describe('promise', () => { diff --git a/test/scan.spec.js b/test/scan.spec.js index c29005cd6..42d0266ef 100644 --- a/test/scan.spec.js +++ b/test/scan.spec.js @@ -9,6 +9,7 @@ const _ = require('lodash'); const axios = require('axios'); const chai = require('chai'); const sinon = require('sinon'); +// eslint-disable-next-line no-redeclare const Promise = require('./../lib/promise'); chai.use(require('chai-as-promised')); chai.should();