From b6afa864d20745f1394f67b7576a1b8c0261c98c Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 09:56:22 +1200 Subject: [PATCH 1/9] Update node to v24 / v26 --- .github/workflows/ci.yaml | 4 ++-- package-lock.json | 4 ++-- package.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3eca90d18..970aed5d3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [20, 22, 24] + node: [24, 26] steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v6 @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [20, 22, 24] + node: [24, 26] steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v6 diff --git a/package-lock.json b/package-lock.json index 119203516..27dbd65cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,8 +130,8 @@ "typescript": "~5.9" }, "engines": { - "node": "^20 || ^22 || ^24", - "npm": "^9 || ^10 || ^11" + "node": "^24 || ^26", + "npm": "^11" } }, "node_modules/@asamuzakjp/css-color": { diff --git a/package.json b/package.json index 82a5df6d4..3a48acd64 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "repository": "github:nextstrain/auspice", "homepage": "https://www.npmjs.com/package/auspice", "engines": { - "node": "^20 || ^22 || ^24", - "npm": "^9 || ^10 || ^11" + "node": "^24 || ^26", + "npm": "^11" }, "bin": { "auspice": "./auspice.js" From 4afc15d5a98bfab9e34dbec5e4591d4ab321476e Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 13:15:00 +1200 Subject: [PATCH 2/9] Migrate server and build tooling from CommonJS to ES Modules Convert all server-side code (cli/, auspice.js, index.js, src/version.js) and the test file from CommonJS require/module.exports syntax to ES module import/export syntax. This also addresses the downstream effects on webpack bundling for the frontend code in src/. package.json: Added "type": "module" to declare the package as ESM. This makes Node treat all .js files as ES modules by default. Replaced the "main" field with "exports" to use the modern package entry point specification. Added babel-plugin-transform-import-meta as a dev dependency for Jest compatibility. Server code (cli/, auspice.js, index.js, src/version.js): Converted all require() calls to import statements and all module.exports/exports assignments to named or default exports. For packages that use CommonJS internally (argparse, webpack config), createRequire(import.meta.url) is used to obtain a require function that can load CJS modules from an ESM context. __dirname shim: Since __dirname is not available in ES modules, files that reference it (cli/utils.js, cli/build.js, cli/develop.js, cli/view.js) now derive it via path.dirname(fileURLToPath(import.meta.url)). The test file also uses this pattern. Dynamic require(handlersPath) in cli/view.js: The user-provided custom handlers path was previously loaded with require(). This is now await import(handlersPath), which required making customRouteHandlers() and run() async functions. Config file renames: webpack.config.js and babel.config.js are renamed to .cjs since they use CommonJS syntax (module.exports) and would otherwise be treated as ESM due to the package-level "type": "module" setting. Babel transform for Jest: Jest runs tests through babel-jest which transforms ESM to CJS. However, babel leaves import.meta.url untouched, causing a runtime error when Jest executes the transformed code. Added babel-plugin-transform-import-meta (test env only) to convert import.meta.url to its CJS equivalent during testing. The test/server-fetch.test.js file itself was also converted to ESM syntax. webpack.config.cjs updates: Added resolve.fullySpecified: false (both top-level and as a per-module rule) to allow extensionless imports in the bundled frontend code -- without this, webpack enforces mandatory file extensions for all imports in "type": "module" packages. The JS/TS rule also sets type: "javascript/auto" so webpack parses source files in mixed mode, recognizing both require() and import syntax. module.hot to import.meta.webpackHot: In src/root.js and src/store.ts, the webpack HMR API was accessed via module.hot which is a CJS-only global. Replaced with import.meta.webpackHot, the ESM equivalent. The HMR accept callback in store.ts now uses dynamic import() instead of require() to reload reducers. Frontend require() calls for assets: Several React components used require() to load images (SVG, PNG, JPG). These are converted to static import statements at the top of each file, which webpack asset/resource loader handles identically. Affected files: navBar/content.js, splash/splash.js, framework/fine-print.js, framework/footer-descriptions.js, info/byline.js. Dynamic extension loading (src/util/extensions.ts): The extensions.ts file retains its synchronous require(`@extensions/...`) pattern. This works because webpack's javascript/auto parser mode (set via the module rule) handles require() at build time even in a "type": "module" package. An earlier approach using top-level await with dynamic import() caused async module semantics to cascade through the dependency graph (via util/globals.js), which broke component rendering by wrapping module exports in async module namespace objects. Co-Authored-By: Claude Opus 4.6 --- auspice.js | 14 ++++---- babel.config.js => babel.config.cjs | 3 ++ cli/build.js | 18 ++++++---- cli/convert.js | 8 ++--- cli/dev/reverse-proxy.js | 15 ++++---- cli/develop.js | 34 ++++++++++-------- cli/server/convertJsonSchemas.js | 9 ++--- cli/server/getAvailable.js | 25 +++++-------- cli/server/getDataset.js | 19 ++++------ cli/server/getDatasetHelpers.js | 27 +++++--------- cli/server/getNarrative.js | 16 ++++----- cli/server/processPaths.js | 9 ++--- cli/utils.js | 36 ++++++++----------- cli/view.js | 47 ++++++++++++++----------- docs/server/api.rst | 2 +- index.js | 12 +++---- package-lock.json | 38 ++++++++++++++++---- package.json | 4 ++- scripts/diff-lang.js | 7 ++-- scripts/extract-release-notes.js | 2 +- scripts/fetch-test-data | 7 ++-- src/components/framework/fine-print.js | 2 +- src/components/info/byline.js | 3 +- src/components/navBar/content.js | 3 +- src/components/splash/splash.js | 5 ++- src/root.js | 2 +- src/store.ts | 7 ++-- src/util/extensions.ts | 3 -- src/util/parseNarrative.js | 24 ++++--------- src/version.js | 6 +--- test/colorScales.test.js | 2 +- test/server-fetch.test.js | 11 +++--- test/smoke-test/urls.test.js | 6 ++-- webpack.config.js => webpack.config.cjs | 6 ++++ 34 files changed, 213 insertions(+), 219 deletions(-) rename babel.config.js => babel.config.cjs (93%) rename webpack.config.js => webpack.config.cjs (98%) diff --git a/auspice.js b/auspice.js index 6b352c44b..a230ca7a4 100755 --- a/auspice.js +++ b/auspice.js @@ -1,11 +1,11 @@ #!/usr/bin/env node -const argparse = require('argparse'); -const version = require('./src/version').version; -const view = require("./cli/view"); -const build = require("./cli/build"); -const develop = require("./cli/develop"); -const convert = require("./cli/convert"); +import argparse from 'argparse'; +import { version } from './src/version.js'; +import * as view from "./cli/view.js"; +import * as build from "./cli/build.js"; +import * as develop from "./cli/develop.js"; +import * as convert from "./cli/convert.js"; const parser = new argparse.ArgumentParser({ version: version, @@ -38,5 +38,3 @@ if (args.subcommand === "build") { } else if (args.subcommand === "convert") { convert.run(args); } - -// console.dir(args); diff --git a/babel.config.js b/babel.config.cjs similarity index 93% rename from babel.config.js rename to babel.config.cjs index 25c781165..ef3d88762 100644 --- a/babel.config.js +++ b/babel.config.cjs @@ -31,6 +31,9 @@ module.exports = function babelConfig(api) { if (api.env("development")) { plugins.push(["react-hot-loader/babel", { safetyNet: false }]); } + if (api.env('test')) { + plugins.push("babel-plugin-transform-import-meta"); + } if (process.env.BABEL_INCLUDE_TIMING_FUNCTIONS === "false") { plugins.push(["strip-function-call", {strip: ["timerStart", "timerEnd"]}]); } diff --git a/cli/build.js b/cli/build.js index ad4cb34e0..545eadbb6 100644 --- a/cli/build.js +++ b/cli/build.js @@ -1,14 +1,20 @@ -const webpack = require("webpack"); -const path = require("path"); -const generateWebpackConfig = require("../webpack.config.js").default; -const utils = require("./utils"); +import webpack from "webpack"; +import path from "path"; +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; +import * as utils from "./utils.js"; + +const require = createRequire(import.meta.url); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const generateWebpackConfig = require("../webpack.config.cjs").default; const SUPPRESS = require('argparse').Const.SUPPRESS; const addParser = (parser) => { const description = `Build the client source code bundle. For development, you may want to use "auspice develop" which recompiles code on the fly as changes are made. You may provide customisations (e.g. code, options) to this step to modify the functionality and appearance of auspice. - To serve the bundle you will need a server such as "auspice view". + To serve the bundle you will need a server such as "auspice view". `; const subparser = parser.addParser('build', {addHelp: true, description}); @@ -71,7 +77,7 @@ function getCustomOutputPath(extensions) { return false; } -module.exports = { +export { addParser, run }; diff --git a/cli/convert.js b/cli/convert.js index fa0ef3938..afb2429dd 100644 --- a/cli/convert.js +++ b/cli/convert.js @@ -1,7 +1,7 @@ /* eslint no-console: off */ -const fs = require("fs"); -const convertFromV1 = require("./server/convertJsonSchemas").convertFromV1; -const utils = require("./utils"); +import fs from "fs"; +import { convertFromV1 } from "./server/convertJsonSchemas.js"; +import * as utils from "./utils.js"; const addParser = (parser) => { @@ -35,7 +35,7 @@ const run = (args) => { fs.writeFileSync(args.output, JSON.stringify(v2, null, args.minify_json ? 0 : 2)); }; -module.exports = { +export { addParser, run }; diff --git a/cli/dev/reverse-proxy.js b/cli/dev/reverse-proxy.js index 3de2062a1..10dc00956 100644 --- a/cli/dev/reverse-proxy.js +++ b/cli/dev/reverse-proxy.js @@ -1,7 +1,6 @@ - -const utils = require("../utils"); -const { URL } = require("url"); -const fetch = require("node-fetch"); +import * as utils from "../utils.js"; +import { URL } from "url"; +import fetch from "node-fetch"; const PROXY = process.env.PROXY || `http://localhost:5000` @@ -59,8 +58,6 @@ async function proxy(req, res) { } } -module.exports = { - getAvailable: proxy, - getDataset: proxy, - getNarrative: proxy, -}; \ No newline at end of file +export const getAvailable = proxy; +export const getDataset = proxy; +export const getNarrative = proxy; diff --git a/cli/develop.js b/cli/develop.js index 87d594704..dc69c12b0 100644 --- a/cli/develop.js +++ b/cli/develop.js @@ -1,16 +1,22 @@ /* eslint no-console: off */ -const path = require("path"); -const express = require("express"); -const webpack = require("webpack"); -const webpackDevMiddleware = require("webpack-dev-middleware"); -const webpackHotMiddleware = require("webpack-hot-middleware"); -const utils = require("./utils"); -const view = require("./view"); -const version = require('../src/version').version; -const chalk = require('chalk'); -const generateWebpackConfig = require("../webpack.config.js").default; +import path from "path"; +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; +import express from "express"; +import webpack from "webpack"; +import webpackDevMiddleware from "webpack-dev-middleware"; +import webpackHotMiddleware from "webpack-hot-middleware"; +import * as utils from "./utils.js"; +import * as view from "./view.js"; +import { version } from '../src/version.js'; +import chalk from 'chalk'; +import { processPathArguments } from "./server/processPaths.js"; + +const require = createRequire(import.meta.url); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const generateWebpackConfig = require("../webpack.config.cjs").default; const SUPPRESS = require('argparse').Const.SUPPRESS; -const { processPathArguments } = require("./server/processPaths"); const addParser = (parser) => { const description = `Launch auspice in development mode. @@ -30,7 +36,7 @@ const addParser = (parser) => { }; -const run = (args) => { +const run = async (args) => { const dataPaths = processPathArguments(args) /* Basic server set up */ @@ -73,7 +79,7 @@ const run = (args) => { if (args.gh_pages) { handlerMsg = view.serveRelativeFilepaths({app, dir: path.resolve(args.gh_pages)}); } else if (args.handlers) { - handlerMsg = view.customRouteHandlers(app, path.resolve(args.handlers)); + handlerMsg = await view.customRouteHandlers(app, path.resolve(args.handlers)); } else { handlerMsg = view.defaultRouteHandlers({app, dataPaths}); } @@ -115,7 +121,7 @@ const run = (args) => { }; -module.exports = { +export { addParser, run }; diff --git a/cli/server/convertJsonSchemas.js b/cli/server/convertJsonSchemas.js index f95e16629..be90c4355 100644 --- a/cli/server/convertJsonSchemas.js +++ b/cli/server/convertJsonSchemas.js @@ -1,4 +1,4 @@ -const utils = require("../utils"); +import * as utils from "../utils.js"; /** In auspice v1, the `prettyString` function was used extensively to transform values * for "nicer" display. v2 JSONs intentially avoid this -- the strings are intended to @@ -397,7 +397,7 @@ const setNodeBranchAttrs = (v2) => { }; -const convertFromV1 = ({tree, meta}) => { +export const convertFromV1 = ({tree, meta}) => { const v2 = {version: "v2", meta: { extensions: { original_version: "v1" }}}; // set metadata setColorings(v2["meta"], meta); @@ -411,8 +411,3 @@ const convertFromV1 = ({tree, meta}) => { removeNonV2TreeProps(v2); return v2; }; - - -module.exports = { - convertFromV1 -}; diff --git a/cli/server/getAvailable.js b/cli/server/getAvailable.js index 6c6d25b64..1f67d8603 100644 --- a/cli/server/getAvailable.js +++ b/cli/server/getAvailable.js @@ -1,12 +1,12 @@ -const utils = require("../utils"); -const fs = require('fs'); -const path = require("path"); -const { promisify } = require('util'); -const { findAvailableSecondTreeOptions } = require('./getDatasetHelpers'); +import * as utils from "../utils.js"; +import fs from 'fs'; +import path from "path"; +import { promisify } from 'util'; +import { findAvailableSecondTreeOptions } from './getDatasetHelpers.js'; const readdir = promisify(fs.readdir); -const getAvailableDatasets = (dir, files) => { +export const getAvailableDatasets = (dir, files) => { const datasets = []; /* NOTE: if there are v1 & v2 files with the same name the v2 JSON is * preferentially fetched. E.g. if `zika.json`, `zika_meta.json` and @@ -62,7 +62,7 @@ const getAvailableDatasets = (dir, files) => { return datasets; }; -const getAvailableNarratives = (dir, files) => { +export const getAvailableNarratives = (dir, files) => { return files .filter((file) => file.endsWith(".md") && file!=="README.md") .map((file) => ({ @@ -72,7 +72,7 @@ const getAvailableNarratives = (dir, files) => { })); }; -const setUpGetAvailableHandler = (dataPaths) => { +export const setUpGetAvailableHandler = (dataPaths) => { /* return Auspice's default handler for "/charon/getAvailable" requests. * Remember that auspice itself only serves local files. * Servers often use their own handler instead of this. @@ -103,13 +103,6 @@ const setUpGetAvailableHandler = (dataPaths) => { }; - -module.exports = { - setUpGetAvailableHandler, - getAvailableDatasets, - getAvailableNarratives, -}; - function availableResponseStructure(resources) { const datasets = resources.filter((r) => r.fileType==='dataset') .map((r) => ({request: r.request, buildUrl: r.buildUrl, secondTreeOptions: r.secondTreeOptions})); @@ -131,4 +124,4 @@ function unique(resources) { seen[r.fileType].add(r.request); return true; }) -} \ No newline at end of file +} diff --git a/cli/server/getDataset.js b/cli/server/getDataset.js index abc3929b8..788048314 100644 --- a/cli/server/getDataset.js +++ b/cli/server/getDataset.js @@ -1,9 +1,9 @@ -const { promisify } = require('util'); -const path = require("path"); -const fs = require('fs'); -const getAvailable = require("./getAvailable"); -const helpers = require("./getDatasetHelpers"); -const utils = require("../utils"); +import { promisify } from 'util'; +import path from "path"; +import fs from 'fs'; +import * as getAvailable from "./getAvailable.js"; +import * as helpers from "./getDatasetHelpers.js"; +import * as utils from "../utils.js"; const readdir = promisify(fs.readdir); @@ -11,7 +11,7 @@ const readdir = promisify(fs.readdir); * Returns a route handler which responds to requests by serving the relevant JSON file * from disk. */ -const setUpGetDatasetHandler = (dataPaths) => { +export const setUpGetDatasetHandler = (dataPaths) => { return async (req, res) => { let requestInfo; @@ -99,8 +99,3 @@ async function matchDatasetFile(dataPaths, requestInfo) { } return allAvailableDatasets; } - - -module.exports = { - setUpGetDatasetHandler -}; diff --git a/cli/server/getDatasetHelpers.js b/cli/server/getDatasetHelpers.js index f46a55928..b99a7ef16 100644 --- a/cli/server/getDatasetHelpers.js +++ b/cli/server/getDatasetHelpers.js @@ -8,13 +8,12 @@ * */ +import * as utils from "../utils.js"; +import queryString from "query-string"; +import { convertFromV1 } from "./convertJsonSchemas.js"; +import fs from "fs"; -const utils = require("../utils"); -const queryString = require("query-string"); -const convertFromV1 = require("./convertJsonSchemas").convertFromV1; -const fs = require("fs"); - -const handleError = (res, clientMsg, serverMsg="", code=500) => { +export const handleError = (res, clientMsg, serverMsg="", code=500) => { utils.warn(`${clientMsg} -- ${serverMsg}`); return res.status(code).type("text/plain").send(clientMsg); }; @@ -32,7 +31,7 @@ const splitPrefixIntoParts = (url) => url * @returns {string[]} ret.parts is the dataset name spit on '/' character * @returns {string} ret.dataType is the dataset type ('dataset', 'root-sequence' etc) */ -const interpretRequest = (req) => { +export const interpretRequest = (req) => { const query = queryString.parse(req.url.split('?')[1]); utils.log(`[GET DATASET] ${Object.entries(query).map(([k,v]) => `${k}: '${v}'`).join(', ')}`); if (!query.prefix) throw new Error("'prefix' not defined in request"); @@ -57,7 +56,7 @@ const interpretRequest = (req) => { * Given a request for which there is no perfect match, return a close match * if one exists else return false */ -const closestMatch = (requestedDatasetParts, availableDatasets) => { +export const closestMatch = (requestedDatasetParts, availableDatasets) => { let matchingDatasets = availableDatasets; let i; const matchDatasetRequest = (d) => d.request.split("/")[i] === requestedDatasetParts[i]; @@ -77,7 +76,7 @@ const closestMatch = (requestedDatasetParts, availableDatasets) => { }; -const sendJson = async (res, info) => { +export const sendJson = async (res, info) => { if (typeof info.address === "string") { /* In general, JSONs are designed such that no server modifications are needed by the server. This allows us to read as a stream and @@ -112,7 +111,7 @@ const sendJson = async (res, info) => { * (c) differ from the `currentDatasetUrl` by only 1 part * Note: the "parts" of the URL are formed by splitting it on `"/"` */ -const findAvailableSecondTreeOptions = (currentDatasetUrl, availableDatasetUrls) => { +export const findAvailableSecondTreeOptions = (currentDatasetUrl, availableDatasetUrls) => { const currentDatasetUrlArr = currentDatasetUrl.split('/'); const availableTangleTreeOptions = availableDatasetUrls.filter((datasetUrl) => { @@ -142,11 +141,3 @@ const findAvailableSecondTreeOptions = (currentDatasetUrl, availableDatasetUrls) return availableTangleTreeOptions; }; - -module.exports = { - interpretRequest, - closestMatch, - handleError, - sendJson, - findAvailableSecondTreeOptions -}; diff --git a/cli/server/getNarrative.js b/cli/server/getNarrative.js index 9cd87dbf1..4cd81f8ba 100644 --- a/cli/server/getNarrative.js +++ b/cli/server/getNarrative.js @@ -1,13 +1,13 @@ -const queryString = require("query-string"); -const { promisify } = require('util'); -const fs = require("fs"); -const utils = require("../utils"); -const getAvailable = require("./getAvailable"); +import queryString from "query-string"; +import { promisify } from 'util'; +import fs from "fs"; +import * as utils from "../utils.js"; +import * as getAvailable from "./getAvailable.js"; const readdir = promisify(fs.readdir); -const setUpGetNarrativeHandler = (dataPaths) => { +export const setUpGetNarrativeHandler = (dataPaths) => { return async (req, res) => { utils.log(`GET NARRATIVE request received: ${req.url}`); const query = queryString.parse(req.url.split('?')[1]); @@ -46,7 +46,3 @@ const setUpGetNarrativeHandler = (dataPaths) => { res.status(404).type("text/plain").send(errorMessage); } }; - -module.exports = { - setUpGetNarrativeHandler, -}; diff --git a/cli/server/processPaths.js b/cli/server/processPaths.js index 7f0070315..1c07eb59a 100644 --- a/cli/server/processPaths.js +++ b/cli/server/processPaths.js @@ -1,4 +1,4 @@ -const utils = require("../utils"); +import * as utils from "../utils.js"; /** * Returns an object linking (absolute) paths to a set whose members indicate whether @@ -13,7 +13,7 @@ const utils = require("../utils"); * (via `defaultDataPaths()`), however in my (james) experience it's never worked * well an I recommend providing paths via args. */ -function processPathArguments(args) { +export function processPathArguments(args) { if (args.handlers) { if (args.datasetDir || args.narrativeDir || args.path.length>0) { @@ -70,8 +70,3 @@ function processPathArguments(args) { return dataPaths; } - - -module.exports = { - processPathArguments, -}; diff --git a/cli/utils.js b/cli/utils.js index 8c6ddafe0..88dc32c8b 100644 --- a/cli/utils.js +++ b/cli/utils.js @@ -1,20 +1,23 @@ /* eslint no-console: off */ -const fs = require('fs'); -const chalk = require('chalk'); -const path = require("path"); +import fs from 'fs'; +import chalk from 'chalk'; +import path from 'path'; +import { fileURLToPath } from 'url'; -const verbose = (msg) => { +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export const verbose = (msg) => { if (global.AUSPICE_VERBOSE) { console.log(chalk.greenBright(`[verbose]\t${msg}`)); } }; -const log = (msg) => { +export const log = (msg) => { console.log(chalk.blueBright(msg)); }; -const warn = (msg) => { +export const warn = (msg) => { console.warn(chalk.yellowBright(`[warning]\t${msg}`)); }; -const error = (msg) => { +export const error = (msg) => { console.error(chalk.redBright(`[error]\t${msg}`)); process.exit(2); }; @@ -23,7 +26,7 @@ const isNpmGlobalInstall = () => { return __dirname.indexOf("lib/node_modules/auspice") !== -1; }; -const cleanUpPathname = (pathIn) => { +export const cleanUpPathname = (pathIn) => { let pathOut = pathIn; if (!pathOut.endsWith("/")) pathOut += "/"; if (pathOut.startsWith("~")) { @@ -47,13 +50,13 @@ const getCurrentDirectoriesFor = (type) => { }; -const defaultDataPaths = ({narrative=false} = {}) => { +export const defaultDataPaths = ({narrative=false} = {}) => { return isNpmGlobalInstall() ? [getCurrentDirectoriesFor(narrative ? "narratives" : "data")] : [path.join(path.resolve(__dirname), "..", narrative ? "narratives" : "data")]; } -const readFilePromise = (fileName) => { +export const readFilePromise = (fileName) => { return new Promise((resolve, reject) => { fs.readFile(fileName, 'utf8', (err, data) => { if (err) { @@ -71,7 +74,7 @@ const readFilePromise = (fileName) => { /* write an index.html file to the current working directory * Optionally set the hrefs for local files to relative links (needed for github pages) */ -const exportIndexDotHtml = ({relative=false}) => { +export const exportIndexDotHtml = ({relative=false}) => { if (path.resolve(__dirname, "..") === process.cwd()) { warn("Cannot export index.html to the auspice source directory."); return; @@ -86,14 +89,3 @@ const exportIndexDotHtml = ({relative=false}) => { } fs.writeFileSync(outputFilePath, data); }; - -module.exports = { - verbose, - log, - warn, - error, - readFilePromise, - exportIndexDotHtml, - cleanUpPathname, - defaultDataPaths -}; diff --git a/cli/view.js b/cli/view.js index 3a514c0bf..9f5af9b4a 100644 --- a/cli/view.js +++ b/cli/view.js @@ -1,17 +1,24 @@ /* eslint no-console: off */ -/* eslint global-require: off */ - -const path = require("path"); -const fs = require("fs"); -const express = require("express"); -const expressStaticGzip = require("express-static-gzip"); -const compression = require('compression'); -const nakedRedirect = require('express-naked-redirect'); -const utils = require("./utils"); -const version = require('../src/version').version; -const chalk = require('chalk'); + +import path from "path"; +import fs from "fs"; +import { fileURLToPath } from 'url'; +import { createRequire } from 'module'; +import express from "express"; +import expressStaticGzip from "express-static-gzip"; +import compression from 'compression'; +import nakedRedirect from 'express-naked-redirect'; +import * as utils from "./utils.js"; +import { version } from '../src/version.js'; +import chalk from 'chalk'; +import { processPathArguments } from "./server/processPaths.js"; +import { setUpGetAvailableHandler } from "./server/getAvailable.js"; +import { setUpGetDatasetHandler } from "./server/getDataset.js"; +import { setUpGetNarrativeHandler } from "./server/getNarrative.js"; + +const require = createRequire(import.meta.url); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const SUPPRESS = require('argparse').Const.SUPPRESS; -const { processPathArguments } = require("./server/processPaths"); const addParser = (parser) => { const description = `Launch a local server to view locally available datasets & narratives. @@ -49,9 +56,9 @@ const serveRelativeFilepaths = ({app, dir}) => { return `JSON requests will be served relative to ${dir}.`; }; -function customRouteHandlers(app, handlersPath) { +async function customRouteHandlers(app, handlersPath) { utils.verbose(`Loading handlers from ${handlersPath}`); - const customCode = require(handlersPath); + const customCode = await import(handlersPath); app.get("/charon/getAvailable", customCode.getAvailable); app.get("/charon/getDataset", customCode.getDataset); app.get("/charon/getNarrative", customCode.getNarrative); @@ -62,9 +69,9 @@ function customRouteHandlers(app, handlersPath) { * Adds route handlers for the three canonical charon routes to the *app* */ function defaultRouteHandlers({app, dataPaths}) { - app.get("/charon/getAvailable", require("./server/getAvailable").setUpGetAvailableHandler(dataPaths)); - app.get("/charon/getDataset", require("./server/getDataset").setUpGetDatasetHandler(dataPaths)); - app.get("/charon/getNarrative", require("./server/getNarrative").setUpGetNarrativeHandler(dataPaths)); + app.get("/charon/getAvailable", setUpGetAvailableHandler(dataPaths)); + app.get("/charon/getDataset", setUpGetDatasetHandler(dataPaths)); + app.get("/charon/getNarrative", setUpGetNarrativeHandler(dataPaths)); const sep = "\n - " return 'Looking for datasets & narratives in the following paths,\n' + '(if there are multiple matches then the first one will be used)' + sep + @@ -106,7 +113,7 @@ function hasAuspiceBuild(directory) { ) } -const run = (args) => { +const run = async (args) => { const dataPaths = processPathArguments(args) /* Basic server set up */ @@ -129,7 +136,7 @@ const run = (args) => { if (args.gh_pages) { handlerMsg = serveRelativeFilepaths({app, dir: path.resolve(args.gh_pages)}); } else if (args.handlers) { - handlerMsg = customRouteHandlers(app, path.resolve(args.handlers)); + handlerMsg = await customRouteHandlers(app, path.resolve(args.handlers)); } else { handlerMsg = defaultRouteHandlers({app, dataPaths}); } @@ -172,7 +179,7 @@ const run = (args) => { }; -module.exports = { +export { addParser, run, addDatasetNarrativePathArgs, diff --git a/docs/server/api.rst b/docs/server/api.rst index 9201a7fb8..a85c7279a 100644 --- a/docs/server/api.rst +++ b/docs/server/api.rst @@ -142,7 +142,7 @@ Currently .. code:: js - const auspice = require("auspice"); + import auspice from "auspice"; returns an object with two properties: diff --git a/index.js b/index.js index fe9962920..749ffe267 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,12 @@ /** This file exports the functions / objects available to node packages - * which import auspice (e.g. via `const auspice = require("auspice")`) + * which import auspice (e.g. via `import { convertFromV1 } from "auspice"`) * * These are intended to be "helper functions" for those wishing to write * their own auspice server, i.e. a server which handles the GET * requests originating from a auspice client. */ +import { convertFromV1 } from "./cli/server/convertJsonSchemas.js"; -const convertFromV1 = require("./cli/server/convertJsonSchemas").convertFromV1; -const parseNarrativeFile = require("./cli/server/getNarrative").parseNarrative; - -module.exports = { - convertFromV1, - parseNarrativeFile -}; +export { convertFromV1 }; +export const parseNarrativeFile = undefined; diff --git a/package-lock.json b/package-lock.json index 27dbd65cc..fc1d19de1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -117,6 +117,7 @@ "@types/webpack-env": "^1.18.2", "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.57.0", + "babel-plugin-transform-import-meta": "^2.3.3", "chai": "^4.1.2", "chai-http": "^4.0.0", "eslint": "^8.39.0", @@ -8312,6 +8313,20 @@ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" }, + "node_modules/babel-plugin-transform-import-meta": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.3.tgz", + "integrity": "sha512-bbh30qz1m6ZU1ybJoNOhA2zaDvmeXMnGNBMVMDOJ1Fni4+wMBoy/j7MTRVmqAUCIcy54/rEnr9VEBsfcgbpm3Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "@babel/core": "^7.10.0" + } + }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -17297,9 +17312,10 @@ } }, "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", @@ -22940,6 +22956,16 @@ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" }, + "babel-plugin-transform-import-meta": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.3.tgz", + "integrity": "sha512-bbh30qz1m6ZU1ybJoNOhA2zaDvmeXMnGNBMVMDOJ1Fni4+wMBoy/j7MTRVmqAUCIcy54/rEnr9VEBsfcgbpm3Q==", + "dev": true, + "requires": { + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" + } + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -29471,9 +29497,9 @@ } }, "tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 3a48acd64..b119f613c 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "author": "James Hadfield, Trevor Bedford and Richard Neher", "license": "AGPL-3.0-only", "repository": "github:nextstrain/auspice", + "type": "module", "homepage": "https://www.npmjs.com/package/auspice", "engines": { "node": "^24 || ^26", @@ -13,7 +14,7 @@ "bin": { "auspice": "./auspice.js" }, - "main": "index.js", + "exports": "./index.js", "scripts": { "view": "node auspice.js view --verbose", "dev": "node auspice.js develop --verbose", @@ -139,6 +140,7 @@ "@types/webpack-env": "^1.18.2", "@typescript-eslint/eslint-plugin": "^5.57.0", "@typescript-eslint/parser": "^5.57.0", + "babel-plugin-transform-import-meta": "^2.3.3", "chai": "^4.1.2", "chai-http": "^4.0.0", "eslint": "^8.39.0", diff --git a/scripts/diff-lang.js b/scripts/diff-lang.js index a926d6965..4f7a1e3e1 100755 --- a/scripts/diff-lang.js +++ b/scripts/diff-lang.js @@ -1,7 +1,10 @@ #!/usr/bin/env node /* eslint-disable no-console */ -const fs = require('fs'); -const path = require('path'); +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); main(); diff --git a/scripts/extract-release-notes.js b/scripts/extract-release-notes.js index 52d00fe69..05d989229 100644 --- a/scripts/extract-release-notes.js +++ b/scripts/extract-release-notes.js @@ -3,7 +3,7 @@ * It is intended to be run as part of releaseNewVersion.sh */ -const fs = require('fs'); +import fs from 'fs'; function main() { const releaseNotes = []; diff --git a/scripts/fetch-test-data b/scripts/fetch-test-data index 7d95d331e..b1346db19 100755 --- a/scripts/fetch-test-data +++ b/scripts/fetch-test-data @@ -1,7 +1,10 @@ #!/usr/bin/env node -const fs = require('fs'); -const path = require('path'); +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DEST = path.join(__dirname, '..', 'test', 'fetched-jsons'); const CHARON = 'https://nextstrain.org/charon/getDataset?prefix='; diff --git a/src/components/framework/fine-print.js b/src/components/framework/fine-print.js index 5943a1eec..98ecf5225 100644 --- a/src/components/framework/fine-print.js +++ b/src/components/framework/fine-print.js @@ -11,7 +11,7 @@ import { publications } from "../download/downloadModal"; import { hasExtension, getExtension } from "../../util/extensions"; import { canShowLinkOuts } from "../modal/LinkOutModalContents.jsx"; -const logoPNG = require("../../images/favicon.png"); +import logoPNG from "../../images/favicon.png"; const MarkdownDisplay = lazy(() => import("../markdownDisplay")); diff --git a/src/components/info/byline.js b/src/components/info/byline.js index 8da817e44..cb695d2b9 100644 --- a/src/components/info/byline.js +++ b/src/components/info/byline.js @@ -3,6 +3,7 @@ import { connect } from "react-redux"; import { withTranslation, Trans } from 'react-i18next'; import styled from 'styled-components'; import { headerFont } from "../../globalStyles"; +import gisaidLogo from "../../images/gisaid-logo.png"; /** * React component for the byline of the current dataset. @@ -138,7 +139,7 @@ function renderDataProvenance(t, metadata) { .map((source) => { if (source.name.toUpperCase() === "GISAID") { // SPECIAL CASE return ( - gisaid-logo + gisaid-logo ); } const url = parseUrl(source.url); diff --git a/src/components/navBar/content.js b/src/components/navBar/content.js index dfc1b8136..b96ce4d98 100644 --- a/src/components/navBar/content.js +++ b/src/components/navBar/content.js @@ -1,7 +1,6 @@ import React from "react"; import styled from 'styled-components'; - -const logoPNG = require("../../images/logo-light.svg"); +import logoPNG from "../../images/logo-light.svg"; const AuspiceNavBarContainer = styled.div` display: flex; diff --git a/src/components/splash/splash.js b/src/components/splash/splash.js index deb35e9c4..5c89de5f3 100644 --- a/src/components/splash/splash.js +++ b/src/components/splash/splash.js @@ -4,6 +4,7 @@ import NavBar from "../navBar"; import Flex from "../../components/framework/flex"; import { CenterContent } from "./centerContent"; import { FinePrintStyles, getCitation, getCustomFinePrint } from "../../components/framework/fine-print"; +import logoLightSvg from "../../images/logo-light.svg"; const getNumColumns = (width) => width > 1000 ? 3 : width > 750 ? 2 : 1; @@ -32,9 +33,7 @@ const SplashContent = ({available, browserDimensions, errorMessage}) => { logo diff --git a/src/root.js b/src/root.js index d774ef4e8..28bd662ed 100644 --- a/src/root.js +++ b/src/root.js @@ -16,7 +16,7 @@ const DebugNarrative = lazy(() => import("./components/narrativeEditor/narrative * This triggers a window resize which in turn triggers a general * rerender. A bit ham-fisted but gets the job done for the time being * */ -if (module.hot) { +if (import.meta.webpackHot) { setTimeout(() => window.dispatchEvent(new Event('resize')), 500); } diff --git a/src/store.ts b/src/store.ts index 69c87306b..5a6ff4247 100644 --- a/src/store.ts +++ b/src/store.ts @@ -41,10 +41,9 @@ const store = configureStore({ devTools: process.env.NODE_ENV !== 'production', }) -if (process.env.NODE_ENV !== 'production' && module.hot) { - // console.log("hot reducer reload"); - module.hot.accept('./reducers', () => { - const nextRootReducer = require('./reducers/index'); +if (process.env.NODE_ENV !== 'production' && import.meta.webpackHot) { + import.meta.webpackHot.accept('./reducers', async () => { + const nextRootReducer = (await import('./reducers/index')).default; store.replaceReducer(nextRootReducer); }); } diff --git a/src/util/extensions.ts b/src/util/extensions.ts index 1f7c5caa1..6e4e7de19 100644 --- a/src/util/extensions.ts +++ b/src/util/extensions.ts @@ -6,7 +6,6 @@ type Extensions = { const registry: Extensions = ((): Extensions => { if (!process.env.EXTENSION_DATA) { - // console.log("no EXTENSION_DATA found"); return {}; } @@ -15,12 +14,10 @@ const registry: Extensions = ((): Extensions => { Object.keys(extensions).forEach((key: string) => { if (key.endsWith("Component")) { - // console.log("loading component", key); /* "@extensions" is a webpack alias */ extensions[key] = require(`@extensions/${extensions[key]}`).default; } }); - // console.log("extensions", extensions); return extensions; })(); diff --git a/src/util/parseNarrative.js b/src/util/parseNarrative.js index 5ab213539..f5cb3d5bc 100644 --- a/src/util/parseNarrative.js +++ b/src/util/parseNarrative.js @@ -1,10 +1,10 @@ /* eslint no-param-reassign: off */ -const { safeLoadFront } = require('yaml-front-matter'); -const queryString = require("query-string"); +import { safeLoadFront } from 'yaml-front-matter'; +import queryString from "query-string"; -const parseMarkdownNarrativeFile = (fileContents, markdownParser) => { +export const parseMarkdownNarrativeFile = (fileContents, markdownParser) => { const frontMatter = safeLoadFront(fileContents); if (Object.keys(frontMatter).length === 1) { @@ -22,7 +22,7 @@ const parseMarkdownNarrativeFile = (fileContents, markdownParser) => { }; -function createTitleSlideFromFrontmatter(frontMatter, markdownParser) { +export function createTitleSlideFromFrontmatter(frontMatter, markdownParser) { let markdown = ""; // A markdown interpretation of the YAML for display markdown += parseTitleSlideTitle(frontMatter); @@ -45,7 +45,7 @@ function createTitleSlideFromFrontmatter(frontMatter, markdownParser) { }; } -function parseTitleSlideTitle(frontMatter) { +export function parseTitleSlideTitle(frontMatter) { if (!frontMatter.title) throw new Error("Narrative YAML frontmatter must define a title!"); return `## ${frontMatter.title}\n`; } @@ -139,7 +139,7 @@ function* parseNarrativeBody(markdown, fallbackDataset, markdownParser) { } } -function parseNarrativeAuthors(frontMatter) { +export function parseNarrativeAuthors(frontMatter) { let authorMd = ""; const authors = parseAttributions(frontMatter, "authors", "authorLinks"); if (authors) { @@ -152,7 +152,7 @@ function parseNarrativeAuthors(frontMatter) { return authorMd+"\n"; } -function parseNarrativeTranslators(frontMatter) { +export function parseNarrativeTranslators(frontMatter) { const translators = parseAttributions(frontMatter, "translators", "translatorLinks"); if (translators) return `### Translators: ${translators}\n`; return ""; @@ -212,13 +212,3 @@ function attributionLink(attribution, attributionLinkValue) { } return attribution; } - - -module.exports = { - parseMarkdownNarrativeFile, - /* following functions exported for unit testing */ - createTitleSlideFromFrontmatter, - parseTitleSlideTitle, - parseNarrativeAuthors, - parseNarrativeTranslators -}; diff --git a/src/version.js b/src/version.js index fcc0c5a6a..72dd2e177 100644 --- a/src/version.js +++ b/src/version.js @@ -1,5 +1 @@ -const version = "2.72.0"; - -module.exports = { - version -}; +export const version = "2.72.0"; diff --git a/test/colorScales.test.js b/test/colorScales.test.js index fb61a75a1..e0debdcc3 100644 --- a/test/colorScales.test.js +++ b/test/colorScales.test.js @@ -1,6 +1,6 @@ import { unknownColor, createNonContinuousScaleFromProvidedScaleMap } from "../src/util/colorScale"; -const crypto = require("crypto"); +import crypto from "crypto" /* ---------------------------------------------------------------------- */ diff --git a/test/server-fetch.test.js b/test/server-fetch.test.js index ede7c7c76..05326624c 100644 --- a/test/server-fetch.test.js +++ b/test/server-fetch.test.js @@ -13,10 +13,13 @@ * (see src/actions/loadData.js). */ -const express = require("express"); -const fs = require("fs"); -const path = require("path"); -const { setUpGetDatasetHandler } = require("../cli/server/getDataset"); +import express from "express"; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import { setUpGetDatasetHandler } from "../cli/server/getDataset.js"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DATA_DIR = path.resolve(__dirname, "fetched-jsons"); const MAIN_FIXTURE = path.join(DATA_DIR, "mumps.json"); diff --git a/test/smoke-test/urls.test.js b/test/smoke-test/urls.test.js index d2a06abe0..3036ee7ef 100644 --- a/test/smoke-test/urls.test.js +++ b/test/smoke-test/urls.test.js @@ -1,5 +1,5 @@ -const {readFileSync} = require('fs'); -const {expect, test} = require('@playwright/test'); +import {readFileSync} from 'fs'; +import {expect, test} from '@playwright/test'; test.describe.configure({ mode: 'parallel' }); @@ -7,7 +7,7 @@ const testCases = []; // Load a suite of smoke tests from a simple text file. File is of the format: // [path], [comma separated text assertions] -const text = readFileSync(require.resolve('./urls.txt'), 'utf8').trim(); +const text = readFileSync(new URL('./urls.txt', import.meta.url), 'utf8').trim(); for (const line of text.split(/\r?\n/)) { if (line.length === 0) continue; // allow for blank lines. if (line.match(/^#/)) continue; // allow for comments. diff --git a/webpack.config.js b/webpack.config.cjs similarity index 98% rename from webpack.config.js rename to webpack.config.cjs index f6a4168c3..83b1f4b6a 100644 --- a/webpack.config.js +++ b/webpack.config.cjs @@ -212,6 +212,7 @@ const generateConfig = ({extensionPath, devMode=false, customOutputPath, analyze resolve: { alias: aliasesToResolve, extensions: ['.ts', '.tsx', '...'], + fullySpecified: false, fallback: { buffer: require.resolve("buffer/"), fs: false @@ -269,6 +270,11 @@ const generateConfig = ({extensionPath, devMode=false, customOutputPath, analyze }, module: { rules: [ + { + test: /\.(ts|js)x?$/, + type: "javascript/auto", + resolve: { fullySpecified: false } + }, { test: /\.(ts|js)x?$/, loader: 'babel-loader', From bf764dcd7ea73c6c0288f488c2cef1c72fb243a7 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 14:41:24 +1200 Subject: [PATCH 3/9] [cli] Migrate server files from JavaScript to TypeScript Convert 8 cli files from .js to .ts, leveraging Node 24's native type stripping to run them directly without a build step. tsc is used for type-checking only (noEmit). Files converted: - cli/utils.ts - cli/server/getDataset.ts - cli/server/getDatasetHelpers.ts - cli/server/getAvailable.ts - cli/server/getNarrative.ts - cli/server/processPaths.ts - cli/view.ts - cli/develop.ts - cli/build.ts Supporting changes: - Add cli/tsconfig.json extending root with nodenext module resolution and allowImportingTsExtensions for Node-native .ts imports - Add allowImportingTsExtensions to root tsconfig.json (needed because cli .ts files are pulled in transitively via test imports) - Exclude cli/**/* from root tsconfig include/add to exclude (prevents checking cli files under the wrong moduleResolution) - Update package.json type-check script to run both tsconfigs - Update all import paths across 11 files (.js -> .ts extensions) - Update webpack.config.cjs require for cli/utils.ts - Add eslint-disable for explicit-function-return-type and consistent-type-assertions in converted files (incremental migration) - Apply chalk 2.x workaround (type assertion) for nodenext compat - Fix TypeScript strict errors: unknown in catch blocks, Object.entries casting for Set methods, undefined-in-object check Co-Authored-By: Claude Opus 4.6 --- auspice.js | 6 +++--- babel.config.cjs | 2 +- cli/{build.js => build.ts} | 4 ++-- cli/convert.js | 2 +- cli/dev/reverse-proxy.js | 2 +- cli/{develop.js => develop.ts} | 20 ++++++++++--------- cli/server/convertJsonSchemas.js | 2 +- .../{getAvailable.js => getAvailable.ts} | 8 ++++---- cli/server/{getDataset.js => getDataset.ts} | 15 +++++++------- ...DatasetHelpers.js => getDatasetHelpers.ts} | 4 ++-- .../{getNarrative.js => getNarrative.ts} | 8 ++++---- .../{processPaths.js => processPaths.ts} | 4 ++-- cli/tsconfig.json | 12 +++++++++++ cli/{utils.js => utils.ts} | 17 +++++++++------- cli/{view.js => view.ts} | 20 ++++++++++--------- package.json | 4 ++-- test/server-fetch.test.js | 2 +- tsconfig.json | 4 ++++ webpack.config.cjs | 2 +- 19 files changed, 81 insertions(+), 57 deletions(-) rename cli/{build.js => build.ts} (97%) rename cli/{develop.js => develop.ts} (90%) rename cli/server/{getAvailable.js => getAvailable.ts} (95%) rename cli/server/{getDataset.js => getDataset.ts} (87%) rename cli/server/{getDatasetHelpers.js => getDatasetHelpers.ts} (97%) rename cli/server/{getNarrative.js => getNarrative.ts} (89%) rename cli/server/{processPaths.js => processPaths.ts} (97%) create mode 100644 cli/tsconfig.json rename cli/{utils.js => utils.ts} (83%) rename cli/{view.js => view.ts} (93%) diff --git a/auspice.js b/auspice.js index a230ca7a4..292d4058d 100755 --- a/auspice.js +++ b/auspice.js @@ -2,9 +2,9 @@ import argparse from 'argparse'; import { version } from './src/version.js'; -import * as view from "./cli/view.js"; -import * as build from "./cli/build.js"; -import * as develop from "./cli/develop.js"; +import * as view from "./cli/view.ts"; +import * as build from "./cli/build.ts"; +import * as develop from "./cli/develop.ts"; import * as convert from "./cli/convert.js"; const parser = new argparse.ArgumentParser({ diff --git a/babel.config.cjs b/babel.config.cjs index ef3d88762..6f1bd17b0 100644 --- a/babel.config.cjs +++ b/babel.config.cjs @@ -1,4 +1,4 @@ -const utils = require('./cli/utils'); +const utils = require('./cli/utils.ts'); /* What variables does this config depend on? * process.env.BABEL_EXTENSION_PATH -- a resolved path diff --git a/cli/build.js b/cli/build.ts similarity index 97% rename from cli/build.js rename to cli/build.ts index 545eadbb6..53f0bee14 100644 --- a/cli/build.js +++ b/cli/build.ts @@ -2,7 +2,7 @@ import webpack from "webpack"; import path from "path"; import { fileURLToPath } from 'url'; import { createRequire } from 'module'; -import * as utils from "./utils.js"; +import * as utils from "./utils.ts"; const require = createRequire(import.meta.url); const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -10,7 +10,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const generateWebpackConfig = require("../webpack.config.cjs").default; const SUPPRESS = require('argparse').Const.SUPPRESS; -const addParser = (parser) => { +const addParser = (parser): void => { const description = `Build the client source code bundle. For development, you may want to use "auspice develop" which recompiles code on the fly as changes are made. You may provide customisations (e.g. code, options) to this step to modify the functionality and appearance of auspice. diff --git a/cli/convert.js b/cli/convert.js index afb2429dd..b9335f00d 100644 --- a/cli/convert.js +++ b/cli/convert.js @@ -1,7 +1,7 @@ /* eslint no-console: off */ import fs from "fs"; import { convertFromV1 } from "./server/convertJsonSchemas.js"; -import * as utils from "./utils.js"; +import * as utils from "./utils.ts"; const addParser = (parser) => { diff --git a/cli/dev/reverse-proxy.js b/cli/dev/reverse-proxy.js index 10dc00956..8c349b82c 100644 --- a/cli/dev/reverse-proxy.js +++ b/cli/dev/reverse-proxy.js @@ -1,4 +1,4 @@ -import * as utils from "../utils.js"; +import * as utils from "../utils.ts"; import { URL } from "url"; import fetch from "node-fetch"; diff --git a/cli/develop.js b/cli/develop.ts similarity index 90% rename from cli/develop.js rename to cli/develop.ts index dc69c12b0..1060ec269 100644 --- a/cli/develop.js +++ b/cli/develop.ts @@ -6,11 +6,13 @@ import express from "express"; import webpack from "webpack"; import webpackDevMiddleware from "webpack-dev-middleware"; import webpackHotMiddleware from "webpack-hot-middleware"; -import * as utils from "./utils.js"; -import * as view from "./view.js"; +import * as utils from "./utils.ts"; +import * as view from "./view.ts"; import { version } from '../src/version.js'; -import chalk from 'chalk'; -import { processPathArguments } from "./server/processPaths.js"; +import _chalk from 'chalk'; +/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ +const chalk = _chalk as any as import('chalk').Chalk; +import { processPathArguments } from "./server/processPaths.ts"; const require = createRequire(import.meta.url); const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -18,7 +20,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); const generateWebpackConfig = require("../webpack.config.cjs").default; const SUPPRESS = require('argparse').Const.SUPPRESS; -const addParser = (parser) => { +const addParser = (parser): void => { const description = `Launch auspice in development mode. This runs a local server and uses hot-reloading to allow automatic updating as you edit the code. NOTE: there is a speed penalty for this ability and this should never be used for production. @@ -36,7 +38,7 @@ const addParser = (parser) => { }; -const run = async (args) => { +const run = async (args): Promise => { const dataPaths = processPathArguments(args) /* Basic server set up */ @@ -46,7 +48,7 @@ const run = async (args) => { const baseDir = path.resolve(__dirname, ".."); utils.verbose(`Serving index / favicon etc from "${baseDir}"`); - app.get("/favicon.png", (req, res) => {res.sendFile(path.join(baseDir, "favicon.png"));}); + app.get("/favicon.png", (_req, res) => {res.sendFile(path.join(baseDir, "favicon.png"));}); /* webpack set up */ const extensionPath = args.extend ? path.resolve(args.extend) : undefined; @@ -59,7 +61,7 @@ const run = async (args) => { process.env.BABEL_EXTENSION_PATH = extensionPath; /* Redirects / to webpack-generated index */ - app.use((req, res, next) => { + app.use((req, _res, next) => { if (!/^\/__webpack_hmr|^\/charon|\.[A-Za-z0-9]{1,5}$/.test(req.path)) { req.url = webpackConfig.output.publicPath; } @@ -90,7 +92,7 @@ const run = async (args) => { return res.status(500).type("text/plain").send(errorMessage); }); - app.get("*", (req, res) => res.redirect("/")); + app.get("*", (_req, res) => res.redirect("/")); const server = app.listen(app.get('port'), app.get('host'), () => { utils.log("\n\n---------------------------------------------------"); diff --git a/cli/server/convertJsonSchemas.js b/cli/server/convertJsonSchemas.js index be90c4355..d36bb102f 100644 --- a/cli/server/convertJsonSchemas.js +++ b/cli/server/convertJsonSchemas.js @@ -1,4 +1,4 @@ -import * as utils from "../utils.js"; +import * as utils from "../utils.ts"; /** In auspice v1, the `prettyString` function was used extensively to transform values * for "nicer" display. v2 JSONs intentially avoid this -- the strings are intended to diff --git a/cli/server/getAvailable.js b/cli/server/getAvailable.ts similarity index 95% rename from cli/server/getAvailable.js rename to cli/server/getAvailable.ts index 1f67d8603..7063e5b8a 100644 --- a/cli/server/getAvailable.js +++ b/cli/server/getAvailable.ts @@ -1,8 +1,8 @@ -import * as utils from "../utils.js"; +import * as utils from "../utils.ts"; import fs from 'fs'; import path from "path"; import { promisify } from 'util'; -import { findAvailableSecondTreeOptions } from './getDatasetHelpers.js'; +import { findAvailableSecondTreeOptions } from './getDatasetHelpers.ts'; const readdir = promisify(fs.readdir); @@ -77,10 +77,10 @@ export const setUpGetAvailableHandler = (dataPaths) => { * Remember that auspice itself only serves local files. * Servers often use their own handler instead of this. */ - return async (req, res) => { + return async (_req, res) => { utils.log("GET AVAILABLE returning locally available datasets & narratives"); let resources = [] - for (const [p, dataTypes] of Object.entries(dataPaths)) { + for (const [p, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { try { // FUTURE TODO - recurse into subfolders (readdir can do this natively) const files = await readdir(p); diff --git a/cli/server/getDataset.js b/cli/server/getDataset.ts similarity index 87% rename from cli/server/getDataset.js rename to cli/server/getDataset.ts index 788048314..b7e90448b 100644 --- a/cli/server/getDataset.js +++ b/cli/server/getDataset.ts @@ -1,9 +1,9 @@ import { promisify } from 'util'; import path from "path"; import fs from 'fs'; -import * as getAvailable from "./getAvailable.js"; -import * as helpers from "./getDatasetHelpers.js"; -import * as utils from "../utils.js"; +import * as getAvailable from "./getAvailable.ts"; +import * as helpers from "./getDatasetHelpers.ts"; +import * as utils from "../utils.ts"; const readdir = promisify(fs.readdir); @@ -18,7 +18,8 @@ export const setUpGetDatasetHandler = (dataPaths) => { try { requestInfo = helpers.interpretRequest(req); } catch (err) { - return helpers.handleError(res, err.message, err.message, 400); + const msg = err instanceof Error ? err.message : String(err); + return helpers.handleError(res, msg, msg, 400); } const matchResult = await matchDatasetFile(dataPaths, requestInfo); @@ -65,13 +66,13 @@ async function matchDatasetFile(dataPaths, requestInfo) { * (this "first match wins" approach mirrors that of `getAvailable`) */ const allAvailableDatasets = [] - for (const [dir, dataTypes] of Object.entries(dataPaths)) { + for (const [dir, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { if (!dataTypes.has('datasets')) continue; - let files = []; + let files: string[] = []; try { files = await readdir(dir); } catch (err) { - utils.warn(`Error reading datasets from ${dir}: ${err.message}`) + utils.warn(`Error reading datasets from ${dir}: ${err instanceof Error ? err.message : err}`) } if (requestInfo.dataType==='dataset') { diff --git a/cli/server/getDatasetHelpers.js b/cli/server/getDatasetHelpers.ts similarity index 97% rename from cli/server/getDatasetHelpers.js rename to cli/server/getDatasetHelpers.ts index b99a7ef16..5f9b2ae98 100644 --- a/cli/server/getDatasetHelpers.js +++ b/cli/server/getDatasetHelpers.ts @@ -8,7 +8,7 @@ * */ -import * as utils from "../utils.js"; +import * as utils from "../utils.ts"; import queryString from "query-string"; import { convertFromV1 } from "./convertJsonSchemas.js"; import fs from "fs"; @@ -36,7 +36,7 @@ export const interpretRequest = (req) => { utils.log(`[GET DATASET] ${Object.entries(query).map(([k,v]) => `${k}: '${v}'`).join(', ')}`); if (!query.prefix) throw new Error("'prefix' not defined in request"); const datanameParts = splitPrefixIntoParts(query.prefix); - const info = {parts: datanameParts}; + const info: {parts: string[], dataType?: string} = {parts: datanameParts}; /* query.type is used to indicate which sidecar file should be fetched, without it we fetch the "main" dataset JSON. See the `Dataset` constructor in `./src/actions/loadData.js` for which sidecars auspice may try to fetch */ diff --git a/cli/server/getNarrative.js b/cli/server/getNarrative.ts similarity index 89% rename from cli/server/getNarrative.js rename to cli/server/getNarrative.ts index 4cd81f8ba..7afa8a637 100644 --- a/cli/server/getNarrative.js +++ b/cli/server/getNarrative.ts @@ -1,8 +1,8 @@ import queryString from "query-string"; import { promisify } from 'util'; import fs from "fs"; -import * as utils from "../utils.js"; -import * as getAvailable from "./getAvailable.js"; +import * as utils from "../utils.ts"; +import * as getAvailable from "./getAvailable.ts"; const readdir = promisify(fs.readdir); @@ -23,7 +23,7 @@ export const setUpGetNarrativeHandler = (dataPaths) => { .replace(/^\//, "") // remove leading slash .replace(/\/$/, "") // remove ending slash - for (const [p, dataTypes] of Object.entries(dataPaths)) { + for (const [p, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { if (!dataTypes.has('narratives')) continue; try { const files = await readdir(p); @@ -36,7 +36,7 @@ export const setUpGetNarrativeHandler = (dataPaths) => { } // else go scan the next dataPaths (directory) } catch (err) { - const errorMessage = `Narratives couldn't be served -- ${err.message}`; + const errorMessage = `Narratives couldn't be served -- ${err instanceof Error ? err.message : err}`; utils.warn(errorMessage); return res.status(500).type("text/plain").send(errorMessage); } diff --git a/cli/server/processPaths.js b/cli/server/processPaths.ts similarity index 97% rename from cli/server/processPaths.js rename to cli/server/processPaths.ts index 1c07eb59a..d88b2462f 100644 --- a/cli/server/processPaths.js +++ b/cli/server/processPaths.ts @@ -1,4 +1,4 @@ -import * as utils from "../utils.js"; +import * as utils from "../utils.ts"; /** * Returns an object linking (absolute) paths to a set whose members indicate whether @@ -64,7 +64,7 @@ export function processPathArguments(args) { } } - if (undefined in dataPaths) { + if ("undefined" in dataPaths) { utils.error("One or more provided paths does not exist") } diff --git a/cli/tsconfig.json b/cli/tsconfig.json new file mode 100644 index 000000000..08e517a38 --- /dev/null +++ b/cli/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "allowImportingTsExtensions": true, + "types": ["node"], + "lib": ["ES2022"] + }, + "include": ["./**/*"], + "exclude": [] +} diff --git a/cli/utils.js b/cli/utils.ts similarity index 83% rename from cli/utils.js rename to cli/utils.ts index 88dc32c8b..39a6fcc82 100644 --- a/cli/utils.js +++ b/cli/utils.ts @@ -1,28 +1,31 @@ /* eslint no-console: off */ import fs from 'fs'; -import chalk from 'chalk'; +import _chalk from 'chalk'; +// chalk 2.x types aren't compatible with nodenext module resolution +/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ +const chalk = _chalk as any as import('chalk').Chalk; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -export const verbose = (msg) => { +export const verbose = (msg): void => { if (global.AUSPICE_VERBOSE) { console.log(chalk.greenBright(`[verbose]\t${msg}`)); } }; -export const log = (msg) => { +export const log = (msg): void => { console.log(chalk.blueBright(msg)); }; -export const warn = (msg) => { +export const warn = (msg): void => { console.warn(chalk.yellowBright(`[warning]\t${msg}`)); }; -export const error = (msg) => { +export const error = (msg): void => { console.error(chalk.redBright(`[error]\t${msg}`)); process.exit(2); }; -const isNpmGlobalInstall = () => { +const isNpmGlobalInstall = (): boolean => { return __dirname.indexOf("lib/node_modules/auspice") !== -1; }; @@ -74,7 +77,7 @@ export const readFilePromise = (fileName) => { /* write an index.html file to the current working directory * Optionally set the hrefs for local files to relative links (needed for github pages) */ -export const exportIndexDotHtml = ({relative=false}) => { +export const exportIndexDotHtml = ({relative=false}): void => { if (path.resolve(__dirname, "..") === process.cwd()) { warn("Cannot export index.html to the auspice source directory."); return; diff --git a/cli/view.js b/cli/view.ts similarity index 93% rename from cli/view.js rename to cli/view.ts index 9f5af9b4a..a218bf620 100644 --- a/cli/view.js +++ b/cli/view.ts @@ -1,4 +1,5 @@ /* eslint no-console: off */ +/* eslint-disable @typescript-eslint/explicit-function-return-type, @typescript-eslint/consistent-type-assertions */ import path from "path"; import fs from "fs"; @@ -8,13 +9,14 @@ import express from "express"; import expressStaticGzip from "express-static-gzip"; import compression from 'compression'; import nakedRedirect from 'express-naked-redirect'; -import * as utils from "./utils.js"; +import * as utils from "./utils.ts"; import { version } from '../src/version.js'; -import chalk from 'chalk'; -import { processPathArguments } from "./server/processPaths.js"; -import { setUpGetAvailableHandler } from "./server/getAvailable.js"; -import { setUpGetDatasetHandler } from "./server/getDataset.js"; -import { setUpGetNarrativeHandler } from "./server/getNarrative.js"; +import _chalk from 'chalk'; +const chalk = _chalk as any as import('chalk').Chalk; +import { processPathArguments } from "./server/processPaths.ts"; +import { setUpGetAvailableHandler } from "./server/getAvailable.ts"; +import { setUpGetDatasetHandler } from "./server/getDataset.ts"; +import { setUpGetNarrativeHandler } from "./server/getNarrative.ts"; const require = createRequire(import.meta.url); const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -75,7 +77,7 @@ function defaultRouteHandlers({app, dataPaths}) { const sep = "\n - " return 'Looking for datasets & narratives in the following paths,\n' + '(if there are multiple matches then the first one will be used)' + sep + - Object.entries(dataPaths) + (Object.entries(dataPaths) as [string, Set][]) .map(([p, dataTypes]) => `${p} (${Array.from(dataTypes).join(', ')})`) .join(sep); } @@ -126,7 +128,7 @@ const run = async (args) => { const auspiceBuild = getAuspiceBuild(args.customBuildOnly); utils.verbose(`Serving favicon from "${auspiceBuild.baseDir}"`); utils.verbose(`Serving index and built javascript from "${auspiceBuild.distDir}"`); - app.get("/favicon.png", (req, res) => {res.sendFile(path.join(auspiceBuild.baseDir, "favicon.png"));}); + app.get("/favicon.png", (_req, res) => {res.sendFile(path.join(auspiceBuild.baseDir, "favicon.png"));}); app.use("/dist", expressStaticGzip(auspiceBuild.distDir, { maxAge: '30d', enableBrotli: true, @@ -148,7 +150,7 @@ const run = async (args) => { }); /* this must be the last "get" handler, else the "*" swallows all other requests */ - app.get("*", (req, res) => { + app.get("*", (_req, res) => { res.sendFile(path.join(auspiceBuild.baseDir, "dist/index.html"), {headers: {"Cache-Control": "no-cache, no-store, must-revalidate"}}); }); diff --git a/package.json b/package.json index b119f613c..579fdadc7 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "prepare": "npm run build", "lint": "eslint --max-warnings=0 .", "lint:fix": "eslint --fix .", - "type-check": "tsc", - "type-check:watch": "npm run type-check -- --watch", + "type-check": "tsc && tsc --project cli/tsconfig.json", + "type-check:watch": "tsc --watch", "get-data": "env bash ./scripts/get-data.sh", "fetch-test-data": "./scripts/fetch-test-data", "heroku-postbuild": "npm run build && npm run get-data", diff --git a/test/server-fetch.test.js b/test/server-fetch.test.js index 05326624c..da163d6c3 100644 --- a/test/server-fetch.test.js +++ b/test/server-fetch.test.js @@ -17,7 +17,7 @@ import express from "express"; import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; -import { setUpGetDatasetHandler } from "../cli/server/getDataset.js"; +import { setUpGetDatasetHandler } from "../cli/server/getDataset.ts"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); diff --git a/tsconfig.json b/tsconfig.json index 23bb52501..7723a7abe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,7 @@ Visit https://aka.ms/tsconfig.json for a detailed list of options. /* Modules */ "module": "esnext", /* Specify what module code is generated. Required for dynamic `import()`. */ "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "allowImportingTsExtensions": true, /* Allow .ts extensions in imports (required as cli .ts files are pulled in transitively). */ "types": ["node", "webpack-env", "jest"], /* Specify type package names to be included without being referenced in a source file. */ "resolveJsonModule": true, /* Allow importing .json files. */ @@ -53,5 +54,8 @@ Visit https://aka.ms/tsconfig.json for a detailed list of options. "include": [ "src/**/*", "test/**/*" + ], + "exclude": [ + "cli/**/*" ] } diff --git a/webpack.config.cjs b/webpack.config.cjs index 83b1f4b6a..3b1329f19 100644 --- a/webpack.config.cjs +++ b/webpack.config.cjs @@ -3,7 +3,7 @@ const path = require("path"); const webpack = require("webpack"); const CompressionPlugin = require('compression-webpack-plugin'); const fs = require('fs'); -const utils = require('./cli/utils'); +const utils = require('./cli/utils.ts'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); From 31a91fcfb2b73519e6c8f747945913bdd2805729 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Tue, 9 Jun 2026 12:56:50 +1200 Subject: [PATCH 4/9] [cli] update api code/docs The docs and code had fallen out of sync over the years. * `parseNarrativeFile` was not only deprecated as the docs indicated ("This function is deprecated as of vXXX"), it no longer existed in the codebase. * The docs for the getNarrative route incorrectly indicated the `type` query as optional --- docs/server/api.rst | 54 +++++---------------------------------------- index.js | 1 - 2 files changed, 5 insertions(+), 50 deletions(-) diff --git a/docs/server/api.rst b/docs/server/api.rst index a85c7279a..36adf4afe 100644 --- a/docs/server/api.rst +++ b/docs/server/api.rst @@ -71,27 +71,12 @@ A ``204`` reponse will cause Auspice to show its splash page listing the availab **URL query arguments:** - ``prefix`` (required) - the pathname of the requesting page in Auspice. Use this to determine which narrative to return. -- ``type`` (optional) - the format of the data returned (see below for more information). Current valid values are "json" and "md". If no type is specified the server will use "json" as a default (for backwards compatibility reasons). Requests to this API from the Auspice client are made with ``type=md``. +- ``type`` (required) - this must be ``type=md`` for historical reasons **Response (on success):** -The response depends on the ``type`` specified in the query. +The narrative file is sent to the client (unmodified, to be parsed client-side). -If a markdown format is requested, then the narrative file is sent to the client unmodified to be parsed on the client. - -If a JSON is requested then the narrative file is parsed into JSON format by the server. For Auspice versions prior to v2.18 this was the only expected behavior. The transformation from markdown (i.e. the narrative file itself) to JSON is via the ``parseNarrativeFile()`` function (see below for how this is exported from Auspice for use in other servers). Here, roughly, is the code we use in the auspice server for this transformation: - -.. code:: js - - const fileContents = fs.readFileSync(pathName, 'utf8'); - if (type === "json") { - const blocks = parseNarrative(fileContents); - res.send(JSON.stringify(blocks).replace(/`__. - -``parseNarrativeFile`` -~~~~~~~~~~~~~~~~~~~~~~ - -.. warning:: - - This function is deprecated as of vXXX. You can now send the untransformed contents of the narrative file (markdown) for client-side parsing. See :ref:`above ` for more details. - -**Signature:** - -.. code:: js - - const blocks = parseNarrativeFile(fileContents); - -where ``fileContents`` is a string representation of the narrative Markdown file. - -**Returns:** - -An array of objects, each entry representing a different narrative "block" or "page". Each object has properties - -* ``__html`` -- the HTML to render in the sidebar to form the narrative -* ``dataset`` -- the dataset associated with this block -* ``query`` -- the query associated with this block diff --git a/index.js b/index.js index 749ffe267..be52de20b 100644 --- a/index.js +++ b/index.js @@ -9,4 +9,3 @@ import { convertFromV1 } from "./cli/server/convertJsonSchemas.js"; export { convertFromV1 }; -export const parseNarrativeFile = undefined; From 7b0af966af71b758b576f1832c6beffc59209cfb Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 17:52:08 +1200 Subject: [PATCH 5/9] [cli] Add explicit return types Co-Authored-By: Claude Opus 4.6 --- cli/build.ts | 4 ++-- cli/server/getAvailable.ts | 32 ++++++++++++++++++++++++-------- cli/server/getDataset.ts | 6 ++++-- cli/server/getDatasetHelpers.ts | 14 +++++++------- cli/server/getNarrative.ts | 3 ++- cli/server/processPaths.ts | 8 +++++--- cli/utils.ts | 10 +++++----- 7 files changed, 49 insertions(+), 28 deletions(-) diff --git a/cli/build.ts b/cli/build.ts index 53f0bee14..c86e0267f 100644 --- a/cli/build.ts +++ b/cli/build.ts @@ -30,7 +30,7 @@ const addParser = (parser): void => { subparser.addArgument('--serverless', {action: "storeTrue", help: SUPPRESS}); }; -const run = (args) => { +const run = (args): void => { /* webpack set up */ const extensionPath = args.extend ? path.resolve(args.extend) : undefined; @@ -70,7 +70,7 @@ const run = (args) => { /* Where should the built files be saved? (or sourced??) * This may grow more complex over time */ -function getCustomOutputPath(extensions) { +function getCustomOutputPath(extensions): string | false { if (extensions && path.resolve(__dirname, "..") !== process.cwd()) { return process.cwd(); } diff --git a/cli/server/getAvailable.ts b/cli/server/getAvailable.ts index 7063e5b8a..888a2d689 100644 --- a/cli/server/getAvailable.ts +++ b/cli/server/getAvailable.ts @@ -6,7 +6,22 @@ import { findAvailableSecondTreeOptions } from './getDatasetHelpers.ts'; const readdir = promisify(fs.readdir); -export const getAvailableDatasets = (dir, files) => { +export interface DatasetInfo { + request: string; + v2: boolean; + secondTreeOptions: string[]; + fileType: string; + dir: string; + buildUrl?: string; +} + +export interface NarrativeInfo { + fullPath: string; + request: string; + fileType: string; +} + +export const getAvailableDatasets = (dir, files): DatasetInfo[] => { const datasets = []; /* NOTE: if there are v1 & v2 files with the same name the v2 JSON is * preferentially fetched. E.g. if `zika.json`, `zika_meta.json` and @@ -62,7 +77,7 @@ export const getAvailableDatasets = (dir, files) => { return datasets; }; -export const getAvailableNarratives = (dir, files) => { +export const getAvailableNarratives = (dir, files): NarrativeInfo[] => { return files .filter((file) => file.endsWith(".md") && file!=="README.md") .map((file) => ({ @@ -77,9 +92,10 @@ export const setUpGetAvailableHandler = (dataPaths) => { * Remember that auspice itself only serves local files. * Servers often use their own handler instead of this. */ - return async (_req, res) => { + return async (_req, res): Promise => { utils.log("GET AVAILABLE returning locally available datasets & narratives"); - let resources = [] + let resources: (DatasetInfo | NarrativeInfo)[] = [] + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ for (const [p, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { try { // FUTURE TODO - recurse into subfolders (readdir can do this natively) @@ -103,10 +119,10 @@ export const setUpGetAvailableHandler = (dataPaths) => { }; -function availableResponseStructure(resources) { - const datasets = resources.filter((r) => r.fileType==='dataset') +function availableResponseStructure(resources: (DatasetInfo | NarrativeInfo)[]): {datasets: {request: string, buildUrl?: string, secondTreeOptions?: string[]}[], narratives: {request: string}[]} { + const datasets = resources.filter((r): r is DatasetInfo => r.fileType==='dataset') .map((r) => ({request: r.request, buildUrl: r.buildUrl, secondTreeOptions: r.secondTreeOptions})); - const narratives = resources.filter((r) => r.fileType==='narrative') + const narratives = resources.filter((r): r is NarrativeInfo => r.fileType==='narrative') .map((r) => ({request: r.request})); return {datasets, narratives}; } @@ -114,7 +130,7 @@ function availableResponseStructure(resources) { /** * First match wins */ -function unique(resources) { +function unique(resources: (DatasetInfo | NarrativeInfo)[]): (DatasetInfo | NarrativeInfo)[] { const seen = {dataset: new Set(), narrative: new Set()}; return resources.filter((r) => { if (seen[r.fileType].has(r.request)) { diff --git a/cli/server/getDataset.ts b/cli/server/getDataset.ts index b7e90448b..e9a2b5331 100644 --- a/cli/server/getDataset.ts +++ b/cli/server/getDataset.ts @@ -2,6 +2,7 @@ import { promisify } from 'util'; import path from "path"; import fs from 'fs'; import * as getAvailable from "./getAvailable.ts"; +import type { DatasetInfo } from "./getAvailable.ts"; import * as helpers from "./getDatasetHelpers.ts"; import * as utils from "../utils.ts"; @@ -12,7 +13,7 @@ const readdir = promisify(fs.readdir); * from disk. */ export const setUpGetDatasetHandler = (dataPaths) => { - return async (req, res) => { + return async (req, res): Promise => { let requestInfo; try { @@ -60,12 +61,13 @@ const SIDECARS = { * - object: the paths for (v1) meta/tree dataset JSONs * - array: no matching file found. The array represents all available datasets */ -async function matchDatasetFile(dataPaths, requestInfo) { +async function matchDatasetFile(dataPaths, requestInfo): Promise { /** * Iterate through the dataPaths and return the first match we find * (this "first match wins" approach mirrors that of `getAvailable`) */ const allAvailableDatasets = [] + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ for (const [dir, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { if (!dataTypes.has('datasets')) continue; let files: string[] = []; diff --git a/cli/server/getDatasetHelpers.ts b/cli/server/getDatasetHelpers.ts index 5f9b2ae98..74fcd3da3 100644 --- a/cli/server/getDatasetHelpers.ts +++ b/cli/server/getDatasetHelpers.ts @@ -13,12 +13,12 @@ import queryString from "query-string"; import { convertFromV1 } from "./convertJsonSchemas.js"; import fs from "fs"; -export const handleError = (res, clientMsg, serverMsg="", code=500) => { +export const handleError = (res, clientMsg, serverMsg="", code=500): void => { utils.warn(`${clientMsg} -- ${serverMsg}`); return res.status(code).type("text/plain").send(clientMsg); }; -const splitPrefixIntoParts = (url) => url +const splitPrefixIntoParts = (url): string[] => url .replace(/^\//, '') .replace(/\/$/, '') .split("/"); @@ -31,7 +31,7 @@ const splitPrefixIntoParts = (url) => url * @returns {string[]} ret.parts is the dataset name spit on '/' character * @returns {string} ret.dataType is the dataset type ('dataset', 'root-sequence' etc) */ -export const interpretRequest = (req) => { +export const interpretRequest = (req): {parts: string[], dataType?: string} => { const query = queryString.parse(req.url.split('?')[1]); utils.log(`[GET DATASET] ${Object.entries(query).map(([k,v]) => `${k}: '${v}'`).join(', ')}`); if (!query.prefix) throw new Error("'prefix' not defined in request"); @@ -56,10 +56,10 @@ export const interpretRequest = (req) => { * Given a request for which there is no perfect match, return a close match * if one exists else return false */ -export const closestMatch = (requestedDatasetParts, availableDatasets) => { +export const closestMatch = (requestedDatasetParts, availableDatasets): string | false => { let matchingDatasets = availableDatasets; let i; - const matchDatasetRequest = (d) => d.request.split("/")[i] === requestedDatasetParts[i]; + const matchDatasetRequest = (d): boolean => d.request.split("/")[i] === requestedDatasetParts[i]; // Filter gradually by path fragment, starting from the root for (i = 0; i < requestedDatasetParts.length; i++) { const newMatchingDatasets = matchingDatasets.filter(matchDatasetRequest); @@ -76,7 +76,7 @@ export const closestMatch = (requestedDatasetParts, availableDatasets) => { }; -export const sendJson = async (res, info) => { +export const sendJson = async (res, info): Promise => { if (typeof info.address === "string") { /* In general, JSONs are designed such that no server modifications are needed by the server. This allows us to read as a stream and @@ -111,7 +111,7 @@ export const sendJson = async (res, info) => { * (c) differ from the `currentDatasetUrl` by only 1 part * Note: the "parts" of the URL are formed by splitting it on `"/"` */ -export const findAvailableSecondTreeOptions = (currentDatasetUrl, availableDatasetUrls) => { +export const findAvailableSecondTreeOptions = (currentDatasetUrl, availableDatasetUrls): string[] => { const currentDatasetUrlArr = currentDatasetUrl.split('/'); const availableTangleTreeOptions = availableDatasetUrls.filter((datasetUrl) => { diff --git a/cli/server/getNarrative.ts b/cli/server/getNarrative.ts index 7afa8a637..6fe7fd39c 100644 --- a/cli/server/getNarrative.ts +++ b/cli/server/getNarrative.ts @@ -8,7 +8,7 @@ const readdir = promisify(fs.readdir); export const setUpGetNarrativeHandler = (dataPaths) => { - return async (req, res) => { + return async (req, res): Promise => { utils.log(`GET NARRATIVE request received: ${req.url}`); const query = queryString.parse(req.url.split('?')[1]); const type = query.type ? query.type.toLowerCase() : null; @@ -23,6 +23,7 @@ export const setUpGetNarrativeHandler = (dataPaths) => { .replace(/^\//, "") // remove leading slash .replace(/\/$/, "") // remove ending slash + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ for (const [p, dataTypes] of Object.entries(dataPaths) as [string, Set][]) { if (!dataTypes.has('narratives')) continue; try { diff --git a/cli/server/processPaths.ts b/cli/server/processPaths.ts index d88b2462f..a319ca1a5 100644 --- a/cli/server/processPaths.ts +++ b/cli/server/processPaths.ts @@ -1,5 +1,7 @@ import * as utils from "../utils.ts"; +type AvailableResourceTypes = Set<'datasets' | 'narratives'>; + /** * Returns an object linking (absolute) paths to a set whose members indicate whether * the path should be searched for dataset JSONs, narrative markdown files, or both. @@ -13,7 +15,7 @@ import * as utils from "../utils.ts"; * (via `defaultDataPaths()`), however in my (james) experience it's never worked * well an I recommend providing paths via args. */ -export function processPathArguments(args) { +export function processPathArguments(args): Record { if (args.handlers) { if (args.datasetDir || args.narrativeDir || args.path.length>0) { @@ -42,13 +44,13 @@ export function processPathArguments(args) { utils.warn(`[DEPRECATED] Instead of 'auspice ... --narrativeDir ${args.narrativeDir}' please use 'auspice ... ${args.narrativeDir}' `) } - const dataPaths = Object.fromEntries( + const dataPaths: Record = Object.fromEntries( (args.path.length ? args.path.map(utils.cleanUpPathname) : args.datasetDir ? [utils.cleanUpPathname(args.datasetDir)] : utils.defaultDataPaths() - ).map((p) => [p, new Set(['datasets'])]) + ).map((p: string) => [p, new Set(['datasets'])]) ); for (const narrativePath of diff --git a/cli/utils.ts b/cli/utils.ts index 39a6fcc82..58546e8a2 100644 --- a/cli/utils.ts +++ b/cli/utils.ts @@ -20,7 +20,7 @@ export const log = (msg): void => { export const warn = (msg): void => { console.warn(chalk.yellowBright(`[warning]\t${msg}`)); }; -export const error = (msg): void => { +export const error = (msg): never => { console.error(chalk.redBright(`[error]\t${msg}`)); process.exit(2); }; @@ -29,7 +29,7 @@ const isNpmGlobalInstall = (): boolean => { return __dirname.indexOf("lib/node_modules/auspice") !== -1; }; -export const cleanUpPathname = (pathIn) => { +export const cleanUpPathname = (pathIn): string | undefined => { let pathOut = pathIn; if (!pathOut.endsWith("/")) pathOut += "/"; if (pathOut.startsWith("~")) { @@ -43,7 +43,7 @@ export const cleanUpPathname = (pathIn) => { return pathOut; }; -const getCurrentDirectoriesFor = (type) => { +const getCurrentDirectoriesFor = (type): string | undefined => { const cwd = process.cwd(); const folderName = type === "data" ? "auspice" : "narratives"; if (fs.existsSync(path.join(cwd, folderName))) { @@ -53,13 +53,13 @@ const getCurrentDirectoriesFor = (type) => { }; -export const defaultDataPaths = ({narrative=false} = {}) => { +export const defaultDataPaths = ({narrative=false} = {}): (string | undefined)[] => { return isNpmGlobalInstall() ? [getCurrentDirectoriesFor(narrative ? "narratives" : "data")] : [path.join(path.resolve(__dirname), "..", narrative ? "narratives" : "data")]; } -export const readFilePromise = (fileName) => { +export const readFilePromise = (fileName): Promise => { return new Promise((resolve, reject) => { fs.readFile(fileName, 'utf8', (err, data) => { if (err) { From 7c153eab4ec6070adab924442886cc59d5304c28 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 18:34:17 +1200 Subject: [PATCH 6/9] [dev] Update eslint Triggered by existing warnings: WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree. --- .eslintrc.yaml | 2 +- package-lock.json | 1330 ++++++++++++++++++++++----------------------- package.json | 6 +- 3 files changed, 663 insertions(+), 675 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index b8b666983..6f61a78ba 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -32,7 +32,7 @@ rules: "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "destructuredArrayIgnorePattern": "^_" }] no-use-before-define: off "@typescript-eslint/no-use-before-define": ["error", { "functions": false }] - "@typescript-eslint/no-var-requires": off # Remove this override once all files use ES6 style imports. + "@typescript-eslint/no-require-imports": off # Remove this override once all files use ES6 style imports. prefer-const: ["error", {"destructuring": "all"}] react/no-array-index-key: error react/prop-types: off # Remove this override once all props have been typed using PropTypes or TypeScript. diff --git a/package-lock.json b/package-lock.json index fc1d19de1..90bd5911b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -115,12 +115,12 @@ "@types/lodash": "^4.17.13", "@types/node": "^18.15.11", "@types/webpack-env": "^1.18.2", - "@typescript-eslint/eslint-plugin": "^5.57.0", - "@typescript-eslint/parser": "^5.57.0", + "@typescript-eslint/eslint-plugin": "^8.60.1", + "@typescript-eslint/parser": "^8.60.1", "babel-plugin-transform-import-meta": "^2.3.3", "chai": "^4.1.2", "chai-http": "^4.0.0", - "eslint": "^8.39.0", + "eslint": "^8.57.1", "eslint-plugin-react": "^7.2.1", "eslint-plugin-react-hooks": "^4.0.1", "jest": "^29.5.0", @@ -2102,50 +2102,44 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, "funding": { "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -2164,13 +2158,15 @@ "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 + "dev": true, + "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2181,11 +2177,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -2199,6 +2215,7 @@ "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" }, @@ -2207,10 +2224,11 @@ } }, "node_modules/@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2230,13 +2248,15 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "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", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -2257,10 +2277,12 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "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", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -7167,12 +7189,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, "node_modules/@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -7284,130 +7300,149 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", - "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", + "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/type-utils": "5.59.2", - "@typescript-eslint/utils": "5.59.2", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/type-utils": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.60.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "node_modules/@typescript-eslint/parser": { + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", + "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "debug": "^4.4.3" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", - "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", + "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.60.1", + "@typescript-eslint/types": "^8.60.1", + "debug": "^4.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", + "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", + "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", - "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", + "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.2", - "@typescript-eslint/utils": "5.59.2", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", + "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", "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": { "type": "opencollective", @@ -7415,65 +7450,76 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", + "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@typescript-eslint/project-service": "8.60.1", + "@typescript-eslint/tsconfig-utils": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": "18 || 20 || >=22" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, + "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz", + "integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==", "dev": true, "license": "ISC", "bin": { @@ -7484,55 +7530,41 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", + "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", + "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.59.2", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.60.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -7540,17 +7572,25 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "dev": true, + "license": "ISC" + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -7750,6 +7790,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -9615,9 +9656,10 @@ } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -9658,7 +9700,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -9757,18 +9800,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -10153,27 +10184,30 @@ } }, "node_modules/eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "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.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -10181,22 +10215,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "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.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -10308,6 +10339,19 @@ "node": ">=8.0.0" } }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -10385,10 +10429,11 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -10400,23 +10445,12 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -10461,6 +10495,16 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -10483,19 +10527,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint/node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -10511,23 +10542,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10558,15 +10572,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -10591,18 +10596,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -10616,27 +10609,16 @@ } }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "eslint-visitor-keys": "^3.4.1" }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -10909,34 +10891,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -11484,11 +11438,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true + "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/gzip-size": { "version": "5.1.1", @@ -11816,10 +11771,11 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -14249,16 +14205,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -14438,6 +14384,20 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -14659,15 +14619,6 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -14852,12 +14803,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -15172,6 +15117,24 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/outer-product": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/outer-product/-/outer-product-0.0.4.tgz", @@ -15566,6 +15529,16 @@ "node": ">=0.10.0" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -17187,6 +17160,54 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tldts": { "version": "6.1.86", "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", @@ -17254,6 +17275,19 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -17317,27 +17351,19 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, - "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/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^1.8.1" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">= 6" - }, - "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" + "node": ">= 0.8.0" } }, - "node_modules/tsutils/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/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -19546,37 +19572,29 @@ "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "requires": { - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true - } + "eslint-visitor-keys": "^3.4.3" } }, "@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true }, "@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -19592,18 +19610,24 @@ "dev": true }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, "js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -19618,9 +19642,9 @@ } }, "@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true }, "@hot-loader/react-dom": { @@ -19635,13 +19659,13 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -19652,9 +19676,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "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==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -22114,12 +22138,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -22226,156 +22244,166 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", - "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", + "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/type-utils": "5.59.2", - "@typescript-eslint/utils": "5.59.2", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true - } + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/type-utils": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" } }, "@typescript-eslint/parser": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", - "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", + "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "debug": "^4.4.3" + } + }, + "@typescript-eslint/project-service": { + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", + "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", + "dev": true, + "requires": { + "@typescript-eslint/tsconfig-utils": "^8.60.1", + "@typescript-eslint/types": "^8.60.1", + "debug": "^4.4.3" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", + "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1" } }, + "@typescript-eslint/tsconfig-utils": { + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", + "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "dev": true, + "requires": {} + }, "@typescript-eslint/type-utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", - "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", + "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.2", - "@typescript-eslint/utils": "5.59.2", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1", + "@typescript-eslint/utils": "8.60.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" } }, "@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", + "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", + "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@typescript-eslint/project-service": "8.60.1", + "@typescript-eslint/tsconfig-utils": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/visitor-keys": "8.60.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "requires": { + "balanced-match": "^4.0.2" + } + }, + "minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "brace-expansion": "^5.0.5" } }, "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz", + "integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==", "dev": true } } }, "@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", + "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", "dev": true, "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "dependencies": { - "semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true - } + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.60.1", + "@typescript-eslint/types": "8.60.1", + "@typescript-eslint/typescript-estree": "8.60.1" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "8.60.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", + "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.2", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.60.1", + "eslint-visitor-keys": "^5.0.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true } } }, + "@ungap/structured-clone": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -23930,9 +23958,9 @@ } }, "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "requires": { "ms": "^2.1.3" } @@ -24027,15 +24055,6 @@ "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -24323,27 +24342,28 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -24351,22 +24371,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "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.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -24423,21 +24440,15 @@ "dev": true }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, - "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true - }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", @@ -24469,6 +24480,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -24484,16 +24501,6 @@ "argparse": "^2.0.1" } }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -24503,20 +24510,6 @@ "p-locate": "^5.0.0" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -24535,12 +24528,6 @@ "p-limit": "^3.0.2" } }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -24559,15 +24546,6 @@ "has-flag": "^4.0.0" } }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -24651,23 +24629,21 @@ "estraverse": "^4.1.1" } }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, "espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true - } + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -24862,30 +24838,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -25272,10 +25224,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "gzip-size": { @@ -25499,9 +25451,9 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true }, "immer": { @@ -27273,12 +27225,6 @@ } } }, - "js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -27403,6 +27349,16 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -27579,12 +27535,6 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -27721,12 +27671,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -27939,6 +27883,20 @@ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" }, + "optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + } + }, "outer-product": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/outer-product/-/outer-product-0.0.4.tgz", @@ -28223,6 +28181,12 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "pretty-error": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", @@ -29410,6 +29374,31 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "dependencies": { + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true + } + } + }, "tldts": { "version": "6.1.86", "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", @@ -29464,6 +29453,13 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "requires": {} + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -29501,21 +29497,13 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } + "prelude-ls": "^1.2.1" } }, "type-detect": { diff --git a/package.json b/package.json index 579fdadc7..703092c3d 100644 --- a/package.json +++ b/package.json @@ -138,12 +138,12 @@ "@types/lodash": "^4.17.13", "@types/node": "^18.15.11", "@types/webpack-env": "^1.18.2", - "@typescript-eslint/eslint-plugin": "^5.57.0", - "@typescript-eslint/parser": "^5.57.0", + "@typescript-eslint/eslint-plugin": "^8.60.1", + "@typescript-eslint/parser": "^8.60.1", "babel-plugin-transform-import-meta": "^2.3.3", "chai": "^4.1.2", "chai-http": "^4.0.0", - "eslint": "^8.39.0", + "eslint": "^8.57.1", "eslint-plugin-react": "^7.2.1", "eslint-plugin-react-hooks": "^4.0.1", "jest": "^29.5.0", From 7229793b6f5e096d33734bf3415b0d8603193906 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 18:44:27 +1200 Subject: [PATCH 7/9] eslint fixes Errors were new since version bump in parent commit --- .eslintrc.yaml | 2 +- src/actions/updateMetadata/updateMetadata.ts | 2 +- src/components/controls/animation-controls.js | 5 ++--- src/components/controls/filter.js | 1 - src/components/controls/language.js | 2 +- src/components/info/byline.js | 2 +- src/components/map/mapHelpersLatLong.js | 6 +++--- src/components/tree/tree.tsx | 5 ++++- src/util/entropy.js | 19 ++++++++++--------- src/util/parseNarrative.js | 2 +- src/util/treeJsonProcessing.ts | 1 + src/util/treeMiscHelpers.js | 2 +- src/util/treeVisibilityHelpers.js | 4 ++-- test/request_urls.js | 1 + 14 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 6f61a78ba..88673e93f 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -29,7 +29,7 @@ rules: # Not possible while strictNullChecks is disabled in tsconfig. "@typescript-eslint/no-non-null-assertion": "error" no-unused-vars: off - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "destructuredArrayIgnorePattern": "^_" }] + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "destructuredArrayIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_"}] no-use-before-define: off "@typescript-eslint/no-use-before-define": ["error", { "functions": false }] "@typescript-eslint/no-require-imports": off # Remove this override once all files use ES6 style imports. diff --git a/src/actions/updateMetadata/updateMetadata.ts b/src/actions/updateMetadata/updateMetadata.ts index f9bb84a3b..f00942a4f 100644 --- a/src/actions/updateMetadata/updateMetadata.ts +++ b/src/actions/updateMetadata/updateMetadata.ts @@ -128,7 +128,7 @@ function _reduxControls( /* geographic resolutions */ if (newMetadata.geographic?.length && !state.panelsAvailable.includes("map")) { - updates.panelsAvailable = [...state.panelsAvailable, "map"], + updates.panelsAvailable = [...state.panelsAvailable, "map"]; updates.panelsToDisplay = [...updates.panelsAvailable]; updates.canTogglePanelLayout = hasMultipleGridPanels(updates.panelsAvailable); updates.geoResolution = newMetadata.geographic[0].key; diff --git a/src/components/controls/animation-controls.js b/src/components/controls/animation-controls.js index 203aabc74..0f782f42c 100644 --- a/src/components/controls/animation-controls.js +++ b/src/components/controls/animation-controls.js @@ -21,9 +21,8 @@ class AnimationControls extends React.Component { return ( { - this.props.animationPlayPauseButton === "Play" ? - this.props.dispatch({type: MAP_ANIMATION_PLAY_PAUSE_BUTTON, data: "Pause"}) : - this.props.dispatch({type: MAP_ANIMATION_PLAY_PAUSE_BUTTON, data: "Play"}); + const newState = this.props.animationPlayPauseButton === "Play" ? "Pause" : "Play"; + this.props.dispatch({ type: MAP_ANIMATION_PLAY_PAUSE_BUTTON, data: newState }); }} > diff --git a/src/components/controls/filter.js b/src/components/controls/filter.js index f27e949b3..3c3f9069a 100644 --- a/src/components/controls/filter.js +++ b/src/components/controls/filter.js @@ -82,7 +82,6 @@ class FilterData extends React.Component { ...(this.props.totalStateCountsSecondTree?.[traitName]?.keys() || []), ]); - this.props.totalStateCounts[traitName]; const traitTitle = this.getFilterTitle(traitName); const filterValuesCurrentlyActive = new Set((this.props.activeFilters[traitName] || []).filter((x) => x.active).map((x) => x.value)); for (const traitValue of Array.from(traitData).sort()) { diff --git a/src/components/controls/language.js b/src/components/controls/language.js index 452031ac8..dea408410 100644 --- a/src/components/controls/language.js +++ b/src/components/controls/language.js @@ -20,7 +20,7 @@ class Language extends React.Component { try { const res = await import(/* webpackMode: "lazy-once" */ `../../locales/${lang}/${ns}.json`); i18n.addResourceBundle(lang, ns, res.default); - } catch (err) { + } catch (_err) { console.error(`Language ${lang} not found!`); } } diff --git a/src/components/info/byline.js b/src/components/info/byline.js index cb695d2b9..33da38f80 100644 --- a/src/components/info/byline.js +++ b/src/components/info/byline.js @@ -172,7 +172,7 @@ function parseUrl(potentialUrl) { try { const urlObj = new URL(potentialUrl); return urlObj.href; - } catch (err) { + } catch (_err) { return false; } } diff --git a/src/components/map/mapHelpersLatLong.js b/src/components/map/mapHelpersLatLong.js index 09abe4b51..b51162674 100644 --- a/src/components/map/mapHelpersLatLong.js +++ b/src/components/map/mapHelpersLatLong.js @@ -221,13 +221,13 @@ const maybeConstructTransmissionEvent = ( try { latOrig = demeToLatLongs[nodeLocation].latitude; longOrig = demeToLatLongs[nodeLocation].longitude; - } catch (e) { + } catch (_err) { demesMissingLatLongs.add(nodeLocation); } try { latDest = demeToLatLongs[childLocation].latitude; longDest = demeToLatLongs[childLocation].longitude; - } catch (e) { + } catch (_err) { demesMissingLatLongs.add(childLocation); } @@ -503,7 +503,7 @@ const updateTransmissionDataColAndVis = (transmissionData, transmissionIndices, transmissionDataCopy[index].color = col; transmissionDataCopy[index].visible = vis; }); - } catch (err) { + } catch (_err) { console.warn(`Error trying to access ${id} in transmissionIndices. Map transmissions may be wrong.`); } }); diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx index c615c2111..bd6fb68d6 100644 --- a/src/components/tree/tree.tsx +++ b/src/components/tree/tree.tsx @@ -138,7 +138,10 @@ export class TreeComponent extends React.Component {mainTree ? this.domRefs.mainTree = c : this.domRefs.secondTree = c;}} + ref={(c): void => { + if (mainTree) { this.domRefs.mainTree = c; } + else { this.domRefs.secondTree = c; } + }} /> diff --git a/src/util/entropy.js b/src/util/entropy.js index 076771e6d..b9aa76edc 100644 --- a/src/util/entropy.js +++ b/src/util/entropy.js @@ -29,6 +29,7 @@ const calcMutationCounts = (nodes, visibility, selectedCds) => { mutations?.[cdsName]?.forEach((m) => { const {from, to, pos} = parseMutation(m); if (valid(from, to, isAA)) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions sparse[pos] ? sparse[pos]++ : sparse[pos] = 1; } }); @@ -39,7 +40,7 @@ const calcMutationCounts = (nodes, visibility, selectedCds) => { for (let i = 0; i < sparse.length; i++) { if (!sparse[i]) {continue;} if (sparse[i] > m) {m = sparse[i];} - counts[j] = isAA ? + counts[j] = isAA ? {codon: parseInt(i, 10), y: sparse[i]} : {x: i, y: sparse[i]}; /* TODO reset y scale in D3 or compute entropy */ j++; @@ -118,7 +119,7 @@ const calcEntropy = (nodes, visibility, selectedCds) => { counts[position][anc_state[position]] = nUnobserved; } } - + let s = 0; /* shannon entropy */ for (const count of Object.values(counts[position])) { const a = count / visibleTips; @@ -177,10 +178,10 @@ export function getCdsByName(genomeMap, name) { * codon). * If _either_ of the rangeGenome positions are _beyond_ the CDS then we return * the entire rangeLocal of the cds + set the flag `valid` to false. - * + * * For wrapping genes, the UI forces the rangeGenome (i.e. the zoomCoordinates) * to be on either side of the origin, and we maintain thus assumption here. - * + * * Returns [rangeLocalInView:rangeLocal, valid:bool] */ export function getCdsRangeLocalFromRangeGenome(cds, rangeGenome) { @@ -203,12 +204,12 @@ export function getCdsRangeLocalFromRangeGenome(cds, rangeGenome) { * The general approach is to visit the segments in the order they appear, * i.e. in the context of the strand it's always 5' -> 3' but for -ve strand * CDSs this appears 3' -> 5' in the context of the +ve strand. Once we find - * an intersection we can work out the appropriate local coordinate. + * an intersection we can work out the appropriate local coordinate. * Remember that zoomStart/End are reversed if the CDS is wrapping! */ let prevSeg; for (const seg of segments) { - /* If the zoom start (5') is inside the segment, then we know one of the local bounds */ + /* If the zoom start (5') is inside the segment, then we know one of the local bounds */ if (seg.rangeGenome[0]<=zoomStart && seg.rangeGenome[1]>=zoomStart) { if (positive) { const delta = zoomStart - seg.rangeGenome[0]; @@ -217,8 +218,8 @@ export function getCdsRangeLocalFromRangeGenome(cds, rangeGenome) { const delta = zoomStart - seg.rangeGenome[0]; cdsLocalEnd = seg.rangeLocal[1] - delta; } - } - /* If the zoom end (3') is inside the segment, then we know one of the local bounds */ + } + /* If the zoom end (3') is inside the segment, then we know one of the local bounds */ if (seg.rangeGenome[0]<=zoomEnd && seg.rangeGenome[1]>=zoomEnd) { if (positive) { const delta = zoomEnd - seg.rangeGenome[0]; @@ -349,4 +350,4 @@ export function nucleotideToAaPosition(genomeMap, nucPos) { } }) return matches; -} \ No newline at end of file +} diff --git a/src/util/parseNarrative.js b/src/util/parseNarrative.js index f5cb3d5bc..378ee9185 100644 --- a/src/util/parseNarrative.js +++ b/src/util/parseNarrative.js @@ -54,7 +54,7 @@ function parseUrl(urlString, fallbackDataset=false) { let url, dataset; try { url = new URL(urlString); - } catch (err) { + } catch (_err) { if (fallbackDataset) { console.error(`Couldn't parse the URL "${urlString}". Falling back to "${fallbackDataset}".`); return {dataset: fallbackDataset, query: ""}; diff --git a/src/util/treeJsonProcessing.ts b/src/util/treeJsonProcessing.ts index 6ff2de6b1..9bb1b4984 100644 --- a/src/util/treeJsonProcessing.ts +++ b/src/util/treeJsonProcessing.ts @@ -164,6 +164,7 @@ const collectObservedMutations = (nodesArray: ReduxNode[]): Mutations => { if (!n.branch_attrs || !n.branch_attrs.mutations) return; Object.entries(n.branch_attrs.mutations).forEach(([gene, muts]) => { muts.forEach((mut) => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions mutations[`${gene}:${mut}`] ? mutations[`${gene}:${mut}`]++ : (mutations[`${gene}:${mut}`] = 1); }); }); diff --git a/src/util/treeMiscHelpers.js b/src/util/treeMiscHelpers.js index 6960bd8c9..117c6ab25 100644 --- a/src/util/treeMiscHelpers.js +++ b/src/util/treeMiscHelpers.js @@ -103,7 +103,7 @@ function validateUrl(url) { if (url.startsWith("https_")) url = url.replace("https_", "https:"); const urlObj = new URL(url); return urlObj.href; - } catch (err) { + } catch (_err) { console.warn(`Dataset provided the invalid URL ${url}`); return undefined; } diff --git a/src/util/treeVisibilityHelpers.js b/src/util/treeVisibilityHelpers.js index 20987d265..101447021 100644 --- a/src/util/treeVisibilityHelpers.js +++ b/src/util/treeVisibilityHelpers.js @@ -25,7 +25,7 @@ export const strainNameToIdx = (nodes, name) => { /** * Find the node with the given label name & value * NOTE: if there are multiple nodes with the same label then `null` is returned - * + * * @param {Array} nodes tree nodes (flat) * @param {string} labelName label name * @param {string} labelValue label value @@ -157,7 +157,7 @@ const getInView = (tree) => { let inView; try { inView = tree.nodes.map((d) => d.shell.inView); - } catch (e) { + } catch (_err) { /* edge case: this fn may be called before the shell structure of the nodes * has been created (i.e. phyloTree's not run yet). In this case, it's * safe to assume that everything's in view */ diff --git a/test/request_urls.js b/test/request_urls.js index 8b96b1d0f..2a82923dd 100644 --- a/test/request_urls.js +++ b/test/request_urls.js @@ -14,6 +14,7 @@ const isValidURLCallback = (url) => { chai.request(url) .get('') .end((err, res) => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions expect(err).to.be.null; expect(res).to.have.status(200); done(); // Call done to signal callback end From 67343cfbc99119d2671e21220f10c5ee9b68ebfa Mon Sep 17 00:00:00 2001 From: james hadfield Date: Mon, 8 Jun 2026 18:57:35 +1200 Subject: [PATCH 8/9] [tests] Remove unused test This is an old and now unused test that's been fully superseded by the Playwright smoke tests. It was the only test that used "chai" (and "mocha", although that wasn't listed as a dep). I only noticed this as the eslint version bump flagged up an error in the test file --- package-lock.json | 451 ------------------------------------------- package.json | 2 - test/request_urls.js | 27 --- 3 files changed, 480 deletions(-) delete mode 100644 test/request_urls.js diff --git a/package-lock.json b/package-lock.json index 90bd5911b..1d3eadea3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,8 +118,6 @@ "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.60.1", "babel-plugin-transform-import-meta": "^2.3.3", - "chai": "^4.1.2", - "chai-http": "^4.0.0", "eslint": "^8.57.1", "eslint-plugin-react": "^7.2.1", "eslint-plugin-react-hooks": "^4.0.1", @@ -6556,18 +6554,6 @@ "@babel/types": "^7.20.7" } }, - "node_modules/@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "node_modules/@types/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true - }, "node_modules/@types/d3-array": { "version": "2.12.7", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.7.tgz", @@ -7201,16 +7187,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/superagent": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", - "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", - "dev": true, - "dependencies": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, "node_modules/@types/tapable": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", @@ -8078,26 +8054,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -8796,62 +8757,6 @@ "node": ">=0.8" } }, - "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-http": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", - "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", - "dev": true, - "dependencies": { - "@types/chai": "4", - "@types/superagent": "^3.8.3", - "cookiejar": "^2.1.1", - "is-ip": "^2.0.0", - "methods": "^1.1.2", - "qs": "^6.5.1", - "superagent": "^3.7.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-http/node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-http/node_modules/is-ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", - "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", - "dev": true, - "dependencies": { - "ip-regex": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chain-function": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz", @@ -8879,15 +8784,6 @@ "node": ">=10" } }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/check-types": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", @@ -9048,18 +8944,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -9073,12 +8957,6 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -9239,12 +9117,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true - }, "node_modules/copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -9684,18 +9556,6 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -9744,15 +9604,6 @@ "node": ">=6" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -10880,12 +10731,6 @@ } ] }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -11081,55 +10926,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/form-data": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/form-data/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", - "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", - "dev": true, - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -11247,16 +11043,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -15327,15 +15113,6 @@ "node": ">=8" } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -16896,37 +16673,6 @@ "stylis": "^3.5.0" } }, - "node_modules/superagent": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", - "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", - "dev": true, - "dependencies": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.3.5" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/superagent/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -21605,18 +21351,6 @@ "@babel/types": "^7.20.7" } }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "@types/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true - }, "@types/d3-array": { "version": "2.12.7", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-2.12.7.tgz", @@ -22149,16 +21883,6 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, - "@types/superagent": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", - "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", - "dev": true, - "requires": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, "@types/tapable": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", @@ -22768,23 +22492,11 @@ "is-string": "^1.0.7" } }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -23285,52 +22997,6 @@ } } }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-http": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", - "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", - "dev": true, - "requires": { - "@types/chai": "4", - "@types/superagent": "^3.8.3", - "cookiejar": "^2.1.1", - "is-ip": "^2.0.0", - "methods": "^1.1.2", - "qs": "^6.5.1", - "superagent": "^3.7.0" - }, - "dependencies": { - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "is-ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", - "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", - "dev": true, - "requires": { - "ip-regex": "^2.0.0" - } - } - } - }, "chain-function": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz", @@ -23352,12 +23018,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, "check-types": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", @@ -23476,15 +23136,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -23495,12 +23146,6 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -23604,12 +23249,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true - }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -23977,15 +23616,6 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -24021,12 +23651,6 @@ "rimraf": "^2.6.3" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -24827,12 +24451,6 @@ "mime": "^1.3.4" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -24987,34 +24605,6 @@ "is-callable": "^1.1.3" } }, - "form-data": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", - "dev": true - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -25093,12 +24683,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true - }, "get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -28038,12 +27622,6 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, "picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -29195,35 +28773,6 @@ "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", "requires": {} }, - "superagent": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", - "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "dev": true, - "requires": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/package.json b/package.json index 703092c3d..c3271b94d 100644 --- a/package.json +++ b/package.json @@ -141,8 +141,6 @@ "@typescript-eslint/eslint-plugin": "^8.60.1", "@typescript-eslint/parser": "^8.60.1", "babel-plugin-transform-import-meta": "^2.3.3", - "chai": "^4.1.2", - "chai-http": "^4.0.0", "eslint": "^8.57.1", "eslint-plugin-react": "^7.2.1", "eslint-plugin-react-hooks": "^4.0.1", diff --git a/test/request_urls.js b/test/request_urls.js deleted file mode 100644 index 2a82923dd..000000000 --- a/test/request_urls.js +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint no-unused-expressions: off */ - -/* HOW TO RUN THESE TESTS? -npx mocha -*/ - -const chai = require('chai'); -chai.use(require('chai-http')); - -const expect = chai.expect; - -const isValidURLCallback = (url) => { - return (done) => { - chai.request(url) - .get('') - .end((err, res) => { - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - expect(err).to.be.null; - expect(res).to.have.status(200); - done(); // Call done to signal callback end - }); - }; -}; - - -it('loads the spash page as expected', isValidURLCallback('http://localhost:4000')); -it('loads /zika', isValidURLCallback('http://localhost:4000/zika')); From 649c636010e2ab6e66cdffebc5832fcdbcdef23b Mon Sep 17 00:00:00 2001 From: james hadfield Date: Tue, 9 Jun 2026 11:57:26 +1200 Subject: [PATCH 9/9] [dev] remove unused npm script (This was from an ancient method of deploying auspice) --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index c3271b94d..ce3978220 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "get-data": "env bash ./scripts/get-data.sh", "fetch-test-data": "./scripts/fetch-test-data", "heroku-postbuild": "npm run build && npm run get-data", - "gzip-and-upload": "env bash ./scripts/gzip-and-upload.sh", "test": "jest test/*.js test/*.ts", "smoke-test": "NODE_ENV=test ENV=dev npx playwright test", "diff-lang": "./scripts/diff-lang.js"