From 80c9d5dac048f819506f21ac968eec985c349ab0 Mon Sep 17 00:00:00 2001 From: Phil Reese Date: Tue, 4 Feb 2025 09:04:24 -0500 Subject: [PATCH] EREGCSC-1509 -- ESLint Enhancements (#1535) * chore: remove prettier, update ESLint rules * chore: begin working through ESLint issues * chore: bump javascript-test checkout action ver * chore: continue formatting Vue/JS based on ESLint rules * chore: eslint-global-rules file at project root * chore: fix all fixable things * chore: remove prettier from package.json * chore: add eslint make commant * chore: add ESLint action * chore: add actual yml file * chore: tweak job name in yml * fix: first fixes due to ESLint action * chore: add eslint to cdk-eregs package.json * chore: more global eslint rules up one dir * chore: add basic eslint config to CDK directory * chore: first pass as CDK linting in GitHub action * fix: tweak eslint github action pathing * chore: remove debug flag from cdk eslint cmd * test: tweak Cypress search test suite * fix: remove duplicate rule * chore: small tweak to cdk eslint config * chore: indent rules * chore: make four-space indent mandatory for js/vue only * chore: update make file * chore: add editorconfig for js/ts spacing diff default * chore: update code comment * chore: update cdk-eregs ESLint to handle JS better * chore: add ESLint JS rules to front end eslint config also update lib vers * chore: further linting and formatting * chore: update ESLint documentation * fix: relative path in README to another md file * fix: relative path in README to another md file * chore: disable CDK linting for now --- .editorconfig | 12 + .github/workflows/eslint-linting.yml | 37 + .github/workflows/javascript-test.yml | 4 +- README.md | 22 + cdk-eregs/eslint.config.mjs | 22 + cdk-eregs/jest.config.js | 12 +- cdk-eregs/package-lock.json | 1139 ++++++++++++++++- cdk-eregs/package.json | 9 +- eslint-global-rules.mjs | 10 + solution/LINTING.md | 70 + solution/Makefile | 12 + solution/ui/e2e/cypress/e2e/search.spec.cy.js | 4 +- solution/ui/regulations/README.md | 108 -- solution/ui/regulations/composables/counts.js | 2 +- .../src/components/CollapseButton.vue | 20 +- .../src/components/Collapsible.vue | 2 +- .../src/components/Dropdown.vue | 70 +- .../src/components/DropdownContent.vue | 22 +- .../src/components/DropdownHeader.vue | 12 +- .../src/components/DropdownItem.vue | 16 +- .../src/components/PartButton.vue | 22 +- .../src/components/RecentResources.vue | 8 +- .../components/RecentSupplementalContent.vue | 5 +- .../src/components/RelatedRule.vue | 7 +- .../src/components/RelatedRuleList.vue | 13 +- .../src/components/RelatedRules.vue | 26 +- .../src/components/ShowMoreButton.vue | 2 +- .../src/components/SupplementalContent.vue | 18 +- .../SupplementalContentCategory.vue | 29 +- .../components/SupplementalContentList.vue | 33 +- .../components/SupplementalContentObject.vue | 20 +- .../src/components/TableComponent.vue | 5 +- .../src/components/ViewResourcesLink.vue | 22 +- .../src/components/index.js | 2 - .../reader-sidebar/InternalDocsContainer.vue | 3 +- .../shared-components/LeftNavCollapse.vue | 16 +- .../shared-components/ResultsItem.vue | 16 +- .../Statutes/TableCaption.vue | 17 +- .../Statutes/table-elements/BodyCell.vue | 5 +- .../Statutes/utils/dateMethods.js | 4 +- .../Statutes/utils/urlMethods.js | 4 +- .../components/shared-components/TOC/Toc.vue | 6 +- .../TOC/TocContainer.test.js | 2 +- .../shared-components/TOC/TocContainer.vue | 6 +- .../shared-components/TOC/TocSubchapter.vue | 2 +- .../shared-components/TOC/TocTitle.vue | 6 +- .../results-item-parts/DivisionLabel.vue | 5 +- .../results-item-parts/DocTypeLabel.vue | 4 +- .../results-item-parts/RelatedSections.vue | 14 +- .../src/components/tooltips/ActionBtn.vue | 9 +- .../src/components/tooltips/CopyCitation.vue | 10 +- .../src/components/tooltips/GovInfoLinks.vue | 6 +- .../components/tooltips/TooltipContainer.vue | 14 +- .../eregs-component-lib/watch-dist.js | 2 +- .../eregs-vite/src/components/Banner.vue | 6 +- .../eregs-vite/src/components/JumpTo.vue | 22 +- .../src/components/SearchContinueResearch.vue | 32 +- .../src/components/SearchErrorMsg.vue | 30 +- .../eregs-vite/src/components/SearchInput.vue | 16 +- .../eregs-vite/src/components/SignInCTA.vue | 15 +- .../eregs-vite/src/components/SignInLink.vue | 6 +- .../src/components/dropdowns/Categories.vue | 7 +- .../dropdowns/FetchItemsContainer.vue | 2 +- .../components/dropdowns/GenericDropdown.vue | 2 +- .../src/components/dropdowns/Subjects.vue | 2 +- .../src/components/header/HeaderComponent.vue | 12 +- .../components/header/HeaderDropdownMenu.vue | 2 +- .../src/components/header/HeaderLinks.vue | 2 +- .../src/components/header/HeaderSearch.vue | 10 +- .../components/header/HeaderUserWidget.vue | 9 +- .../src/components/navigation/NavBtn.vue | 2 +- .../src/components/pagination/PageNumber.vue | 23 +- .../pagination/PaginationController.vue | 28 +- .../subjects/DocumentTypeSelector.vue | 6 +- .../src/components/subjects/PolicyResults.vue | 63 +- .../components/subjects/PolicySelections.vue | 4 +- .../src/components/subjects/PolicySidebar.vue | 20 +- .../subjects/SelectedSubjectChip.vue | 10 +- .../subjects/SelectedSubjectHeading.vue | 3 +- .../components/subjects/SubjectLanding.vue | 11 +- .../subjects/SubjectSelector.test.js | 2 +- .../components/subjects/SubjectSelector.vue | 14 +- .../src/components/svgs/user-icon.vue | 6 +- .../ui/regulations/eregs-vite/src/main.js | 4 +- .../eregs-vite/src/views/CacheExplorer.vue | 44 +- .../eregs-vite/src/views/Search.vue | 13 +- .../eregs-vite/src/views/Statutes.vue | 6 +- .../eregs-vite/src/views/Subjects.vue | 10 +- solution/ui/regulations/eslint.config.js | 44 +- .../ui/regulations/msw/mockServiceWorker.js | 441 ++++--- solution/ui/regulations/msw/mocks/handlers.js | 6 +- solution/ui/regulations/package-lock.json | 457 +++---- solution/ui/regulations/package.json | 14 +- solution/ui/regulations/prettier.config.js | 12 - solution/ui/regulations/utilities/api.js | 2 +- solution/ui/regulations/utilities/api.test.js | 2 +- .../ui/regulations/utilities/utils.test.js | 2 +- 97 files changed, 2279 insertions(+), 1113 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/eslint-linting.yml create mode 100644 cdk-eregs/eslint.config.mjs create mode 100644 eslint-global-rules.mjs create mode 100644 solution/LINTING.md delete mode 100644 solution/ui/regulations/README.md delete mode 100644 solution/ui/regulations/prettier.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..7d070d6ca9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# top-most EditorConfig file +root = true + +# 2 space indentation for .ts files +[*.ts] +indent_style = space +indent_size = 2 + +# 4 space indentation for .js/.cjs/.mjs files +[*.{js,cjs,mjs}] +indent_style = space +indent_size = 4 diff --git a/.github/workflows/eslint-linting.yml b/.github/workflows/eslint-linting.yml new file mode 100644 index 0000000000..1e00f38214 --- /dev/null +++ b/.github/workflows/eslint-linting.yml @@ -0,0 +1,37 @@ +name: "ESLint" + +on: + pull_request: + types: [ opened, synchronize, reopened ] + push: + branches: + - main + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + lint-eslint: + runs-on: ubuntu-22.04 + steps: + # Checkout the code + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + # Setup node environment + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + # Execute linting + - name: Run ESLint on front end + if: success() + working-directory: ./solution + run: | + make eslint-frontend + - name: Run ESLint on CDK TS files + # if: success() + if: false # Disable CDK linting for now + working-directory: ./solution + run: | + make eslint-cdk diff --git a/.github/workflows/javascript-test.yml b/.github/workflows/javascript-test.yml index bea65c0bf6..f8900447d3 100644 --- a/.github/workflows/javascript-test.yml +++ b/.github/workflows/javascript-test.yml @@ -17,12 +17,12 @@ jobs: steps: # Checkout the code - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true # Setup node environment - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 # Install Front End dependencies diff --git a/README.md b/README.md index d02922bd5c..89a9914478 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,28 @@ Before running the tests for the first time, you may need to install Cypress dep 4. For Python unit tests, run `make test.pytest`. This will run our Python unittest using pytest. 5. For Vitest run `make test.vitest`. This will run our Vitest suite. +## Linting and Formatting + +#### ESLint + +This project utilizes ESLint to maintain high code quality and enforce consistent coding styles across both the frontend (JavaScript) and infrastructure (TypeScript) components. ESLint helps identify potential issues early, improving code readability and reducing the likelihood of runtime errors. + +We leverage a shared ESLint configuration (`eslint-global-rules.mjs` file) at the project root to define a baseline of rules applicable to both the frontend and infrastructure code. This promotes consistency in fundamental coding practices across the entire project. + +Each application (frontend and CDK) also maintains its own dedicated ESLint configuration file. This allows us to tailor rules and plugins specifically to the nuances of JavaScript and TypeScript, respectively, while still adhering to the core shared principles. This approach ensures that each part of the project benefits from the appropriate linting rules for its language and context. + +To run ESLint, execute the following commands from the project root: + +``` +// lint the frontend JS +make eslint-frontend + +// lint CDK TS +make eslint-cdk +``` + +For more information on ESLint, as well as resources to help integrate ESLint into your text editor, see [LINTING.md](solution/LINTING.md). + ## Working with assets Navigate to project root. diff --git a/cdk-eregs/eslint.config.mjs b/cdk-eregs/eslint.config.mjs new file mode 100644 index 0000000000..94e1b6eb2b --- /dev/null +++ b/cdk-eregs/eslint.config.mjs @@ -0,0 +1,22 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; +import globalConfig from "../eslint-global-rules.mjs"; + +export default [ + { files: ["**/*.{js,mjs,cjs,ts}"] }, + { languageOptions: { globals: globals.browser } }, + ...tseslint.configs.recommended, + { + files: ["**/*.js"], + rules: { + ...pluginJs.configs.recommended.rules, + "indent": ["error", 4, { SwitchCase: 1 }], + } + }, + { + rules: { + ...globalConfig, + }, + }, +]; diff --git a/cdk-eregs/jest.config.js b/cdk-eregs/jest.config.js index 08263b8954..04c32d0550 100644 --- a/cdk-eregs/jest.config.js +++ b/cdk-eregs/jest.config.js @@ -1,8 +1,8 @@ module.exports = { - testEnvironment: 'node', - roots: ['/test'], - testMatch: ['**/*.test.ts'], - transform: { - '^.+\\.tsx?$': 'ts-jest' - } + testEnvironment: 'node', + roots: ['/test'], + testMatch: ['**/*.test.ts'], + transform: { + '^.+\\.tsx?$': 'ts-jest' + } }; diff --git a/cdk-eregs/package-lock.json b/cdk-eregs/package-lock.json index 1fcf1c0ae1..35a67fb649 100644 --- a/cdk-eregs/package-lock.json +++ b/cdk-eregs/package-lock.json @@ -18,13 +18,19 @@ "cdk-eregs": "bin/cdk-eregs.js" }, "devDependencies": { + "@eslint/js": "^9.19.0", "@types/jest": "^29.5.12", "@types/node": "22.5.4", + "@typescript-eslint/eslint-plugin": "^8.22.0", + "@typescript-eslint/parser": "^8.22.0", "aws-cdk": "2.158.0", + "eslint": "^9.19.0", + "globals": "^15.14.0", "jest": "^29.7.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "~5.6.2" + "typescript": "~5.6.2", + "typescript-eslint": "^8.22.0" } }, "node_modules/@ampproject/remapping": { @@ -1334,6 +1340,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.25.8", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", @@ -1380,6 +1395,216 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "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/eslint-utils/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, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1752,6 +1977,41 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -2432,6 +2692,12 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -2480,6 +2746,12 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/node": { "version": "22.5.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", @@ -2520,12 +2792,219 @@ "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", + "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/type-utils": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", + "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4" + }, + "engines": { + "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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", + "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", + "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0" + }, + "engines": { + "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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2533,6 +3012,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", @@ -2546,6 +3034,22 @@ "node": ">=0.4.0" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3392,11 +3896,10 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3439,6 +3942,12 @@ } } }, + "node_modules/deep-is": { + "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 + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -3532,24 +4041,186 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.19.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, - "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -3566,6 +4237,48 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "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, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3616,6 +4329,40 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "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.8" + }, + "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", @@ -3623,6 +4370,12 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fast-xml-parser": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", @@ -3645,6 +4398,15 @@ "fxparser": "src/cli/cli.js" } }, + "node_modules/fastq": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -3655,6 +4417,18 @@ "bser": "2.1.1" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -3715,6 +4489,25 @@ "node": ">=8" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3812,14 +4605,28 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { @@ -3829,6 +4636,12 @@ "dev": true, "license": "ISC" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3869,6 +4682,40 @@ "node": ">=10.17.0" } }, + "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, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -3941,6 +4788,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3961,6 +4817,18 @@ "node": ">=6" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4735,6 +5603,12 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4742,6 +5616,18 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4755,6 +5641,15 @@ "node": ">=6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -4775,6 +5670,19 @@ "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, + "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", @@ -4802,6 +5710,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4865,6 +5779,15 @@ "dev": true, "license": "MIT" }, + "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/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4979,6 +5902,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "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.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5034,6 +5974,18 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -5143,6 +6095,15 @@ "node": ">=8" } }, + "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/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -5194,6 +6155,15 @@ "node": ">= 6" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -5211,6 +6181,26 @@ ], "license": "MIT" }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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" + } + ] + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -5279,6 +6269,39 @@ "node": ">=10" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -5527,6 +6550,18 @@ "node": ">=8.0" } }, + "node_modules/ts-api-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-jest": { "version": "29.2.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", @@ -5639,6 +6674,18 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "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/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -5676,6 +6723,28 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.22.0.tgz", + "integrity": "sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.22.0", + "@typescript-eslint/parser": "8.22.0", + "@typescript-eslint/utils": "8.22.0" + }, + "engines": { + "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", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -5714,6 +6783,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", @@ -5790,6 +6868,15 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/cdk-eregs/package.json b/cdk-eregs/package.json index d29c3562a5..f58d197514 100644 --- a/cdk-eregs/package.json +++ b/cdk-eregs/package.json @@ -5,19 +5,26 @@ "cdk-eregs": "bin/cdk-eregs.js" }, "scripts": { + "eslint": "eslint", "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk" }, "devDependencies": { + "@eslint/js": "^9.19.0", "@types/jest": "^29.5.12", "@types/node": "22.5.4", + "@typescript-eslint/eslint-plugin": "^8.22.0", + "@typescript-eslint/parser": "^8.22.0", "aws-cdk": "2.158.0", + "eslint": "^9.19.0", + "globals": "^15.14.0", "jest": "^29.7.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "~5.6.2" + "typescript": "~5.6.2", + "typescript-eslint": "^8.22.0" }, "dependencies": { "@aws-sdk/client-ssm": "^3.682.0", diff --git a/eslint-global-rules.mjs b/eslint-global-rules.mjs new file mode 100644 index 0000000000..606bd53e33 --- /dev/null +++ b/eslint-global-rules.mjs @@ -0,0 +1,10 @@ +const configObject ={ + eqeqeq: "off", + "import/no-unresolved": "off", + "import/first": "off", + "no-console": ["error", { allow: ["warn", "error", "info"] }], + "no-nested-ternary": "off", + "prefer-template": "off", +}; + +export default configObject; diff --git a/solution/LINTING.md b/solution/LINTING.md new file mode 100644 index 0000000000..59064a7d8c --- /dev/null +++ b/solution/LINTING.md @@ -0,0 +1,70 @@ +# ERegs static files + +## Adding linting and code formatting to static files + +### Why linting and code formatting? + +Linting helps find errors earlier. + +Adopting a common style guide stops on-going debates about code style. + +Linting and code formatting can be added to projects in many ways: + +* Live feedback in text editor that validates code as it is written and provides immediate feedback +* CLI integration that can validate and format code via commands executed from the command line +* CI/CD integration that can validate code as part of the build process + +### Why ESLint? + +ESLint helps find and fix problems in JavaScript and TypeScript code. It exposes bugs and style errors, as well as offering opinions about syntax. + +[Django recommends ESLint when working with JavaScript files](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/javascript/), and also recommends installing an ESLint plugin into your text editor. + +We've added the official ESLint plugin for Vue.js: [eslint-plugin-vue](https://eslint.vuejs.org/user-guide/#installation). This will specifically [expose syntax errors, the wrong uses of Vue.js Directives, and violations of the Vue.js Style Guide](https://eslint.vuejs.org/#introduction). + +### Getting Started + +ESLint will run as a GitHub Action on every pull request. If you want to run ESLint locally, you can do so by running the following commands from `./solution`: + +``` +// lint the frontend JS +make eslint-frontend + +// lint CDK TS +make eslint-cdk +``` + +This will return a list of errors and warnings that need to be fixed. + +### Integrating with Text Editors (recommended) + +The best way to start using ESLint is to integrate it into your text editor so you get immediate feedback while writing code. You can manually fix these alerts yourself, or use CodeActions to automatically fix all fixable problems. + +Typical workflow for using ESLint in your text editor: + +1. Write code +2. See real-time validation alerts +3. Manually change code to satisfy linter and make validation alerts disappear OR +4. Execute ESLint code actions/keyboard shortcuts to automatically fix and format entire file + +[ESLint official Integrations page](https://eslint.org/docs/user-guide/integrations) + +#### VSCode + +[ESLint plugin for VSCode](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + +#### Neovim via nvim.coc + +[coc-eslint](https://github.com/neoclide/coc-eslint) + +#### VIM via ALE - Untested + +[Configuring ESLint and Prettier for Vim with ALE](https://miikanissi.com/blog/configure-eslint-prettier-ale-vim.html) + +[Prettier plugin for use with ALE](https://prettier.io/docs/en/vim.html#alehttpsgithubcomdense-analysisale) + +#### JetBrains IDEs - Untested + +[Webstorm](https://www.jetbrains.com/help/webstorm/eslint.html) + +[Pycharm](https://www.jetbrains.com/help/pycharm/eslint.html) diff --git a/solution/Makefile b/solution/Makefile index e31b6f45d9..dd847ee64c 100644 --- a/solution/Makefile +++ b/solution/Makefile @@ -75,6 +75,18 @@ watch-all: ## watch everything for changes watch-all: ${MAKE} -j4 watch-css watch-component-lib watch-eregs-main watch-spa watch-text-extractor +.PHONY: eslint-frontend +eslint-frontend: ## Run eslint + cd ui/regulations; \ + npm install; \ + npm run eslint; + +.PHONY: eslint-cdk +eslint-cdk: ## Run eslint + cd ../cdk-eregs; \ + npm install; \ + npm run eslint; + .PHONY: lint lint: flake8; diff --git a/solution/ui/e2e/cypress/e2e/search.spec.cy.js b/solution/ui/e2e/cypress/e2e/search.spec.cy.js index 95861b1cf0..5b3b04415d 100644 --- a/solution/ui/e2e/cypress/e2e/search.spec.cy.js +++ b/solution/ui/e2e/cypress/e2e/search.spec.cy.js @@ -526,7 +526,7 @@ describe("Search flow", () => { cy.get(".research__title").should("exist"); cy.get(".research__title").should( "have.text", - "Continue Your Research", + " Continue Your Research ", ); cy.get("[data-testid=research-row-1]").should("not.exist"); @@ -539,7 +539,7 @@ describe("Search flow", () => { cy.get(".research__title").should("exist"); cy.get(".research__title").should( "have.text", - "Continue Your Research", + " Continue Your Research ", ); cy.get("[data-testid=research-row-1]") diff --git a/solution/ui/regulations/README.md b/solution/ui/regulations/README.md deleted file mode 100644 index dd0d915848..0000000000 --- a/solution/ui/regulations/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# ERegs static files - -## Adding linting and code formatting to static files - -### Why linting and code formatting? - -Linting helps find errors earlier. - -Adopting a common style guide stops on-going debates about code style. - -Linting and code formatting can be added to projects in many ways: - -* Live feedback in text editor that validates code as it is written and provides immediate feedback -* CLI integration that can validate and format code via commands executed from the command line -* Format-on-save functionality that validates and formats code automatically when saved -* Format-on-commit functionality that validates and formats code automatically when committed to source control using a git hook -* Format-on-push functionality built into a CI/CD pipeline that validates and formats code automatically when pushing to source control - -**This story will focus on text editor integration and CLI command execution.** - -### Why ESLint? - -ESLint helps find and fix problems in JavaScript code. It exposes bugs and style errors, as well as offering opinions about syntax. - -[Django recommends ESLint when working with JavaScript files](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/javascript/), and also recommends installing an ESLint plugin into your text editor. - -When setting up ESLint, you are asked to choose a default style guide. **I've chosen the Airbnb style guide** because it's a very popular, [with 117k stars on github](https://github.com/airbnb/javascript). It's been around quite a while and it's the one I've been personally using for a long time. Here's a comparison between [Airbnb, Google, and Standard](https://betterprogramming.pub/comparing-the-top-three-style-guides-and-setting-them-up-with-eslint-98ea0d2fc5b7) style guides. - -Additionally, we've added the official ESLint plugin for Vue.js: [eslint-plugin-vue](https://eslint.vuejs.org/user-guide/#installation). This will specifically [expose syntax errors, the wrong uses of Vue.js Directives, and violations of the Vue.js Style Guide](https://eslint.vuejs.org/#introduction). - -And finally we've added Prettier, an opinionated code formatter. This is another very popular library - [41.3k stars on github](https://github.com/prettier/prettier). It complements ESLint, the Airbnb style guide, and the Vue.js plugin. - -### Getting Started - -[ESLint official Getting Started page](https://eslint.org/docs/user-guide/getting-started) - -ESLint has been added to the package.json in `/regulations/static/`, including vue, airbnb, and prettier plugins. - -`.eslintrc.json` has been created in `/regulations/static/`. It is mainly boilerplate but adds the Airbnb style guide, the Vue.js plugin, and Prettier. - -`.prettierrc.json` has been created for any overrides that we want to add. Right now, it overrides `tabWidth` to be `4` spaces. - -`.prettierignore` has been created because it was recommended by the Prettier docs. It includes an incomplete list of file types and directories to ignore when running Prettier from the command line. - -### Integrating with Text Editors (recommended) - -The best way to start using ESLint is to integrate it into your text editor so you get immediate feedback while writing code. You can manually fix these alerts yourself, or use CodeActions to automatically fix all fixable problems. - -Typical workflow for using ESLint and Prettier in your text editor: - -1. Write code -2. See real-time validation alerts -3. Manually change code to satisfy linter and make validation alerts disappear OR -4. Execute ESLint and Prettier code actions/keyboard shortcuts to automatically fix and format entire file - -[ESLint official Integrations page](https://eslint.org/docs/user-guide/integrations) - -**Note:** ESLint 8 had some breaking changing that editor plugins are only now resolving. See notes below about plugin versions needed. - -[Prettier official Editor Integration page](https://prettier.io/docs/en/editors.html) - -#### VSCode - -[ESLint plugin for VSCode](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - -Make sure you install ESLint v2.2.x. - -**Note:** If there are issues installing the above version, you may need to install a pre-release version from VSIX, as outlined in the comment: - -[Why 2.2.0 needs to be installed](https://github.com/microsoft/vscode-eslint/issues/972#issuecomment-903573031) - -[VSCode ESLint releases](https://github.com/microsoft/vscode-eslint/releases/tag/release%2F2.2.20-Insider) - -[Prettier plugin for VSCode](https://prettier.io/docs/en/editors.html#visual-studio-code) - -#### Neovim via nvim.coc - -[coc-eslint](https://github.com/neoclide/coc-eslint) - -**Note**: For the same reason that a pre-release build must be used for VSCode above, a custom coc eslint plugin must also be installed for now: [coc-eslint8](https://github.com/neoclide/coc-eslint/pull/118#issuecomment-973640987) - -[coc-prettier](https://prettier.io/docs/en/vim.html#coc-prettierhttpsgithubcomneoclidecoc-prettier) - -#### VIM via ALE - Untested - -[Configuring ESLint and Prettier for Vim with ALE](https://miikanissi.com/blog/configure-eslint-prettier-ale-vim.html) - -[Prettier plugin for use with ALE](https://prettier.io/docs/en/vim.html#alehttpsgithubcomdense-analysisale) - -#### JetBrains IDEs - Untested - -[Webstorm](https://www.jetbrains.com/help/webstorm/eslint.html) - -[Pycharm](https://www.jetbrains.com/help/pycharm/eslint.html) - -### Using from the command line - -[Official ESLint Command Line Interface page](https://eslint.org/docs/user-guide/command-line-interface) - -To run ESLint from the command line, you may need to install eslint globally on your machine: - -`npm i -g eslint` - -There are many options from which to choose. - -To use as a diagnostic tool to see problems without fixing them, use `--fix-dry-run`: - -`eslint --fix-dry-run ./regulations/js/main.js` diff --git a/solution/ui/regulations/composables/counts.js b/solution/ui/regulations/composables/counts.js index eb9dbd3a50..0cdbb73267 100644 --- a/solution/ui/regulations/composables/counts.js +++ b/solution/ui/regulations/composables/counts.js @@ -22,7 +22,7 @@ export default function useCounts() { }); counts.value.results = response; - } catch (error) { + } catch (_error) { counts.value.error = true; counts.value.results = {}; } finally { diff --git a/solution/ui/regulations/eregs-component-lib/src/components/CollapseButton.vue b/solution/ui/regulations/eregs-component-lib/src/components/CollapseButton.vue index 3f75025ac8..77aa9da95b 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/CollapseButton.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/CollapseButton.vue @@ -6,13 +6,21 @@ class="collapsible-title" @click="click" > - Hide - Show + - Click here + Show + + + Click here + @@ -78,7 +86,7 @@ export default { }, methods: { - click(event) { + click() { eventbus.emit("collapse-toggle", this.dataName); }, toggle(target) { diff --git a/solution/ui/regulations/eregs-component-lib/src/components/Collapsible.vue b/solution/ui/regulations/eregs-component-lib/src/components/Collapsible.vue index 09063c1def..971199b14c 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/Collapsible.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/Collapsible.vue @@ -5,7 +5,7 @@ :class="{ invisible: !visible }" :style="[styles]" > - + diff --git a/solution/ui/regulations/eregs-component-lib/src/components/Dropdown.vue b/solution/ui/regulations/eregs-component-lib/src/components/Dropdown.vue index 4b1b521aa8..6852cee52f 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/Dropdown.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/Dropdown.vue @@ -1,45 +1,45 @@ diff --git a/solution/ui/regulations/eregs-component-lib/src/components/DropdownContent.vue b/solution/ui/regulations/eregs-component-lib/src/components/DropdownContent.vue index 28311d3f87..f84b90ec8d 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/DropdownContent.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/DropdownContent.vue @@ -1,19 +1,19 @@ diff --git a/solution/ui/regulations/eregs-component-lib/src/components/DropdownHeader.vue b/solution/ui/regulations/eregs-component-lib/src/components/DropdownHeader.vue index a7beb5bcb7..403fc0a34e 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/DropdownHeader.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/DropdownHeader.vue @@ -1,11 +1,11 @@ diff --git a/solution/ui/regulations/eregs-component-lib/src/components/DropdownItem.vue b/solution/ui/regulations/eregs-component-lib/src/components/DropdownItem.vue index 9656f5c1e1..a6b43e84b5 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/DropdownItem.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/DropdownItem.vue @@ -1,13 +1,13 @@ diff --git a/solution/ui/regulations/eregs-component-lib/src/components/PartButton.vue b/solution/ui/regulations/eregs-component-lib/src/components/PartButton.vue index 26b4ba6fdc..9a2c5f38c1 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/PartButton.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/PartButton.vue @@ -1,19 +1,19 @@ diff --git a/solution/ui/regulations/eregs-component-lib/src/components/RecentResources.vue b/solution/ui/regulations/eregs-component-lib/src/components/RecentResources.vue index 86527f48bd..56dd8c4275 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/RecentResources.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/RecentResources.vue @@ -53,7 +53,9 @@ export default { Recent Subregulatory Guidance - Recent Rules + + Recent Rules + @@ -63,7 +65,7 @@ export default { :categories="categories" type="supplemental" class="recent-supplemental-content" - > + />

@@ -72,7 +74,7 @@ export default { + /> diff --git a/solution/ui/regulations/eregs-component-lib/src/components/RecentSupplementalContent.vue b/solution/ui/regulations/eregs-component-lib/src/components/RecentSupplementalContent.vue index cf8110ae56..3903785eba 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/RecentSupplementalContent.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/RecentSupplementalContent.vue @@ -46,10 +46,9 @@ export default { :description="content.title" :date="content.date" :url="content.url" - > - + /> -

+
diff --git a/solution/ui/regulations/eregs-component-lib/src/components/RelatedRule.vue b/solution/ui/regulations/eregs-component-lib/src/components/RelatedRule.vue index e90bf09a09..65807aaac1 100644 --- a/solution/ui/regulations/eregs-component-lib/src/components/RelatedRule.vue +++ b/solution/ui/regulations/eregs-component-lib/src/components/RelatedRule.vue @@ -16,7 +16,11 @@ citation }} -
+
{{ title }}
@@ -24,6 +28,7 @@ - diff --git a/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectChip.vue b/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectChip.vue index 8cae86da8f..e63e34b56a 100644 --- a/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectChip.vue +++ b/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectChip.vue @@ -38,7 +38,7 @@ import { computed, inject } from "vue"; import { getSubjectName, getSubjectNameParts } from "utilities/filters"; -const props = defineProps({ +defineProps({ subject: { type: Object, default: () => ({}), @@ -54,16 +54,16 @@ const buttonTextClasses = computed(() => getButtonTextClasses(parent)); + /> diff --git a/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectHeading.vue b/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectHeading.vue index 59b424659e..8120b776e9 100644 --- a/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectHeading.vue +++ b/solution/ui/regulations/eregs-vite/src/components/subjects/SelectedSubjectHeading.vue @@ -18,8 +18,7 @@ defineProps({ 'subj-heading__span--border': index === 0, 'subj-heading__span--bold': part[1], }" - >{{ part[0] }} + >{{ part[0] }} diff --git a/solution/ui/regulations/eregs-vite/src/components/subjects/SubjectLanding.vue b/solution/ui/regulations/eregs-vite/src/components/subjects/SubjectLanding.vue index c45716a026..c35b033996 100644 --- a/solution/ui/regulations/eregs-vite/src/components/subjects/SubjectLanding.vue +++ b/solution/ui/regulations/eregs-vite/src/components/subjects/SubjectLanding.vue @@ -1,6 +1,6 @@