diff --git a/.cirrus.star b/.cirrus.star
deleted file mode 100644
index 28b17b70fc3..00000000000
--- a/.cirrus.star
+++ /dev/null
@@ -1,4 +0,0 @@
-load("github.com/SonarSource/cirrus-modules@v2", "load_features")
-
-def main(ctx):
- return load_features(ctx)
diff --git a/.cirrus.yml b/.cirrus.yml
deleted file mode 100644
index 99c4b618c48..00000000000
--- a/.cirrus.yml
+++ /dev/null
@@ -1,234 +0,0 @@
-env:
- CIRRUS_VAULT_URL: https://vault.sonar.build:8200
- CIRRUS_VAULT_AUTH_PATH: jwt-cirrusci
- CIRRUS_VAULT_ROLE: cirrusci-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}
-
- ARTIFACTORY_URL: VAULT[development/kv/data/repox data.url]
- ARTIFACTORY_PRIVATE_USERNAME: vault-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader
- ARTIFACTORY_PRIVATE_PASSWORD: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader access_token]
- ARTIFACTORY_DEPLOY_USERNAME: vault-${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-qa-deployer
- ARTIFACTORY_DEPLOY_PASSWORD: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-qa-deployer access_token]
- ARTIFACTORY_DEPLOY_REPO: sonarsource-public-qa
- ARTIFACTORY_ACCESS_TOKEN: VAULT[development/artifactory/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-private-reader access_token]
- GITHUB_TOKEN: VAULT[development/github/token/licenses-ro token]
- # burgr notification
- BURGR_URL: VAULT[development/kv/data/burgr data.url]
- BURGR_USERNAME: VAULT[development/kv/data/burgr data.cirrus_username]
- BURGR_PASSWORD: VAULT[development/kv/data/burgr data.cirrus_password]
-
- # Use bash (instead of sh on linux or cmd.exe on windows)
- CIRRUS_SHELL: bash
-
-container_definition: &CONTAINER_DEFINITION
- dockerfile: .cirrus/nodejs.Dockerfile
- docker_arguments:
- CIRRUS_AWS_ACCOUNT: ${CIRRUS_AWS_ACCOUNT}
- cluster_name: ${CIRRUS_CLUSTER_NAME}
- builder_role: cirrus-builder
- builder_image: docker-builder-v*
- builder_instance_type: t3.small
- builder_subnet_id: ${CIRRUS_AWS_SUBNET}
- region: eu-central-1
- namespace: default
- use_in_memory_disk: true
-
-maven_cache_definition: &MAVEN_CACHE
- maven_cache:
- folder: ${CIRRUS_WORKING_DIR}/.m2/repository
- fingerprint_script: cat **/pom.xml
-
-win_vm_definition: &WINDOWS_VM_DEFINITION
- ec2_instance:
- experimental: true # see https://github.com/cirruslabs/cirrus-ci-docs/issues/1051
- image: base-windows-jdk11-v*
- platform: windows
- region: eu-central-1
- type: t3.2xlarge
- subnet_id: ${CIRRUS_AWS_SUBNET}
- preemptible: false
- use_ssd: true
-
-only_sonarsource_qa: &ONLY_SONARSOURCE_QA
- only_if: $CIRRUS_USER_COLLABORATOR == 'true' && ($CIRRUS_PR != "" || $CIRRUS_BRANCH == "master" || $CIRRUS_BRANCH =~ "branch-.*" || $CIRRUS_BRANCH =~ "dogfood-on-.*")
-
-plugin_qa_body: &PLUGIN_QA_BODY
- depends_on:
- - build
- <<: *ONLY_SONARSOURCE_QA
- eks_container:
- <<: *CONTAINER_DEFINITION
- cpu: 15
- memory: 30G
- env:
- CIRRUS_CLONE_DEPTH: 10
- SONARSOURCE_QA: true
- <<: *MAVEN_CACHE
- node_version_script:
- - node -v
- qa_script:
- - source cirrus-env QA
- - source set_maven_build_version $BUILD_NUMBER
- - mvn -f its/plugin/pom.xml -Dsonar.runtimeVersion=${SQ_VERSION} -B -e -V verify surefire-report:report
- cleanup_before_cache_script: cleanup_maven_repository
-
-
-build_task:
- eks_container:
- <<: *CONTAINER_DEFINITION
- cpu: 15
- memory: 30G
- env:
- # analysis on next
- SONAR_TOKEN: VAULT[development/kv/data/next data.token]
- SONAR_HOST_URL: https://next.sonarqube.com/sonarqube
- #allow deployment of pull request artifacts to repox
- DEPLOY_PULL_REQUEST: true
- #sign artifacts
- SIGN_KEY: VAULT[development/kv/data/sign data.key]
- PGP_PASSPHRASE: VAULT[development/kv/data/sign data.passphrase]
- <<: *MAVEN_CACHE
- sonar_cache:
- folder: ${HOME}/.sonar/cache
- fingerprint_script:
- - echo ${CIRRUS_OS}
- - curl --silent ${SONAR_HOST_URL}/deploy/plugins/index.txt | sort
- build_script:
- - source cirrus-env BUILD
- - npm config set registry "${ARTIFACTORY_URL}/api/npm/npm"
- - regular_mvn_build_deploy_analyze
- cleanup_before_cache_script: cleanup_maven_repository
-
-build_win_task:
- depends_on:
- - build
- <<: *WINDOWS_VM_DEFINITION
- <<: *ONLY_SONARSOURCE_QA
- <<: *MAVEN_CACHE
- build_script:
- - source cirrus-env CI
- - npm config set registry "${ARTIFACTORY_URL}/api/npm/npm"
- - mvn test
- cleanup_before_cache_script: cleanup_maven_repository
-
-ws_scan_task:
- depends_on:
- - build
- eks_container:
- <<: *CONTAINER_DEFINITION
- cpu: 4
- memory: 8G
- # run only on master and long-term branches
- only_if: $CIRRUS_USER_COLLABORATOR == 'true' && ($CIRRUS_BRANCH == "master" || $CIRRUS_BRANCH =~ "branch-.*")
- env:
- WS_APIKEY: VAULT[development/kv/data/mend data.apikey]
- <<: *MAVEN_CACHE
- whitesource_script:
- - source cirrus-env QA
- - npm config set registry "${ARTIFACTORY_URL}/api/npm/npm"
- - source set_maven_build_version $BUILD_NUMBER
- - mvn clean install -DskipTests
- - source ws_scan.sh
- allow_failures: "true"
- always:
- ws_artifacts:
- path: "whitesource/**/*"
-
-plugin_qa_task:
- <<: *PLUGIN_QA_BODY
- eks_container:
- dockerfile: .cirrus/nodejs.jdk17.Dockerfile
- docker_arguments:
- matrix:
- - NODE_VERSION: 14
- - NODE_VERSION: 16
- - NODE_VERSION: 18
- env:
- SQ_VERSION: LATEST_RELEASE
-
-plugin_qa_sq_dev_task:
- <<: *PLUGIN_QA_BODY
- eks_container:
- dockerfile: .cirrus/nodejs.jdk17.Dockerfile
- env:
- SQ_VERSION: DEV
-
-# Plugin QA for Windows is splint into 2 parts to make it faster
-plugin_qa_win_task:
- depends_on:
- - build
- <<: *WINDOWS_VM_DEFINITION
- <<: *ONLY_SONARSOURCE_QA
- env:
- SONARSOURCE_QA: true
- SQ_VERSION: LATEST_RELEASE
- matrix:
- - TEST: "!CoverageTest,!TypeScriptAnalysisTest,!EslintBasedRulesTest,!SonarLintTest"
- - TEST: "CoverageTest,TypeScriptAnalysisTest,EslintBasedRulesTest,SonarLintTest"
- <<: *MAVEN_CACHE
- qa_script:
- - source /c/buildTools-docker/bin/cirrus-env QA
- - source /c/buildTools-docker/bin/set_maven_build_version $BUILD_NUMBER
- # building the custom plugin required for the further tests
- - mvn clean package -f its/plugin/plugins/pom.xml
- - mvn -f its/plugin/tests/pom.xml -Dsonar.runtimeVersion=${SQ_VERSION} "-Dtest=${TEST}" -B -e -V verify surefire-report:report
- cleanup_before_cache_script: cleanup_maven_repository
- always:
- surefire_report_artifacts:
- path: "its/plugin/tests/target/site/**/*"
- type: text/html
- surefire_artifacts:
- path: "its/plugin/tests/target/surefire-reports/**/*"
- type: text/xml
-
-ruling_task:
- depends_on:
- - build
- <<: *ONLY_SONARSOURCE_QA
- eks_container:
- <<: *CONTAINER_DEFINITION
- dockerfile: .cirrus/nodejs.jdk17.Dockerfile
- cpu: 15
- memory: 24G
- env:
- CIRRUS_CLONE_DEPTH: 10
- SONARSOURCE_QA: true
- matrix:
- - RULING: JavaScriptRulingTest
- - RULING: TypeScriptRulingTest
- - RULING: CssRulingTest
- <<: *MAVEN_CACHE
- submodules_script:
- - git submodule update --init
- ruling_script:
- - source cirrus-env QA
- - source set_maven_build_version $BUILD_NUMBER
- - cd its/ruling
- - mvn verify -Dtest=${RULING} -Dsonar.runtimeVersion=LATEST_RELEASE -Dmaven.test.redirectTestOutputToFile=false -Djunit.jupiter.execution.parallel.config.dynamic.factor=1 -B -e -V
- cleanup_before_cache_script: cleanup_maven_repository
- on_failure:
- diff_artifacts:
- path: "**/target/actual/**/*"
-
-promote_task:
- depends_on:
- - ws_scan
- - build_win
- - plugin_qa
- - plugin_qa_sq_dev
- - plugin_qa_win
- - ruling
- <<: *ONLY_SONARSOURCE_QA
- eks_container:
- <<: *CONTAINER_DEFINITION
- cpu: 1
- memory: 1G
- env:
- #promotion cloud function
- GCF_ACCESS_TOKEN: VAULT[development/kv/data/promote data.token]
- PROMOTE_URL: VAULT[development/kv/data/promote data.url]
- GITHUB_TOKEN: VAULT[development/github/token/${CIRRUS_REPO_OWNER}-${CIRRUS_REPO_NAME}-promotion token]
- #artifacts that will have downloadable links in burgr
- ARTIFACTS: org.sonarsource.javascript:sonar-javascript-plugin:jar
- <<: *MAVEN_CACHE
- script: cirrus_promote_maven
- cleanup_before_cache_script: cleanup_maven_repository
diff --git a/.cirrus/nodejs.Dockerfile b/.cirrus/nodejs.Dockerfile
deleted file mode 100644
index 5f4405cd8b7..00000000000
--- a/.cirrus/nodejs.Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-ARG CIRRUS_AWS_ACCOUNT=275878209202
-FROM ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j11-latest
-
-USER root
-
-RUN apt-get update && apt-get install -y nodejs=14.*
-
-USER sonarsource
diff --git a/.cirrus/nodejs.jdk17.Dockerfile b/.cirrus/nodejs.jdk17.Dockerfile
deleted file mode 100644
index 12bc05cff1b..00000000000
--- a/.cirrus/nodejs.jdk17.Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-ARG CIRRUS_AWS_ACCOUNT=275878209202
-FROM ${CIRRUS_AWS_ACCOUNT}.dkr.ecr.eu-central-1.amazonaws.com/base:j17-latest
-
-USER root
-
-ARG NODE_VERSION=14
-
-RUN apt-get update && apt-get install -y nodejs=${NODE_VERSION}.*
-
-USER sonarsource
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 4a7e762f813..00000000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1 +0,0 @@
-.github/CODEOWNERS @SonarSource/languages-team-jsts
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index f67751d930c..00000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 27d5672816d..00000000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1 +0,0 @@
-Fixes #
diff --git a/.github/workflows/CreatePullRequest.yml b/.github/workflows/CreatePullRequest.yml
deleted file mode 100644
index 155ac80456e..00000000000
--- a/.github/workflows/CreatePullRequest.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Create Pull Request
-
-on:
- pull_request:
- types: ["opened"]
-
-jobs:
- CreateCardForStandalonePR_job:
- name: Assign PR to the author and create a Kanban card
- runs-on: ubuntu-latest
- # Single quotes must be used here https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#literals
- # PRs from forks don't have required token authorization
- # Dependabot works directly under our repository, but doesn't have enough priviledges to create project card
- if: |
- github.event.pull_request.head.repo.full_name == github.repository
- && github.event.sender.type != 'Bot'
- steps:
- - uses: sonarsource/gh-action-lt-backlog/CreateCardForStandalonePR@v1
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
- column-id: 16320787
diff --git a/.github/workflows/RequestReview.yml b/.github/workflows/RequestReview.yml
deleted file mode 100644
index 29447da40b5..00000000000
--- a/.github/workflows/RequestReview.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: Request review
-
-on:
- pull_request:
- types: ["review_requested"]
-
-jobs:
- MoveCardToReview_job:
- name: Move card to review
- runs-on: ubuntu-latest
- # PRs from forks don't have required token authorization
- if: github.event.pull_request.head.repo.full_name == github.repository
- steps:
- - uses: sonarsource/gh-action-lt-backlog/MoveCardToReview@v1
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
- column-id: 16320793 # Kanban "In review" column
diff --git a/.github/workflows/StartProgress.yml b/.github/workflows/StartProgress.yml
deleted file mode 100644
index e58003977d0..00000000000
--- a/.github/workflows/StartProgress.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Start Progress
-
-on:
- project_card:
- types: ["moved"]
-
-jobs:
- AssignCardToSender_job:
- runs-on: ubuntu-latest
- if: |
- github.event.changes.column_id.from == 16320786
- && github.event.project_card.content_url != null
- steps:
- - uses: sonarsource/gh-action-lt-backlog/AssignCardToSender@v1
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
diff --git a/.github/workflows/SubmitReview.yml b/.github/workflows/SubmitReview.yml
deleted file mode 100644
index 3ffd61658f8..00000000000
--- a/.github/workflows/SubmitReview.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Submit Review
-
-on:
- pull_request_review:
- types: ["submitted"]
-
-jobs:
- MoveCardToProgress_job:
- name: Move card to progress
- runs-on: ubuntu-latest
- # Single quotes must be used here https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#literals
- # PRs from forks don't have required token authorization
- if: |
- github.event.pull_request.head.repo.full_name == github.repository
- && github.event.review.state == 'changes_requested'
- steps:
- - uses: sonarsource/gh-action-lt-backlog/MoveCardAfterReview@v1
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
- column-id: 16320787 # Kanban "In progress" column
-
- ReviewApproved_job:
- name: Move card to review approved
- runs-on: ubuntu-latest
- if: |
- github.event.pull_request.head.repo.full_name == github.repository
- && github.event.review.state == 'approved'
- steps:
- - uses: sonarsource/gh-action-lt-backlog/MoveCardAfterReview@v1
- with:
- github-token: ${{secrets.GITHUB_TOKEN}}
- column-id: 16320799 # Kanban "Resolved" column
diff --git a/.github/workflows/dogfood.yml b/.github/workflows/dogfood.yml
deleted file mode 100644
index 7723b8c9bb1..00000000000
--- a/.github/workflows/dogfood.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: dogfood merge
-# This workflow is triggered on pushes to master and dogfood branches
-on:
- push:
- branches:
- - master
- - 'dogfood/*'
-
-jobs:
- dogfood_merge:
- runs-on: ubuntu-latest
- name: Update dogfood branch
- steps:
- - name: git octopus step
- env:
- GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- id: dogfood
- uses: SonarSource/gh-action_dogfood_merge@master
- with:
- dogfood-branch: 'dogfood-on-peach'
- # Use the output from the `dogfood` step
- - name: Get the name of the dogfood branch and its HEAD SHA1
- run: echo "The dogfood branch was ${{ steps.dogfood.outputs.dogfood-branch }} and its HEAD SHA1 was ${{ steps.dogfood.outputs.sha1 }}"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 1509fd23168..00000000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-name: sonar-release
-# This workflow is triggered when publishing a new github release
-# yamllint disable-line rule:truthy
-on:
- release:
- types:
- - published
-
-jobs:
- release:
- permissions:
- id-token: write
- contents: write
- uses: SonarSource/gh-action_release/.github/workflows/main.yaml@v5
- with:
- publishToBinaries: true
- mavenCentralSync: true
- slackChannel: team-lang-js-ts-css
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 90d5480835d..00000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,89 +0,0 @@
-
-[submodule "its/typescript-test-sources"]
- path = its/typescript-test-sources
- url = https://github.com/SonarSource/typescript-test-sources.git
- ignore = untracked
-[submodule "its/sources/jquery"]
- path = its/sources/jquery
- url = https://github.com/SonarSource/jquery.git
- ignore = untracked
-[submodule "its/sources/angular.js"]
- path = its/sources/angular.js
- url = https://github.com/SonarSource/angular.js.git
- ignore = untracked
-[submodule "its/sources/p5.js"]
- path = its/sources/p5.js
- url = https://github.com/SonarSource/p5.js.git
- ignore = untracked
-[submodule "its/sources/amplify"]
- path = its/sources/amplify
- url = https://github.com/SonarSource/amplify.git
- ignore = untracked
-[submodule "its/sources/backbone"]
- path = its/sources/backbone
- url = https://github.com/SonarSource/backbone.git
- ignore = untracked
-[submodule "its/sources/es5-shim"]
- path = its/sources/es5-shim
- url = https://github.com/SonarSource/es5-shim.git
- ignore = untracked
-[submodule "its/sources/fireact"]
- path = its/sources/fireact
- url = https://github.com/chaoming/fireact.git
- ignore = untracked
-[submodule "its/sources/jira-clone"]
- path = its/sources/jira-clone
- url = https://github.com/oldboyxx/jira_clone.git
- ignore = untracked
-[submodule "its/sources/jshint"]
- path = its/sources/jshint
- url = https://github.com/SonarSource/jshint.git
- ignore = untracked
-[submodule "its/sources/jStorage"]
- path = its/sources/jStorage
- url = https://github.com/SonarSource/jStorage.git
- ignore = untracked
-[submodule "its/sources/knockout"]
- path = its/sources/knockout
- url = https://github.com/SonarSource/knockout.git
- ignore = untracked
-[submodule "its/sources/mootools-core"]
- path = its/sources/mootools-core
- url = https://github.com/SonarSource/mootools-core.git
- ignore = untracked
-[submodule "its/sources/ocanvas"]
- path = its/sources/ocanvas
- url = https://github.com/SonarSource/ocanvas.git
- ignore = untracked
-[submodule "its/sources/paper.js"]
- path = its/sources/paper.js
- url = https://github.com/SonarSource/paper.js.git
- ignore = untracked
-[submodule "its/sources/prototype"]
- path = its/sources/prototype
- url = https://github.com/SonarSource/prototype.git
- ignore = untracked
-[submodule "its/sources/qunit"]
- path = its/sources/qunit
- url = https://github.com/SonarSource/qunit.git
- ignore = untracked
-[submodule "its/sources/react-cloud-music"]
- path = its/sources/react-cloud-music
- url = https://github.com/sanyuan0704/react-cloud-music.git
- ignore = untracked
-[submodule "its/sources/sizzle"]
- path = its/sources/sizzle
- url = https://github.com/SonarSource/sizzle.git
- ignore = untracked
-[submodule "its/sources/underscore"]
- path = its/sources/underscore
- url = https://github.com/SonarSource/underscore.git
- ignore = untracked
-
-[submodule "its/sources/javascript-test-sources"]
- path = its/sources/javascript-test-sources
- url = https://github.com/SonarSource/javascript-test-sources.git
- ignore = untracked
-[submodule "its/css-sources/projects"]
- path = its/css-sources/projects
- url = https://github.com/SonarSource/css-test-sources
diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644
index 0a041280bd0..00000000000
--- a/LICENSE.txt
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/NOTICE.txt b/NOTICE.txt
deleted file mode 100644
index f12bd85fae3..00000000000
--- a/NOTICE.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-JavaScript
-Copyright (C) 2011-2017 SonarSource SA
-mailto:info AT sonarsource DOT com
-
-This product includes software developed at
-SonarSource (http://www.sonarsource.com/).
diff --git a/README.md b/README.md
deleted file mode 100644
index 0504ba7c3f5..00000000000
--- a/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-[](https://next.sonarqube.com/sonarqube/dashboard?id=org.sonarsource.javascript%3Ajavascript) [](https://next.sonarqube.com/sonarqube/component_measures/domain/Coverage?id=org.sonarsource.javascript%3Ajavascript)
-
-This SonarSource project is a [static code analyser](https://en.wikipedia.org/wiki/Static_program_analysis) for JavaScript, TypeScript and CSS languages.
-
-:arrow_right: [Have some feedback?](#support)
-
-:arrow_right: [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs), our plugin for ESLint
-
-# Features
-
-* Advanced rules based on pattern matching and control flow analysis
-* ~280 rules for [JavaScript](https://rules.sonarsource.com/javascript) and [TypeScript](https://rules.sonarsource.com/typescript)
-* ~30 rules for [CSS](https://rules.sonarsource.com/css)
-* Compatible with ECMAScript 2015-2020
-* React JSX, Flow and Vue support for JavaScript and TypeScript
-* CSS, SCSS, Less, also 'style' inside PHP, HTML and VueJS files
-* Metrics (complexity, number of lines etc.)
-* Import of test coverage reports
-* Import of ESLint, TSLint and Stylelint issues
-
-# Documentation
-You can find [documentation here](https://docs.sonarqube.org/latest/analysis/languages/javascript/)
-
-# Have question or feedback?
-### SonarSource Community Forum
-If you want to report a bug, request a feature or provide other kind of feedback, please use [SonarQube Community Forum](https://community.sonarsource.com/). Please do not forget to specify the details of your request, code reproducer, versions of projects you use.
-
-# Contributing
-
-#### 1. Request a new feature
-To request a new feature, create a new thread in [SonarSource Community Forum](https://community.sonarsource.com/). Even if you plan to implement it yourself and submit it back to the community, please create a thread to be sure that we can follow up on it.
-
-#### 2. Pull Request
-To submit a contribution, create a pull request for this repository. Please make sure that you follow our [code style](https://github.com/SonarSource/sonar-developer-toolset) and all [tests](/docs/DEV.md#testing) are passing.
-
-#### Work with us
-Would you like to work on this project full-time? We are hiring! Check out https://www.sonarsource.com/hiring
-
-## License
-
-Copyright 2011-2021 SonarSource.
-
-Licensed under the [GNU Lesser General Public License, Version 3.0](http://www.gnu.org/licenses/lgpl.txt)
diff --git a/check-license-compliance.sh b/check-license-compliance.sh
deleted file mode 100755
index de09f1f5640..00000000000
--- a/check-license-compliance.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-
-# See https://xtranet.sonarsource.com/display/DEV/Open+Source+Licenses
-
-mvn org.codehaus.mojo:license-maven-plugin:aggregate-add-third-party
diff --git a/css-sonarpedia/sonarpedia.json b/css-sonarpedia/sonarpedia.json
deleted file mode 100644
index 4a2865b6c17..00000000000
--- a/css-sonarpedia/sonarpedia.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "rules-metadata-path": "../sonar-javascript-plugin/src/main/resources/org/sonar/l10n/css/rules/css",
- "languages": [
- "CSS"
- ],
- "latest-update": "2023-01-12T15:04:36.239650Z",
- "options": {
- "no-language-in-filenames": true
- }
-}
\ No newline at end of file
diff --git a/docs/DEV.md b/docs/DEV.md
deleted file mode 100644
index dc6d8d67191..00000000000
--- a/docs/DEV.md
+++ /dev/null
@@ -1,264 +0,0 @@
-# Developer Guide
-
-## Prerequisites
-- [JDK 11](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/what-is-corretto-11.html)
-- [Maven](https://maven.apache.org/install.html)
-- Node.js (we recommend using [NVM](https://github.com/nvm-sh/nvm#installing-and-updating))
-
-You can also use Docker container defined in `./.cirrus/nodejs-lts.Dockerfile` which bundles all required dependencies and is used for our CI pipeline.
-
-## Build and run unit tests
-To build the plugin and run its unit tests, execute this command from the project's root directory:
-
-```sh
-mvn clean install
-```
-
-## Integration Tests
-First make sure the submodules are checked out:
-
-```sh
- git submodule init
- git submodule update
-```
-
-### Plugin Tests
-The "Plugin Test" is an integration test which verifies plugin features such as metric calculation, coverage etc.
-```sh
-cd its/plugin
-mvn clean install
-```
-
-### Ruling Tests
-The "Ruling Test" is an integration test which launches the analysis of a large code base (stored as submodules), saves the issues created by the plugin in report files, and then compares those results to the set of expected issues (stored as JSON files).
-```sh
-cd its/ruling
-mvn verify -Dtest=JavaScriptRulingTest -Dmaven.test.redirectTestOutputToFile=false
-mvn verify -Dtest=TypeScriptRulingTest -Dmaven.test.redirectTestOutputToFile=false
-mvn verify -Dtest=CssRulingTest -Dmaven.test.redirectTestOutputToFile=false
-```
-
-This test gives you the opportunity to examine the issues created by each rule and make sure that they are what you expect. You can inspect new/lost issues checking the SonarQube UI (use DEBUG mode and put a breakpoint on the assertion) at the end of analysis.
-
-If everything looks good to you, you can copy the file with the actual issues located at `its/ruling/target/actual/`
-into the directory with the expected issues `its/ruling/src/test/resources/expected/`.
-
-From `its/ruling/`:
-* for JS `cp -R target/actual/js/ src/test/expected/js`
-* for TS `cp -R target/actual/ts/ src/test/expected/ts`
-* for CSS `cp -R target/actual/css/ src/test/expected/css`
-
-You can review the Ruling difference by running `diff -rq src/test/expected/js target/actual/js` from `its/ruling`.
-
-To review the Ruling difference in SonarQube UI, put the breakpoint on `assertThat(...)` in `{JavaScript/CSS}RulingTest.java` and open in the browser the orchestrated local SonarQube.
-Note that you can fix the port in `orchestrator.properties files`, e.g. `orchestrator.container.port=9100`.
-
-## Adding a rule
-
-### Rule Description
-1. Create a PR with a rule description in RSPEC repo like described [here](https://github.com/SonarSource/rspec#create-or-modify-a-rule)
-2. Link this RSPEC PR to the implementation issue in this repo
-5. Make sure the implementation issue title contains the RSPEC number and name
-
-### Implementing a rule
-1. Generate rule metadata (JSON and HTML files) from [RSPEC](https://github.com/SonarSource/rspec#4-implement-the-rule) by running this command from the project's root:
-
-```sh
-java -jar generate -rule S1234 [-branch ]
-```
-
-2. Generate other files required for a new rule. If the rule is already covered by ESLint or its plugins, use the existing and add the `eslint` option.
-```sh
-cd eslint-bridge
-npm run new-rule S1234
-// e.g.
-npm run new-rule S1234 no-invalid-something [eslint]
-```
-This script:
-* generates a Java check class for the rule `NoInvalidSomethingCheck.java`
-* generates a `no-invalid-something.ts` file for the rule implementation
-* generates a `comment-based/no-invalid-something.js` test file
-* updates the `index.ts` file to include the new rule
-* updates the `CheckList.java` to include the new rule
-
-3. Update generated files
- * Make sure annotations in the Java class specify languages to cover (`@JavaScriptRule` and/or `@TypeScriptRule`)
- * If required, override the `configurations()` method of the Java check class
- * If writing a rule for the test files, replace `implements EslintBasedCheck` with `extends TestFileCheck` in the Java class
- * In the generated metadata JSON file `javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S1234.json`, add (one or both):
- ```json
- "compatibleLanguages": [
- "JAVASCRIPT",
- "TYPESCRIPT"
- ]
- ```
-4. Implement the rule logic in `no-invalid-something.ts`
- * Prefer using `meta.messages` to specify messages through `messageId`s. Message can be part of the RSPEC description, like [here](https://sonarsource.github.io/rspec/#/rspec/S4036/javascript#message).
- * Note that there are some helper functions in `src/linting/eslint/rules/helpers/`
- * If writing a regex rule, use [createRegExpRule](https://github.com/SonarSource/SonarJS/blob/2831eb9a53da914d58b8e063a017c68e71eab839/eslint-bridge/src/linting/eslint/rules/helpers/regex/rule-template.ts#L52)
- * If possible implement quick fixes for the rule (then add its rule key in `eslint-bridge/src/linting/eslint/linter/quickfixes/rules.ts`).
-
-## Testing a rule
-
-`eslint-bridge` supports 2 kinds of rule unit-tests: ESLint's [RuleTester](https://eslint.org/docs/developer-guide/nodejs-api#ruletester) or our comment-based tests. Prefer comment-based tests as they are more readable!
-
-### Comment-based testing
-
-These tests are located in `eslint-bridge/tests/linting/eslint/rules/comment-based/` and they **MUST** be named after the rule they are testing (i.e. `semi.[(js|ts)x?]` to test ESLint `semi` rule). If options are to be passed to the tested rule, add a JSON file to the same directory following the same naming convention but with a `.json` extension (i.e. `semi.json`). The file must contain the array of options.
-
-The contents of the test code have the following structure:
-
-```javascript
-some.clean.code();
-some.faulty.code(); // Noncompliant N [[qf1,qf2,...]] {{Optional message to assert}}
-// ^^^^^^
-// fix@qf1 {{Optional suggestion description}}
-// edit@qf1 [[sc=1;ec=5]] {{text to replace line from [sc] column to [ec] column}}
-faulty.setFaultyParam(true)
-// ^^^^^^^^^^^^^^< {{Optional secondary message to assert}}
-```
-
-The contents of the options file must be a valid JSON array:
-
-```javascript
-// brace-style.json
-["1tbs", { "allowSingleLine": true }]
-```
-
-#### Tests syntax
-
-Given the above test snippet: the issue primary location (`// ^^^^`), issue messages (`{{...}}`), secondary location(s) (`// ^^^<`), issues count (`N`) and quick fixes are optional.
-
-`N` is an integer defining the amount of issues will be reported in the line.
-
-Only one of the methods (`{{messageN}}+` OR `N`) to define the expected issues can be used in a `Noncompliant` line. If you set both `N` and messages, the framework will throw an error.
-
-If no `N` nor messages are provided, the engine will expect one issue to be raised. Meaning, `//Noncompliant` is equivalent to `//Noncompliant 1`.
-
-`Noncompliant` lines will be associated by default to the line of code where they are writen. The syntax `@line_number` allows for an issue to be associated to another line:
-
-```javascript
-// Noncompliant@2 N [[qf1,qf2,...]] {{Optional message to assert}}
-some.faulty.code();
-```
-
-Another option is to use relative line increments (`@+line_increment`) or decrements (`@-line_decrement`):
-```javascript
-// Noncompliant@+1
-some.faulty.code();
-
-another.faulty.code();
-// another comment
-// Noncompliant@-2
-```
-
-#### Secondary locations
-
-Secondary locations are part of [Sonar issues](https://docs.sonarqube.org/latest/user-guide/issues/). They provide additional context to the raised issue. In order to use them, you must call the [toEncodedMessage()](https://github.com/SonarSource/SonarJS/blob/66c14e5d1a68232940d540a19fb89872d41c206d/eslint-bridge/src/linting/eslint/rules/helpers/location.ts#L44) function when reporting the issue message like this:
-
-```javascript
-context.report({
- node,
- message: toEncodedMessage(...),
-});
-```
-
-In order to indicate secondary locations, you must use either `// ^^^^^<` or `// ^^^^>`, the arrow indicating whether the matching main location is either before or after the secondary one.
-
-As stated before, the message is optional.
-
-**/!\** If you have used a secondary location in your test file, you must always report error messages using [toEncodedMessage()](https://github.com/SonarSource/SonarJS/blob/66c14e5d1a68232940d540a19fb89872d41c206d/eslint-bridge/src/linting/eslint/rules/helpers/location.ts#L44) in your rule, as it will be expecting it.
-
-#### Quick fixes
-
-Quick fixes refer to both ESLint [Suggestions](https://eslint.org/docs/latest/developer-guide/working-with-rules#providing-suggestions) and [Fixes](https://eslint.org/docs/latest/developer-guide/working-with-rules#applying-fixes). In our comment-based framework both use the same syntax, with the difference that a quick fix ID followed by an exclamation mark (`!`) will be internally treated as a `fix` with ESLint instead of as a suggestion. Please note that rules providing fixes **MUST** be tested always with fixes, otherwise the test will fail with the following error: `The rule fixed the code. Please add 'output' property.`. On the other side, it is optional to check against rule suggestions, meaning that even if a rule provides them, the tests can choose not to test their contents.
-
-The `fix@` comment referring to a quick fix provides the suggestion description and is optional. Eslint fixes do not support descriptions, meaning a quick fix ID declared with an exclamation mark (i.e. `qf1!`) must **NOT** have a `fix@` matching comment (i.e. `fix@qf1`).
-
-Each quick fix can have multiple editions associated to it. There are three different kind of operations to edit the code with quick fixes. Given a quick fix ID `qf`, these are the syntaxes used for each operation:
-
-- `add@qf {{code to add}}` Add the string between the double brackets to a new line in the code.
-- `del@qf` Remove the line
-- `edit@qf1 [[sc=1;ec=5]] {{text to replace the range }}` Edit the line from start column `sc` to end column `ec` (both 0-based) with the provided string between the double brackets. Alternatively, one can conveniently use only `sc` or `ec`. also optional, meaning this syntax can be used too:
- - `edit@qf1 {{text to replace the whole line -do not include //Noncompliant comment- }}`
-
-The line affected in each of these operations will be the line of the issue to which the quick fix is linked to. It is possible to use the line modifier syntax (`@[+|-]?line`). When using line increments/decrements, keep in mind the base number is the issue line number, not the line of the quick fix edit comment. Example for rule `brace-style`:
-
-```javascript
-//Noncompliant@+1 [[qf!]]
-if (condition) { doSomething()
-}
-// edit@qf [[sc=16]] {{}}
-// add@qf@+1 {{ doSomething()}}
-```
-The expected output is:
-```javascript
-if (condition) {
- doSomething()
-}
-```
-Let's go through the syntax used in this example:
-- The test provides a fix (note the `!` after the ID `qf`).
-- The line `//Noncompliant@+1 [[qf!]]` means that in the following (`@+1`) line there is an issue for which we provide a quick fix.
-- The line `// edit@qf [[sc=16]] {{}}` is providing an edit to the same line of the issue, replacing the contents after column 16 (`sc=16`) by an empty string (`{{}}`). An alternative with the same effect would be `// edit@qf {{if (condition) {}}`, which would replace the whole line by `if (condition) {`.
-- Lastly, the line `// add@qf@+1 {{ doSomething()}}` will add a new line just after the issue line (`@+1`) with the contents ` doSomething()`
-
-
-
-Note that the length of the list of quick fixes cannot surpass the number of issues declared by `N` or the number of expected messages unless their matching issue is reassigned (see below).
-
-Quick fixes IDs can be any `string`, they don't have to follow the `qfN` convention. The order of the list is important, as they will be assigned to the message in the matching position. If one provides 3 messages and 2 quick fixes which are not to be matched against first and second message, there are two options:
-
-* A *dummy* quick fix can be used as placeholder:
-
-```javascript
-some.faulty.code(); // Noncompliant [[qf1,qf2,qf3]] {{message1}} {{message2}} {{message3}}
-// edit@qf1 {{fix for message1}}
-// edit@qf3 {{fix for message3}}
-// qf2 is declared but never used --> ignored by the engine
-```
-
-* Explicitly set the index (0-based) of the message to which the quick fix refers to with the syntax `=index` next to the quick fix ID:
-
-```javascript
-some.faulty.code(); // Noncompliant [[qf1,qf3=2]] {{message1}} {{message2}} {{message3}}
-// edit@qf1 {{fix for message1}}
-// edit@qf3 {{fix for message3}}
-```
-
-This last syntax is also needed if multiple suggestions are to be provided for the same issue:
-
-```javascript
-some.faulty.code(); // Noncompliant [[qf1,qf2=0]]
-// fix@qf1 {{first alternative quickfix description}}
-// edit@qf1 {{some.faulty?.code();}}
-// fix@qf2 {{second alternative quickfix description}}
-// edit@qf2 {{some.faulty && some.faulty.code();}}
-```
-
-To execute a single comment-based test:
-```sh
-npm run ctest -- -t="no-invalid-something"
-```
-
-#### Ruling
-
-Make sure to run [Ruling ITs](#ruling-tests) for the new or updated rule (don't forget to rebuild the jar before that!).
-
-If your rule does not raise any issue, you should write your own code that triggers your rule in:
-- `its/sources/file-for-rules/S1234.js` for code
-- `its/sources/file-for-rules/tests/S1234.js` for test code
-
-You can simply copy and paste compliant and non-compliant examples from your RSPEC HTML description.
-
-## Examples
-
-* Security Hotspot implementation: [PR](https://github.com/SonarSource/SonarJS/pull/3148)
-* Quality rule implemented with quickfix: [PR](https://github.com/SonarSource/SonarJS/pull/3141)
-* Adding a rule already covered by ESLint or its plugins: [PR](https://github.com/SonarSource/SonarJS/pull/3134)
-* Adding a quickfix for rule covered by ESLint or its plugins: [PR](https://github.com/SonarSource/SonarJS/pull/3058)
-
-## Misc
-* Use issue number for a branch name, e.g. `issue-1234`
-* You can use [AST explorer](https://astexplorer.net/) to explore the tree share. Use the `regexpp` parser when implementing a Regex rule.
-* [ESlint's working with rules](https://eslint.org/docs/developer-guide/working-with-rules)
diff --git a/eslint-bridge/.gitignore b/eslint-bridge/.gitignore
deleted file mode 100644
index c65962f165a..00000000000
--- a/eslint-bridge/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-lib/
-node_modules/
-coverage/
-test-report.xml
diff --git a/eslint-bridge/.prettierignore b/eslint-bridge/.prettierignore
deleted file mode 100644
index f6f05a13bdc..00000000000
--- a/eslint-bridge/.prettierignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.lint.js
-tests/**/fixtures
-tests/**/rules/comment-based
diff --git a/eslint-bridge/.vscode/launch.json b/eslint-bridge/.vscode/launch.json
deleted file mode 100644
index 23624a04d61..00000000000
--- a/eslint-bridge/.vscode/launch.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- "type": "node",
- "request": "launch",
- "name": "All Tests",
- "program": "${workspaceFolder}/node_modules/.bin/jest",
- "args": ["-i"],
- "internalConsoleOptions": "openOnSessionStart"
- },
- {
- "type": "node",
- "request": "launch",
- "name": "Current Open Test",
- "program": "${workspaceFolder}/node_modules/.bin/jest",
- "args": ["-i", "${fileBasenameNoExtension}"],
- "internalConsoleOptions": "openOnSessionStart"
- }
- ]
-}
diff --git a/eslint-bridge/.vscode/settings.json b/eslint-bridge/.vscode/settings.json
deleted file mode 100644
index b42a197153e..00000000000
--- a/eslint-bridge/.vscode/settings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "[typescript]": {
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true
- },
- "sonarlint.connectedMode.project": {
- "projectKey": "org.sonarsource.javascript:javascript"
- }
-}
diff --git a/eslint-bridge/bin/server b/eslint-bridge/bin/server
deleted file mode 100644
index 989246e39d7..00000000000
--- a/eslint-bridge/bin/server
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script expects following arguments
- *
- * port - port number on which server should listen
- * host - host address on which server should listen
- * workDir - working directory from SonarQube API
- * shouldUseTypeScriptParserForJS - whether TypeScript parser should be used for JS code (default true, can be set to false in case of perf issues)
- * sonarlint - when running in SonarLint (used to not compute metrics, highlighting, etc)
- * bundles - ; or : delimited paths to additional rule bundles
- */
-
-const server = require('../lib/server');
-const path = require('path');
-const context = require('../lib/helpers');
-
-const port = process.argv[2];
-const host = process.argv[3];
-const workDir = process.argv[4];
-const shouldUseTypeScriptParserForJS = process.argv[5] === 'true';
-const sonarlint = process.argv[6] === 'true';
-
-let bundles = [];
-if (process.argv[7]) {
- bundles = process.argv[7].split(path.delimiter);
-}
-
-context.setContext({ workDir, shouldUseTypeScriptParserForJS, sonarlint, bundles });
-server.start(port, host);
diff --git a/eslint-bridge/jest.config.js b/eslint-bridge/jest.config.js
deleted file mode 100644
index d365c61c6c0..00000000000
--- a/eslint-bridge/jest.config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-module.exports = {
- collectCoverageFrom: ['src/**/*.ts'],
- globals: {
- 'ts-jest': {
- tsconfig: 'tests/tsconfig.json',
- },
- },
- moduleFileExtensions: ['js', 'ts', 'json'],
- moduleDirectories: ['node_modules', '/src', '/tests/**/fixtures'],
- modulePathIgnorePatterns: [
- '/tests/linting/eslint/rules/fixtures/no-implicit-dependencies/bom-package-json-project/package.json',
- ],
- testResultsProcessor: 'jest-sonar-reporter',
- transform: {
- '^.+\\.ts$': 'ts-jest',
- },
- testMatch: ['/tests/**/*.test.ts'],
- testTimeout: 20000,
-};
diff --git a/eslint-bridge/package-lock.json b/eslint-bridge/package-lock.json
deleted file mode 100644
index 594572c5a8b..00000000000
--- a/eslint-bridge/package-lock.json
+++ /dev/null
@@ -1,18574 +0,0 @@
-{
- "name": "eslint-bridge",
- "version": "1.0.0",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "eslint-bridge",
- "version": "1.0.0",
- "bundleDependencies": [
- "@typescript-eslint/eslint-plugin",
- "@typescript-eslint/experimental-utils",
- "@typescript-eslint/parser",
- "@babel/core",
- "@babel/eslint-parser",
- "@babel/plugin-proposal-decorators",
- "@babel/preset-env",
- "@babel/preset-flow",
- "@babel/preset-react",
- "builtin-modules",
- "bytes",
- "eslint",
- "eslint-plugin-react",
- "eslint-plugin-react-hooks",
- "eslint-plugin-sonarjs",
- "express",
- "functional-red-black-tree",
- "lodash.clone",
- "module-alias",
- "postcss-html",
- "postcss-less",
- "postcss-scss",
- "postcss-syntax",
- "postcss-value-parser",
- "regexpp",
- "run-node",
- "scslre",
- "stylelint",
- "tmp",
- "vue-eslint-parser",
- "typescript",
- "yaml"
- ],
- "license": "LGPL-3.0",
- "dependencies": {
- "@babel/core": "7.19.0",
- "@babel/eslint-parser": "7.18.9",
- "@babel/plugin-proposal-decorators": "7.19.3",
- "@babel/preset-env": "7.19.0",
- "@babel/preset-flow": "7.18.6",
- "@babel/preset-react": "7.18.6",
- "@typescript-eslint/eslint-plugin": "5.48.1",
- "@typescript-eslint/experimental-utils": "5.48.1",
- "@typescript-eslint/parser": "5.48.1",
- "builtin-modules": "3.3.0",
- "bytes": "3.1.2",
- "eslint": "8.26.0",
- "eslint-plugin-react": "7.31.8",
- "eslint-plugin-react-hooks": "4.6.0",
- "eslint-plugin-sonarjs": "0.18.0",
- "express": "4.18.1",
- "functional-red-black-tree": "1.0.1",
- "lodash.clone": "4.5.0",
- "module-alias": "2.2.2",
- "postcss-html": "0.36.0",
- "postcss-less": "6.0.0",
- "postcss-scss": "4.0.3",
- "postcss-syntax": "0.36.2",
- "postcss-value-parser": "4.2.0",
- "regexpp": "3.2.0",
- "run-node": "2.0.0",
- "scslre": "0.1.6",
- "stylelint": "14.13.0",
- "tmp": "0.2.1",
- "typescript": "4.9.4",
- "vue-eslint-parser": "9.1.0",
- "yaml": "2.1.1"
- },
- "devDependencies": {
- "@types/bytes": "3.1.1",
- "@types/eslint": " 8.4.10",
- "@types/eslint-scope": "3.7.4",
- "@types/estree": "1.0.0",
- "@types/express": "4.17.14",
- "@types/functional-red-black-tree": "1.0.1",
- "@types/jest": "28.1.6",
- "@types/lodash.clone": "4.5.7",
- "@types/node": "16.11.9",
- "@types/tmp": "0.2.3",
- "jest": "28.1.3",
- "jest-sonar-reporter": "2.0.0",
- "mkdirp": "1.0.4",
- "prettier": "2.7.1",
- "ts-jest": "28.0.7",
- "ts-node": "10.9.1"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
- "inBundle": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.1.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
- "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/highlight": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.20.10",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
- "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
- "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
- "inBundle": true,
- "dependencies": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.0",
- "@babel/helper-module-transforms": "^7.19.0",
- "@babel/helpers": "^7.19.0",
- "@babel/parser": "^7.19.0",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.1",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/eslint-parser": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz",
- "integrity": "sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ==",
- "inBundle": true,
- "dependencies": {
- "eslint-scope": "^5.1.1",
- "eslint-visitor-keys": "^2.1.0",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || >=14.0.0"
- },
- "peerDependencies": {
- "@babel/core": ">=7.11.0",
- "eslint": "^7.5.0 || ^8.0.0"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
- "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.20.7",
- "@jridgewell/gen-mapping": "^0.3.2",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
- "inBundle": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
- "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz",
- "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-explode-assignable-expression": "^7.18.6",
- "@babel/types": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
- "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/compat-data": "^7.20.5",
- "@babel/helper-validator-option": "^7.18.6",
- "browserslist": "^4.21.3",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.20.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
- "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-member-expression-to-functions": "^7.20.7",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/helper-replace-supers": "^7.20.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/helper-split-export-declaration": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz",
- "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "regexpu-core": "^5.2.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz",
- "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.17.7",
- "@babel/helper-plugin-utils": "^7.16.7",
- "debug": "^4.1.1",
- "lodash.debounce": "^4.0.8",
- "resolve": "^1.14.2",
- "semver": "^6.1.2"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0-0"
- }
- },
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-explode-assignable-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz",
- "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
- "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
- "inBundle": true,
- "dependencies": {
- "@babel/template": "^7.18.10",
- "@babel/types": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
- "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz",
- "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
- "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
- "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.20.2",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/helper-validator-identifier": "^7.19.1",
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.10",
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz",
- "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
- "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
- "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-wrap-function": "^7.18.9",
- "@babel/types": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-replace-supers": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz",
- "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-member-expression-to-functions": "^7.20.7",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.7",
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-simple-access": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
- "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
- "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.20.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
- "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
- "inBundle": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
- "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
- "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-wrap-function": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz",
- "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-function-name": "^7.19.0",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.20.5",
- "@babel/types": "^7.20.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
- "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
- "inBundle": true,
- "dependencies": {
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.7",
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
- "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.18.6",
- "chalk": "^2.0.0",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
- "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==",
- "inBundle": true,
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz",
- "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz",
- "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/plugin-proposal-optional-chaining": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.13.0"
- }
- },
- "node_modules/@babel/plugin-proposal-async-generator-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz",
- "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-remap-async-to-generator": "^7.18.9",
- "@babel/plugin-syntax-async-generators": "^7.8.4"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-class-properties": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
- "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-class-static-block": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz",
- "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.20.7",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.12.0"
- }
- },
- "node_modules/@babel/plugin-proposal-decorators": {
- "version": "7.19.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz",
- "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.19.0",
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/helper-replace-supers": "^7.19.1",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/plugin-syntax-decorators": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-dynamic-import": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz",
- "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-export-namespace-from": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz",
- "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-json-strings": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz",
- "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz",
- "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
- "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-numeric-separator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz",
- "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-object-rest-spread": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
- "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
- "inBundle": true,
- "dependencies": {
- "@babel/compat-data": "^7.20.5",
- "@babel/helper-compilation-targets": "^7.20.7",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-optional-catch-binding": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz",
- "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-optional-chaining": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz",
- "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-private-methods": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz",
- "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-private-property-in-object": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz",
- "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-create-class-features-plugin": "^7.20.5",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
- "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-bigint": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-decorators": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz",
- "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-flow": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz",
- "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz",
- "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
- "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.10.4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.14.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
- "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz",
- "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz",
- "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-remap-async-to-generator": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz",
- "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz",
- "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-classes": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz",
- "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-compilation-targets": "^7.20.7",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-replace-supers": "^7.20.7",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz",
- "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/template": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz",
- "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz",
- "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz",
- "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz",
- "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-flow-strip-types": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz",
- "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/plugin-syntax-flow": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-for-of": {
- "version": "7.18.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz",
- "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-function-name": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz",
- "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.18.9",
- "@babel/helper-function-name": "^7.18.9",
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-literals": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz",
- "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz",
- "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz",
- "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz",
- "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-simple-access": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz",
- "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-validator-identifier": "^7.19.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz",
- "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-module-transforms": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz",
- "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.20.5",
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-new-target": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz",
- "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-object-super": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz",
- "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-replace-supers": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-parameters": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz",
- "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz",
- "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz",
- "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz",
- "integrity": "sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-jsx": "^7.18.6",
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-development": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz",
- "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==",
- "inBundle": true,
- "dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-pure-annotations": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz",
- "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
- "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "regenerator-transform": "^0.15.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz",
- "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz",
- "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-spread": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz",
- "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz",
- "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz",
- "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz",
- "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.18.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
- "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz",
- "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-env": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
- "integrity": "sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/compat-data": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.0",
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
- "@babel/plugin-proposal-async-generator-functions": "^7.19.0",
- "@babel/plugin-proposal-class-properties": "^7.18.6",
- "@babel/plugin-proposal-class-static-block": "^7.18.6",
- "@babel/plugin-proposal-dynamic-import": "^7.18.6",
- "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
- "@babel/plugin-proposal-json-strings": "^7.18.6",
- "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
- "@babel/plugin-proposal-numeric-separator": "^7.18.6",
- "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
- "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
- "@babel/plugin-proposal-optional-chaining": "^7.18.9",
- "@babel/plugin-proposal-private-methods": "^7.18.6",
- "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
- "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.18.6",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
- "@babel/plugin-transform-arrow-functions": "^7.18.6",
- "@babel/plugin-transform-async-to-generator": "^7.18.6",
- "@babel/plugin-transform-block-scoped-functions": "^7.18.6",
- "@babel/plugin-transform-block-scoping": "^7.18.9",
- "@babel/plugin-transform-classes": "^7.19.0",
- "@babel/plugin-transform-computed-properties": "^7.18.9",
- "@babel/plugin-transform-destructuring": "^7.18.13",
- "@babel/plugin-transform-dotall-regex": "^7.18.6",
- "@babel/plugin-transform-duplicate-keys": "^7.18.9",
- "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
- "@babel/plugin-transform-for-of": "^7.18.8",
- "@babel/plugin-transform-function-name": "^7.18.9",
- "@babel/plugin-transform-literals": "^7.18.9",
- "@babel/plugin-transform-member-expression-literals": "^7.18.6",
- "@babel/plugin-transform-modules-amd": "^7.18.6",
- "@babel/plugin-transform-modules-commonjs": "^7.18.6",
- "@babel/plugin-transform-modules-systemjs": "^7.19.0",
- "@babel/plugin-transform-modules-umd": "^7.18.6",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.0",
- "@babel/plugin-transform-new-target": "^7.18.6",
- "@babel/plugin-transform-object-super": "^7.18.6",
- "@babel/plugin-transform-parameters": "^7.18.8",
- "@babel/plugin-transform-property-literals": "^7.18.6",
- "@babel/plugin-transform-regenerator": "^7.18.6",
- "@babel/plugin-transform-reserved-words": "^7.18.6",
- "@babel/plugin-transform-shorthand-properties": "^7.18.6",
- "@babel/plugin-transform-spread": "^7.19.0",
- "@babel/plugin-transform-sticky-regex": "^7.18.6",
- "@babel/plugin-transform-template-literals": "^7.18.9",
- "@babel/plugin-transform-typeof-symbol": "^7.18.9",
- "@babel/plugin-transform-unicode-escapes": "^7.18.10",
- "@babel/plugin-transform-unicode-regex": "^7.18.6",
- "@babel/preset-modules": "^0.1.5",
- "@babel/types": "^7.19.0",
- "babel-plugin-polyfill-corejs2": "^0.3.2",
- "babel-plugin-polyfill-corejs3": "^0.5.3",
- "babel-plugin-polyfill-regenerator": "^0.4.0",
- "core-js-compat": "^3.22.1",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-flow": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz",
- "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-transform-flow-strip-types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-modules": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
- "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
- "@babel/plugin-transform-dotall-regex": "^7.4.4",
- "@babel/types": "^7.4.4",
- "esutils": "^2.0.2"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-react": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz",
- "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-transform-react-display-name": "^7.18.6",
- "@babel/plugin-transform-react-jsx": "^7.18.6",
- "@babel/plugin-transform-react-jsx-development": "^7.18.6",
- "@babel/plugin-transform-react-pure-annotations": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
- "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
- "inBundle": true,
- "dependencies": {
- "regenerator-runtime": "^0.13.11"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
- "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
- "inBundle": true,
- "dependencies": {
- "@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.20.12",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
- "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
- "inBundle": true,
- "dependencies": {
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.20.7",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
- "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-string-parser": "^7.19.4",
- "@babel/helper-validator-identifier": "^7.19.1",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true
- },
- "node_modules/@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "dependencies": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@csstools/selector-specificity": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
- "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
- "inBundle": true,
- "engines": {
- "node": "^12 || ^14 || >=16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- },
- "peerDependencies": {
- "postcss": "^8.2",
- "postcss-selector-parser": "^6.0.10"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
- "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
- "inBundle": true,
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.4.0",
- "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
- "inBundle": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "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==",
- "inBundle": true
- },
- "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",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/console": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz",
- "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/console/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/console/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/console/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/console/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/console/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/console/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/core": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz",
- "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==",
- "dev": true,
- "dependencies": {
- "@jest/console": "^28.1.3",
- "@jest/reporters": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-changed-files": "^28.1.3",
- "jest-config": "^28.1.3",
- "jest-haste-map": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-resolve-dependencies": "^28.1.3",
- "jest-runner": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "jest-watcher": "^28.1.3",
- "micromatch": "^4.0.4",
- "pretty-format": "^28.1.3",
- "rimraf": "^3.0.0",
- "slash": "^3.0.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/core/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/core/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/core/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/core/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/core/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/core/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/environment": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
- "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
- "dev": true,
- "dependencies": {
- "@jest/fake-timers": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "jest-mock": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/expect": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz",
- "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==",
- "dev": true,
- "dependencies": {
- "expect": "^28.1.3",
- "jest-snapshot": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/expect-utils": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz",
- "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==",
- "dev": true,
- "dependencies": {
- "jest-get-type": "^28.0.2"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/fake-timers": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
- "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "@sinonjs/fake-timers": "^9.1.2",
- "@types/node": "*",
- "jest-message-util": "^28.1.3",
- "jest-mock": "^28.1.3",
- "jest-util": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/globals": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz",
- "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==",
- "dev": true,
- "dependencies": {
- "@jest/environment": "^28.1.3",
- "@jest/expect": "^28.1.3",
- "@jest/types": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/reporters": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz",
- "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==",
- "dev": true,
- "dependencies": {
- "@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@jridgewell/trace-mapping": "^0.3.13",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^5.1.0",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-worker": "^28.1.3",
- "slash": "^3.0.0",
- "string-length": "^4.0.1",
- "strip-ansi": "^6.0.0",
- "terminal-link": "^2.0.0",
- "v8-to-istanbul": "^9.0.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/@jest/reporters/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/reporters/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/reporters/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/reporters/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/reporters/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/reporters/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/schemas": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
- "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
- "dev": true,
- "dependencies": {
- "@sinclair/typebox": "^0.24.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/source-map": {
- "version": "28.1.2",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz",
- "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==",
- "dev": true,
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.13",
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.9"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/test-result": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz",
- "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==",
- "dev": true,
- "dependencies": {
- "@jest/console": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "collect-v8-coverage": "^1.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/test-sequencer": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz",
- "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==",
- "dev": true,
- "dependencies": {
- "@jest/test-result": "^28.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/transform": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz",
- "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^28.1.3",
- "@jridgewell/trace-mapping": "^0.3.13",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
- "convert-source-map": "^1.4.0",
- "fast-json-stable-stringify": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-util": "^28.1.3",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
- "slash": "^3.0.0",
- "write-file-atomic": "^4.0.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/transform/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/transform/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/transform/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/transform/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/transform/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/transform/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/types": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
- "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^28.1.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/@jest/types/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/types/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/types/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/types/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/types/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/types/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
- "inBundle": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
- "inBundle": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
- "inBundle": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "inBundle": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.17",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
- "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
- "inBundle": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@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==",
- "inBundle": 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==",
- "inBundle": 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==",
- "inBundle": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@sinclair/typebox": {
- "version": "0.24.51",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
- "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
- "dev": true
- },
- "node_modules/@sinonjs/commons": {
- "version": "1.8.6",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
- "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/@sinonjs/fake-timers": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
- "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^1.7.0"
- }
- },
- "node_modules/@tsconfig/node10": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
- "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
- "dev": true
- },
- "node_modules/@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true
- },
- "node_modules/@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true
- },
- "node_modules/@tsconfig/node16": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
- "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
- "dev": true
- },
- "node_modules/@types/babel__core": {
- "version": "7.1.20",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
- "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
- "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
- "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
- "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.3.0"
- }
- },
- "node_modules/@types/body-parser": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
- "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
- "dev": true,
- "dependencies": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/bytes": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz",
- "integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==",
- "dev": true
- },
- "node_modules/@types/connect": {
- "version": "3.4.35",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
- "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/eslint": {
- "version": "8.4.10",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
- "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==",
- "dev": true,
- "dependencies": {
- "@types/estree": "*",
- "@types/json-schema": "*"
- }
- },
- "node_modules/@types/eslint-scope": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
- "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
- "dev": true,
- "dependencies": {
- "@types/eslint": "*",
- "@types/estree": "*"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
- "dev": true
- },
- "node_modules/@types/express": {
- "version": "4.17.14",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz",
- "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==",
- "dev": true,
- "dependencies": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^4.17.18",
- "@types/qs": "*",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/express-serve-static-core": {
- "version": "4.17.32",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.32.tgz",
- "integrity": "sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==",
- "dev": true,
- "dependencies": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*"
- }
- },
- "node_modules/@types/functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@types/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha512-gUXkc6hiRJ2yPyiidbDbtU5YDt0c8JjYjq671QPYmJg2kiYS53/814Hg2SY4wqL/hfCzfa3NZzeh2e30YhALww==",
- "dev": true
- },
- "node_modules/@types/graceful-fs": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
- "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
- "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
- "dev": true
- },
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
- "dev": true,
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
- "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
- "dev": true,
- "dependencies": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "node_modules/@types/jest": {
- "version": "28.1.6",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.6.tgz",
- "integrity": "sha512-0RbGAFMfcBJKOmqRazM8L98uokwuwD5F8rHrv/ZMbrZBwVOWZUyPG6VFNscjYr/vjM3Vu4fRrCPbOs42AfemaQ==",
- "dev": true,
- "dependencies": {
- "jest-matcher-utils": "^28.0.0",
- "pretty-format": "^28.0.0"
- }
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
- "inBundle": true
- },
- "node_modules/@types/lodash": {
- "version": "4.14.191",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
- "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
- "dev": true
- },
- "node_modules/@types/lodash.clone": {
- "version": "4.5.7",
- "resolved": "https://registry.npmjs.org/@types/lodash.clone/-/lodash.clone-4.5.7.tgz",
- "integrity": "sha512-jugWYM+xBUQCpWbn7p6BSbf8bRMHtJYnEIGZYngbStaU0aN4VFgAAkGgsc+MtHuepBOmjyUGiGv+dHnQQIGLZA==",
- "dev": true,
- "dependencies": {
- "@types/lodash": "*"
- }
- },
- "node_modules/@types/mime": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
- "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
- "dev": true
- },
- "node_modules/@types/minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
- "inBundle": true
- },
- "node_modules/@types/node": {
- "version": "16.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.9.tgz",
- "integrity": "sha512-MKmdASMf3LtPzwLyRrFjtFFZ48cMf8jmX5VRYrDQiJa8Ybu5VAmkqBWqKU8fdCwD8ysw4mQ9nrEHvzg6gunR7A==",
- "dev": true
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
- "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
- "inBundle": true
- },
- "node_modules/@types/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
- "inBundle": true
- },
- "node_modules/@types/prettier": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
- "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
- "dev": true
- },
- "node_modules/@types/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
- "dev": true
- },
- "node_modules/@types/range-parser": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
- "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
- "dev": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/@types/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
- "dev": true,
- "dependencies": {
- "@types/mime": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/stack-utils": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
- "dev": true
- },
- "node_modules/@types/tmp": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz",
- "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==",
- "dev": true
- },
- "node_modules/@types/yargs": {
- "version": "17.0.19",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
- "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
- "dev": true,
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@types/yargs-parser": {
- "version": "21.0.0",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
- "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
- "dev": true
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz",
- "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/type-utils": "5.48.1",
- "@typescript-eslint/utils": "5.48.1",
- "debug": "^4.3.4",
- "ignore": "^5.2.0",
- "natural-compare-lite": "^1.4.0",
- "regexpp": "^3.2.0",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.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
- }
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/@typescript-eslint/experimental-utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.48.1.tgz",
- "integrity": "sha512-8OoIZZuOeqsm5cxn2f01qHWtVC3M4iixSsfZXPiQUg4Sl4LiU+b5epcJFwxNfqeoLl+SGncELyi3x99zI6C0ng==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/utils": "5.48.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.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/parser": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz",
- "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/typescript-estree": "5.48.1",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.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
- }
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz",
- "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/visitor-keys": "5.48.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz",
- "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/typescript-estree": "5.48.1",
- "@typescript-eslint/utils": "5.48.1",
- "debug": "^4.3.4",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "*"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz",
- "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg==",
- "inBundle": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz",
- "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/visitor-keys": "5.48.1",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz",
- "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==",
- "inBundle": true,
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/typescript-estree": "5.48.1",
- "eslint-scope": "^5.1.1",
- "eslint-utils": "^3.0.0",
- "semver": "^7.3.7"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.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/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/utils/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/utils/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz",
- "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==",
- "inBundle": true,
- "dependencies": {
- "@typescript-eslint/types": "5.48.1",
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "inBundle": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "inBundle": true,
- "dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
- "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
- "inBundle": true,
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "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==",
- "inBundle": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
- "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
- "dev": true,
- "engines": {
- "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==",
- "inBundle": 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",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "inBundle": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
- "inBundle": true
- },
- "node_modules/array-includes": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
- "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "is-string": "^1.0.7"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/array.prototype.flatmap": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
- "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/babel-jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
- "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==",
- "dev": true,
- "dependencies": {
- "@jest/transform": "^28.1.3",
- "@types/babel__core": "^7.1.14",
- "babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^28.1.3",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.8.0"
- }
- },
- "node_modules/babel-jest/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/babel-jest/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/babel-jest/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/babel-jest/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/babel-jest/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-jest/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-istanbul": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^5.0.4",
- "test-exclude": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-plugin-jest-hoist": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz",
- "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz",
- "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==",
- "inBundle": true,
- "dependencies": {
- "@babel/compat-data": "^7.17.7",
- "@babel/helper-define-polyfill-provider": "^0.3.3",
- "semver": "^6.1.1"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
- "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.3.2",
- "core-js-compat": "^3.21.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz",
- "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==",
- "inBundle": true,
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.3.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-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",
- "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
- "dev": true,
- "dependencies": {
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.8.3",
- "@babel/plugin-syntax-import-meta": "^7.8.3",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.8.3",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-top-level-await": "^7.8.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/babel-preset-jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz",
- "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==",
- "dev": true,
- "dependencies": {
- "babel-plugin-jest-hoist": "^28.1.3",
- "babel-preset-current-node-syntax": "^1.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "inBundle": true
- },
- "node_modules/body-parser": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
- "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
- "inBundle": true,
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.10.3",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/body-parser/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "inBundle": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/body-parser/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "inBundle": true
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "inBundle": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "inBundle": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.21.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
- "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- }
- ],
- "inBundle": true,
- "dependencies": {
- "caniuse-lite": "^1.0.30001400",
- "electron-to-chromium": "^1.4.251",
- "node-releases": "^2.0.6",
- "update-browserslist-db": "^1.0.9"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "dev": true,
- "dependencies": {
- "fast-json-stable-stringify": "2.x"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/bser": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
- "dev": true,
- "dependencies": {
- "node-int64": "^0.4.0"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
- },
- "node_modules/builtin-modules": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
- "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "inBundle": true,
- "dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase-keys": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
- "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
- "inBundle": true,
- "dependencies": {
- "camelcase": "^5.3.1",
- "map-obj": "^4.0.0",
- "quick-lru": "^4.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001442",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
- "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- }
- ],
- "inBundle": true
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "inBundle": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/char-regex": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
- "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ci-info": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
- "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cjs-module-lexer": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
- "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
- "dev": true
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
- "dev": true,
- "engines": {
- "iojs": ">= 1.0.0",
- "node": ">= 0.12.0"
- }
- },
- "node_modules/collect-v8-coverage": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
- "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
- "dev": true
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "inBundle": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "inBundle": true
- },
- "node_modules/colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
- "inBundle": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "inBundle": true
- },
- "node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "inBundle": true,
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
- "inBundle": true
- },
- "node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
- "inBundle": true
- },
- "node_modules/core-js-compat": {
- "version": "3.27.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz",
- "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==",
- "inBundle": true,
- "dependencies": {
- "browserslist": "^4.21.4"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
- "node_modules/cosmiconfig": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
- "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
- "inBundle": true,
- "dependencies": {
- "@types/parse-json": "^4.0.0",
- "import-fresh": "^3.2.1",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0",
- "yaml": "^1.10.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/cosmiconfig/node_modules/yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "inBundle": true,
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/css-functions-list": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz",
- "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==",
- "inBundle": true,
- "engines": {
- "node": ">=12.22"
- }
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "inBundle": true,
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "inBundle": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "inBundle": true,
- "dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dedent": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
- "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
- "dev": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/deepmerge": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/define-properties": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
- "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
- "inBundle": true,
- "dependencies": {
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/detect-newline": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
- "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/diff-sequences": {
- "version": "28.1.1",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz",
- "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==",
- "dev": true,
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.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==",
- "inBundle": 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",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "inBundle": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/dom-serializer": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
- "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
- "inBundle": true,
- "dependencies": {
- "domelementtype": "^2.0.1",
- "entities": "^2.0.0"
- }
- },
- "node_modules/dom-serializer/node_modules/domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "inBundle": true
- },
- "node_modules/dom-serializer/node_modules/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
- "inBundle": true,
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/domelementtype": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
- "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
- "inBundle": true
- },
- "node_modules/domhandler": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
- "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
- "inBundle": true,
- "dependencies": {
- "domelementtype": "1"
- }
- },
- "node_modules/domutils": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
- "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
- "inBundle": true,
- "dependencies": {
- "dom-serializer": "0",
- "domelementtype": "1"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "inBundle": true
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.284",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
- "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
- "inBundle": true
- },
- "node_modules/emittery": {
- "version": "0.10.2",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz",
- "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/emittery?sponsor=1"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "inBundle": true
- },
- "node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
- "inBundle": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "inBundle": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/es-abstract": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz",
- "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "es-set-tostringtag": "^2.0.0",
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.1.3",
- "get-symbol-description": "^1.0.0",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
- "has": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.4",
- "is-array-buffer": "^3.0.0",
- "is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.10",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.12.2",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.4.3",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trimend": "^1.0.6",
- "string.prototype.trimstart": "^1.0.6",
- "typed-array-length": "^1.0.4",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.9"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
- "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
- "inBundle": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-shim-unscopables": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
- "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
- "inBundle": true,
- "dependencies": {
- "has": "^1.0.3"
- }
- },
- "node_modules/es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
- "inBundle": true,
- "dependencies": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "inBundle": true
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "inBundle": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/eslint": {
- "version": "8.26.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz",
- "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==",
- "inBundle": true,
- "dependencies": {
- "@eslint/eslintrc": "^1.3.3",
- "@humanwhocodes/config-array": "^0.11.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.10.0",
- "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.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.4.0",
- "esquery": "^1.4.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.15.0",
- "grapheme-splitter": "^1.0.4",
- "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",
- "regexpp": "^3.2.0",
- "strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-plugin-react": {
- "version": "7.31.8",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz",
- "integrity": "sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==",
- "inBundle": true,
- "dependencies": {
- "array-includes": "^3.1.5",
- "array.prototype.flatmap": "^1.3.0",
- "doctrine": "^2.1.0",
- "estraverse": "^5.3.0",
- "jsx-ast-utils": "^2.4.1 || ^3.0.0",
- "minimatch": "^3.1.2",
- "object.entries": "^1.1.5",
- "object.fromentries": "^2.0.5",
- "object.hasown": "^1.1.1",
- "object.values": "^1.1.5",
- "prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.3",
- "semver": "^6.3.0",
- "string.prototype.matchall": "^4.0.7"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
- }
- },
- "node_modules/eslint-plugin-react-hooks": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
- "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
- }
- },
- "node_modules/eslint-plugin-react/node_modules/doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
- "inBundle": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/eslint-plugin-react/node_modules/resolve": {
- "version": "2.0.0-next.4",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
- "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
- "inBundle": true,
- "dependencies": {
- "is-core-module": "^2.9.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/eslint-plugin-sonarjs": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.18.0.tgz",
- "integrity": "sha512-DJ3osLnt6KFdT5e9ZuIDOjT5A6wUGSLeiJJT03lPgpdD+7CVWlYAw9Goe3bt7SmbFO3Xh89NOCZAuB9XA7bAUQ==",
- "inBundle": true,
- "engines": {
- "node": ">=14"
- },
- "peerDependencies": {
- "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "inBundle": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/eslint-scope/node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "inBundle": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "inBundle": true,
- "dependencies": {
- "eslint-visitor-keys": "^2.0.0"
- },
- "engines": {
- "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=5"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "inBundle": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "inBundle": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "inBundle": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "inBundle": true
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "inBundle": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "inBundle": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint/node_modules/globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
- "inBundle": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "inBundle": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/espree": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
- "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
- "inBundle": true,
- "dependencies": {
- "acorn": "^8.8.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/espree/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "inBundle": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
- "inBundle": 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==",
- "inBundle": 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==",
- "inBundle": 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==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/expect": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
- "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==",
- "dev": true,
- "dependencies": {
- "@jest/expect-utils": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/express": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
- "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
- "inBundle": true,
- "dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.0",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.5.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.2.0",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.7",
- "qs": "6.10.3",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "inBundle": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/express/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "inBundle": 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",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "inBundle": true
- },
- "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==",
- "inBundle": 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==",
- "inBundle": 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",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "inBundle": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
- "inBundle": true,
- "engines": {
- "node": ">= 4.9.1"
- }
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "inBundle": 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",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
- "dev": true,
- "dependencies": {
- "bser": "2.1.1"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "inBundle": true,
- "dependencies": {
- "flat-cache": "^3.0.4"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "inBundle": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "inBundle": true,
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "inBundle": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "inBundle": true
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "inBundle": true,
- "dependencies": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
- "inBundle": true
- },
- "node_modules/for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
- "inBundle": true,
- "dependencies": {
- "is-callable": "^1.1.3"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "inBundle": true
- },
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "inBundle": true
- },
- "node_modules/function.prototype.name": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
- "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0",
- "functions-have-names": "^1.2.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
- "inBundle": true
- },
- "node_modules/functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "inBundle": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "inBundle": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
- "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
- "inBundle": true,
- "dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-package-type": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true,
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "inBundle": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "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==",
- "inBundle": true,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "inBundle": true,
- "dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "inBundle": true,
- "dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "inBundle": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/globalthis": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
- "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
- "inBundle": true,
- "dependencies": {
- "define-properties": "^1.1.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "inBundle": true,
- "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"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globjoin": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
- "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
- "inBundle": true
- },
- "node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
- "inBundle": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "dev": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "inBundle": true,
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
- "inBundle": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/has-property-descriptors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
- "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
- "inBundle": true,
- "dependencies": {
- "get-intrinsic": "^1.1.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "inBundle": true,
- "dependencies": {
- "has-symbols": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/hosted-git-info/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/hosted-git-info/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "node_modules/html-tags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz",
- "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/htmlparser2": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
- "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
- "inBundle": true,
- "dependencies": {
- "domelementtype": "^1.3.1",
- "domhandler": "^2.3.0",
- "domutils": "^1.5.1",
- "entities": "^1.1.1",
- "inherits": "^2.0.1",
- "readable-stream": "^3.1.1"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "inBundle": true,
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "dev": true,
- "engines": {
- "node": ">=10.17.0"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "inBundle": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/ignore": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
- "inBundle": 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==",
- "inBundle": 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-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/import-local": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
- "dev": true,
- "dependencies": {
- "pkg-dir": "^4.2.0",
- "resolve-cwd": "^3.0.0"
- },
- "bin": {
- "import-local-fixture": "fixtures/cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "inBundle": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "inBundle": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "inBundle": true
- },
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "inBundle": true
- },
- "node_modules/internal-slot": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz",
- "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==",
- "inBundle": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-array-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz",
- "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "is-typed-array": "^1.1.10"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "inBundle": true
- },
- "node_modules/is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
- "inBundle": true,
- "dependencies": {
- "has-bigints": "^1.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
- "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
- "inBundle": true,
- "dependencies": {
- "has": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
- "inBundle": true,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "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==",
- "inBundle": 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",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-generator-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
- "dev": true,
- "engines": {
- "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==",
- "inBundle": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "inBundle": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
- "inBundle": true,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-plain-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
- "inBundle": true,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
- "inBundle": true,
- "dependencies": {
- "has-symbols": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-typed-array": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
- "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
- "inBundle": true,
- "dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "inBundle": true
- },
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
- "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-instrument": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
- "dev": true,
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^3.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "dependencies": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
- "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
- "dev": true,
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz",
- "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==",
- "dev": true,
- "dependencies": {
- "@jest/core": "^28.1.3",
- "@jest/types": "^28.1.3",
- "import-local": "^3.0.2",
- "jest-cli": "^28.1.3"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-changed-files": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz",
- "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==",
- "dev": true,
- "dependencies": {
- "execa": "^5.0.0",
- "p-limit": "^3.1.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-circus": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz",
- "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==",
- "dev": true,
- "dependencies": {
- "@jest/environment": "^28.1.3",
- "@jest/expect": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "co": "^4.6.0",
- "dedent": "^0.7.0",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^28.1.3",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "p-limit": "^3.1.0",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-circus/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-circus/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-circus/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-circus/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-cli": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz",
- "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==",
- "dev": true,
- "dependencies": {
- "@jest/core": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "import-local": "^3.0.2",
- "jest-config": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "prompts": "^2.0.1",
- "yargs": "^17.3.1"
- },
- "bin": {
- "jest": "bin/jest.js"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/jest-cli/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-cli/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-cli/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-cli/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-cli/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-cli/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-config": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz",
- "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^28.1.3",
- "@jest/types": "^28.1.3",
- "babel-jest": "^28.1.3",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "deepmerge": "^4.2.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-circus": "^28.1.3",
- "jest-environment-node": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-runner": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "micromatch": "^4.0.4",
- "parse-json": "^5.2.0",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "@types/node": "*",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/jest-config/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-config/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-config/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-config/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-config/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-config/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-diff": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz",
- "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.0.0",
- "diff-sequences": "^28.1.1",
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-diff/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-diff/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-diff/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-diff/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-diff/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-diff/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-docblock": {
- "version": "28.1.1",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz",
- "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==",
- "dev": true,
- "dependencies": {
- "detect-newline": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-each": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz",
- "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "jest-get-type": "^28.0.2",
- "jest-util": "^28.1.3",
- "pretty-format": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-each/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-each/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-each/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-each/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-each/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-each/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-environment-node": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz",
- "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==",
- "dev": true,
- "dependencies": {
- "@jest/environment": "^28.1.3",
- "@jest/fake-timers": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "jest-mock": "^28.1.3",
- "jest-util": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-get-type": {
- "version": "28.0.2",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
- "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==",
- "dev": true,
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-haste-map": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz",
- "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "@types/graceful-fs": "^4.1.3",
- "@types/node": "*",
- "anymatch": "^3.0.3",
- "fb-watchman": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-regex-util": "^28.0.2",
- "jest-util": "^28.1.3",
- "jest-worker": "^28.1.3",
- "micromatch": "^4.0.4",
- "walker": "^1.0.8"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "optionalDependencies": {
- "fsevents": "^2.3.2"
- }
- },
- "node_modules/jest-leak-detector": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz",
- "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==",
- "dev": true,
- "dependencies": {
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-matcher-utils": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz",
- "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.0.0",
- "jest-diff": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-matcher-utils/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-message-util": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
- "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^28.1.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-message-util/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-message-util/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-message-util/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-message-util/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-mock": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
- "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "@types/node": "*"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-pnp-resolver": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
- "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
- "dev": true,
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "jest-resolve": "*"
- },
- "peerDependenciesMeta": {
- "jest-resolve": {
- "optional": true
- }
- }
- },
- "node_modules/jest-regex-util": {
- "version": "28.0.2",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz",
- "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==",
- "dev": true,
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-resolve": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz",
- "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-pnp-resolver": "^1.2.2",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "resolve": "^1.20.0",
- "resolve.exports": "^1.1.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-resolve-dependencies": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz",
- "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==",
- "dev": true,
- "dependencies": {
- "jest-regex-util": "^28.0.2",
- "jest-snapshot": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-resolve/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-resolve/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-resolve/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-resolve/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-resolve/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-resolve/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runner": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz",
- "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==",
- "dev": true,
- "dependencies": {
- "@jest/console": "^28.1.3",
- "@jest/environment": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "emittery": "^0.10.2",
- "graceful-fs": "^4.2.9",
- "jest-docblock": "^28.1.1",
- "jest-environment-node": "^28.1.3",
- "jest-haste-map": "^28.1.3",
- "jest-leak-detector": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-resolve": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-watcher": "^28.1.3",
- "jest-worker": "^28.1.3",
- "p-limit": "^3.1.0",
- "source-map-support": "0.5.13"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-runner/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-runner/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-runner/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-runner/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-runner/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runner/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runtime": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz",
- "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==",
- "dev": true,
- "dependencies": {
- "@jest/environment": "^28.1.3",
- "@jest/fake-timers": "^28.1.3",
- "@jest/globals": "^28.1.3",
- "@jest/source-map": "^28.1.2",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "cjs-module-lexer": "^1.0.0",
- "collect-v8-coverage": "^1.0.0",
- "execa": "^5.0.0",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-mock": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "slash": "^3.0.0",
- "strip-bom": "^4.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-runtime/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-runtime/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-runtime/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-runtime/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-runtime/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runtime/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-snapshot": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz",
- "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.11.6",
- "@babel/generator": "^7.7.2",
- "@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/traverse": "^7.7.2",
- "@babel/types": "^7.3.3",
- "@jest/expect-utils": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/babel__traverse": "^7.0.6",
- "@types/prettier": "^2.1.5",
- "babel-preset-current-node-syntax": "^1.0.0",
- "chalk": "^4.0.0",
- "expect": "^28.1.3",
- "graceful-fs": "^4.2.9",
- "jest-diff": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-haste-map": "^28.1.3",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "natural-compare": "^1.4.0",
- "pretty-format": "^28.1.3",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-snapshot/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-snapshot/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-snapshot/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-snapshot/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-snapshot/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-snapshot/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jest-snapshot/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jest-snapshot/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-snapshot/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/jest-sonar-reporter": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz",
- "integrity": "sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==",
- "dev": true,
- "dependencies": {
- "xml": "^1.0.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/jest-util": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
- "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-util/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-util/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-util/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-util/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-util/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-util/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-validate": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz",
- "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==",
- "dev": true,
- "dependencies": {
- "@jest/types": "^28.1.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^28.0.2",
- "leven": "^3.1.0",
- "pretty-format": "^28.1.3"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-validate/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-validate/node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/jest-validate/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-validate/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-validate/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-validate/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-validate/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-watcher": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz",
- "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==",
- "dev": true,
- "dependencies": {
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "emittery": "^0.10.2",
- "jest-util": "^28.1.3",
- "string-length": "^4.0.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-watcher/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-watcher/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-watcher/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-watcher/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-watcher/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-watcher/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-worker": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
- "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
- "dev": true,
- "dependencies": {
- "@types/node": "*",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/jest-worker/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/js-sdsl": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
- "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==",
- "inBundle": 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",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "inBundle": true
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "inBundle": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "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",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "inBundle": true
- },
- "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==",
- "inBundle": 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==",
- "inBundle": true
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "inBundle": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsx-ast-utils": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
- "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==",
- "inBundle": true,
- "dependencies": {
- "array-includes": "^3.1.5",
- "object.assign": "^4.1.3"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/known-css-properties": {
- "version": "0.25.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.25.0.tgz",
- "integrity": "sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA==",
- "inBundle": true
- },
- "node_modules/leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true,
- "engines": {
- "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==",
- "inBundle": 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",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "inBundle": true
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "inBundle": true
- },
- "node_modules/lodash.clone": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
- "integrity": "sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==",
- "inBundle": true
- },
- "node_modules/lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "inBundle": true
- },
- "node_modules/lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
- "dev": true
- },
- "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==",
- "inBundle": true
- },
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "inBundle": true
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "inBundle": true,
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "dev": true,
- "dependencies": {
- "semver": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
- },
- "node_modules/makeerror": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
- "dev": true,
- "dependencies": {
- "tmpl": "1.0.5"
- }
- },
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mathml-tag-names": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
- "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
- "inBundle": true,
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/meow": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
- "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
- "inBundle": true,
- "dependencies": {
- "@types/minimist": "^1.2.0",
- "camelcase-keys": "^6.2.2",
- "decamelize": "^1.2.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.0",
- "read-pkg-up": "^7.0.1",
- "redent": "^3.0.0",
- "trim-newlines": "^3.0.0",
- "type-fest": "^0.18.0",
- "yargs-parser": "^20.2.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/meow/node_modules/type-fest": {
- "version": "0.18.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
- "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
- "inBundle": true
- },
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "inBundle": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "inBundle": true,
- "dependencies": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "inBundle": true,
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "inBundle": true,
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "inBundle": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "inBundle": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/module-alias": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
- "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==",
- "inBundle": true
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "inBundle": true
- },
- "node_modules/nanoid": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
- "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
- "inBundle": true,
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "inBundle": 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==",
- "inBundle": true
- },
- "node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/node-int64": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
- "dev": true
- },
- "node_modules/node-releases": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
- "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
- "inBundle": true
- },
- "node_modules/normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "inBundle": true,
- "dependencies": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/normalize-package-data/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/normalize-package-data/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
- "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
- "inBundle": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.assign": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
- "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "has-symbols": "^1.0.3",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.entries": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz",
- "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.fromentries": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz",
- "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.hasown": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz",
- "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==",
- "inBundle": true,
- "dependencies": {
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.values": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
- "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "inBundle": true,
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "inBundle": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "inBundle": 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/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "inBundle": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "inBundle": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "inBundle": true,
- "engines": {
- "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==",
- "inBundle": 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",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "inBundle": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "inBundle": true
- },
- "node_modules/path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
- "inBundle": true
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "inBundle": true
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "inBundle": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
- "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-dir/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/pkg-dir/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.21",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
- "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- }
- ],
- "inBundle": true,
- "dependencies": {
- "nanoid": "^3.3.4",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-html": {
- "version": "0.36.0",
- "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz",
- "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==",
- "inBundle": true,
- "dependencies": {
- "htmlparser2": "^3.10.0"
- },
- "peerDependencies": {
- "postcss": ">=5.0.0",
- "postcss-syntax": ">=0.36.0"
- }
- },
- "node_modules/postcss-less": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz",
- "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==",
- "inBundle": true,
- "engines": {
- "node": ">=12"
- },
- "peerDependencies": {
- "postcss": "^8.3.5"
- }
- },
- "node_modules/postcss-media-query-parser": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
- "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
- "inBundle": true
- },
- "node_modules/postcss-resolve-nested-selector": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
- "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
- "inBundle": true
- },
- "node_modules/postcss-safe-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
- "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
- "inBundle": true,
- "engines": {
- "node": ">=12.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.3.3"
- }
- },
- "node_modules/postcss-scss": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.3.tgz",
- "integrity": "sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA==",
- "inBundle": true,
- "engines": {
- "node": ">=12.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.3.3"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.11",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
- "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
- "inBundle": true,
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-syntax": {
- "version": "0.36.2",
- "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
- "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
- "inBundle": true,
- "peerDependencies": {
- "postcss": ">=5.0.0"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "inBundle": true
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/prettier": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
- "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
- "dev": true,
- "bin": {
- "prettier": "bin-prettier.js"
- },
- "engines": {
- "node": ">=10.13.0"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/pretty-format": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
- "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
- "dev": true,
- "dependencies": {
- "@jest/schemas": "^28.1.3",
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "dev": true,
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "inBundle": true,
- "dependencies": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.13.1"
- }
- },
- "node_modules/prop-types/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "inBundle": true
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "inBundle": true,
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/punycode": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz",
- "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==",
- "inBundle": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.10.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
- "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
- "inBundle": true,
- "dependencies": {
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true
- },
- "node_modules/quick-lru": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
- "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "inBundle": true,
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/react-is": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
- },
- "node_modules/read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
- "inBundle": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "inBundle": true,
- "dependencies": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "inBundle": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "inBundle": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "inBundle": true,
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "inBundle": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg/node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "inBundle": true
- },
- "node_modules/read-pkg/node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "inBundle": true,
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/read-pkg/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "inBundle": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/read-pkg/node_modules/type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "inBundle": true,
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "inBundle": true,
- "dependencies": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/refa": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/refa/-/refa-0.9.1.tgz",
- "integrity": "sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==",
- "inBundle": true,
- "dependencies": {
- "regexpp": "^3.2.0"
- }
- },
- "node_modules/regenerate": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "inBundle": true
- },
- "node_modules/regenerate-unicode-properties": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
- "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
- "inBundle": true,
- "dependencies": {
- "regenerate": "^1.4.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "inBundle": true
- },
- "node_modules/regenerator-transform": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz",
- "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==",
- "inBundle": true,
- "dependencies": {
- "@babel/runtime": "^7.8.4"
- }
- },
- "node_modules/regexp-ast-analysis": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz",
- "integrity": "sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==",
- "inBundle": true,
- "dependencies": {
- "refa": "^0.9.0",
- "regexpp": "^3.2.0"
- }
- },
- "node_modules/regexp.prototype.flags": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
- "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "functions-have-names": "^1.2.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
- "node_modules/regexpu-core": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz",
- "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==",
- "inBundle": true,
- "dependencies": {
- "regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsgen": "^0.7.1",
- "regjsparser": "^0.9.1",
- "unicode-match-property-ecmascript": "^2.0.0",
- "unicode-match-property-value-ecmascript": "^2.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regjsgen": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz",
- "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==",
- "inBundle": true
- },
- "node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
- "inBundle": true,
- "dependencies": {
- "jsesc": "~0.5.0"
- },
- "bin": {
- "regjsparser": "bin/parser"
- }
- },
- "node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
- "inBundle": true,
- "bin": {
- "jsesc": "bin/jsesc"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
- "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
- "inBundle": true,
- "dependencies": {
- "is-core-module": "^2.9.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve-cwd": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
- "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
- "dev": true,
- "dependencies": {
- "resolve-from": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve-cwd/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "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==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/resolve.exports": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
- "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
- "dev": true,
- "engines": {
- "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==",
- "inBundle": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "inBundle": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-node": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/run-node/-/run-node-2.0.0.tgz",
- "integrity": "sha512-M024oSKOfXRbBZ4dzWeS4mZfLlkVrLbR+02lSno344whh60hFN7qjWnf3QXm/JePD9CR7W4gRe9tt4H/2PGkcw==",
- "inBundle": true,
- "bin": {
- "run-node": "run-node"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true,
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "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==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "inBundle": true
- },
- "node_modules/safe-regex-test": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "is-regex": "^1.1.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "inBundle": true
- },
- "node_modules/scslre": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.1.6.tgz",
- "integrity": "sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==",
- "inBundle": true,
- "dependencies": {
- "refa": "^0.9.0",
- "regexp-ast-analysis": "^0.2.3",
- "regexpp": "^3.2.0"
- }
- },
- "node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "inBundle": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "inBundle": true,
- "dependencies": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/send/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "inBundle": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/send/node_modules/debug/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "inBundle": true
- },
- "node_modules/send/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "inBundle": true
- },
- "node_modules/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "inBundle": true,
- "dependencies": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.18.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "inBundle": true
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "inBundle": true,
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "inBundle": true
- },
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "inBundle": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "inBundle": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "inBundle": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/slice-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "inBundle": true
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "inBundle": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.13",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
- "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
- "dev": true,
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/spdx-correct": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
- "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
- "inBundle": true,
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "inBundle": true
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "inBundle": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
- "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
- "inBundle": true
- },
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true
- },
- "node_modules/stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "dependencies": {
- "escape-string-regexp": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/stack-utils/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,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "inBundle": true,
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/string-length": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
- "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
- "dev": true,
- "dependencies": {
- "char-regex": "^1.0.2",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "inBundle": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string.prototype.matchall": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
- "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "regexp.prototype.flags": "^1.4.3",
- "side-channel": "^1.0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimend": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
- "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimstart": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
- "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "inBundle": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-bom": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "inBundle": true,
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/style-search": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
- "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==",
- "inBundle": true
- },
- "node_modules/stylelint": {
- "version": "14.13.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.13.0.tgz",
- "integrity": "sha512-NJSAdloiAB/jgVJKxMR90mWlctvmeBFGFVUvyKngi9+j/qPSJ5ZB+u8jOmGbLTnS7OHrII9NFGehPRyar8U5vg==",
- "inBundle": true,
- "dependencies": {
- "@csstools/selector-specificity": "^2.0.2",
- "balanced-match": "^2.0.0",
- "colord": "^2.9.3",
- "cosmiconfig": "^7.0.1",
- "css-functions-list": "^3.1.0",
- "debug": "^4.3.4",
- "fast-glob": "^3.2.12",
- "fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^6.0.1",
- "global-modules": "^2.0.0",
- "globby": "^11.1.0",
- "globjoin": "^0.1.4",
- "html-tags": "^3.2.0",
- "ignore": "^5.2.0",
- "import-lazy": "^4.0.0",
- "imurmurhash": "^0.1.4",
- "is-plain-object": "^5.0.0",
- "known-css-properties": "^0.25.0",
- "mathml-tag-names": "^2.1.3",
- "meow": "^9.0.0",
- "micromatch": "^4.0.5",
- "normalize-path": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.16",
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-safe-parser": "^6.0.0",
- "postcss-selector-parser": "^6.0.10",
- "postcss-value-parser": "^4.2.0",
- "resolve-from": "^5.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "style-search": "^0.1.0",
- "supports-hyperlinks": "^2.3.0",
- "svg-tags": "^1.0.0",
- "table": "^6.8.0",
- "v8-compile-cache": "^2.3.0",
- "write-file-atomic": "^4.0.2"
- },
- "bin": {
- "stylelint": "bin/stylelint.js"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/stylelint"
- }
- },
- "node_modules/stylelint/node_modules/balanced-match": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
- "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
- "inBundle": true
- },
- "node_modules/stylelint/node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "inBundle": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/supports-hyperlinks": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
- "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
- "inBundle": true,
- "dependencies": {
- "has-flag": "^4.0.0",
- "supports-color": "^7.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "inBundle": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/svg-tags": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
- "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
- "inBundle": true
- },
- "node_modules/table": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
- "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
- "inBundle": true,
- "dependencies": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/table/node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "inBundle": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/table/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "inBundle": true
- },
- "node_modules/terminal-link": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
- "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
- "dev": true,
- "dependencies": {
- "ansi-escapes": "^4.2.1",
- "supports-hyperlinks": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "dependencies": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "inBundle": true
- },
- "node_modules/tmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
- "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
- "inBundle": true,
- "dependencies": {
- "rimraf": "^3.0.0"
- },
- "engines": {
- "node": ">=8.17.0"
- }
- },
- "node_modules/tmpl": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "inBundle": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "inBundle": true,
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/trim-newlines": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
- "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
- "inBundle": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ts-jest": {
- "version": "28.0.7",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.7.tgz",
- "integrity": "sha512-wWXCSmTwBVmdvWrOpYhal79bDpioDy4rTT+0vyUnE3ZzM7LOAAGG9NXwzkEL/a516rQEgnMmS/WKP9jBPCVJyA==",
- "dev": true,
- "dependencies": {
- "bs-logger": "0.x",
- "fast-json-stable-stringify": "2.x",
- "jest-util": "^28.0.0",
- "json5": "^2.2.1",
- "lodash.memoize": "4.x",
- "make-error": "1.x",
- "semver": "7.x",
- "yargs-parser": "^21.0.1"
- },
- "bin": {
- "ts-jest": "cli.js"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
- },
- "peerDependencies": {
- "@babel/core": ">=7.0.0-beta.0 <8",
- "@jest/types": "^28.0.0",
- "babel-jest": "^28.0.0",
- "jest": "^28.0.0",
- "typescript": ">=4.3"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@jest/types": {
- "optional": true
- },
- "babel-jest": {
- "optional": true
- },
- "esbuild": {
- "optional": true
- }
- }
- },
- "node_modules/ts-jest/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ts-jest/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ts-jest/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/ts-jest/node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/ts-node": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
- "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
- "dev": true,
- "dependencies": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- },
- "bin": {
- "ts-node": "dist/bin.js",
- "ts-node-cwd": "dist/bin-cwd.js",
- "ts-node-esm": "dist/bin-esm.js",
- "ts-node-script": "dist/bin-script.js",
- "ts-node-transpile-only": "dist/bin-transpile.js",
- "ts-script": "dist/bin-script-deprecated.js"
- },
- "peerDependencies": {
- "@swc/core": ">=1.2.50",
- "@swc/wasm": ">=1.2.50",
- "@types/node": "*",
- "typescript": ">=2.7"
- },
- "peerDependenciesMeta": {
- "@swc/core": {
- "optional": true
- },
- "@swc/wasm": {
- "optional": true
- }
- }
- },
- "node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "inBundle": true
- },
- "node_modules/tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "inBundle": true,
- "dependencies": {
- "tslib": "^1.8.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_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==",
- "inBundle": 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",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "inBundle": true,
- "dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typed-array-length": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
- "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "is-typed-array": "^1.1.9"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typescript": {
- "version": "4.9.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
- "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
- "inBundle": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/unbox-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
- "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
- "inBundle": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "has-bigints": "^1.0.2",
- "has-symbols": "^1.0.3",
- "which-boxed-primitive": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
- "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
- "inBundle": true,
- "dependencies": {
- "unicode-canonical-property-names-ecmascript": "^2.0.0",
- "unicode-property-aliases-ecmascript": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-property-aliases-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
- "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
- "inBundle": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
- "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- }
- ],
- "inBundle": true,
- "dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
- },
- "bin": {
- "browserslist-lint": "cli.js"
- },
- "peerDependencies": {
- "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==",
- "inBundle": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "inBundle": true
- },
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
- "inBundle": true
- },
- "node_modules/v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true
- },
- "node_modules/v8-to-istanbul": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
- "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
- "dev": true,
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "inBundle": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "inBundle": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/vue-eslint-parser": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.0.tgz",
- "integrity": "sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==",
- "inBundle": true,
- "dependencies": {
- "debug": "^4.3.4",
- "eslint-scope": "^7.1.1",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
- "lodash": "^4.17.21",
- "semver": "^7.3.6"
- },
- "engines": {
- "node": "^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=6.0.0"
- }
- },
- "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "inBundle": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "inBundle": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/vue-eslint-parser/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "inBundle": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/vue-eslint-parser/node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "inBundle": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/vue-eslint-parser/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "inBundle": true
- },
- "node_modules/walker": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
- "dev": true,
- "dependencies": {
- "makeerror": "1.0.12"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "inBundle": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
- "inBundle": true,
- "dependencies": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
- "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
- "inBundle": true,
- "dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0",
- "is-typed-array": "^1.1.10"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "inBundle": 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",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "inBundle": true
- },
- "node_modules/write-file-atomic": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
- "inBundle": true,
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.7"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/xml": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
- "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
- "dev": true
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "inBundle": true
- },
- "node_modules/yaml": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
- "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==",
- "inBundle": true,
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/yargs": {
- "version": "17.6.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
- "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
- "dev": true,
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yargs/node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "inBundle": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- },
- "dependencies": {
- "@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
- "requires": {
- "@jridgewell/gen-mapping": "^0.1.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
- },
- "@babel/code-frame": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
- "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
- "requires": {
- "@babel/highlight": "^7.18.6"
- }
- },
- "@babel/compat-data": {
- "version": "7.20.10",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
- "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg=="
- },
- "@babel/core": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
- "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
- "requires": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.0",
- "@babel/helper-module-transforms": "^7.19.0",
- "@babel/helpers": "^7.19.0",
- "@babel/parser": "^7.19.0",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.1",
- "semver": "^6.3.0"
- }
- },
- "@babel/eslint-parser": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz",
- "integrity": "sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ==",
- "requires": {
- "eslint-scope": "^5.1.1",
- "eslint-visitor-keys": "^2.1.0",
- "semver": "^6.3.0"
- }
- },
- "@babel/generator": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
- "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
- "requires": {
- "@babel/types": "^7.20.7",
- "@jridgewell/gen-mapping": "^0.3.2",
- "jsesc": "^2.5.1"
- },
- "dependencies": {
- "@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
- "requires": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- }
- }
- }
- },
- "@babel/helper-annotate-as-pure": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz",
- "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz",
- "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==",
- "requires": {
- "@babel/helper-explode-assignable-expression": "^7.18.6",
- "@babel/types": "^7.18.9"
- }
- },
- "@babel/helper-compilation-targets": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
- "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
- "requires": {
- "@babel/compat-data": "^7.20.5",
- "@babel/helper-validator-option": "^7.18.6",
- "browserslist": "^4.21.3",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.0"
- }
- },
- "@babel/helper-create-class-features-plugin": {
- "version": "7.20.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
- "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-member-expression-to-functions": "^7.20.7",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/helper-replace-supers": "^7.20.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/helper-split-export-declaration": "^7.18.6"
- }
- },
- "@babel/helper-create-regexp-features-plugin": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz",
- "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "regexpu-core": "^5.2.1"
- }
- },
- "@babel/helper-define-polyfill-provider": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz",
- "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==",
- "requires": {
- "@babel/helper-compilation-targets": "^7.17.7",
- "@babel/helper-plugin-utils": "^7.16.7",
- "debug": "^4.1.1",
- "lodash.debounce": "^4.0.8",
- "resolve": "^1.14.2",
- "semver": "^6.1.2"
- }
- },
- "@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg=="
- },
- "@babel/helper-explode-assignable-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz",
- "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-function-name": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
- "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
- "requires": {
- "@babel/template": "^7.18.10",
- "@babel/types": "^7.19.0"
- }
- },
- "@babel/helper-hoist-variables": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
- "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-member-expression-to-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz",
- "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==",
- "requires": {
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/helper-module-imports": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
- "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-module-transforms": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
- "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
- "requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.20.2",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/helper-validator-identifier": "^7.19.1",
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.10",
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/helper-optimise-call-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz",
- "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-plugin-utils": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
- "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
- },
- "@babel/helper-remap-async-to-generator": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
- "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-wrap-function": "^7.18.9",
- "@babel/types": "^7.18.9"
- }
- },
- "@babel/helper-replace-supers": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz",
- "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==",
- "requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-member-expression-to-functions": "^7.20.7",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.7",
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/helper-simple-access": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
- "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
- "requires": {
- "@babel/types": "^7.20.2"
- }
- },
- "@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
- "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
- "requires": {
- "@babel/types": "^7.20.0"
- }
- },
- "@babel/helper-split-export-declaration": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
- "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
- "@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw=="
- },
- "@babel/helper-validator-identifier": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
- "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
- },
- "@babel/helper-validator-option": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
- "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw=="
- },
- "@babel/helper-wrap-function": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz",
- "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==",
- "requires": {
- "@babel/helper-function-name": "^7.19.0",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.20.5",
- "@babel/types": "^7.20.5"
- }
- },
- "@babel/helpers": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
- "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
- "requires": {
- "@babel/template": "^7.20.7",
- "@babel/traverse": "^7.20.7",
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/highlight": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
- "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
- "requires": {
- "@babel/helper-validator-identifier": "^7.18.6",
- "chalk": "^2.0.0",
- "js-tokens": "^4.0.0"
- }
- },
- "@babel/parser": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
- "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg=="
- },
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz",
- "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz",
- "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/plugin-proposal-optional-chaining": "^7.20.7"
- }
- },
- "@babel/plugin-proposal-async-generator-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz",
- "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==",
- "requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-remap-async-to-generator": "^7.18.9",
- "@babel/plugin-syntax-async-generators": "^7.8.4"
- }
- },
- "@babel/plugin-proposal-class-properties": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
- "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
- "requires": {
- "@babel/helper-create-class-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-proposal-class-static-block": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz",
- "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==",
- "requires": {
- "@babel/helper-create-class-features-plugin": "^7.20.7",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
- }
- },
- "@babel/plugin-proposal-decorators": {
- "version": "7.19.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz",
- "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==",
- "requires": {
- "@babel/helper-create-class-features-plugin": "^7.19.0",
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/helper-replace-supers": "^7.19.1",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/plugin-syntax-decorators": "^7.19.0"
- }
- },
- "@babel/plugin-proposal-dynamic-import": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz",
- "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-export-namespace-from": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz",
- "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-json-strings": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz",
- "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-logical-assignment-operators": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz",
- "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
- }
- },
- "@babel/plugin-proposal-nullish-coalescing-operator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
- "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-numeric-separator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz",
- "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
- }
- },
- "@babel/plugin-proposal-object-rest-spread": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
- "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
- "requires": {
- "@babel/compat-data": "^7.20.5",
- "@babel/helper-compilation-targets": "^7.20.7",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.20.7"
- }
- },
- "@babel/plugin-proposal-optional-catch-binding": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz",
- "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-optional-chaining": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz",
- "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
- }
- },
- "@babel/plugin-proposal-private-methods": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz",
- "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==",
- "requires": {
- "@babel/helper-create-class-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-proposal-private-property-in-object": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz",
- "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-create-class-features-plugin": "^7.20.5",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
- }
- },
- "@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
- "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
- "requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-syntax-async-generators": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
- "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-bigint": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
- "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
- "dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-class-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
- "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
- }
- },
- "@babel/plugin-syntax-class-static-block": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
- "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.14.5"
- }
- },
- "@babel/plugin-syntax-decorators": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz",
- "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.19.0"
- }
- },
- "@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.3"
- }
- },
- "@babel/plugin-syntax-flow": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz",
- "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-syntax-import-assertions": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz",
- "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.19.0"
- }
- },
- "@babel/plugin-syntax-import-meta": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
- "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
- "dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.4"
- }
- },
- "@babel/plugin-syntax-json-strings": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
- "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-jsx": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
- "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
- "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.4"
- }
- },
- "@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
- "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.4"
- }
- },
- "@babel/plugin-syntax-object-rest-spread": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
- "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-optional-catch-binding": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
- "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.8.0"
- }
- },
- "@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
- "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.14.5"
- }
- },
- "@babel/plugin-syntax-top-level-await": {
- "version": "7.14.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
- "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.14.5"
- }
- },
- "@babel/plugin-syntax-typescript": {
- "version": "7.20.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
- "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
- "dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.19.0"
- }
- },
- "@babel/plugin-transform-arrow-functions": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz",
- "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-async-to-generator": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz",
- "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==",
- "requires": {
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-remap-async-to-generator": "^7.18.9"
- }
- },
- "@babel/plugin-transform-block-scoped-functions": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz",
- "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-block-scoping": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz",
- "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-classes": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz",
- "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-compilation-targets": "^7.20.7",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-optimise-call-expression": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-replace-supers": "^7.20.7",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "globals": "^11.1.0"
- }
- },
- "@babel/plugin-transform-computed-properties": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz",
- "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/template": "^7.20.7"
- }
- },
- "@babel/plugin-transform-destructuring": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz",
- "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-dotall-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz",
- "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==",
- "requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-duplicate-keys": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz",
- "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-exponentiation-operator": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz",
- "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==",
- "requires": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-flow-strip-types": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz",
- "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/plugin-syntax-flow": "^7.18.6"
- }
- },
- "@babel/plugin-transform-for-of": {
- "version": "7.18.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz",
- "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-function-name": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz",
- "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==",
- "requires": {
- "@babel/helper-compilation-targets": "^7.18.9",
- "@babel/helper-function-name": "^7.18.9",
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-literals": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz",
- "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-member-expression-literals": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz",
- "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-modules-amd": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz",
- "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==",
- "requires": {
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-modules-commonjs": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz",
- "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==",
- "requires": {
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-simple-access": "^7.20.2"
- }
- },
- "@babel/plugin-transform-modules-systemjs": {
- "version": "7.20.11",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz",
- "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==",
- "requires": {
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-module-transforms": "^7.20.11",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-validator-identifier": "^7.19.1"
- }
- },
- "@babel/plugin-transform-modules-umd": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz",
- "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==",
- "requires": {
- "@babel/helper-module-transforms": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz",
- "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==",
- "requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.20.5",
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-new-target": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz",
- "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-object-super": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz",
- "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-replace-supers": "^7.18.6"
- }
- },
- "@babel/plugin-transform-parameters": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz",
- "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
- }
- },
- "@babel/plugin-transform-property-literals": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz",
- "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-react-display-name": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz",
- "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-react-jsx": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz",
- "integrity": "sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/plugin-syntax-jsx": "^7.18.6",
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/plugin-transform-react-jsx-development": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz",
- "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==",
- "requires": {
- "@babel/plugin-transform-react-jsx": "^7.18.6"
- }
- },
- "@babel/plugin-transform-react-pure-annotations": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz",
- "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==",
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-regenerator": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
- "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "regenerator-transform": "^0.15.1"
- }
- },
- "@babel/plugin-transform-reserved-words": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz",
- "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-shorthand-properties": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz",
- "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-spread": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz",
- "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.20.2",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0"
- }
- },
- "@babel/plugin-transform-sticky-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz",
- "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/plugin-transform-template-literals": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz",
- "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-typeof-symbol": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz",
- "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-unicode-escapes": {
- "version": "7.18.10",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
- "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.9"
- }
- },
- "@babel/plugin-transform-unicode-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz",
- "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==",
- "requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- }
- },
- "@babel/preset-env": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
- "integrity": "sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ==",
- "requires": {
- "@babel/compat-data": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.0",
- "@babel/helper-plugin-utils": "^7.19.0",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
- "@babel/plugin-proposal-async-generator-functions": "^7.19.0",
- "@babel/plugin-proposal-class-properties": "^7.18.6",
- "@babel/plugin-proposal-class-static-block": "^7.18.6",
- "@babel/plugin-proposal-dynamic-import": "^7.18.6",
- "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
- "@babel/plugin-proposal-json-strings": "^7.18.6",
- "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
- "@babel/plugin-proposal-numeric-separator": "^7.18.6",
- "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
- "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
- "@babel/plugin-proposal-optional-chaining": "^7.18.9",
- "@babel/plugin-proposal-private-methods": "^7.18.6",
- "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
- "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.18.6",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
- "@babel/plugin-transform-arrow-functions": "^7.18.6",
- "@babel/plugin-transform-async-to-generator": "^7.18.6",
- "@babel/plugin-transform-block-scoped-functions": "^7.18.6",
- "@babel/plugin-transform-block-scoping": "^7.18.9",
- "@babel/plugin-transform-classes": "^7.19.0",
- "@babel/plugin-transform-computed-properties": "^7.18.9",
- "@babel/plugin-transform-destructuring": "^7.18.13",
- "@babel/plugin-transform-dotall-regex": "^7.18.6",
- "@babel/plugin-transform-duplicate-keys": "^7.18.9",
- "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
- "@babel/plugin-transform-for-of": "^7.18.8",
- "@babel/plugin-transform-function-name": "^7.18.9",
- "@babel/plugin-transform-literals": "^7.18.9",
- "@babel/plugin-transform-member-expression-literals": "^7.18.6",
- "@babel/plugin-transform-modules-amd": "^7.18.6",
- "@babel/plugin-transform-modules-commonjs": "^7.18.6",
- "@babel/plugin-transform-modules-systemjs": "^7.19.0",
- "@babel/plugin-transform-modules-umd": "^7.18.6",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.0",
- "@babel/plugin-transform-new-target": "^7.18.6",
- "@babel/plugin-transform-object-super": "^7.18.6",
- "@babel/plugin-transform-parameters": "^7.18.8",
- "@babel/plugin-transform-property-literals": "^7.18.6",
- "@babel/plugin-transform-regenerator": "^7.18.6",
- "@babel/plugin-transform-reserved-words": "^7.18.6",
- "@babel/plugin-transform-shorthand-properties": "^7.18.6",
- "@babel/plugin-transform-spread": "^7.19.0",
- "@babel/plugin-transform-sticky-regex": "^7.18.6",
- "@babel/plugin-transform-template-literals": "^7.18.9",
- "@babel/plugin-transform-typeof-symbol": "^7.18.9",
- "@babel/plugin-transform-unicode-escapes": "^7.18.10",
- "@babel/plugin-transform-unicode-regex": "^7.18.6",
- "@babel/preset-modules": "^0.1.5",
- "@babel/types": "^7.19.0",
- "babel-plugin-polyfill-corejs2": "^0.3.2",
- "babel-plugin-polyfill-corejs3": "^0.5.3",
- "babel-plugin-polyfill-regenerator": "^0.4.0",
- "core-js-compat": "^3.22.1",
- "semver": "^6.3.0"
- }
- },
- "@babel/preset-flow": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz",
- "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-transform-flow-strip-types": "^7.18.6"
- }
- },
- "@babel/preset-modules": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
- "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
- "@babel/plugin-transform-dotall-regex": "^7.4.4",
- "@babel/types": "^7.4.4",
- "esutils": "^2.0.2"
- }
- },
- "@babel/preset-react": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz",
- "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==",
- "requires": {
- "@babel/helper-plugin-utils": "^7.18.6",
- "@babel/helper-validator-option": "^7.18.6",
- "@babel/plugin-transform-react-display-name": "^7.18.6",
- "@babel/plugin-transform-react-jsx": "^7.18.6",
- "@babel/plugin-transform-react-jsx-development": "^7.18.6",
- "@babel/plugin-transform-react-pure-annotations": "^7.18.6"
- }
- },
- "@babel/runtime": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
- "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
- "requires": {
- "regenerator-runtime": "^0.13.11"
- }
- },
- "@babel/template": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
- "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
- "requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7"
- }
- },
- "@babel/traverse": {
- "version": "7.20.12",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
- "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
- "requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.20.7",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- }
- },
- "@babel/types": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
- "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
- "requires": {
- "@babel/helper-string-parser": "^7.19.4",
- "@babel/helper-validator-identifier": "^7.19.1",
- "to-fast-properties": "^2.0.0"
- }
- },
- "@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true
- },
- "@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "requires": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "dependencies": {
- "@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "requires": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- }
- }
- },
- "@csstools/selector-specificity": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
- "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
- "requires": {}
- },
- "@eslint/eslintrc": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
- "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
- "requires": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.4.0",
- "globals": "^13.19.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"
- },
- "dependencies": {
- "globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
- "requires": {
- "type-fest": "^0.20.2"
- }
- },
- "type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
- }
- }
- },
- "@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==",
- "requires": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.5"
- }
- },
- "@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="
- },
- "@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=="
- },
- "@istanbuljs/load-nyc-config": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
- "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "get-package-type": "^0.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
- },
- "dependencies": {
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "requires": {
- "sprintf-js": "~1.0.2"
- }
- },
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "requires": {
- "p-try": "^2.0.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true
- }
- }
- },
- "@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
- "dev": true
- },
- "@jest/console": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz",
- "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "slash": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "@jest/core": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz",
- "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==",
- "dev": true,
- "requires": {
- "@jest/console": "^28.1.3",
- "@jest/reporters": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "jest-changed-files": "^28.1.3",
- "jest-config": "^28.1.3",
- "jest-haste-map": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-resolve-dependencies": "^28.1.3",
- "jest-runner": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "jest-watcher": "^28.1.3",
- "micromatch": "^4.0.4",
- "pretty-format": "^28.1.3",
- "rimraf": "^3.0.0",
- "slash": "^3.0.0",
- "strip-ansi": "^6.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "@jest/environment": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
- "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
- "dev": true,
- "requires": {
- "@jest/fake-timers": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "jest-mock": "^28.1.3"
- }
- },
- "@jest/expect": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz",
- "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==",
- "dev": true,
- "requires": {
- "expect": "^28.1.3",
- "jest-snapshot": "^28.1.3"
- }
- },
- "@jest/expect-utils": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz",
- "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==",
- "dev": true,
- "requires": {
- "jest-get-type": "^28.0.2"
- }
- },
- "@jest/fake-timers": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
- "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "@sinonjs/fake-timers": "^9.1.2",
- "@types/node": "*",
- "jest-message-util": "^28.1.3",
- "jest-mock": "^28.1.3",
- "jest-util": "^28.1.3"
- }
- },
- "@jest/globals": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz",
- "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==",
- "dev": true,
- "requires": {
- "@jest/environment": "^28.1.3",
- "@jest/expect": "^28.1.3",
- "@jest/types": "^28.1.3"
- }
- },
- "@jest/reporters": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz",
- "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==",
- "dev": true,
- "requires": {
- "@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@jridgewell/trace-mapping": "^0.3.13",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^5.1.0",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-worker": "^28.1.3",
- "slash": "^3.0.0",
- "string-length": "^4.0.1",
- "strip-ansi": "^6.0.0",
- "terminal-link": "^2.0.0",
- "v8-to-istanbul": "^9.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "@jest/schemas": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
- "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
- "dev": true,
- "requires": {
- "@sinclair/typebox": "^0.24.1"
- }
- },
- "@jest/source-map": {
- "version": "28.1.2",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz",
- "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==",
- "dev": true,
- "requires": {
- "@jridgewell/trace-mapping": "^0.3.13",
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.9"
- }
- },
- "@jest/test-result": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz",
- "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==",
- "dev": true,
- "requires": {
- "@jest/console": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "collect-v8-coverage": "^1.0.0"
- }
- },
- "@jest/test-sequencer": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz",
- "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==",
- "dev": true,
- "requires": {
- "@jest/test-result": "^28.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "slash": "^3.0.0"
- }
- },
- "@jest/transform": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz",
- "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==",
- "dev": true,
- "requires": {
- "@babel/core": "^7.11.6",
- "@jest/types": "^28.1.3",
- "@jridgewell/trace-mapping": "^0.3.13",
- "babel-plugin-istanbul": "^6.1.1",
- "chalk": "^4.0.0",
- "convert-source-map": "^1.4.0",
- "fast-json-stable-stringify": "^2.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-util": "^28.1.3",
- "micromatch": "^4.0.4",
- "pirates": "^4.0.4",
- "slash": "^3.0.0",
- "write-file-atomic": "^4.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "@jest/types": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
- "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
- "dev": true,
- "requires": {
- "@jest/schemas": "^28.1.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
- "requires": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
- },
- "@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
- },
- "@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
- },
- "@jridgewell/trace-mapping": {
- "version": "0.3.17",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
- "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
- "requires": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
- }
- },
- "@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==",
- "requires": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- }
- },
- "@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=="
- },
- "@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==",
- "requires": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- }
- },
- "@sinclair/typebox": {
- "version": "0.24.51",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
- "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
- "dev": true
- },
- "@sinonjs/commons": {
- "version": "1.8.6",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
- "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
- "dev": true,
- "requires": {
- "type-detect": "4.0.8"
- }
- },
- "@sinonjs/fake-timers": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
- "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
- "dev": true,
- "requires": {
- "@sinonjs/commons": "^1.7.0"
- }
- },
- "@tsconfig/node10": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
- "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
- "dev": true
- },
- "@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true
- },
- "@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true
- },
- "@tsconfig/node16": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
- "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
- "dev": true
- },
- "@types/babel__core": {
- "version": "7.1.20",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
- "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
- "dev": true,
- "requires": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "@types/babel__generator": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
- "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.0.0"
- }
- },
- "@types/babel__template": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
- "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
- "dev": true,
- "requires": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "@types/babel__traverse": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
- "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.3.0"
- }
- },
- "@types/body-parser": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
- "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
- "dev": true,
- "requires": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "@types/bytes": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz",
- "integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==",
- "dev": true
- },
- "@types/connect": {
- "version": "3.4.35",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
- "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
- },
- "@types/eslint": {
- "version": "8.4.10",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
- "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==",
- "dev": true,
- "requires": {
- "@types/estree": "*",
- "@types/json-schema": "*"
- }
- },
- "@types/eslint-scope": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz",
- "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==",
- "dev": true,
- "requires": {
- "@types/eslint": "*",
- "@types/estree": "*"
- }
- },
- "@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
- "dev": true
- },
- "@types/express": {
- "version": "4.17.14",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz",
- "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==",
- "dev": true,
- "requires": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^4.17.18",
- "@types/qs": "*",
- "@types/serve-static": "*"
- }
- },
- "@types/express-serve-static-core": {
- "version": "4.17.32",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.32.tgz",
- "integrity": "sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==",
- "dev": true,
- "requires": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*"
- }
- },
- "@types/functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@types/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha512-gUXkc6hiRJ2yPyiidbDbtU5YDt0c8JjYjq671QPYmJg2kiYS53/814Hg2SY4wqL/hfCzfa3NZzeh2e30YhALww==",
- "dev": true
- },
- "@types/graceful-fs": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
- "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
- "dev": true,
- "requires": {
- "@types/node": "*"
- }
- },
- "@types/istanbul-lib-coverage": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
- "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
- "dev": true
- },
- "@types/istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
- "dev": true,
- "requires": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "@types/istanbul-reports": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
- "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
- "dev": true,
- "requires": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "@types/jest": {
- "version": "28.1.6",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.6.tgz",
- "integrity": "sha512-0RbGAFMfcBJKOmqRazM8L98uokwuwD5F8rHrv/ZMbrZBwVOWZUyPG6VFNscjYr/vjM3Vu4fRrCPbOs42AfemaQ==",
- "dev": true,
- "requires": {
- "jest-matcher-utils": "^28.0.0",
- "pretty-format": "^28.0.0"
- }
- },
- "@types/json-schema": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
- },
- "@types/lodash": {
- "version": "4.14.191",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
- "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
- "dev": true
- },
- "@types/lodash.clone": {
- "version": "4.5.7",
- "resolved": "https://registry.npmjs.org/@types/lodash.clone/-/lodash.clone-4.5.7.tgz",
- "integrity": "sha512-jugWYM+xBUQCpWbn7p6BSbf8bRMHtJYnEIGZYngbStaU0aN4VFgAAkGgsc+MtHuepBOmjyUGiGv+dHnQQIGLZA==",
- "dev": true,
- "requires": {
- "@types/lodash": "*"
- }
- },
- "@types/mime": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
- "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
- "dev": true
- },
- "@types/minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ=="
- },
- "@types/node": {
- "version": "16.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.9.tgz",
- "integrity": "sha512-MKmdASMf3LtPzwLyRrFjtFFZ48cMf8jmX5VRYrDQiJa8Ybu5VAmkqBWqKU8fdCwD8ysw4mQ9nrEHvzg6gunR7A==",
- "dev": true
- },
- "@types/normalize-package-data": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
- "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
- },
- "@types/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
- },
- "@types/prettier": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
- "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
- "dev": true
- },
- "@types/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
- "dev": true
- },
- "@types/range-parser": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
- "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
- "dev": true
- },
- "@types/semver": {
- "version": "7.3.13",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
- "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw=="
- },
- "@types/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
- "dev": true,
- "requires": {
- "@types/mime": "*",
- "@types/node": "*"
- }
- },
- "@types/stack-utils": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
- "dev": true
- },
- "@types/tmp": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz",
- "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==",
- "dev": true
- },
- "@types/yargs": {
- "version": "17.0.19",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
- "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
- "dev": true,
- "requires": {
- "@types/yargs-parser": "*"
- }
- },
- "@types/yargs-parser": {
- "version": "21.0.0",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
- "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
- "dev": true
- },
- "@typescript-eslint/eslint-plugin": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz",
- "integrity": "sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==",
- "requires": {
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/type-utils": "5.48.1",
- "@typescript-eslint/utils": "5.48.1",
- "debug": "^4.3.4",
- "ignore": "^5.2.0",
- "natural-compare-lite": "^1.4.0",
- "regexpp": "^3.2.0",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "@typescript-eslint/experimental-utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.48.1.tgz",
- "integrity": "sha512-8OoIZZuOeqsm5cxn2f01qHWtVC3M4iixSsfZXPiQUg4Sl4LiU+b5epcJFwxNfqeoLl+SGncELyi3x99zI6C0ng==",
- "requires": {
- "@typescript-eslint/utils": "5.48.1"
- }
- },
- "@typescript-eslint/parser": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.1.tgz",
- "integrity": "sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==",
- "requires": {
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/typescript-estree": "5.48.1",
- "debug": "^4.3.4"
- }
- },
- "@typescript-eslint/scope-manager": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz",
- "integrity": "sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ==",
- "requires": {
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/visitor-keys": "5.48.1"
- }
- },
- "@typescript-eslint/type-utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz",
- "integrity": "sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==",
- "requires": {
- "@typescript-eslint/typescript-estree": "5.48.1",
- "@typescript-eslint/utils": "5.48.1",
- "debug": "^4.3.4",
- "tsutils": "^3.21.0"
- }
- },
- "@typescript-eslint/types": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.1.tgz",
- "integrity": "sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg=="
- },
- "@typescript-eslint/typescript-estree": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz",
- "integrity": "sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==",
- "requires": {
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/visitor-keys": "5.48.1",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "@typescript-eslint/utils": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.1.tgz",
- "integrity": "sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==",
- "requires": {
- "@types/json-schema": "^7.0.9",
- "@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.48.1",
- "@typescript-eslint/types": "5.48.1",
- "@typescript-eslint/typescript-estree": "5.48.1",
- "eslint-scope": "^5.1.1",
- "eslint-utils": "^3.0.0",
- "semver": "^7.3.7"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "@typescript-eslint/visitor-keys": {
- "version": "5.48.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz",
- "integrity": "sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA==",
- "requires": {
- "@typescript-eslint/types": "5.48.1",
- "eslint-visitor-keys": "^3.3.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA=="
- }
- }
- },
- "accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "requires": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- }
- },
- "acorn": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
- "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA=="
- },
- "acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "requires": {}
- },
- "acorn-walk": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
- "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
- "dev": true
- },
- "ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- }
- },
- "ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "dev": true,
- "requires": {
- "type-fest": "^0.21.3"
- }
- },
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "^1.9.0"
- }
- },
- "anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true
- },
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
- },
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
- },
- "array-includes": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
- "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "is-string": "^1.0.7"
- }
- },
- "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=="
- },
- "array.prototype.flatmap": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
- "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "es-shim-unscopables": "^1.0.0"
- }
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="
- },
- "astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
- },
- "available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
- },
- "babel-jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
- "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==",
- "dev": true,
- "requires": {
- "@jest/transform": "^28.1.3",
- "@types/babel__core": "^7.1.14",
- "babel-plugin-istanbul": "^6.1.1",
- "babel-preset-jest": "^28.1.3",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "slash": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "babel-plugin-istanbul": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
- "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
- "dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.0.0",
- "@istanbuljs/load-nyc-config": "^1.0.0",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^5.0.4",
- "test-exclude": "^6.0.0"
- }
- },
- "babel-plugin-jest-hoist": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz",
- "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==",
- "dev": true,
- "requires": {
- "@babel/template": "^7.3.3",
- "@babel/types": "^7.3.3",
- "@types/babel__core": "^7.1.14",
- "@types/babel__traverse": "^7.0.6"
- }
- },
- "babel-plugin-polyfill-corejs2": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz",
- "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==",
- "requires": {
- "@babel/compat-data": "^7.17.7",
- "@babel/helper-define-polyfill-provider": "^0.3.3",
- "semver": "^6.1.1"
- }
- },
- "babel-plugin-polyfill-corejs3": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
- "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
- "requires": {
- "@babel/helper-define-polyfill-provider": "^0.3.2",
- "core-js-compat": "^3.21.0"
- }
- },
- "babel-plugin-polyfill-regenerator": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz",
- "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==",
- "requires": {
- "@babel/helper-define-polyfill-provider": "^0.3.3"
- }
- },
- "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",
- "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
- "dev": true,
- "requires": {
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.8.3",
- "@babel/plugin-syntax-import-meta": "^7.8.3",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.8.3",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-top-level-await": "^7.8.3"
- }
- },
- "babel-preset-jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz",
- "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==",
- "dev": true,
- "requires": {
- "babel-plugin-jest-hoist": "^28.1.3",
- "babel-preset-current-node-syntax": "^1.0.0"
- }
- },
- "balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
- },
- "body-parser": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
- "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
- "requires": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.10.3",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- }
- }
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "browserslist": {
- "version": "4.21.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
- "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
- "requires": {
- "caniuse-lite": "^1.0.30001400",
- "electron-to-chromium": "^1.4.251",
- "node-releases": "^2.0.6",
- "update-browserslist-db": "^1.0.9"
- }
- },
- "bs-logger": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
- "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
- "dev": true,
- "requires": {
- "fast-json-stable-stringify": "2.x"
- }
- },
- "bser": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
- "dev": true,
- "requires": {
- "node-int64": "^0.4.0"
- }
- },
- "buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
- },
- "builtin-modules": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
- "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw=="
- },
- "bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
- },
- "call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "requires": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- }
- },
- "callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
- },
- "camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
- },
- "camelcase-keys": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
- "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
- "requires": {
- "camelcase": "^5.3.1",
- "map-obj": "^4.0.0",
- "quick-lru": "^4.0.1"
- }
- },
- "caniuse-lite": {
- "version": "1.0.30001442",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
- "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow=="
- },
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "char-regex": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
- "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
- "dev": true
- },
- "ci-info": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
- "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
- "dev": true
- },
- "cjs-module-lexer": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
- "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
- "dev": true
- },
- "cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- }
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
- "dev": true
- },
- "collect-v8-coverage": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
- "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
- "dev": true
- },
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
- "colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
- },
- "content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "requires": {
- "safe-buffer": "5.2.1"
- }
- },
- "content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
- },
- "convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
- },
- "cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
- },
- "core-js-compat": {
- "version": "3.27.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.1.tgz",
- "integrity": "sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==",
- "requires": {
- "browserslist": "^4.21.4"
- }
- },
- "cosmiconfig": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
- "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
- "requires": {
- "@types/parse-json": "^4.0.0",
- "import-fresh": "^3.2.1",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0",
- "yaml": "^1.10.0"
- },
- "dependencies": {
- "yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
- }
- }
- },
- "create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true
- },
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
- "css-functions-list": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz",
- "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w=="
- },
- "cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
- },
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "requires": {
- "ms": "2.1.2"
- }
- },
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
- },
- "decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "requires": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "dependencies": {
- "map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="
- }
- }
- },
- "dedent": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
- "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
- "dev": true
- },
- "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=="
- },
- "deepmerge": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "dev": true
- },
- "define-properties": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
- "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
- "requires": {
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- }
- },
- "depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
- },
- "destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
- },
- "detect-newline": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
- "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
- "dev": true
- },
- "diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true
- },
- "diff-sequences": {
- "version": "28.1.1",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz",
- "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==",
- "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==",
- "requires": {
- "path-type": "^4.0.0"
- }
- },
- "doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "requires": {
- "esutils": "^2.0.2"
- }
- },
- "dom-serializer": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
- "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
- "requires": {
- "domelementtype": "^2.0.1",
- "entities": "^2.0.0"
- },
- "dependencies": {
- "domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
- },
- "entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
- }
- }
- },
- "domelementtype": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
- "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
- },
- "domhandler": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
- "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
- "requires": {
- "domelementtype": "1"
- }
- },
- "domutils": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
- "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
- "requires": {
- "dom-serializer": "0",
- "domelementtype": "1"
- }
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
- },
- "electron-to-chromium": {
- "version": "1.4.284",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
- "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA=="
- },
- "emittery": {
- "version": "0.10.2",
- "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz",
- "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==",
- "dev": true
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
- },
- "entities": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
- "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
- },
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "requires": {
- "is-arrayish": "^0.2.1"
- }
- },
- "es-abstract": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz",
- "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==",
- "requires": {
- "call-bind": "^1.0.2",
- "es-set-tostringtag": "^2.0.0",
- "es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.1.3",
- "get-symbol-description": "^1.0.0",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
- "has": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.4",
- "is-array-buffer": "^3.0.0",
- "is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.10",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.12.2",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.4.3",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trimend": "^1.0.6",
- "string.prototype.trimstart": "^1.0.6",
- "typed-array-length": "^1.0.4",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.9"
- }
- },
- "es-set-tostringtag": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
- "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
- "requires": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "has-tostringtag": "^1.0.0"
- }
- },
- "es-shim-unscopables": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
- "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
- "requires": {
- "has": "^1.0.3"
- }
- },
- "es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
- "requires": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
- }
- },
- "escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
- },
- "eslint": {
- "version": "8.26.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz",
- "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==",
- "requires": {
- "@eslint/eslintrc": "^1.3.3",
- "@humanwhocodes/config-array": "^0.11.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.10.0",
- "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.1.1",
- "eslint-utils": "^3.0.0",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.4.0",
- "esquery": "^1.4.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.15.0",
- "grapheme-splitter": "^1.0.4",
- "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",
- "regexpp": "^3.2.0",
- "strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "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=="
- },
- "eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "requires": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- }
- },
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA=="
- },
- "globals": {
- "version": "13.19.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
- "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
- "requires": {
- "type-fest": "^0.20.2"
- }
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
- }
- }
- },
- "eslint-plugin-react": {
- "version": "7.31.8",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz",
- "integrity": "sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==",
- "requires": {
- "array-includes": "^3.1.5",
- "array.prototype.flatmap": "^1.3.0",
- "doctrine": "^2.1.0",
- "estraverse": "^5.3.0",
- "jsx-ast-utils": "^2.4.1 || ^3.0.0",
- "minimatch": "^3.1.2",
- "object.entries": "^1.1.5",
- "object.fromentries": "^2.0.5",
- "object.hasown": "^1.1.1",
- "object.values": "^1.1.5",
- "prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.3",
- "semver": "^6.3.0",
- "string.prototype.matchall": "^4.0.7"
- },
- "dependencies": {
- "doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
- "requires": {
- "esutils": "^2.0.2"
- }
- },
- "resolve": {
- "version": "2.0.0-next.4",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
- "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
- "requires": {
- "is-core-module": "^2.9.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- }
- }
- }
- },
- "eslint-plugin-react-hooks": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
- "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
- "requires": {}
- },
- "eslint-plugin-sonarjs": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.18.0.tgz",
- "integrity": "sha512-DJ3osLnt6KFdT5e9ZuIDOjT5A6wUGSLeiJJT03lPgpdD+7CVWlYAw9Goe3bt7SmbFO3Xh89NOCZAuB9XA7bAUQ==",
- "requires": {}
- },
- "eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "requires": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "dependencies": {
- "estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
- }
- }
- },
- "eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "requires": {
- "eslint-visitor-keys": "^2.0.0"
- }
- },
- "eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
- },
- "espree": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
- "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
- "requires": {
- "acorn": "^8.8.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.3.0"
- },
- "dependencies": {
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA=="
- }
- }
- },
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true
- },
- "esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
- "requires": {
- "estraverse": "^5.1.0"
- }
- },
- "esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "requires": {
- "estraverse": "^5.2.0"
- }
- },
- "estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
- },
- "esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
- },
- "execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dev": true,
- "requires": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- }
- },
- "exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
- "dev": true
- },
- "expect": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
- "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==",
- "dev": true,
- "requires": {
- "@jest/expect-utils": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3"
- }
- },
- "express": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
- "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
- "requires": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.0",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.5.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.2.0",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.7",
- "qs": "6.10.3",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- }
- }
- },
- "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=="
- },
- "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==",
- "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==",
- "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",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
- },
- "fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="
- },
- "fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "requires": {
- "reusify": "^1.0.4"
- }
- },
- "fb-watchman": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
- "dev": true,
- "requires": {
- "bser": "2.1.1"
- }
- },
- "file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "requires": {
- "flat-cache": "^3.0.4"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- }
- }
- },
- "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==",
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "requires": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- }
- },
- "flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
- },
- "for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
- "requires": {
- "is-callable": "^1.1.3"
- }
- },
- "forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
- },
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- },
- "function.prototype.name": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
- "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0",
- "functions-have-names": "^1.2.2"
- }
- },
- "functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g=="
- },
- "functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
- },
- "gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
- },
- "get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
- },
- "get-intrinsic": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
- "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
- "requires": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.3"
- }
- },
- "get-package-type": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
- "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true
- },
- "get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true
- },
- "get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
- "requires": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
- }
- },
- "glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "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==",
- "requires": {
- "is-glob": "^4.0.3"
- }
- },
- "global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "requires": {
- "global-prefix": "^3.0.0"
- }
- },
- "global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "requires": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "dependencies": {
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "requires": {
- "isexe": "^2.0.0"
- }
- }
- }
- },
- "globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
- },
- "globalthis": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
- "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
- "requires": {
- "define-properties": "^1.1.3"
- }
- },
- "globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "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"
- }
- },
- "globjoin": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
- "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg=="
- },
- "gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
- "requires": {
- "get-intrinsic": "^1.1.3"
- }
- },
- "graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "dev": true
- },
- "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=="
- },
- "hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA=="
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ=="
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
- },
- "has-property-descriptors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
- "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
- "requires": {
- "get-intrinsic": "^1.1.1"
- }
- },
- "has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
- },
- "has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
- },
- "has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "requires": {
- "has-symbols": "^1.0.2"
- }
- },
- "hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "requires": {
- "lru-cache": "^6.0.0"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "html-tags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz",
- "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg=="
- },
- "htmlparser2": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
- "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
- "requires": {
- "domelementtype": "^1.3.1",
- "domhandler": "^2.3.0",
- "domutils": "^1.5.1",
- "entities": "^1.1.1",
- "inherits": "^2.0.1",
- "readable-stream": "^3.1.1"
- }
- },
- "http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "requires": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- }
- },
- "human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "dev": true
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "ignore": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
- },
- "import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "requires": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- }
- },
- "import-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw=="
- },
- "import-local": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
- "dev": true,
- "requires": {
- "pkg-dir": "^4.2.0",
- "resolve-cwd": "^3.0.0"
- }
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
- },
- "indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
- },
- "internal-slot": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz",
- "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==",
- "requires": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "side-channel": "^1.0.4"
- }
- },
- "ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
- },
- "is-array-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz",
- "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==",
- "requires": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "is-typed-array": "^1.1.10"
- }
- },
- "is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
- },
- "is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
- "requires": {
- "has-bigints": "^1.0.1"
- }
- },
- "is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
- "requires": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
- },
- "is-core-module": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
- "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
- "requires": {
- "has": "^1.0.3"
- }
- },
- "is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
- "requires": {
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
- },
- "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",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "is-generator-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
- "dev": true
- },
- "is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
- },
- "is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
- "requires": {
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="
- },
- "is-plain-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="
- },
- "is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
- },
- "is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
- "requires": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-shared-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
- "requires": {
- "call-bind": "^1.0.2"
- }
- },
- "is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "dev": true
- },
- "is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
- "requires": {
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
- "requires": {
- "has-symbols": "^1.0.2"
- }
- },
- "is-typed-array": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
- "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
- "requires": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0"
- }
- },
- "is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
- "requires": {
- "call-bind": "^1.0.2"
- }
- },
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
- },
- "istanbul-lib-coverage": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
- "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
- "dev": true
- },
- "istanbul-lib-instrument": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
- "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
- "dev": true,
- "requires": {
- "@babel/core": "^7.12.3",
- "@babel/parser": "^7.14.7",
- "@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.2.0",
- "semver": "^6.3.0"
- }
- },
- "istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
- "dev": true,
- "requires": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^3.0.0",
- "supports-color": "^7.1.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "istanbul-lib-source-maps": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
- "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
- "dev": true,
- "requires": {
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0",
- "source-map": "^0.6.1"
- }
- },
- "istanbul-reports": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
- "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
- "dev": true,
- "requires": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- }
- },
- "jest": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz",
- "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==",
- "dev": true,
- "requires": {
- "@jest/core": "^28.1.3",
- "@jest/types": "^28.1.3",
- "import-local": "^3.0.2",
- "jest-cli": "^28.1.3"
- }
- },
- "jest-changed-files": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz",
- "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==",
- "dev": true,
- "requires": {
- "execa": "^5.0.0",
- "p-limit": "^3.1.0"
- }
- },
- "jest-circus": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz",
- "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==",
- "dev": true,
- "requires": {
- "@jest/environment": "^28.1.3",
- "@jest/expect": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "co": "^4.6.0",
- "dedent": "^0.7.0",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^28.1.3",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "p-limit": "^3.1.0",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-cli": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz",
- "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==",
- "dev": true,
- "requires": {
- "@jest/core": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.9",
- "import-local": "^3.0.2",
- "jest-config": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "prompts": "^2.0.1",
- "yargs": "^17.3.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-config": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz",
- "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==",
- "dev": true,
- "requires": {
- "@babel/core": "^7.11.6",
- "@jest/test-sequencer": "^28.1.3",
- "@jest/types": "^28.1.3",
- "babel-jest": "^28.1.3",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "deepmerge": "^4.2.2",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-circus": "^28.1.3",
- "jest-environment-node": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-runner": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "micromatch": "^4.0.4",
- "parse-json": "^5.2.0",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "strip-json-comments": "^3.1.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-diff": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz",
- "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==",
- "dev": true,
- "requires": {
- "chalk": "^4.0.0",
- "diff-sequences": "^28.1.1",
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-docblock": {
- "version": "28.1.1",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz",
- "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==",
- "dev": true,
- "requires": {
- "detect-newline": "^3.0.0"
- }
- },
- "jest-each": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz",
- "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "jest-get-type": "^28.0.2",
- "jest-util": "^28.1.3",
- "pretty-format": "^28.1.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-environment-node": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz",
- "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==",
- "dev": true,
- "requires": {
- "@jest/environment": "^28.1.3",
- "@jest/fake-timers": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "jest-mock": "^28.1.3",
- "jest-util": "^28.1.3"
- }
- },
- "jest-get-type": {
- "version": "28.0.2",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
- "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==",
- "dev": true
- },
- "jest-haste-map": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz",
- "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "@types/graceful-fs": "^4.1.3",
- "@types/node": "*",
- "anymatch": "^3.0.3",
- "fb-watchman": "^2.0.0",
- "fsevents": "^2.3.2",
- "graceful-fs": "^4.2.9",
- "jest-regex-util": "^28.0.2",
- "jest-util": "^28.1.3",
- "jest-worker": "^28.1.3",
- "micromatch": "^4.0.4",
- "walker": "^1.0.8"
- }
- },
- "jest-leak-detector": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz",
- "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==",
- "dev": true,
- "requires": {
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- }
- },
- "jest-matcher-utils": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz",
- "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==",
- "dev": true,
- "requires": {
- "chalk": "^4.0.0",
- "jest-diff": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "pretty-format": "^28.1.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-message-util": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
- "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@jest/types": "^28.1.3",
- "@types/stack-utils": "^2.0.0",
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "micromatch": "^4.0.4",
- "pretty-format": "^28.1.3",
- "slash": "^3.0.0",
- "stack-utils": "^2.0.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-mock": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
- "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "@types/node": "*"
- }
- },
- "jest-pnp-resolver": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
- "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
- "dev": true,
- "requires": {}
- },
- "jest-regex-util": {
- "version": "28.0.2",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz",
- "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==",
- "dev": true
- },
- "jest-resolve": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz",
- "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==",
- "dev": true,
- "requires": {
- "chalk": "^4.0.0",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-pnp-resolver": "^1.2.2",
- "jest-util": "^28.1.3",
- "jest-validate": "^28.1.3",
- "resolve": "^1.20.0",
- "resolve.exports": "^1.1.0",
- "slash": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-resolve-dependencies": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz",
- "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==",
- "dev": true,
- "requires": {
- "jest-regex-util": "^28.0.2",
- "jest-snapshot": "^28.1.3"
- }
- },
- "jest-runner": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz",
- "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==",
- "dev": true,
- "requires": {
- "@jest/console": "^28.1.3",
- "@jest/environment": "^28.1.3",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "emittery": "^0.10.2",
- "graceful-fs": "^4.2.9",
- "jest-docblock": "^28.1.1",
- "jest-environment-node": "^28.1.3",
- "jest-haste-map": "^28.1.3",
- "jest-leak-detector": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-resolve": "^28.1.3",
- "jest-runtime": "^28.1.3",
- "jest-util": "^28.1.3",
- "jest-watcher": "^28.1.3",
- "jest-worker": "^28.1.3",
- "p-limit": "^3.1.0",
- "source-map-support": "0.5.13"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-runtime": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz",
- "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==",
- "dev": true,
- "requires": {
- "@jest/environment": "^28.1.3",
- "@jest/fake-timers": "^28.1.3",
- "@jest/globals": "^28.1.3",
- "@jest/source-map": "^28.1.2",
- "@jest/test-result": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "chalk": "^4.0.0",
- "cjs-module-lexer": "^1.0.0",
- "collect-v8-coverage": "^1.0.0",
- "execa": "^5.0.0",
- "glob": "^7.1.3",
- "graceful-fs": "^4.2.9",
- "jest-haste-map": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-mock": "^28.1.3",
- "jest-regex-util": "^28.0.2",
- "jest-resolve": "^28.1.3",
- "jest-snapshot": "^28.1.3",
- "jest-util": "^28.1.3",
- "slash": "^3.0.0",
- "strip-bom": "^4.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-snapshot": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz",
- "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==",
- "dev": true,
- "requires": {
- "@babel/core": "^7.11.6",
- "@babel/generator": "^7.7.2",
- "@babel/plugin-syntax-typescript": "^7.7.2",
- "@babel/traverse": "^7.7.2",
- "@babel/types": "^7.3.3",
- "@jest/expect-utils": "^28.1.3",
- "@jest/transform": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/babel__traverse": "^7.0.6",
- "@types/prettier": "^2.1.5",
- "babel-preset-current-node-syntax": "^1.0.0",
- "chalk": "^4.0.0",
- "expect": "^28.1.3",
- "graceful-fs": "^4.2.9",
- "jest-diff": "^28.1.3",
- "jest-get-type": "^28.0.2",
- "jest-haste-map": "^28.1.3",
- "jest-matcher-utils": "^28.1.3",
- "jest-message-util": "^28.1.3",
- "jest-util": "^28.1.3",
- "natural-compare": "^1.4.0",
- "pretty-format": "^28.1.3",
- "semver": "^7.3.5"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- }
- }
- },
- "jest-sonar-reporter": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz",
- "integrity": "sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==",
- "dev": true,
- "requires": {
- "xml": "^1.0.1"
- }
- },
- "jest-util": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
- "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-validate": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz",
- "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==",
- "dev": true,
- "requires": {
- "@jest/types": "^28.1.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^28.0.2",
- "leven": "^3.1.0",
- "pretty-format": "^28.1.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-watcher": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz",
- "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==",
- "dev": true,
- "requires": {
- "@jest/test-result": "^28.1.3",
- "@jest/types": "^28.1.3",
- "@types/node": "*",
- "ansi-escapes": "^4.2.1",
- "chalk": "^4.0.0",
- "emittery": "^0.10.2",
- "jest-util": "^28.1.3",
- "string-length": "^4.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-worker": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
- "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
- "dev": true,
- "requires": {
- "@types/node": "*",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "js-sdsl": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
- "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ=="
- },
- "js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- },
- "js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "requires": {
- "argparse": "^2.0.1"
- }
- },
- "jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
- },
- "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",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
- },
- "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=="
- },
- "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=="
- },
- "json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
- },
- "jsx-ast-utils": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
- "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==",
- "requires": {
- "array-includes": "^3.1.5",
- "object.assign": "^4.1.3"
- }
- },
- "kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
- },
- "kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true
- },
- "known-css-properties": {
- "version": "0.25.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.25.0.tgz",
- "integrity": "sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA=="
- },
- "leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "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==",
- "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",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
- },
- "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==",
- "requires": {
- "p-locate": "^5.0.0"
- }
- },
- "lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "lodash.clone": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
- "integrity": "sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg=="
- },
- "lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
- },
- "lodash.memoize": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
- "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
- "dev": true
- },
- "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=="
- },
- "lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw=="
- },
- "loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "requires": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- }
- },
- "lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "requires": {
- "yallist": "^3.0.2"
- }
- },
- "make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "dev": true,
- "requires": {
- "semver": "^6.0.0"
- }
- },
- "make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
- },
- "makeerror": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
- "dev": true,
- "requires": {
- "tmpl": "1.0.5"
- }
- },
- "map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="
- },
- "mathml-tag-names": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
- "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg=="
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
- },
- "meow": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
- "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
- "requires": {
- "@types/minimist": "^1.2.0",
- "camelcase-keys": "^6.2.2",
- "decamelize": "^1.2.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.0",
- "read-pkg-up": "^7.0.1",
- "redent": "^3.0.0",
- "trim-newlines": "^3.0.0",
- "type-fest": "^0.18.0",
- "yargs-parser": "^20.2.3"
- },
- "dependencies": {
- "type-fest": {
- "version": "0.18.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
- "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw=="
- }
- }
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
- },
- "merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
- },
- "merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
- },
- "micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "requires": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- }
- },
- "mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
- },
- "mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
- },
- "mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "requires": {
- "mime-db": "1.52.0"
- }
- },
- "mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true
- },
- "min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
- },
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "requires": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- }
- },
- "mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true
- },
- "module-alias": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
- "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q=="
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
- "nanoid": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
- "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
- },
- "natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
- },
- "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=="
- },
- "negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
- },
- "node-int64": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
- "dev": true
- },
- "node-releases": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
- "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A=="
- },
- "normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "requires": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
- },
- "npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "requires": {
- "path-key": "^3.0.0"
- }
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
- },
- "object-inspect": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
- "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
- },
- "object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
- },
- "object.assign": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
- "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "has-symbols": "^1.0.3",
- "object-keys": "^1.1.1"
- }
- },
- "object.entries": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz",
- "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "object.fromentries": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz",
- "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "object.hasown": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz",
- "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==",
- "requires": {
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "object.values": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
- "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "requires": {
- "wrappy": "1"
- }
- },
- "onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dev": true,
- "requires": {
- "mimic-fn": "^2.1.0"
- }
- },
- "optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "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",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "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==",
- "requires": {
- "p-limit": "^3.0.2"
- }
- },
- "p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
- },
- "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==",
- "requires": {
- "callsites": "^3.0.0"
- }
- },
- "parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- }
- },
- "parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
- },
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
- },
- "path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
- },
- "path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
- },
- "path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
- },
- "picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
- },
- "picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
- },
- "pirates": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
- "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
- "dev": true
- },
- "pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "requires": {
- "find-up": "^4.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "requires": {
- "p-try": "^2.0.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- }
- }
- },
- "postcss": {
- "version": "8.4.21",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
- "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
- "requires": {
- "nanoid": "^3.3.4",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- }
- },
- "postcss-html": {
- "version": "0.36.0",
- "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz",
- "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==",
- "requires": {
- "htmlparser2": "^3.10.0"
- }
- },
- "postcss-less": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz",
- "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==",
- "requires": {}
- },
- "postcss-media-query-parser": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
- "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig=="
- },
- "postcss-resolve-nested-selector": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
- "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw=="
- },
- "postcss-safe-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
- "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
- "requires": {}
- },
- "postcss-scss": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.3.tgz",
- "integrity": "sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA==",
- "requires": {}
- },
- "postcss-selector-parser": {
- "version": "6.0.11",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
- "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
- "requires": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- }
- },
- "postcss-syntax": {
- "version": "0.36.2",
- "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
- "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
- "requires": {}
- },
- "postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
- },
- "prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
- },
- "prettier": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
- "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
- "dev": true
- },
- "pretty-format": {
- "version": "28.1.3",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
- "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
- "dev": true,
- "requires": {
- "@jest/schemas": "^28.1.3",
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true
- }
- }
- },
- "prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "dev": true,
- "requires": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- }
- },
- "prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "requires": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.13.1"
- },
- "dependencies": {
- "react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- }
- }
- },
- "proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "requires": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- }
- },
- "punycode": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz",
- "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw=="
- },
- "qs": {
- "version": "6.10.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
- "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
- "requires": {
- "side-channel": "^1.0.4"
- }
- },
- "queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
- },
- "quick-lru": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
- "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g=="
- },
- "range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
- },
- "raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "requires": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- }
- },
- "react-is": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
- },
- "read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
- "requires": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
- },
- "dependencies": {
- "hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
- },
- "normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- },
- "type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg=="
- }
- }
- },
- "read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "requires": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "dependencies": {
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "requires": {
- "p-try": "^2.0.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
- }
- }
- },
- "readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
- "redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "requires": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- }
- },
- "refa": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/refa/-/refa-0.9.1.tgz",
- "integrity": "sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==",
- "requires": {
- "regexpp": "^3.2.0"
- }
- },
- "regenerate": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
- },
- "regenerate-unicode-properties": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
- "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
- "requires": {
- "regenerate": "^1.4.2"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
- },
- "regenerator-transform": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz",
- "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==",
- "requires": {
- "@babel/runtime": "^7.8.4"
- }
- },
- "regexp-ast-analysis": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz",
- "integrity": "sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==",
- "requires": {
- "refa": "^0.9.0",
- "regexpp": "^3.2.0"
- }
- },
- "regexp.prototype.flags": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
- "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "functions-have-names": "^1.2.2"
- }
- },
- "regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
- },
- "regexpu-core": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz",
- "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==",
- "requires": {
- "regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsgen": "^0.7.1",
- "regjsparser": "^0.9.1",
- "unicode-match-property-ecmascript": "^2.0.0",
- "unicode-match-property-value-ecmascript": "^2.1.0"
- }
- },
- "regjsgen": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz",
- "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA=="
- },
- "regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
- "requires": {
- "jsesc": "~0.5.0"
- },
- "dependencies": {
- "jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA=="
- }
- }
- },
- "require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true
- },
- "require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
- },
- "resolve": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
- "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
- "requires": {
- "is-core-module": "^2.9.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- }
- },
- "resolve-cwd": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
- "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
- "dev": true,
- "requires": {
- "resolve-from": "^5.0.0"
- },
- "dependencies": {
- "resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true
- }
- }
- },
- "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=="
- },
- "resolve.exports": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
- "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
- "dev": true
- },
- "reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
- },
- "rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "requires": {
- "glob": "^7.1.3"
- }
- },
- "run-node": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/run-node/-/run-node-2.0.0.tgz",
- "integrity": "sha512-M024oSKOfXRbBZ4dzWeS4mZfLlkVrLbR+02lSno344whh60hFN7qjWnf3QXm/JePD9CR7W4gRe9tt4H/2PGkcw=="
- },
- "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==",
- "requires": {
- "queue-microtask": "^1.2.2"
- }
- },
- "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=="
- },
- "safe-regex-test": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
- "requires": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "is-regex": "^1.1.4"
- }
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "scslre": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.1.6.tgz",
- "integrity": "sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==",
- "requires": {
- "refa": "^0.9.0",
- "regexp-ast-analysis": "^0.2.3",
- "regexpp": "^3.2.0"
- }
- },
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- },
- "send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "requires": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- },
- "dependencies": {
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- }
- }
- },
- "ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- }
- }
- },
- "serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.18.0"
- }
- },
- "setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
- },
- "shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "requires": {
- "shebang-regex": "^3.0.0"
- }
- },
- "shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
- },
- "side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
- "requires": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
- }
- },
- "signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
- },
- "sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true
- },
- "slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
- },
- "slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- }
- }
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
- },
- "source-map-support": {
- "version": "0.5.13",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
- "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "spdx-correct": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
- "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
- },
- "spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
- "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA=="
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true
- },
- "stack-utils": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
- "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
- "dev": true,
- "requires": {
- "escape-string-regexp": "^2.0.0"
- },
- "dependencies": {
- "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
- }
- }
- },
- "statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
- },
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "requires": {
- "safe-buffer": "~5.2.0"
- }
- },
- "string-length": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
- "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
- "dev": true,
- "requires": {
- "char-regex": "^1.0.2",
- "strip-ansi": "^6.0.0"
- }
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "string.prototype.matchall": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
- "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "regexp.prototype.flags": "^1.4.3",
- "side-channel": "^1.0.4"
- }
- },
- "string.prototype.trimend": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
- "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "string.prototype.trimstart": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
- "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.20.4"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "strip-bom": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
- "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true
- },
- "strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true
- },
- "strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "requires": {
- "min-indent": "^1.0.0"
- }
- },
- "strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
- },
- "style-search": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
- "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg=="
- },
- "stylelint": {
- "version": "14.13.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.13.0.tgz",
- "integrity": "sha512-NJSAdloiAB/jgVJKxMR90mWlctvmeBFGFVUvyKngi9+j/qPSJ5ZB+u8jOmGbLTnS7OHrII9NFGehPRyar8U5vg==",
- "requires": {
- "@csstools/selector-specificity": "^2.0.2",
- "balanced-match": "^2.0.0",
- "colord": "^2.9.3",
- "cosmiconfig": "^7.0.1",
- "css-functions-list": "^3.1.0",
- "debug": "^4.3.4",
- "fast-glob": "^3.2.12",
- "fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^6.0.1",
- "global-modules": "^2.0.0",
- "globby": "^11.1.0",
- "globjoin": "^0.1.4",
- "html-tags": "^3.2.0",
- "ignore": "^5.2.0",
- "import-lazy": "^4.0.0",
- "imurmurhash": "^0.1.4",
- "is-plain-object": "^5.0.0",
- "known-css-properties": "^0.25.0",
- "mathml-tag-names": "^2.1.3",
- "meow": "^9.0.0",
- "micromatch": "^4.0.5",
- "normalize-path": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.16",
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-safe-parser": "^6.0.0",
- "postcss-selector-parser": "^6.0.10",
- "postcss-value-parser": "^4.2.0",
- "resolve-from": "^5.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "style-search": "^0.1.0",
- "supports-hyperlinks": "^2.3.0",
- "svg-tags": "^1.0.0",
- "table": "^6.8.0",
- "v8-compile-cache": "^2.3.0",
- "write-file-atomic": "^4.0.2"
- },
- "dependencies": {
- "balanced-match": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
- "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA=="
- },
- "resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="
- }
- }
- },
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "supports-hyperlinks": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
- "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
- "requires": {
- "has-flag": "^4.0.0",
- "supports-color": "^7.0.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
- },
- "svg-tags": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
- "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA=="
- },
- "table": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
- "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
- "requires": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "dependencies": {
- "ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- }
- },
- "json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
- }
- }
- },
- "terminal-link": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
- "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
- "dev": true,
- "requires": {
- "ansi-escapes": "^4.2.1",
- "supports-hyperlinks": "^2.0.0"
- }
- },
- "test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
- "dev": true,
- "requires": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
- }
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
- },
- "tmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
- "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
- "requires": {
- "rimraf": "^3.0.0"
- }
- },
- "tmpl": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
- "dev": true
- },
- "to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "requires": {
- "is-number": "^7.0.0"
- }
- },
- "toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
- },
- "trim-newlines": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
- "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="
- },
- "ts-jest": {
- "version": "28.0.7",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.7.tgz",
- "integrity": "sha512-wWXCSmTwBVmdvWrOpYhal79bDpioDy4rTT+0vyUnE3ZzM7LOAAGG9NXwzkEL/a516rQEgnMmS/WKP9jBPCVJyA==",
- "dev": true,
- "requires": {
- "bs-logger": "0.x",
- "fast-json-stable-stringify": "2.x",
- "jest-util": "^28.0.0",
- "json5": "^2.2.1",
- "lodash.memoize": "4.x",
- "make-error": "1.x",
- "semver": "7.x",
- "yargs-parser": "^21.0.1"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true
- }
- }
- },
- "ts-node": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
- "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
- "dev": true,
- "requires": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- }
- },
- "tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "requires": {
- "tslib": "^1.8.1"
- }
- },
- "type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "requires": {
- "prelude-ls": "^1.2.1"
- }
- },
- "type-detect": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true
- },
- "type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "dev": true
- },
- "type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- }
- },
- "typed-array-length": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
- "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
- "requires": {
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "is-typed-array": "^1.1.9"
- }
- },
- "typescript": {
- "version": "4.9.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
- "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg=="
- },
- "unbox-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
- "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
- "requires": {
- "call-bind": "^1.0.2",
- "has-bigints": "^1.0.2",
- "has-symbols": "^1.0.3",
- "which-boxed-primitive": "^1.0.2"
- }
- },
- "unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ=="
- },
- "unicode-match-property-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
- "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
- "requires": {
- "unicode-canonical-property-names-ecmascript": "^2.0.0",
- "unicode-property-aliases-ecmascript": "^2.0.0"
- }
- },
- "unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA=="
- },
- "unicode-property-aliases-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
- "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w=="
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
- },
- "update-browserslist-db": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
- "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
- "requires": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
- }
- },
- "uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
- },
- "v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA=="
- },
- "v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true
- },
- "v8-to-istanbul": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
- "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
- "dev": true,
- "requires": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0"
- }
- },
- "validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
- },
- "vue-eslint-parser": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.0.tgz",
- "integrity": "sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==",
- "requires": {
- "debug": "^4.3.4",
- "eslint-scope": "^7.1.1",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
- "lodash": "^4.17.21",
- "semver": "^7.3.6"
- },
- "dependencies": {
- "eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "requires": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- }
- },
- "eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA=="
- },
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- },
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- }
- }
- },
- "walker": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
- "dev": true,
- "requires": {
- "makeerror": "1.0.12"
- }
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "requires": {
- "isexe": "^2.0.0"
- }
- },
- "which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
- "requires": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
- }
- },
- "which-typed-array": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
- "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
- "requires": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0",
- "is-typed-array": "^1.1.10"
- }
- },
- "word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
- },
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- }
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
- },
- "write-file-atomic": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
- "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
- "requires": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.7"
- }
- },
- "xml": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
- "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
- "dev": true
- },
- "y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true
- },
- "yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
- },
- "yaml": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
- "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw=="
- },
- "yargs": {
- "version": "17.6.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
- "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
- "dev": true,
- "requires": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "dependencies": {
- "yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true
- }
- }
- },
- "yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
- },
- "yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true
- },
- "yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
- }
- }
-}
diff --git a/eslint-bridge/package.json b/eslint-bridge/package.json
deleted file mode 100644
index 62634bf1567..00000000000
--- a/eslint-bridge/package.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "name": "eslint-bridge",
- "version": "1.0.0",
- "description": "bridge between SonarJS and ESLint",
- "scripts": {
- "build": "npm ci && npm run check-format && npm run clear && npm run compile",
- "clear": "tsc -b src tests --clean",
- "check-format": "prettier --list-different \"{src,tests}/**/!(*.lint).ts\"",
- "test": "jest",
- "ctest": "jest tests/tools/testers/comment-based/launcher.test.ts --verbose=false",
- "format": "prettier --write \"{src,tests,tools,profiling}/**/!(*.lint).ts\"",
- "compile": "tsc -b src tests profiling",
- "jar": "npm pack && mkdirp target/classes && mv eslint-bridge-1.0.0.tgz target/classes && bash tools/check-distribution-filepath-length.sh",
- "new-rule": "ts-node tools/newRule.ts"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/SonarSource/SonarJS.git"
- },
- "license": "LGPL-3.0",
- "bugs": {
- "url": "https://github.com/SonarSource/SonarJS/issues"
- },
- "homepage": "https://github.com/SonarSource/SonarJS#readme",
- "engines": {
- "node": ">=14"
- },
- "type": "commonjs",
- "devDependencies": {
- "@types/bytes": "3.1.1",
- "@types/eslint": " 8.4.10",
- "@types/eslint-scope": "3.7.4",
- "@types/estree": "1.0.0",
- "@types/express": "4.17.14",
- "@types/functional-red-black-tree": "1.0.1",
- "@types/jest": "28.1.6",
- "@types/lodash.clone": "4.5.7",
- "@types/node": "16.11.9",
- "@types/tmp": "0.2.3",
- "jest": "28.1.3",
- "jest-sonar-reporter": "2.0.0",
- "mkdirp": "1.0.4",
- "prettier": "2.7.1",
- "ts-jest": "28.0.7",
- "ts-node": "10.9.1"
- },
- "dependencies": {
- "@babel/core": "7.19.0",
- "@babel/eslint-parser": "7.18.9",
- "@babel/plugin-proposal-decorators": "7.19.3",
- "@babel/preset-env": "7.19.0",
- "@babel/preset-flow": "7.18.6",
- "@babel/preset-react": "7.18.6",
- "@typescript-eslint/eslint-plugin": "5.48.1",
- "@typescript-eslint/experimental-utils": "5.48.1",
- "@typescript-eslint/parser": "5.48.1",
- "builtin-modules": "3.3.0",
- "bytes": "3.1.2",
- "eslint": "8.26.0",
- "eslint-plugin-react": "7.31.8",
- "eslint-plugin-react-hooks": "4.6.0",
- "eslint-plugin-sonarjs": "0.18.0",
- "express": "4.18.1",
- "functional-red-black-tree": "1.0.1",
- "lodash.clone": "4.5.0",
- "module-alias": "2.2.2",
- "postcss-html": "0.36.0",
- "postcss-less": "6.0.0",
- "postcss-scss": "4.0.3",
- "postcss-syntax": "0.36.2",
- "postcss-value-parser": "4.2.0",
- "regexpp": "3.2.0",
- "run-node": "2.0.0",
- "scslre": "0.1.6",
- "stylelint": "14.13.0",
- "tmp": "0.2.1",
- "typescript": "4.9.4",
- "vue-eslint-parser": "9.1.0",
- "yaml": "2.1.1"
- },
- "bundledDependencies": [
- "@typescript-eslint/eslint-plugin",
- "@typescript-eslint/experimental-utils",
- "@typescript-eslint/parser",
- "@babel/core",
- "@babel/eslint-parser",
- "@babel/plugin-proposal-decorators",
- "@babel/preset-env",
- "@babel/preset-flow",
- "@babel/preset-react",
- "builtin-modules",
- "bytes",
- "eslint",
- "eslint-plugin-react",
- "eslint-plugin-react-hooks",
- "eslint-plugin-sonarjs",
- "express",
- "functional-red-black-tree",
- "lodash.clone",
- "module-alias",
- "postcss-html",
- "postcss-less",
- "postcss-scss",
- "postcss-syntax",
- "postcss-value-parser",
- "regexpp",
- "run-node",
- "scslre",
- "stylelint",
- "tmp",
- "vue-eslint-parser",
- "typescript",
- "yaml"
- ],
- "prettier": {
- "printWidth": 100,
- "trailingComma": "all",
- "singleQuote": true,
- "arrowParens": "avoid",
- "endOfLine": "lf"
- },
- "files": [
- "lib/",
- "bin/"
- ],
- "_moduleAliases": {
- "errors": "lib/errors",
- "helpers": "lib/helpers",
- "linting": "lib/linting",
- "parsing": "lib/parsing",
- "routing": "lib/routing",
- "services": "lib/services"
- }
-}
diff --git a/eslint-bridge/pom.xml b/eslint-bridge/pom.xml
deleted file mode 100644
index ccf6e76b606..00000000000
--- a/eslint-bridge/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
- 4.0.0
-
-
- org.sonarsource.javascript
- javascript
- 10.0.0-SNAPSHOT
-
-
- eslint-bridge
- SonarQube JavaScript :: ESLint-bridge
-
-
- src
- tests
- coverage/lcov.info
- ${project.basedir}/tests/tsconfig.json
- tests/**/fixtures/**/*,tests/**/rules/comment-based/**/*
-
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
-
-
- npm run build
- generate-resources
- exec
-
- npm
-
- run
- build
-
-
-
-
- npm run test
- test
-
- exec
-
-
- npm
- run test -- --coverage --silent
- ${skipTests}
-
-
-
- npm run jar
- prepare-package
-
- exec
-
-
- npm
-
- run
- jar
-
-
-
-
-
-
- com.mycila
- license-maven-plugin
-
-
-
- src/**/*.ts
- src/**/*.tsx
- tests/**/*.ts
-
-
- tests/**/fixtures/**/*
- tests/linting/**/comment-based/**/*
-
-
-
-
-
-
diff --git a/eslint-bridge/profiling/README.md b/eslint-bridge/profiling/README.md
deleted file mode 100644
index 9ea53403edf..00000000000
--- a/eslint-bridge/profiling/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# ESlint-bridge profiling
-
-This tool allows identifying the bottlenecks of a rule performance.
-
-## Fetch dependencies
-
-Run: `npm i`
-
-## Chrome dev tools
-
-The Chrome dev tools allow you to see what functions took how much CPU time as:
-- a top-down tree
-- a bottom-up tree
-- a (flame) graph
-
-1. Boot the server in debug mode: `npm run server`. (or `npm run compile-server` if you have modifications in `eslint-bridge/`)
-2. Open dev tools on chrome, using F12
-3. You should see a green NodeJS icon like that, click it to connect the dev tools to the server's debugger:
-
-
-
-4. You might need to make sure the server starts by going to the "sources" tab and pressing the "play" button
-5. In the server logs, you should see that the server is listening
-6. Select the "Profiler" tab
-5. Select "Profiles" on the left
-6. Press "Start" on the bottom
-
-
-
-7. Launch the Analysis on ruling projects: `npm run profile `
- 1. `ts` for TS-only projects, `all` for both JS and TS, JS-only by default.
- 2. `parallelism` sets the number of parallel files sent to the `eslint-bridge` for analysis. Defaults to 5.
-8. Press "Stop"
-9. View the profile
-10. Change the view from "Heavy (Bottom Up)" to "Tree (Top Down)" (on the top menu, above "Self Time")
-
-
-
-11. If you prefer, you can also select the "Chart" view to display a flame graph
-
-
-
-## Links
-
-- [Chrome profiling](https://medium.com/@basakabhijoy/debugging-and-profiling-memory-leaks-in-nodejs-using-chrome-e8ece4560dba)
-- [Chrome profiling - views](https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art037)
-- [Flame graphs with 0x](https://github.com/davidmarkclements/0x)
-- [NodeJS profiling](https://nodejs.org/en/docs/guides/simple-profiling/)
diff --git a/eslint-bridge/profiling/images/0x-flame-graph.png b/eslint-bridge/profiling/images/0x-flame-graph.png
deleted file mode 100644
index 92787b89395..00000000000
Binary files a/eslint-bridge/profiling/images/0x-flame-graph.png and /dev/null differ
diff --git a/eslint-bridge/profiling/images/dev-tools.png b/eslint-bridge/profiling/images/dev-tools.png
deleted file mode 100644
index 92662afda76..00000000000
Binary files a/eslint-bridge/profiling/images/dev-tools.png and /dev/null differ
diff --git a/eslint-bridge/profiling/images/flame.png b/eslint-bridge/profiling/images/flame.png
deleted file mode 100644
index b402f249edc..00000000000
Binary files a/eslint-bridge/profiling/images/flame.png and /dev/null differ
diff --git a/eslint-bridge/profiling/images/profile.png b/eslint-bridge/profiling/images/profile.png
deleted file mode 100644
index fff8856f2dd..00000000000
Binary files a/eslint-bridge/profiling/images/profile.png and /dev/null differ
diff --git a/eslint-bridge/profiling/images/profiler.png b/eslint-bridge/profiling/images/profiler.png
deleted file mode 100644
index 37a89c956c0..00000000000
Binary files a/eslint-bridge/profiling/images/profiler.png and /dev/null differ
diff --git a/eslint-bridge/profiling/package-lock.json b/eslint-bridge/profiling/package-lock.json
deleted file mode 100644
index e34d881afdf..00000000000
--- a/eslint-bridge/profiling/package-lock.json
+++ /dev/null
@@ -1,88 +0,0 @@
-{
- "name": "profiling",
- "version": "1.0.0",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "profiling",
- "version": "1.0.0",
- "license": "LGPL-3.0",
- "devDependencies": {
- "tsconfig-paths": "^4.1.0"
- }
- },
- "node_modules/json5": {
- "version": "2.2.1",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
- "dev": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.7",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/minimist/-/minimist-1.2.7.tgz",
- "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
- "dev": true
- },
- "node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tsconfig-paths": {
- "version": "4.1.0",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz",
- "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==",
- "dev": true,
- "dependencies": {
- "json5": "^2.2.1",
- "minimist": "^1.2.6",
- "strip-bom": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- }
- },
- "dependencies": {
- "json5": {
- "version": "2.2.1",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
- "dev": true
- },
- "minimist": {
- "version": "1.2.7",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/minimist/-/minimist-1.2.7.tgz",
- "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
- "dev": true
- },
- "strip-bom": {
- "version": "3.0.0",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true
- },
- "tsconfig-paths": {
- "version": "4.1.0",
- "resolved": "https://repox.jfrog.io/repox/api/npm/npm/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz",
- "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==",
- "dev": true,
- "requires": {
- "json5": "^2.2.1",
- "minimist": "^1.2.6",
- "strip-bom": "^3.0.0"
- }
- }
- }
-}
diff --git a/eslint-bridge/profiling/package.json b/eslint-bridge/profiling/package.json
deleted file mode 100644
index b041403906e..00000000000
--- a/eslint-bridge/profiling/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "profiling",
- "version": "1.0.0",
- "description": "",
- "main": "server.js",
- "scripts": {
- "server": "node --inspect-brk server.js",
- "compile-server": "cd ..; npm run compile; cd profiling; node --inspect-brk server.js",
- "profile": "../node_modules/.bin/ts-node profile-rule.ts"
- },
- "license": "LGPL-3.0",
- "devDependencies": {
- "tsconfig-paths": "^4.1.0"
- }
-}
diff --git a/eslint-bridge/profiling/profile-rule.ts b/eslint-bridge/profiling/profile-rule.ts
deleted file mode 100644
index 8b73d50fd04..00000000000
--- a/eslint-bridge/profiling/profile-rule.ts
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-import * as http from 'http';
-import path from 'path';
-import * as fs from 'fs';
-import { request } from '../tests/tools';
-
-const server = {
- // must be the same as the one used in ./server.js
- address: () => {
- return { port: 64829 };
- },
-};
-
-const start = Date.now();
-
-try {
- const ruleId = extractRuleFromArgs();
- const { js: jsProjects, ts: tsProjects } = extractScopeFromArgs() as any;
- const parallelism = extractParallelismFromArgs();
-
- (async () => {
- await requestInitLinter(server as http.Server, 'MAIN', ruleId);
-
- if (jsProjects !== undefined) {
- for (let i = 0; i < jsProjects.length; i++) {
- await analyzeJSProject(server as http.Server, jsProjects[i], parallelism);
- }
- }
- if (tsProjects !== undefined) {
- for (let i = 0; i < tsProjects.length; i++) {
- await analyzeTsProject(server as http.Server, tsProjects[i], parallelism);
- }
- }
- })();
-} catch (e) {
- console.error(`Profiling exited because of Error: ${e.message}`);
-} finally {
- const timeSeconds = (Date.now() - start) / 1000;
- console.log(`done in ${timeSeconds}s`);
-}
-
-function extractRuleFromArgs() {
- if (process.argv.length <= 2) {
- throw new Error('Missing rule id. Please provide a rule id as CLI argument');
- }
- return process.argv[2];
-}
-
-function extractScopeFromArgs() {
- const SCOPES = ['js', 'ts', 'all'];
- const JS_PROJECTS = {
- js: [
- 'amplify/src',
- 'angular.js/src',
- 'backbone',
- 'es5-shim',
- 'file-for-rules',
- 'fireact/src',
- 'javascript-test-sources/src',
- 'jira-clone',
- 'jquery/src',
- 'jshint/src',
- 'jStorage',
- 'knockout/src',
- 'mootools-core/Source',
- 'ocanvas/src',
- 'p5.js/src',
- 'paper.js/src',
- 'prototype/src',
- 'qunit/src',
- 'react-cloud-music/src',
- 'sizzle/src',
- 'underscore',
- ],
- };
- JS_PROJECTS.js = JS_PROJECTS.js.map(filePath =>
- path.join(__dirname, '../../its/sources/', filePath),
- );
- const TS_PROJECTS = {
- ts: [
- 'ag-grid/tsconfig.json',
- 'ant-design/tsconfig.json',
- 'console/tsconfig.json',
- // there are other folders in courselit
- 'courselit/apps/web/tsconfig.json',
- 'desktop/tsconfig.json',
- 'eigen/tsconfig.json',
- 'fireface/src/tsconfig.json',
- 'ionic2-auth/tsconfig.json',
- 'Joust/tsconfig.json',
- // other folders as well here
- 'moose/main/tsconfig.json',
- 'postgraphql/tsconfig.json',
- 'prettier-vscode/tsconfig.json',
- 'rxjs/tsconfig.json',
- // other folders as well
- 'searchkit/packages/searchkit-cli/tsconfig.json',
- // other folders as well
- 'TypeScript/src/compiler/tsconfig.json',
- ],
- };
- TS_PROJECTS.ts = TS_PROJECTS.ts.map(filePath =>
- path.join(__dirname, '../../its/typescript-test-sources/src/', filePath),
- );
-
- if (process.argv.length < 4) {
- return JS_PROJECTS;
- }
- const scope = process.argv[3];
- if (!SCOPES.includes(scope)) {
- throw new Error(
- `Unknown scope. Please provide one of the available: ${SCOPES.map(scope => `"${scope}"`)}`,
- );
- }
- switch (scope) {
- case 'js':
- return { ...JS_PROJECTS, ts: undefined };
- case 'ts':
- return { js: undefined, ...TS_PROJECTS };
- case 'all':
- return { ...JS_PROJECTS, ...TS_PROJECTS };
- }
-}
-
-function extractParallelismFromArgs() {
- let parallelism = 5;
- if (process.argv.length < 5) {
- return parallelism;
- }
- parallelism = parseInt(process.argv[4]);
- if (isNaN(parallelism) || parallelism < 1) {
- throw new Error(
- `Invalid parallelism parameter at 3rd position "${process.argv[4]}". Please prove a positive number.`,
- );
- }
- return parallelism;
-}
-
-function requestInitLinter(server: http.Server, fileType: string, ruleId: string) {
- const config = {
- rules: [{ key: ruleId, configurations: [], fileTypeTarget: fileType }],
- };
- return request(server, '/init-linter', 'POST', config);
-}
-
-async function analyzeTsProject(server: http.Server, tsConfigPath: string, parallelism) {
- console.log('####################################');
- console.log(`Analyzing TS project ${tsConfigPath}`);
- console.log('####################################');
-
- const { programId, files } = await createProgram(server, tsConfigPath);
- console.log(`Created program with programId ${programId} containing ${files.length} files`);
- const promises: (() => Promise)[] = buildPromises(server, programId, files);
- await executePromises(promises, parallelism, files, tsConfigPath);
- await deleteProgram(server, programId);
-
- async function createProgram(server: http.Server, tsConfigPath: string): Promise {
- try {
- const response = await request(server, '/create-program', 'POST', { tsConfig: tsConfigPath });
- return JSON.parse(response as string);
- } catch (e) {
- console.error(`Error while creating program for ${tsConfigPath}. Error: ${e.message}`);
- }
- }
-
- async function deleteProgram(server: http.Server, programId: string) {
- try {
- await request(server, '/delete-program', 'POST', { programId });
- } catch (e) {
- console.error(
- `Error while deleting program with programId: ${programId}. Error: ${e.message}`,
- );
- }
- }
-
- function buildPromises(server: http.Server, tsConfigId: string, files: string[]) {
- const promises: (() => Promise)[] = [];
- for (const file of files) {
- promises.push(() => analyzeFile(server, tsConfigId, file));
- }
- return promises;
-
- async function analyzeFile(
- server: http.Server,
- programId: string,
- filePath: string,
- ): Promise {
- return request(server, '/analyze-ts', 'POST', { programId, filePath });
- }
- }
-}
-
-async function analyzeJSProject(server: http.Server, projectPath: string, parallelism: number) {
- console.log('####################################');
- console.log(`Analyzing JS project ${projectPath}`);
- console.log('####################################');
-
- let files: string[] = [];
- collectFilesInFolder(projectPath, files);
- console.log(`Found ${files.length} files`);
- files = files.filter(isJSFile);
- console.log(`of which ${files.length} are JS files`);
- const promises = buildPromises(server, files);
- await executePromises(promises, parallelism, files, projectPath);
-
- function isJSFile(filePath: string) {
- return filePath.endsWith('.js');
- }
-
- function buildPromises(server: http.Server, files: string[]) {
- const promises: (() => Promise)[] = [];
- files.forEach(filePath => {
- promises.push(() => analyzeFile(server, filePath));
- });
- return promises;
-
- async function analyzeFile(server: http.Server, filePath: string) {
- const response = await request(server, '/analyze-js', 'POST', {
- filePath,
- fileType: 'MAIN',
- linterId: 'default',
- });
- return response;
- }
- }
-}
-
-function collectFilesInFolder(folder: string, files: string[]) {
- fs.readdirSync(folder).forEach(file => {
- const filePath = path.join(folder, file);
- if (fs.statSync(filePath).isDirectory()) {
- return collectFilesInFolder(filePath, files);
- } else {
- return files.push(filePath);
- }
- });
-}
-
-async function executePromises(
- promises: (() => Promise)[],
- parallelism: number,
- files: string[],
- projectPath: string,
-) {
- for (let i = 0; i < promises.length; i += parallelism) {
- const endIndex = Math.min(i + parallelism - 1, promises.length - 1);
- try {
- console.log(
- `Analysing files from ${i + 1} to ${endIndex + 1} (out of ${
- promises.length
- }) for ${projectPath}`,
- );
- await Promise.all(promises.slice(i, endIndex + 1).map(fn => fn()));
- } catch (e) {
- console.error(`Failed analyzing files: ${files.slice(i, endIndex + 1)}`);
- }
- }
-}
diff --git a/eslint-bridge/profiling/server.js b/eslint-bridge/profiling/server.js
deleted file mode 100644
index 1f8ade837cf..00000000000
--- a/eslint-bridge/profiling/server.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-const server = require('../lib/server');
-const path = require('path');
-const context = require('../lib/helpers');
-const { tmpdir } = require('os');
-
-// must be the same as the one used in ./profile-rule.ts
-const port = 64829;
-const host = '127.0.0.1';
-const workDir = tmpdir();
-
-context.setContext({ workDir, shouldUseTypeScriptParserForJS: false, sonarlint: false, bundles: [] });
-const BIG_TIMEOUT = 1719925474;
-server.start(port, host, BIG_TIMEOUT);
diff --git a/eslint-bridge/profiling/tsconfig.json b/eslint-bridge/profiling/tsconfig.json
deleted file mode 100644
index 69c12ad95d9..00000000000
--- a/eslint-bridge/profiling/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "extends": "../src/tsconfig.json",
- "compilerOptions": {
- "composite": false,
- "noEmit": true,
- "strictNullChecks": false,
- "noImplicitAny": false,
- "baseUrl": ".",
- "paths": {
- "*": ["../src/*"]
- },
- },
- "references": [
- {
- "path": "../src/tsconfig.json"
- }
- ],
- "ts-node": {
- // Do not forget to `npm i -D tsconfig-paths`
- "require": ["tsconfig-paths/register"]
- }
-}
diff --git a/eslint-bridge/src/errors/error.ts b/eslint-bridge/src/errors/error.ts
deleted file mode 100644
index e6dc2a214a6..00000000000
--- a/eslint-bridge/src/errors/error.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * The possible codes of analysis errors
- *
- * The `Unexpected` value denotes a runtime error which is either
- * unpredictable or occurs rarely to deserve its own category.
- */
-export enum ErrorCode {
- Parsing = 'PARSING',
- FailingTypeScript = 'FAILING_TYPESCRIPT',
- // We are stuck with this name because of possible external dependents
- Unexpected = 'GENERAL_ERROR',
- LinterInitialization = 'LINTER_INITIALIZATION',
-}
-
-export interface ErrorData {
- line: number;
-}
-
-export class APIError extends Error {
- code: ErrorCode;
- data?: ErrorData;
-
- private constructor(code: ErrorCode, message: string, data?: ErrorData) {
- super(message);
- this.code = code;
- this.data = data;
- }
-
- /**
- * Builds a failing TypeScript error.
- */
- static failingTypeScriptError(message: string) {
- return new APIError(ErrorCode.FailingTypeScript, message);
- }
-
- /**
- * Builds a linter initialization error.
- */
- static linterError(message: string) {
- return new APIError(ErrorCode.LinterInitialization, message);
- }
-
- /**
- * Builds a parsing error.
- */
- static parsingError(message: string, data: ErrorData) {
- return new APIError(ErrorCode.Parsing, message, data);
- }
-
- /**
- * Builds an unexpected runtime error.
- */
- static unexpectedError(message: string) {
- return new APIError(ErrorCode.Unexpected, message);
- }
-}
diff --git a/eslint-bridge/src/errors/index.ts b/eslint-bridge/src/errors/index.ts
deleted file mode 100644
index 71836e539e5..00000000000
--- a/eslint-bridge/src/errors/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './error';
diff --git a/eslint-bridge/src/helpers/context.ts b/eslint-bridge/src/helpers/context.ts
deleted file mode 100644
index fa3fe93a79e..00000000000
--- a/eslint-bridge/src/helpers/context.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * A container of contextual information
- *
- * @param workDir the working directory of the analyzed project
- * @param shouldUseTypeScriptParserForJS a flag for parsing JavaScript code with TypeScript ESLint parser
- * @param sonarlint a flag for indicating whether the bridge is used in SonarLint context
- * @param bundles a set of rule bundles to load
- */
-export interface Context {
- workDir: string;
- shouldUseTypeScriptParserForJS: boolean;
- sonarlint: boolean;
- bundles: string[];
-}
-
-/**
- * The global context
- *
- * It is available anywhere within the bridge as well as in
- * external and custom rules provided their definition sets
- * the `sonar-context` internal parameter.
- */
-let context: Context;
-
-/**
- * Returns the global context
- * @returns the global context
- */
-export function getContext(): Context {
- return context;
-}
-
-/**
- * Sets the global context
- * @param ctx the new global context
- */
-export function setContext(ctx: Context) {
- context = { ...ctx };
-}
diff --git a/eslint-bridge/src/helpers/debug.ts b/eslint-bridge/src/helpers/debug.ts
deleted file mode 100644
index 3da875f48af..00000000000
--- a/eslint-bridge/src/helpers/debug.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Prints a message to `stdout` like `console.log` by prefixing it with `DEBUG`.
- *
- * The `DEBUG` prefix is recognized by the scanner, which
- * will show the logged message in the scanner debug logs.
- *
- * @param message the message to log
- */
-export function debug(message: string) {
- console.log(`DEBUG ${message}`);
-}
diff --git a/eslint-bridge/src/helpers/files.ts b/eslint-bridge/src/helpers/files.ts
deleted file mode 100644
index a7e17836022..00000000000
--- a/eslint-bridge/src/helpers/files.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import fs from 'fs/promises';
-import path from 'path';
-
-/**
- * Byte Order Marker
- */
-const BOM_BYTE = 0xfeff;
-
-/**
- * The type of input file
- *
- * The scanner indexes input files based on the project configuration,
- * if any. It determines wheter an input file denotes a `MAIN` file,
- * i.e., a source file, or a `TEST` file.
- *
- * The type of input file is then used by the linter to select which
- * rule configurations to apply, that is, which rules the linter should
- * use to analyze the file.
- */
-export type FileType = 'MAIN' | 'TEST';
-
-/**
- * Asynchronous read of file contents from a file path
- *
- * The function gets rid of any Byte Order Marker (BOM)
- * present in the file's header.
- *
- * @param filePath the path of a file
- * @returns Promise which resolves with the content of the file
- */
-export async function readFile(filePath: string) {
- const fileContent = await fs.readFile(filePath, { encoding: 'utf8' });
- return stripBOM(fileContent);
-}
-
-/**
- * Removes any Byte Order Marker (BOM) from a string's head
- *
- * A string's head is nothing else but its first character.
- *
- * @param str the input string
- * @returns the stripped string
- */
-export function stripBOM(str: string) {
- if (str.charCodeAt(0) === BOM_BYTE) {
- return str.slice(1);
- }
- return str;
-}
-/**
- * Converts a path to Unix format
- * @param path the path to convert
- * @returns the converted path
- */
-export function toUnixPath(path: string) {
- return path.replace(/[\\/]+/g, '/').replace(/(\.\/)/, '');
-}
-
-/**
- * Adds tsconfig.json to a path if it does not exist
- *
- * @param tsConfig
- */
-export async function addTsConfigIfDirectory(tsConfig: string) {
- try {
- if ((await fs.lstat(tsConfig)).isDirectory()) {
- return path.join(tsConfig, 'tsconfig.json');
- }
-
- return tsConfig;
- } catch {
- return null;
- }
-}
diff --git a/eslint-bridge/src/helpers/index.ts b/eslint-bridge/src/helpers/index.ts
deleted file mode 100644
index 06e4660f208..00000000000
--- a/eslint-bridge/src/helpers/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './context';
-export * from './debug';
-export * from './files';
diff --git a/eslint-bridge/src/linting/eslint/index.ts b/eslint-bridge/src/linting/eslint/index.ts
deleted file mode 100644
index 55cd18e58cf..00000000000
--- a/eslint-bridge/src/linting/eslint/index.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { APIError } from 'errors';
-import { debug } from 'helpers';
-import { LinterWrapper, RuleConfig } from './linter';
-
-export * from './linter';
-export * from './rules';
-type Linters = { [id: string]: LinterWrapper };
-/**
- * The global ESLint linters
- *
- * Any linter is expected to be initialized before use.
- * To this end, the plugin is expected to explicitly send a request to
- * initialize a linter before starting the actual analysis of a file.
- * The global linters object will keep the already initialized linters
- * indexed by their linterId. If no linterId is provided, `default` will
- * be used.
- * Having multiple linters (each with different set of rules enabled)
- * is needed in order to not run all rules on 'unchanged' files
- */
-const linters: Linters = {};
-
-/**
- * Initializes the global linter wrapper
- * @param inputRules the rules from the active quality profiles
- * @param environments the JavaScript execution environments
- * @param globals the global variables
- * @param linterId key of the linter
- */
-export function initializeLinter(
- inputRules: RuleConfig[],
- environments: string[] = [],
- globals: string[] = [],
- linterId = 'default',
-) {
- debug(`Initializing linter "${linterId}" with ${inputRules.map(rule => rule.key)}`);
- linters[linterId] = new LinterWrapper({ inputRules, environments, globals });
-}
-
-/**
- * Returns the linter with the given ID
- *
- * @param linterId key of the linter
- *
- * Throws a runtime error if the global linter wrapper is not initialized.
- */
-export function getLinter(linterId: keyof Linters = 'default') {
- if (!linters[linterId]) {
- throw APIError.linterError(`Linter ${linterId} does not exist. Did you call /init-linter?`);
- }
- return linters[linterId];
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/bundle-loader.ts b/eslint-bridge/src/linting/eslint/linter/bundle-loader.ts
deleted file mode 100755
index 4befc04b2a5..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/bundle-loader.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, Rule } from 'eslint';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { rules as pluginRules } from 'eslint-plugin-sonarjs';
-import { rules as reactESLintRules } from 'eslint-plugin-react';
-import { rules as typescriptESLintRules } from '@typescript-eslint/eslint-plugin';
-import { rules as internalRules } from 'linting/eslint';
-import { customRules as internalCustomRules, CustomRule } from './custom-rules';
-import { decorateExternalRules } from './decoration';
-import { debug, getContext } from 'helpers';
-
-export function loadCustomRules(linter: Linter, rules: CustomRule[] = []) {
- for (const rule of rules) {
- linter.defineRule(rule.ruleId, rule.ruleModule);
- }
-}
-
-export function loadBundles(linter: Linter, rulesBundles: (keyof typeof loaders)[]) {
- for (const bundleId of rulesBundles) {
- loaders[bundleId](linter);
- }
-}
-
-/**
- * Loaders for each of the predefined rules bundles. Each bundle comes with a
- * different data structure (array/record/object), plus on some cases
- * there are specifics that must be taken into account, like ignoring some
- * rules from some bundles or decorating them in order to be compatible.
- */
-const loaders: { [key: string]: Function } = {
- /**
- * Loads external rules
- *
- * The external ESLint-based rules include all the rules that are
- * not implemented internally, in other words, rules from external
- * dependencies which include ESLint core rules. Furthermore, the
- * returned rules are decorated either by internal decorators or by
- * special decorations.
- */
- externalRules(linter: Linter) {
- const externalRules: { [key: string]: Rule.RuleModule } = {};
- /**
- * The order of defining rules from external dependencies is important here.
- * Core ESLint rules could be overridden by the implementation from specific
- * dependencies, which should be the default behaviour in most cases. If for
- * some reason a different behaviour is needed for a particular rule, one can
- * specify it in `decorateExternalRules`.
- */
- const dependencies = [eslintRules, typescriptESLintRules, reactESLintRules];
- for (const dependencyRules of dependencies) {
- for (const [name, module] of Object.entries(dependencyRules)) {
- externalRules[name] = module;
- }
- }
- linter.defineRules(decorateExternalRules(externalRules));
- },
- /**
- * Loads plugin rules
- *
- * Adds the rules from the Sonar ESLint plugin.
- */
- pluginRules(linter: Linter) {
- linter.defineRules(pluginRules);
- },
- /**
- * Loads internal rules
- *
- * Adds the rules from SonarJS plugin, i.e. rules in path
- * /src/linting/eslint/rules
- */
- internalRules(linter: Linter) {
- linter.defineRules(internalRules);
- },
- /**
- * Loads global context rules
- *
- * Context bundles define a set of external custom rules (like the taint analysis rule)
- * including rule keys and rule definitions that cannot be provided to the linter
- * wrapper using the same feeding channel as rules from the active quality profile.
- */
- contextRules(linter: Linter) {
- const { bundles } = getContext();
- const customRules: CustomRule[] = [];
- for (const ruleBundle of bundles) {
- const bundle = require(ruleBundle);
- customRules.push(...bundle.rules);
- const ruleIds = bundle.rules.map((r: CustomRule) => r.ruleId);
- debug(`Loaded rules ${ruleIds} from ${ruleBundle}`);
- }
- loadCustomRules(linter, customRules);
- },
- /**
- * Loads internal custom rules
- *
- * These are rules used internally by SonarQube to have the symbol highlighting and
- * the cognitive complexity metrics.
- */
- internalCustomRules(linter: Linter) {
- loadCustomRules(linter, internalCustomRules);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/linter/config/index.ts b/eslint-bridge/src/linting/eslint/linter/config/index.ts
deleted file mode 100644
index 2d4cd813910..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/config/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './linter-config';
-export * from './rule-config';
diff --git a/eslint-bridge/src/linting/eslint/linter/config/linter-config.ts b/eslint-bridge/src/linting/eslint/linter/config/linter-config.ts
deleted file mode 100644
index be806ebaa01..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/config/linter-config.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, Rule } from 'eslint';
-import { getContext } from 'helpers';
-import { customRules as internalCustomRules } from '../custom-rules';
-import { extendRuleConfig, RuleConfig } from './rule-config';
-
-/**
- * Creates an ESLint linting configuration
- *
- * A linter configuration is created based on the input rules enabled by
- * the user through the active quality profile and the rules provided by
- * the linter wrapper.
- *
- * The configuration includes the rules with their configuration that are
- * used during linting as well as the global variables and the JavaScript
- * execution environments defined through the analyzer's properties.
- *
- * @param inputRules the rules from the active quality profile
- * @param linterRules the wrapper's rule database
- * @param environments the JavaScript execution environments
- * @param globs the global variables
- * @returns the created ESLint linting configuration
- */
-export function createLinterConfig(
- inputRules: RuleConfig[],
- linterRules: Map,
- environments: string[],
- globs: string[],
-) {
- const env = createEnv(environments);
- const globals = createGlobals(globs);
- const parserOptions = { sourceType: 'module', ecmaVersion: 2018 } as Linter.ParserOptions;
- const config: Linter.Config = {
- env,
- globals,
- parserOptions,
- rules: {},
- /* using "max" version to prevent `eslint-plugin-react` from printing a warning */
- settings: { react: { version: '999.999.999' } },
- };
- enableRules(config, inputRules, linterRules);
- enableInternalCustomRules(config);
- return config;
-}
-
-/**
- * Creates an ESLint execution environments configuration
- * @param environments the JavaScript execution environments to enable
- * @returns a configuration of JavaScript execution environments
- */
-function createEnv(environments: string[]) {
- const env: { [name: string]: boolean } = { es6: true };
- for (const key of environments) {
- env[key] = true;
- }
- return env;
-}
-
-/**
- * Creates an ESLint global variables configuration
- * @param globs the global variables to enable
- * @returns a configuration of global variables
- */
-function createGlobals(globs: string[]) {
- const globals: { [name: string]: boolean } = {};
- for (const key of globs) {
- globals[key] = true;
- }
- return globals;
-}
-
-/**
- * Enables input rules
- *
- * Enabling an input rule is similar to how rule enabling works with ESLint.
- * However, in the particular case of internal rules, the rule configuration
- * can be decorated with special markers to activate internal features.
- *
- * For example, an ESLint rule configuration for a rule that reports secondary
- * locations would be `["error", "sonar-runtime"]`, where the "sonar-runtime"`
- * is a marker for a post-linting processing to decode such locations.
- *
- * @param config the configuration to augment with rule enabling
- * @param inputRules the input rules to enable
- * @param linterRules the linter rules available
- */
-function enableRules(
- config: Linter.Config,
- inputRules: RuleConfig[],
- linterRules: Map,
-) {
- for (const inputRule of inputRules) {
- const ruleModule = linterRules.get(inputRule.key);
- config.rules![inputRule.key] = ['error', ...extendRuleConfig(ruleModule, inputRule)];
- }
-}
-
-/**
- * Enables internal custom rules in the provided configuration
- *
- * Custom rules like cognitive complexity and symbol highlighting
- * are always enabled as part of metrics computation. Such rules
- * are, therefore, added in the linting configuration by default.
- *
- * _Internal custom rules are not enabled in SonarLint context._
- *
- * @param config the configuration to augment with custom rule enabling
- */
-function enableInternalCustomRules(config: Linter.Config) {
- if (!getContext().sonarlint) {
- for (const internalCustomRule of internalCustomRules) {
- config.rules![internalCustomRule.ruleId] = ['error', ...internalCustomRule.ruleConfig];
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/config/rule-config.ts b/eslint-bridge/src/linting/eslint/linter/config/rule-config.ts
deleted file mode 100644
index fc97b91fff9..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/config/rule-config.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { FileType, getContext } from 'helpers';
-import { hasSonarRuntimeOption, SONAR_RUNTIME, hasSonarContextOption } from '../parameters';
-
-/**
- * An input rule configuration for linting
- *
- * @param key an ESLint rule key that maps a SonarQube rule identifier (SXXX) to the rule implementation
- * @param configurations an ESLint rule configuration provided from the anaylzer if the rule behaviour is customizable
- * @param fileTypeTarget a list of file type targets to filter issues in case the rule applies to main files, test files, or both
- *
- * The configuration of a rule is used to uniquely identify a rule, customize its behaviour,
- * and define what type(s) of file it should apply to during linting.
- *
- * An ESLint rule configuration can theoretically be a plain JavaScript object or a string. However, given the
- * nature of SonarQube' rule properties, it is currently used in the form of a string.
- */
-export interface RuleConfig {
- key: string;
- configurations: any[];
- fileTypeTarget: FileType[];
-}
-
-/**
- * Extends an input rule configuration
- *
- * A rule configuration might be extended depending on the rule definition.
- * The purpose of the extension is to activate additional features during
- * linting, e.g., secondary locations.
- *
- * _A rule extension only applies to rules whose implementation is available._
- *
- * @param ruleModule the rule definition
- * @param inputRule the rule configuration
- * @returns the extended rule configuration
- */
-export function extendRuleConfig(ruleModule: Rule.RuleModule | undefined, inputRule: RuleConfig) {
- const options = [...inputRule.configurations];
- if (hasSonarRuntimeOption(ruleModule, inputRule.key)) {
- options.push(SONAR_RUNTIME);
- }
- if (hasSonarContextOption(ruleModule, inputRule.key)) {
- options.push(getContext());
- }
- return options;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/custom-rules/cognitive-complexity.ts b/eslint-bridge/src/linting/eslint/linter/custom-rules/cognitive-complexity.ts
deleted file mode 100644
index 5997cffe806..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/custom-rules/cognitive-complexity.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rules as sonarjsESLintRules } from 'eslint-plugin-sonarjs';
-import { CustomRule } from './custom-rule';
-
-/**
- * The internal _cognitive complexity_ custom rule
- *
- * The rule computes file-level cognitive complexity.
- */
-export const rule: CustomRule = {
- ruleId: 'internal-cognitive-complexity',
- ruleModule: sonarjsESLintRules['cognitive-complexity'],
- ruleConfig: ['metric'],
-};
diff --git a/eslint-bridge/src/linting/eslint/linter/custom-rules/custom-rule.ts b/eslint-bridge/src/linting/eslint/linter/custom-rules/custom-rule.ts
deleted file mode 100644
index cbc993cd8de..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/custom-rules/custom-rule.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-
-/**
- * An ESLint-based custom rule
- *
- * @param ruleId the ESLint rule key
- * @param ruleModule the ESLint rule implementation
- * @param rule the ESLint rule configuration
- */
-export interface CustomRule {
- ruleId: string;
- ruleModule: Rule.RuleModule;
- ruleConfig: any[];
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/custom-rules/index.ts b/eslint-bridge/src/linting/eslint/linter/custom-rules/index.ts
deleted file mode 100644
index 19b834ebf8d..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/custom-rules/index.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule as cognitiveComplexity } from './cognitive-complexity';
-import { CustomRule } from './custom-rule';
-import { rule as symbolHighlighting } from './symbol-highlighting';
-
-export * from './custom-rule';
-
-/**
- * The set of internal custom rules
- */
-export const customRules: CustomRule[] = [cognitiveComplexity, symbolHighlighting];
diff --git a/eslint-bridge/src/linting/eslint/linter/custom-rules/symbol-highlighting.ts b/eslint-bridge/src/linting/eslint/linter/custom-rules/symbol-highlighting.ts
deleted file mode 100644
index 7f43d24b149..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/custom-rules/symbol-highlighting.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { CustomRule } from './custom-rule';
-import { rule as symbolHighlightingRule } from '../visitors/symbol-highlighting';
-
-/**
- * The internal _symbol highlighting_ custom rule
- */
-export const rule: CustomRule = {
- ruleId: 'internal-symbol-highlighting',
- ruleModule: symbolHighlightingRule,
- ruleConfig: [],
-};
diff --git a/eslint-bridge/src/linting/eslint/linter/decoration/decorate.ts b/eslint-bridge/src/linting/eslint/linter/decoration/decorate.ts
deleted file mode 100644
index 055fcfd8faa..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/decoration/decorate.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { rules as typescriptESLintRules } from '@typescript-eslint/eslint-plugin';
-import { decorators } from 'linting/eslint/rules/decorators';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { sanitizeTypeScriptESLintRule } from './sanitize';
-/**
- * Decorates external rules
- *
- * Decorating an external rule means customizing the original behaviour of the rule that
- * can't be done through rule configuration and requires special adjustments, among which
- * are internal decorators.
- *
- * @param externalRules the external rules to decorate
- */
-export function decorateExternalRules(externalRules: { [name: string]: Rule.RuleModule }): {
- [name: string]: Rule.RuleModule;
-} {
- const decoratedRules = { ...externalRules };
- /**
- * S1537 ('comma-dangle'), S3723 ('enforce-trailing-comma')
- *
- * S1537 and S3723 both depend on the same ESLint implementation but the
- * plugin doesn't allow duplicates of the same rule key.
- */
- const commaDangleRuleId = 'comma-dangle';
- const enforceTrailingCommaRuleId = 'enforce-trailing-comma';
- decoratedRules[enforceTrailingCommaRuleId] = eslintRules[commaDangleRuleId];
-
- /**
- * S3696 ('no-throw-literal')
- *
- * TypeScript ESLint implementation of no-throw-literal does not support JavaScript code.
- */
- const noThrowLiteralRuleId = 'no-throw-literal';
- decoratedRules[noThrowLiteralRuleId] = eslintRules[noThrowLiteralRuleId];
-
- /**
- * TypeScript ESLint rules sanitization
- *
- * TypeScript ESLint rules that rely on type information fail at runtime because
- * they unconditionally assume that TypeScript's type checker is available.
- */
- for (const ruleKey of Object.keys(typescriptESLintRules)) {
- decoratedRules[ruleKey] = sanitizeTypeScriptESLintRule(decoratedRules[ruleKey]);
- }
-
- /**
- * Decorate (TypeScript-) ESLint external rules
- *
- * External rules are decorated with internal decorators to refine their
- * behaviour: exceptions, quick fixes, secondary locations, etc.
- */
- for (const ruleKey in decorators) {
- decoratedRules[ruleKey] = decorators[ruleKey](decoratedRules[ruleKey]);
- }
- return decoratedRules;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/decoration/index.ts b/eslint-bridge/src/linting/eslint/linter/decoration/index.ts
deleted file mode 100644
index efd7ef6f896..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/decoration/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './decorate';
-export * from './sanitize';
diff --git a/eslint-bridge/src/linting/eslint/linter/decoration/sanitize.ts b/eslint-bridge/src/linting/eslint/linter/decoration/sanitize.ts
deleted file mode 100644
index 871e040474b..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/decoration/sanitize.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-
-/**
- * Sanitizes a TypeScript ESLint rule
- *
- * TypeScript ESLint rules that relies on TypeScript's type system unconditionally assumes
- * that the type checker is always available. Linting a source code with such rules could
- * lead to a runtime error if that assumption turned out to be wrong for whatever reason.
- *
- * Aa TypeScript ESLint rule needs, therefore, to be sanitized in case its implementation
- * relies on type checking. The metadata of such a rule sets the `requiresTypeChecking`
- * property to `true`.
- *
- * The sanitization of a rule is nothing more than a decoration of its implementation. It
- * determines whether the rule uses type checking and checks whether type information is
- * available at runtime. If so, the execution of the rule proceeds; otherwise, it stops.
- *
- * @param rule a TypeScript ESLint rule to sanitize
- * @returns the sanitized rule
- */
-export function sanitizeTypeScriptESLintRule(rule: Rule.RuleModule): Rule.RuleModule {
- return {
- ...(!!rule.meta && { meta: rule.meta }),
- create(originalContext: Rule.RuleContext) {
- const interceptingContext: Rule.RuleContext = {
- id: originalContext.id,
- options: originalContext.options,
- settings: originalContext.settings,
- parserPath: originalContext.parserPath,
- parserOptions: originalContext.parserOptions,
- parserServices: originalContext.parserServices,
-
- getCwd(): string {
- return originalContext.getCwd();
- },
-
- getPhysicalFilename(): string {
- return originalContext.getPhysicalFilename();
- },
-
- getAncestors() {
- return originalContext.getAncestors();
- },
-
- getDeclaredVariables(node: Rule.Node) {
- return originalContext.getDeclaredVariables(node);
- },
-
- getFilename() {
- return originalContext.getFilename();
- },
-
- getScope() {
- return originalContext.getScope();
- },
-
- getSourceCode() {
- return originalContext.getSourceCode();
- },
-
- markVariableAsUsed(name: string) {
- return originalContext.markVariableAsUsed(name);
- },
-
- report(descriptor: Rule.ReportDescriptor): void {
- return originalContext.report(descriptor);
- },
- };
- /**
- * Overrides the rule behaviour if it requires TypeScript's type checker
- * but type information is missing.
- */
- if (
- rule.meta?.docs &&
- (rule.meta.docs as any).requiresTypeChecking === true &&
- interceptingContext.parserServices.hasFullTypeInformation !== true
- ) {
- return {};
- }
- return rule.create(interceptingContext);
- },
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/index.ts b/eslint-bridge/src/linting/eslint/linter/index.ts
deleted file mode 100644
index 2d997a3eec4..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './config';
-export * from './custom-rules';
-export * from './issues';
-export * from './quickfixes';
-export * from './visitors';
-export * from './wrapper';
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/decode.ts b/eslint-bridge/src/linting/eslint/linter/issues/decode.ts
deleted file mode 100644
index 832bec69225..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/decode.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { EncodedMessage } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { Issue } from './issue';
-import { hasSonarRuntimeOption } from '../parameters';
-
-/**
- * Decodes an issue with secondary locations, if any
- *
- * Decoding an issue with secondary locations consists in checking
- * if the rule definition claims using secondary locations by the
- * definition of the `sonar-runtime` internal parameter. If it is
- * the case, secondary locations are then decoded and a well-formed
- * issue is then returned. Otherwise, the original issue is returned
- * unchanged.
- *
- * @param ruleModule the rule definition
- * @param issue the issue to decode
- * @throws a runtime error in case of an invalid encoding
- * @returns the decoded issue (or the original one)
- */
-export function decodeSonarRuntime(ruleModule: Rule.RuleModule | undefined, issue: Issue): Issue {
- if (hasSonarRuntimeOption(ruleModule, issue.ruleId)) {
- try {
- const encodedMessage: EncodedMessage = JSON.parse(issue.message);
- return { ...issue, ...encodedMessage };
- } catch (e) {
- throw new Error(
- `Failed to parse encoded issue message for rule ${issue.ruleId}:\n"${issue.message}". ${e.message}`,
- );
- }
- }
- return issue;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/extract.ts b/eslint-bridge/src/linting/eslint/linter/issues/extract.ts
deleted file mode 100644
index 2aa3bb88ab4..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/extract.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Issue } from './issue';
-import { rule as cognitiveComplexityRule } from '../custom-rules/cognitive-complexity';
-import { rule as symbolHighlightingRule } from '../custom-rules/symbol-highlighting';
-import { SymbolHighlight } from '../visitors';
-
-/**
- * Extracts the symbol highlighting
- *
- * The linter enables the internal custom rule for symbol highlighting
- * which eventually creates an issue to this end. The issue encodes the
- * symbol highlighting as a serialized JSON object in its message, which
- * can safely be extracted if it exists in the list of returned issues
- * after linting.
- *
- * @param issues the issues to process
- * @returns the symbol highlighting
- */
-export function extractHighlightedSymbols(issues: Issue[]) {
- const issue = findAndRemoveFirstIssue(issues, symbolHighlightingRule.ruleId);
- if (issue) {
- return JSON.parse(issue.message) as SymbolHighlight[];
- }
- return [];
-}
-
-/**
- * Extracts the cognitive complexity
- *
- * The linter enables the internal custom rule for cognitive complexity
- * which eventually creates an issue to this end. The issue encodes the
- * complexity as a number in its message, which can safely be extracted
- * if it exists in the list of returned issues after linting.
- *
- * @param issues the issues to process
- * @returns the cognitive complexity
- */
-export function extractCognitiveComplexity(issues: Issue[]) {
- const issue = findAndRemoveFirstIssue(issues, cognitiveComplexityRule.ruleId);
- if (issue && !isNaN(Number(issue.message))) {
- return Number(issue.message);
- }
- return undefined;
-}
-
-/**
- * Finds the first issue matching a rule id
- *
- * The functions removes the issue from the list if it exists.
- *
- * @param issues the issues to process
- * @param ruleId the rule id that is looked for
- * @returns the found issue, if any
- */
-function findAndRemoveFirstIssue(issues: Issue[], ruleId: string) {
- for (const issue of issues) {
- if (issue.ruleId === ruleId) {
- const index = issues.indexOf(issue);
- issues.splice(index, 1);
- return issue;
- }
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/index.ts b/eslint-bridge/src/linting/eslint/linter/issues/index.ts
deleted file mode 100644
index ea8df2247e6..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './extract';
-export * from './issue';
-export * from './message';
-export * from './transform';
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/issue.ts b/eslint-bridge/src/linting/eslint/linter/issues/issue.ts
deleted file mode 100644
index 99352806746..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/issue.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { QuickFix } from '../quickfixes';
-import { Location } from './location';
-
-/**
- * A SonarQube-compatible source code issue
- *
- * It is used to send back a JS/TS analysis response to the plugin, which
- * eventually saves the issue data to SonarQube.
- *
- * @param ruleId the rule key
- * @param line the issue starting line
- * @param column the issue starting column
- * @param endLine the issue ending line
- * @param endColumn the issue ending column
- * @param message the issue message
- * @param cost the cost to fix the issue
- * @param secondaryLocations the issue secondary locations
- * @param quickFixes the issue quick fixes
- */
-export interface Issue {
- ruleId: string;
- line: number;
- column: number;
- endLine?: number;
- endColumn?: number;
- message: string;
- cost?: number;
- secondaryLocations: Location[];
- quickFixes?: QuickFix[];
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/location.ts b/eslint-bridge/src/linting/eslint/linter/issues/location.ts
deleted file mode 100644
index 8d6ecdd6c7f..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/location.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * An issue location container
- *
- * It is used for quick fixes and secondary locations.
- *
- * @param line the issue starting line
- * @param column the issue starting column
- * @param endLine the issue ending line
- * @param endColumn the issue ending column
- * @param message the issue message
- */
-export interface Location {
- line: number;
- column: number;
- endLine: number;
- endColumn: number;
- message?: string;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/message.ts b/eslint-bridge/src/linting/eslint/linter/issues/message.ts
deleted file mode 100644
index f86551595da..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/message.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import { transformFixes } from '../quickfixes';
-import { Issue } from './issue';
-
-/**
- * Converts an ESLint message into a SonarQube issue
- *
- * Converting an ESLint message into a SonarQube issue consists in extracting
- * the relevant properties from the message for the most of it. Furthermore,
- * it transforms ESLint fixes into SonarLint quick fixes, if any. On the other
- * hand, encoded secondary locations remain in the issue message at this stage
- * and are decoded in a subsequent step.
- *
- * @param source the source code
- * @param message the ESLint message to convert
- * @returns the converted SonarQube issue
- */
-export function convertMessage(source: SourceCode, message: Linter.LintMessage): Issue | null {
- /**
- * The property `ruleId` equals `null` on parsing errors, but it should not
- * happen because we lint ready SourceCode instances and not file contents.
- */
- if (!message.ruleId) {
- console.error("Illegal 'null' ruleId for eslint issue");
- return null;
- }
- return {
- ruleId: message.ruleId,
- line: message.line,
- column: message.column,
- endLine: message.endLine,
- endColumn: message.endColumn,
- message: message.message,
- quickFixes: transformFixes(source, message),
- secondaryLocations: [],
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/normalize.ts b/eslint-bridge/src/linting/eslint/linter/issues/normalize.ts
deleted file mode 100644
index 39c68ca268b..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/normalize.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Issue } from './issue';
-
-/**
- * Normalizes an issue location
- *
- * SonarQube uses 0-based column indexing when it comes to issue locations
- * while ESLint uses 1-based column indexing for message locations.
- *
- * @param issue the issue to normalize
- * @returns the normalized issue
- */
-export function normalizeLocation(issue: Issue): Issue {
- issue.column -= 1;
- if (issue.endColumn) {
- issue.endColumn -= 1;
- }
- return issue;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/issues/transform.ts b/eslint-bridge/src/linting/eslint/linter/issues/transform.ts
deleted file mode 100644
index 25e3772ed0c..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/issues/transform.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, Rule, SourceCode } from 'eslint';
-import { decodeSonarRuntime } from './decode';
-import { Issue } from './issue';
-import { convertMessage } from './message';
-import { extractCognitiveComplexity, extractHighlightedSymbols } from './extract';
-import { SymbolHighlight } from '../visitors';
-
-/**
- * The result of linting a source code
- *
- * ESLint API returns what it calls messages as results of linting a file.
- * A linting result in the context of the analyzer includes more than that
- * as it needs not only to transform ESLint messages into SonarQube issues
- * as well as analysis data about the analyzed source code, namely symbol
- * highlighting and cognitive complexity.
- *
- * @param issues the issues found in the code
- * @param ucfgPaths list of paths of ucfg files written to disk
- * @param highlightedSymbols the symbol highlighting of the code
- * @param cognitiveComplexity the cognitive complexity of the code
- */
-export type LintingResult = {
- issues: Issue[];
- ucfgPaths: string[];
- highlightedSymbols: SymbolHighlight[];
- cognitiveComplexity?: number;
-};
-
-/**
- * Transforms ESLint messages into SonarQube issues
- *
- * The result of linting a source code requires post-linting transformations
- * to return SonarQube issues. These transformations include extracting ucfg
- * paths, decoding issues with secondary locations as well as converting
- * quick fixes.
- *
- * Besides issues, a few metrics are computed during linting in the form of
- * an internal custom rule execution, namely cognitive complexity and symbol
- * highlighting. These custom rules also produce issues that are extracted.
- *
- * Transforming an ESLint message into a SonarQube issue implies:
- * - extracting UCFG rule file paths
- * - converting ESLint messages into SonarQube issues
- * - converting ESLint fixes into SonarLint quick fixes
- * - decoding encoded secondary locations
- * - normalizing issue locations
- *
- * @param messages ESLint messages to transform
- * @param ctx contextual information
- * @returns the linting result
- */
-export function transformMessages(
- messages: Linter.LintMessage[],
- ctx: { sourceCode: SourceCode; rules: Map },
-): LintingResult {
- const issues: Issue[] = [];
- const ucfgPaths: string[] = [];
-
- for (const message of messages) {
- if (message.ruleId === 'ucfg') {
- ucfgPaths.push(message.message);
- } else {
- let issue = convertMessage(ctx.sourceCode, message);
- if (issue !== null) {
- issue = normalizeLocation(decodeSonarRuntime(ctx.rules.get(issue.ruleId), issue));
- issues.push(issue);
- }
- }
- }
-
- const highlightedSymbols = extractHighlightedSymbols(issues);
- const cognitiveComplexity = extractCognitiveComplexity(issues);
- return {
- issues,
- ucfgPaths,
- highlightedSymbols,
- cognitiveComplexity,
- };
-}
-
-/**
- * Normalizes an issue location
- *
- * SonarQube uses 0-based column indexing when it comes to issue locations
- * while ESLint uses 1-based column indexing for message locations.
- *
- * @param issue the issue to normalize
- * @returns the normalized issue
- */
-function normalizeLocation(issue: Issue): Issue {
- issue.column -= 1;
- if (issue.endColumn) {
- issue.endColumn -= 1;
- }
- return issue;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/parameters/helpers/index.ts b/eslint-bridge/src/linting/eslint/linter/parameters/helpers/index.ts
deleted file mode 100644
index 9d761336af4..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/parameters/helpers/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './schema';
diff --git a/eslint-bridge/src/linting/eslint/linter/parameters/helpers/schema.ts b/eslint-bridge/src/linting/eslint/linter/parameters/helpers/schema.ts
deleted file mode 100644
index 0b11e52ff32..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/parameters/helpers/schema.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { debug } from 'helpers';
-
-/**
- * Extracts the schema of a rule
- * @param ruleModule the rule definition
- * @param ruleId the rule id
- * @returns the extracted rule schema, if any
- */
-export function getRuleSchema(ruleModule: Rule.RuleModule | undefined, ruleId: string) {
- if (!ruleModule) {
- debug(`ruleModule not found for rule ${ruleId}`);
- return undefined;
- }
- if (!ruleModule.meta || !ruleModule.meta.schema) {
- return undefined;
- }
- const { schema } = ruleModule.meta;
- return Array.isArray(schema) ? schema : [schema];
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/parameters/index.ts b/eslint-bridge/src/linting/eslint/linter/parameters/index.ts
deleted file mode 100644
index 3ec32f2f310..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/parameters/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './sonar-context';
-export * from './sonar-runtime';
diff --git a/eslint-bridge/src/linting/eslint/linter/parameters/sonar-context.ts b/eslint-bridge/src/linting/eslint/linter/parameters/sonar-context.ts
deleted file mode 100644
index ed2e4c90a21..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/parameters/sonar-context.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { getRuleSchema } from './helpers/schema';
-
-/**
- * An internal rule parameter for context-passing support
- *
- * Rules implemented in the bridge all have access to the global
- * context since they share the same code base. However, external
- * rules like custom rules don't benefit from the same visibilty.
- *
- * To remedy this, rules that need to access the global context
- * for whatever reason can do so by first setting this parameter:
- *
- *
- * ```
- * meta: {
- * schema: [{
- * title: 'sonar-context',
- * }]
- * }
- * ```
- *
- * The global context object can then be retrieved from the options
- * of ESLint's rule context, that is, `context.options`.
- */
-export const SONAR_CONTEXT = 'sonar-context';
-
-/**
- * Checks if the rule schema sets the `sonar-context` internal parameter
- * @param ruleModule the rule definition
- * @param ruleId the ESLint rule key
- * @returns true if the rule definition includes the parameter
- */
-export function hasSonarContextOption(
- ruleModule: Rule.RuleModule | undefined,
- ruleId: string,
-): boolean {
- const schema = getRuleSchema(ruleModule, ruleId);
- return !!schema && schema.some(option => option.title === SONAR_CONTEXT);
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/parameters/sonar-runtime.ts b/eslint-bridge/src/linting/eslint/linter/parameters/sonar-runtime.ts
deleted file mode 100644
index 5d6a8b055b8..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/parameters/sonar-runtime.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { getRuleSchema } from './helpers';
-
-/**
- * An internal rule parameter for secondary location support
- *
- * ESLint API for reporting messages does not provide a mechanism to
- * include more than locations and fixes in the generated report. It
- * prevents us from having a proper support for secondary locations.
- *
- * As a workaround, internal rules (or even decorated ones) that want
- * to use secondary locations first need to include in their schema a
- * `sonar-runtime` parameter as follows:
- *
- * ```
- * meta: {
- * schema: [{
- * enum: [SONAR_RUNTIME]
- * }]
- * }
- * ```
- *
- * Rules then need to encode secondary locations in the report descriptor
- * with the `toEncodedMessage` helper. This helper function encodes such
- * locations through stringified JSON objects in the `message` property
- * of the descriptor.
- *
- * The linter wrapper eventually decodes issues with secondary locations
- * by checking the presence of the internal parameter in the rule schema
- * while transforming an ESLint message into a SonarQube issue.
- */
-export const SONAR_RUNTIME = 'sonar-runtime';
-
-/**
- * Checks if the rule schema sets the `sonar-runtime` internal parameter
- * @param ruleModule the rule definition
- * @param ruleId the ESLint rule key
- * @returns true if the rule definition includes the parameter
- */
-export function hasSonarRuntimeOption(
- ruleModule: Rule.RuleModule | undefined,
- ruleId: string,
-): boolean {
- const schema = getRuleSchema(ruleModule, ruleId);
- return !!schema && schema.some(option => !!option.enum && option.enum.includes(SONAR_RUNTIME));
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/quickfixes/index.ts b/eslint-bridge/src/linting/eslint/linter/quickfixes/index.ts
deleted file mode 100644
index f5cbee9a27b..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/quickfixes/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './messages';
-export * from './quickfix';
-export * from './rules';
-export * from './transform';
diff --git a/eslint-bridge/src/linting/eslint/linter/quickfixes/messages.ts b/eslint-bridge/src/linting/eslint/linter/quickfixes/messages.ts
deleted file mode 100644
index b135ca8d2ba..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/quickfixes/messages.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * A mapping of ESLint rule keys to quick fix messages
- *
- * Since SonarLint quick fixes always include a message,
- * one needs to define a message for every enabled ESLint
- * rule that includes a fix.
- */
-const quickFixMessages = new Map([
- ['comma-dangle', 'Remove this trailing comma'],
- ['eol-last', 'Add a new line at the end of file'],
- ['no-extra-semi', 'Remove extra semicolon'],
- ['no-trailing-spaces', 'Remove trailing space'],
- ['no-var', "Replace 'var' with 'let'"],
- ['object-shorthand', 'Use shorthand property'],
- ['prefer-const', "Replace with 'const'"],
- ['prefer-template', 'Replace with template string literal'],
- ['quotes', 'Fix quotes'],
- ['radix', 'Add 10 as radix'],
- ['semi', 'Add semicolon'],
- ['prefer-immediate-return', 'Return value immediately'],
- ['prefer-while', "Replace with 'while' loop"],
- ['no-empty-interface', 'Replace with type alias'],
- ['no-inferrable-types', 'Remove type declaration'],
- ['no-unnecessary-type-arguments', 'Remove type argument'],
- ['no-unnecessary-type-assertion', 'Remove type assertion'],
- ['prefer-namespace-keyword', "Replace with 'namespace' keyword"],
- ['prefer-readonly', "Add 'readonly'"],
- ['no-non-null-assertion', "Replace with optional chaining '.?'"],
-]);
-
-/**
- * Gets the quick fix message for a fixable ESLint rule
- *
- * A fixable ESLint rule here means an ESLint rule that provides
- * a fix that doesn't include a message contrary to suggestions.
- *
- * @param ruleKey the rule key of a fixable ESLint rule
- * @throws a runtime error if there are no corresponding messages
- * @returns the corresponding quick fix message
- */
-export function getQuickFixMessage(ruleKey: string): string {
- if (!quickFixMessages.has(ruleKey)) {
- throw Error(`Missing message for quick fix '${ruleKey}'`);
- }
- return quickFixMessages.get(ruleKey)!;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/quickfixes/quickfix.ts b/eslint-bridge/src/linting/eslint/linter/quickfixes/quickfix.ts
deleted file mode 100644
index 5876e9d7603..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/quickfixes/quickfix.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Location } from '../issues/location';
-
-/**
- * A SonarLint quick fix
- *
- * @param message a message describing an action to trigger
- * @param edits a list of changes to apply to the user code
- *
- * _For the record, ESLint defines two types of code fix:_
- *
- * - _A fix is a single change applied to a code snippet_
- * - _Suggestions provide multiple changes at once_
- *
- * _ESLint fixes don't include a message contrary to ESLint suggestions._
- */
-export interface QuickFix {
- message: string;
- edits: QuickFixEdit[];
-}
-
-/**
- * A SonarLint quick fix edit
- *
- * It represents a change to apply to the user code at a location in the source file.
- *
- * @param loc a location in the code to change
- * @param text a change to apply in the code
- */
-export interface QuickFixEdit {
- loc: Location;
- text: string;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/quickfixes/rules.ts b/eslint-bridge/src/linting/eslint/linter/quickfixes/rules.ts
deleted file mode 100644
index d7038c254fd..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/quickfixes/rules.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * The set of enabled rules with quick fixes
- *
- * The purpose of this set is to declare all the rules providing
- * ESLint fixes and suggestions that the linter should consider
- * during the transformation of an ESLint message into a SonarQube
- * issue, including quick fixes.
- *
- * This set needs to be updated whenever one wants to provide (or
- * filter out) the quick fix of a rule, be it an internal one or
- * an external one.
- */
-export const quickFixRules = new Set([
- // eslint core
- 'comma-dangle',
- 'eol-last',
- 'no-extra-semi',
- 'no-trailing-spaces',
- 'no-unsafe-negation',
- 'no-var',
- 'object-shorthand',
- 'prefer-const',
- 'prefer-regex-literals',
- 'prefer-template',
- 'quotes',
- 'radix',
- 'semi',
-
- // decorated eslint core
- 'no-dupe-keys',
- 'no-duplicate-imports',
- 'no-empty',
- 'no-empty-function',
- 'no-throw-literal',
- 'no-unreachable',
- 'use-isnan',
-
- // eslint-plugin-sonarjs
- 'no-collection-size-mischeck',
- 'no-inverted-boolean-check',
- 'no-redundant-jump',
- 'non-existent-operator',
- 'prefer-immediate-return',
- 'prefer-single-boolean-return',
- 'prefer-while',
-
- // @typescript-eslint plugin
- 'no-empty-interface',
- 'no-explicit-any',
- 'no-inferrable-types',
- 'no-unnecessary-type-arguments',
- 'no-unnecessary-type-assertion',
- 'prefer-namespace-keyword',
- 'prefer-readonly',
- 'no-non-null-assertion',
-
- // decorated @typescript-eslint plugin
- 'prefer-for-of',
-
- // sonarjs
- 'different-types-comparison',
- 'inverted-assertion-arguments',
- 'no-alphabetical-sort',
- 'no-commented-code',
- 'no-duplicate-in-composite',
- 'no-exclusive-tests',
- 'no-global-this',
- 'no-in-misuse',
- 'no-primitive-wrappers',
- 'no-redundant-optional',
- 'no-redundant-parentheses',
- 'no-undefined-argument',
- 'no-unthrown-error',
- 'no-unused-function-argument',
- 'prefer-promise-shorthand',
- 'prefer-type-guard',
- 'unused-import',
-]);
diff --git a/eslint-bridge/src/linting/eslint/linter/quickfixes/transform.ts b/eslint-bridge/src/linting/eslint/linter/quickfixes/transform.ts
deleted file mode 100644
index b6150c37fd3..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/quickfixes/transform.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, Rule, SourceCode } from 'eslint';
-import { getQuickFixMessage } from './messages';
-import { QuickFix, QuickFixEdit } from './quickfix';
-import { quickFixRules } from './rules';
-
-/**
- * Transforms ESLint fixes and suggestions into SonarLint quick fixes
- * @param source the source code
- * @param messages the ESLint messages to transform
- * @returns the transformed quick fixes
- */
-export function transformFixes(source: SourceCode, messages: Linter.LintMessage): QuickFix[] {
- if (!hasQuickFix(messages)) {
- return [];
- }
- const quickFixes: QuickFix[] = [];
- if (messages.fix) {
- quickFixes.push({
- message: getQuickFixMessage(messages.ruleId!),
- edits: [fixToEdit(source, messages.fix)],
- });
- }
- if (messages.suggestions) {
- messages.suggestions.forEach(suggestion => {
- quickFixes.push({
- message: suggestion.desc,
- edits: [fixToEdit(source, suggestion.fix)],
- });
- });
- }
- return quickFixes;
-}
-
-/**
- * Checks if an ESLint fix is convertible into a SonarLint quick fix
- *
- * An ESLint fix is convertible into a SonarLint quick fix iff:
- * - it includes a fix or suggestions
- * - the quick fix of the rule is enabled
- *
- * @param message an ESLint message
- * @returns true if the message is convertible
- */
-function hasQuickFix(message: Linter.LintMessage): boolean {
- if (!message.fix && (!message.suggestions || message.suggestions.length === 0)) {
- return false;
- }
- return !!message.ruleId && quickFixRules.has(message.ruleId);
-}
-
-/**
- * Transform an ESLint fix into a SonarLint quick fix edit
- * @param source the source code
- * @param fix the ESLint fix to transform
- * @returns the transformed SonarLint quick fix edit
- */
-function fixToEdit(source: SourceCode, fix: Rule.Fix): QuickFixEdit {
- const [start, end] = fix.range;
- const startPos = source.getLocFromIndex(start);
- const endPos = source.getLocFromIndex(end);
- return {
- loc: {
- line: startPos.line,
- column: startPos.column,
- endLine: endPos.line,
- endColumn: endPos.column,
- },
- text: fix.text,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/CodeRecognizer.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/CodeRecognizer.ts
deleted file mode 100644
index 82b4411683d..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/CodeRecognizer.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import LanguageFootprint from './LanguageFootprint';
-
-export class CodeRecognizer {
- language: LanguageFootprint;
- threshold: number;
-
- constructor(threshold: number, language: LanguageFootprint) {
- this.language = language;
- this.threshold = threshold;
- }
-
- recognition(line: string) {
- let probability = 0;
- for (const pattern of this.language.getDetectors()) {
- probability = 1 - (1 - probability) * (1 - pattern.recognition(line));
- }
- return probability;
- }
-
- extractCodeLines(lines: string[]): string[] {
- return lines.filter(line => this.recognition(line) >= this.threshold);
- }
-
- isLineOfCode(line: string): boolean {
- return this.recognition(line) - this.threshold > 0;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/Detector.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/Detector.ts
deleted file mode 100644
index 8b129c08c72..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/Detector.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export default abstract class Detector {
- probability: number;
-
- constructor(probability: number) {
- if (probability < 0 || probability > 1) {
- throw new Error('probability should be between [0 .. 1]');
- }
- this.probability = probability;
- }
-
- abstract scan(line: string): number;
-
- recognition(line: string): number {
- const matchers = this.scan(line);
- if (matchers === 0) {
- return 0;
- } else {
- return 1 - Math.pow(1 - this.probability, matchers);
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/JavaScriptFootPrint.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/JavaScriptFootPrint.ts
deleted file mode 100644
index 520c2a90843..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/JavaScriptFootPrint.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from './Detector';
-import CamelCaseDetector from './detectors/CamelCaseDetector';
-import ContainsDetector from './detectors/ContainsDetector';
-import EndWithDetector from './detectors/EndWithDetector';
-import KeywordsDetector from './detectors/KeywordsDetector';
-import LanguageFootprint from './LanguageFootprint';
-
-export class JavaScriptFootPrint implements LanguageFootprint {
- detectors: Set = new Set();
-
- constructor() {
- this.detectors.add(new EndWithDetector(0.95, '}', ';', '{'));
- this.detectors.add(new KeywordsDetector(0.7, '++', '||', '&&', '===', '?.', '??'));
- this.detectors.add(
- new KeywordsDetector(
- 0.3,
- 'public',
- 'abstract',
- 'class',
- 'implements',
- 'extends',
- 'return',
- 'throw',
- 'private',
- 'protected',
- 'enum',
- 'continue',
- 'assert',
- 'boolean',
- 'this',
- 'instanceof',
- 'interface',
- 'static',
- 'void',
- 'super',
- 'true',
- 'case:',
- 'let',
- 'const',
- 'var',
- 'async',
- 'await',
- 'break',
- 'yield',
- 'typeof',
- 'import',
- 'export',
- ),
- );
- this.detectors.add(
- new ContainsDetector(
- 0.95,
- 'for(',
- 'if(',
- 'while(',
- 'catch(',
- 'switch(',
- 'try{',
- 'else{',
- 'this.',
- 'window.',
- /;\s+\/\//,
- "import '",
- 'import "',
- 'require(',
- ),
- );
- this.detectors.add(new CamelCaseDetector(0.5));
- }
-
- getDetectors(): Set {
- return this.detectors;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/LanguageFootprint.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/LanguageFootprint.ts
deleted file mode 100644
index efc7f8fd429..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/LanguageFootprint.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from './Detector';
-
-export default interface LanguageFootprint {
- getDetectors(): Set;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/CamelCaseDetector.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/CamelCaseDetector.ts
deleted file mode 100644
index a792b80ba48..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/CamelCaseDetector.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from '../Detector';
-
-export default class CamelCaseDetector extends Detector {
- constructor(probability: number) {
- super(probability);
- }
-
- scan(line: string): number {
- let previousChar = ' ';
- let currentChar;
- for (let i = 0; i < line.length; i++) {
- currentChar = line.charAt(i);
- if (isLowerCaseThenUpperCase(previousChar, currentChar)) {
- return 1;
- }
- previousChar = currentChar;
- }
- return 0;
- }
-}
-
-function isLowerCaseThenUpperCase(previousChar: string, char: string): boolean {
- return isLowercase(previousChar) && isUpprcase(char);
-
- function isLowercase(char: string): boolean {
- return char.toLowerCase() === char;
- }
- function isUpprcase(char: string): boolean {
- return char.toUpperCase() === char;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/ContainsDetector.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/ContainsDetector.ts
deleted file mode 100644
index e558e20a096..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/ContainsDetector.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from '../Detector';
-
-export default class ContainsDetector extends Detector {
- strings: (string | RegExp)[];
-
- constructor(probability: number, ...strings: (string | RegExp)[]) {
- super(probability);
- this.strings = strings;
- }
-
- scan(line: string): number {
- const lineWithoutSpaces = line.replace(/\s+/, '');
- let matchers = 0;
- for (const str of this.strings) {
- let regex = str;
- if (typeof str === 'string') {
- regex = new RegExp(escapeRegex(str), 'g');
- }
- matchers += (lineWithoutSpaces.match(regex) || []).length;
- }
- return matchers;
- }
-}
-
-function escapeRegex(value: string) {
- return value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/EndWithDetector.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/EndWithDetector.ts
deleted file mode 100644
index af59711d5a8..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/EndWithDetector.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from '../Detector';
-
-export default class EndWithDetector extends Detector {
- endOfLines: string[];
-
- constructor(probability: number, ...endOfLines: string[]) {
- super(probability);
- this.endOfLines = endOfLines;
- }
-
- scan(line: string): number {
- for (let i = line.length - 1; i >= 0; i--) {
- const char = line.charAt(i);
- for (const endOfLine of this.endOfLines) {
- if (char === endOfLine) {
- return 1;
- }
- }
- if (!isWhitespace(char) && char !== '*' && char !== '/') {
- return 0;
- }
- }
- return 0;
-
- function isWhitespace(char: string): boolean {
- return /\s/.test(char);
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/KeywordsDetector.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/KeywordsDetector.ts
deleted file mode 100644
index 6e987ed517a..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/detectors/KeywordsDetector.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Detector from '../Detector';
-
-export default class KeywordsDetector extends Detector {
- keywords: string[];
-
- constructor(probability: number, ...keywords: string[]) {
- super(probability);
- this.keywords = keywords;
- }
-
- scan(line: string): number {
- let matchers = 0;
- const words = line.split(/[ \t(),{}]/);
- for (const word of words) {
- if (this.keywords.includes(word)) {
- matchers++;
- }
- }
- return matchers;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/recognizers/index.ts b/eslint-bridge/src/linting/eslint/linter/recognizers/index.ts
deleted file mode 100644
index b93e21646c3..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/recognizers/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// Inspired from sonar-java and sonar-analyzer-commons
-// - https://github.com/SonarSource/sonar-java/blob/e3b4ce381eb994235ab811d253953e400d12aab2/java-checks/src/main/java/org/sonar/java/checks/JavaFootprint.java#L31
-// - https://github.com/SonarSource/sonar-analyzer-commons/blob/e2881512ce632259981c65b587652151e876d736/recognizers/src/main/java/org/sonarsource/analyzer/commons/recognizers/CodeRecognizer.java#L25
-
-export * from './JavaScriptFootPrint';
-export * from './CodeRecognizer';
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/cpd.ts b/eslint-bridge/src/linting/eslint/linter/visitors/cpd.ts
deleted file mode 100644
index b117bf97661..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/cpd.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SourceCode, AST } from 'eslint';
-import { visit } from './visitor';
-import { Location } from './metrics/helpers';
-
-/**
- * A copy-paste detector token (cpd)
- *
- * A cpd token is used by SonarQube to compute code duplication
- * within a code base. It relies on a token location as well as
- * an image, that is, the token value except for string literal
- * which is anonymised to extend the scope of what a duplicated
- * code pattern can be.
- *
- * @param location the token location
- * @param image the token
- */
-export interface CpdToken {
- location: Location;
- image: string;
-}
-
-/**
- * Extracts the copy-paste detector (cpd) tokens
- * @param sourceCode the source code to extract from
- * @returns the cpd tokens
- */
-export function getCpdTokens(sourceCode: SourceCode): { cpdTokens: CpdToken[] } {
- const cpdTokens: CpdToken[] = [];
- const tokens = sourceCode.ast.tokens;
- const { jsxTokens, importTokens, requireTokens } = extractTokens(sourceCode);
-
- tokens.forEach(token => {
- let text = token.value;
-
- if (text.trim().length === 0) {
- // for EndOfFileToken and JsxText tokens containing only whitespaces
- return;
- }
-
- if (importTokens.includes(token)) {
- // for tokens from import statements
- return;
- }
-
- if (requireTokens.includes(token)) {
- // for tokens from require statements
- return;
- }
-
- if (isStringLiteralToken(token) && !jsxTokens.includes(token)) {
- text = 'LITERAL';
- }
-
- const startPosition = token.loc.start;
- const endPosition = token.loc.end;
-
- cpdTokens.push({
- location: {
- startLine: startPosition.line,
- startCol: startPosition.column,
- endLine: endPosition.line,
- endCol: endPosition.column,
- },
- image: text,
- });
- });
-
- return { cpdTokens };
-}
-
-/**
- * Extracts specific tokens to be ignored by copy-paste detection
- * @param sourceCode the source code to extract from
- * @returns a list of tokens to be ignored
- */
-function extractTokens(sourceCode: SourceCode): {
- jsxTokens: AST.Token[];
- importTokens: AST.Token[];
- requireTokens: AST.Token[];
-} {
- const jsxTokens: AST.Token[] = [];
- const importTokens: AST.Token[] = [];
- const requireTokens: AST.Token[] = [];
- visit(sourceCode, (node: estree.Node) => {
- const tsNode = node as TSESTree.Node;
- switch (tsNode.type) {
- case 'JSXAttribute':
- if (tsNode.value?.type === 'Literal') {
- jsxTokens.push(...sourceCode.getTokens(tsNode.value as estree.Node));
- }
- break;
- case 'ImportDeclaration':
- importTokens.push(...sourceCode.getTokens(tsNode as estree.Node));
- break;
- case 'CallExpression':
- if (tsNode.callee.type === 'Identifier' && tsNode.callee.name === 'require') {
- requireTokens.push(...sourceCode.getTokens(tsNode as estree.Node));
- }
- break;
- }
- });
- return { jsxTokens, importTokens, requireTokens };
-}
-
-function isStringLiteralToken(token: AST.Token) {
- return token.value.startsWith('"') || token.value.startsWith("'") || token.value.startsWith('`');
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/index.ts b/eslint-bridge/src/linting/eslint/linter/visitors/index.ts
deleted file mode 100644
index 9a92a0c2ca6..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './cpd';
-export * from './metrics';
-export * from './symbol-highlighting';
-export * from './syntax-highlighting';
-export * from './visitor';
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/classes.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/classes.ts
deleted file mode 100644
index d03d1252264..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/classes.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visitAndCountIf } from './helpers';
-
-/**
- * The ESLint class node types
- */
-const CLASS_NODES = ['ClassDeclaration', 'ClassExpression'];
-
-/**
- * Computes the number of classes in the source code
- */
-export function countClasses(sourceCode: SourceCode): number {
- return visitAndCountIf(sourceCode, node => CLASS_NODES.includes(node.type));
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/comments.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/comments.ts
deleted file mode 100644
index d460d71a029..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/comments.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { addLines } from './helpers';
-
-/**
- * A comment marker to tell SonarQube to ignore any issue on the same line
- * as the one with a comment whose text is `NOSONAR` (case-insensitive).
- */
-const NOSONAR = 'NOSONAR';
-
-/**
- * Finds the line numbers of comments in the source code
- * @param sourceCode the source code to visit
- * @param ignoreHeaderComments a flag to ignore file header comments
- * @returns the line numbers of comments
- */
-export function findCommentLines(
- sourceCode: SourceCode,
- ignoreHeaderComments: boolean,
-): { commentLines: number[]; nosonarLines: number[] } {
- const commentLines: Set = new Set();
- const nosonarLines: Set = new Set();
-
- let comments = sourceCode.ast.comments;
-
- // ignore header comments -> comments before first token
- const firstToken = sourceCode.getFirstToken(sourceCode.ast);
- if (firstToken && ignoreHeaderComments) {
- const header = sourceCode.getCommentsBefore(firstToken);
- comments = comments.slice(header.length);
- }
-
- for (const comment of comments) {
- if (comment.loc) {
- const commentValue = comment.value.startsWith('*')
- ? comment.value.substring(1).trim()
- : comment.value.trim();
- if (commentValue.toUpperCase().startsWith(NOSONAR)) {
- addLines(comment.loc.start.line, comment.loc.end.line, nosonarLines);
- } else if (commentValue.length > 0) {
- addLines(comment.loc.start.line, comment.loc.end.line, commentLines);
- }
- }
- }
-
- return {
- commentLines: Array.from(commentLines).sort((a, b) => a - b),
- nosonarLines: Array.from(nosonarLines).sort((a, b) => a - b),
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/compute.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/compute.ts
deleted file mode 100644
index d196881569d..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/compute.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { countClasses } from './classes';
-import { findCommentLines } from './comments';
-import { computeCyclomaticComplexity } from './cyclomatic-complexity';
-import { findExecutableLines } from './executable-lines';
-import { countFunctions } from './functions';
-import { Metrics } from './metrics';
-import { findNcloc } from './ncloc';
-import { countStatements } from './statements';
-
-/**
- * Computes the metrics of an ESLint source code
- * @param sourceCode the ESLint source code
- * @param ignoreHeaderComments a flag to ignore file header comments
- * @param cognitiveComplexity the cognitive complexity of the source code
- * @returns the source code metrics
- */
-export function computeMetrics(
- sourceCode: SourceCode,
- ignoreHeaderComments: boolean,
- cognitiveComplexity = 0,
-): Metrics {
- return {
- ncloc: findNcloc(sourceCode),
- ...findCommentLines(sourceCode, ignoreHeaderComments),
- executableLines: findExecutableLines(sourceCode),
- functions: countFunctions(sourceCode),
- statements: countStatements(sourceCode),
- classes: countClasses(sourceCode),
- complexity: computeCyclomaticComplexity(sourceCode),
- cognitiveComplexity,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.ts
deleted file mode 100644
index 7aeacdd20f4..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visit } from 'linting/eslint';
-
-/**
- * The ESLint loop node types
- */
-const LOOP_NODES = [
- 'ForStatement',
- 'ForInStatement',
- 'ForOfStatement',
- 'WhileStatement',
- 'DoWhileStatement',
-];
-
-/**
- * The ESLint conditional node types
- */
-const CONDITIONAL_NODES = ['IfStatement', 'ConditionalExpression', 'SwitchCase'];
-
-/**
- * The ESLint function node types
- */
-const FUNCTION_NODES = ['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'];
-
-/**
- * The ESLint node types increasing complexity
- */
-const COMPLEXITY_NODES = [
- ...CONDITIONAL_NODES,
- ...FUNCTION_NODES,
- ...LOOP_NODES,
- 'LogicalExpression',
-];
-
-/**
- * Computes the cyclomatic complexity of an ESLint source code
- * @param sourceCode the ESLint source code
- * @returns the cyclomatic complexity
- */
-export function computeCyclomaticComplexity(sourceCode: SourceCode): number {
- let complexity = 0;
- visit(sourceCode, node => {
- if (COMPLEXITY_NODES.includes(node.type)) {
- complexity++;
- }
- });
- return complexity;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/executable-lines.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/executable-lines.ts
deleted file mode 100644
index 4722c9f3a8b..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/executable-lines.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visit } from 'linting/eslint';
-
-/**
- * The ESLint executable node types
- */
-const EXECUTABLE_NODES = [
- 'ExpressionStatement',
- 'IfStatement',
- 'LabeledStatement',
- 'BreakStatement',
- 'ContinueStatement',
- 'WithStatement',
- 'SwitchStatement',
- 'ReturnStatement',
- 'ThrowStatement',
- 'TryStatement',
- 'WhileStatement',
- 'DoWhileStatement',
- 'ForStatement',
- 'ForInStatement',
- 'DebuggerStatement',
- 'VariableDeclaration',
- 'ForOfStatement',
-];
-
-/**
- * Finds the line numbers of executable lines in the source code
- */
-export function findExecutableLines(sourceCode: SourceCode): number[] {
- const lines: Set = new Set();
- visit(sourceCode, node => {
- if (EXECUTABLE_NODES.includes(node.type) && node.loc) {
- lines.add(node.loc.start.line);
- }
- });
- return Array.from(lines).sort((a, b) => a - b);
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/functions.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/functions.ts
deleted file mode 100644
index 2c4d53dce62..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/functions.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visitAndCountIf } from './helpers';
-
-/**
- * The ESLint function node types
- */
-const FUNCTION_NODES = ['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'];
-
-/**
- * Computes the number of functions in the source code
- */
-export function countFunctions(sourceCode: SourceCode): number {
- return visitAndCountIf(sourceCode, node => FUNCTION_NODES.includes(node.type));
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/counter.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/counter.ts
deleted file mode 100644
index e299f275841..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/counter.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { SourceCode } from 'eslint';
-import { visit } from 'linting/eslint';
-
-/**
- * Counts the number of nodes matching a predicate
- * @param sourceCode the source code to vist
- * @param predicate the condition to count the node
- * @returns the number of nodes matching the predicate
- */
-export function visitAndCountIf(
- sourceCode: SourceCode,
- predicate: (node: estree.Node) => boolean,
-): number {
- let results = 0;
- visit(sourceCode, node => {
- if (predicate(node)) {
- results++;
- }
- });
- return results;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/index.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/index.ts
deleted file mode 100644
index 9a78f926741..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './counter';
-export * from './lines';
-export * from './location';
-export * from './tokens';
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/lines.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/lines.ts
deleted file mode 100644
index 0222b9d19a5..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/lines.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Adds the line numbers within a range into a set
- * @param startLine the lower bound
- * @param endLine the upper bound
- * @param lines the set of lines number to extend
- */
-export function addLines(startLine: number, endLine: number, lines: Set) {
- for (let line = startLine; line <= endLine; line++) {
- lines.add(line);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/location.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/location.ts
deleted file mode 100644
index 52bfe6e19c8..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/location.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-
-/**
- * A metric location
- *
- * @param startLine the starting line of the metric
- * @param startCol the starting column of the metric
- * @param endLine the ending line of the metric
- * @param endCol the ending column of the metric
- */
-export interface Location {
- startLine: number;
- startCol: number;
- endLine: number;
- endCol: number;
-}
-
-/**
- * Converts an ESLint location into a metric location
- * @param loc the ESLint location to convert
- * @returns the converted location
- */
-export function convertLocation(loc: estree.SourceLocation): Location {
- return {
- startLine: loc.start.line,
- startCol: loc.start.column,
- endLine: loc.end.line,
- endCol: loc.end.column,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/tokens.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/tokens.ts
deleted file mode 100644
index 4a941cd0e64..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/helpers/tokens.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { AST } from 'vue-eslint-parser';
-
-/**
- * Extracts comments and tokens from an ESLint source code
- *
- * The returned extracted comments includes also those from
- * the template section of a Vue.js Single File Component.
- *
- * @param sourceCode the source code to extract from
- * @returns the extracted tokens and comments
- */
-export function extractTokensAndComments(sourceCode: SourceCode): {
- tokens: AST.Token[];
- comments: AST.Token[];
-} {
- const ast = sourceCode.ast as AST.ESLintProgram;
- const tokens = [...(ast.tokens || [])];
- const comments = [...(ast.comments || [])];
- if (ast.templateBody) {
- const { templateBody } = ast;
- tokens.push(...templateBody.tokens);
- comments.push(...templateBody.comments);
- }
- return { tokens, comments };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/index.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/index.ts
deleted file mode 100644
index b73f91597ac..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './compute';
-export * from './metrics';
-export * from './nosonar';
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/metrics.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/metrics.ts
deleted file mode 100644
index 51be452061d..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/metrics.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Metrics of the source code
- *
- * @param ncloc the line numbers of physical code
- * @param commentLines the line numbers of comments
- * @param nosonarLines the line numbers of NOSONAR comments
- * @param executableLines the line numbers of executable code
- * @param functions the number of functions
- * @param statements the number of statements
- * @param classes the number of classes
- * @param complexity the cyclomatic complexity
- * @param cognitiveComplexity the cognitive complexity
- */
-export interface Metrics {
- ncloc?: number[];
- commentLines?: number[];
- nosonarLines: number[];
- executableLines?: number[];
- functions?: number;
- statements?: number;
- classes?: number;
- complexity?: number;
- cognitiveComplexity?: number;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/ncloc.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/ncloc.ts
deleted file mode 100644
index 586fb721a31..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/ncloc.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { AST } from 'vue-eslint-parser';
-import { addLines } from './helpers';
-
-/**
- * Finds the line numbers of code (ncloc)
- *
- * The line numbers of code denote physical lines that contain at least
- * one character which is neither a whitespace nor a tabulation nor part
- * of a comment.
- *
- * @param sourceCode the ESLint source code
- * @returns the line numbers of code
- */
-export function findNcloc(sourceCode: SourceCode): number[] {
- const lines: Set = new Set();
- const ast = sourceCode.ast as AST.ESLintProgram;
- const tokens = [...(ast.tokens || [])];
- if (ast.templateBody) {
- tokens.push(...extractVuejsTokens(ast.templateBody));
- }
- for (const token of tokens) {
- addLines(token.loc.start.line, token.loc.end.line, lines);
- }
- return Array.from(lines).sort((a, b) => a - b);
-}
-
-/**
- * Extracts Vue.js-specific tokens
- *
- * The template section parsed by `vue-eslint-parser` includes tokens for the whole `.vue` file.
- * Everything that is not template-related is either raw text or whitespace. Although the style
- * section is not parsed, its tokens are made available. Therefore, in addition to the tokens of
- * the script section, we consider tokens from the template and style sections as well, provided
- * that they don't denote whitespace or comments.
- */
-function extractVuejsTokens(templateBody: AST.VElement & AST.HasConcreteInfo) {
- const tokens = [];
-
- let withinStyle = false;
- let withinComment = false;
- for (const token of templateBody.tokens) {
- /**
- * Style section
- */
- if (token.type === 'HTMLTagOpen' && token.value === 'style') {
- withinStyle = true;
- } else if (token.type === 'HTMLEndTagOpen' && token.value === 'style') {
- withinStyle = false;
- }
-
- /**
- * Whitespace tokens should be ignored in accordance with the
- * definition of ncloc.
- */
- if (token.type === 'HTMLWhitespace') {
- continue;
- }
-
- /**
- * Tokens of type 'HTMLRawText' denote either tokens from the
- * style section or tokens from the script section. Since the
- * tokens from the script section are already retrieved from
- * the root of the ast, we ignore those and only consider the
- * tokens from the style section.
- */
- if (token.type === 'HTMLRawText' && !withinStyle) {
- continue;
- }
-
- /**
- * CSS comment tokens should be ignored in accordance with the
- * definition of ncloc.
- */
- if (withinStyle && !withinComment && token.value === '/*') {
- withinComment = true;
- continue;
- } else if (withinStyle && withinComment) {
- withinComment = token.value !== '*/';
- continue;
- }
-
- tokens.push(token);
- }
-
- return tokens;
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/nosonar.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/nosonar.ts
deleted file mode 100644
index 0d7fb96d40b..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/nosonar.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { findCommentLines } from './comments';
-
-/**
- * Finds the line numbers of `NOSONAR` comments
- *
- * `NOSONAR` comments are indicators for SonarQube to ignore
- * any issues raised on the same lines as those where appear
- * such comments.
- *
- * @param sourceCode the source code to visit
- * @returns the line numbers of `NOSONAR` comments
- */
-export function findNoSonarLines(sourceCode: SourceCode) {
- return {
- nosonarLines: findCommentLines(sourceCode, false).nosonarLines,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/statements.ts b/eslint-bridge/src/linting/eslint/linter/visitors/metrics/statements.ts
deleted file mode 100644
index a51affb8a5e..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/metrics/statements.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visitAndCountIf } from './helpers';
-
-/**
- * The ESLint statement node types
- */
-const STATEMENT_NODES = [
- 'VariableDeclaration',
- 'EmptyStatement',
- 'ExpressionStatement',
- 'IfStatement',
- 'DoWhileStatement',
- 'WhileStatement',
- 'ForInStatement',
- 'ForOfStatement',
- 'ForStatement',
- 'ContinueStatement',
- 'BreakStatement',
- 'ReturnStatement',
- 'WithStatement',
- 'SwitchStatement',
- 'ThrowStatement',
- 'TryStatement',
- 'DebuggerStatement',
-];
-
-/**
- * Computes the number of statements in the source code
- */
-export function countStatements(sourceCode: SourceCode): number {
- return visitAndCountIf(sourceCode, node => STATEMENT_NODES.includes(node.type));
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/symbol-highlighting.ts b/eslint-bridge/src/linting/eslint/linter/visitors/symbol-highlighting.ts
deleted file mode 100644
index 08f7fb1d432..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/symbol-highlighting.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { AST } from 'vue-eslint-parser';
-import { convertLocation, extractTokensAndComments, Location } from './metrics/helpers';
-
-/**
- * A symbol highlight
- *
- * @param declaration the location where the symbol is declared
- * @param references the locations where the symbol is referenced
- */
-export interface SymbolHighlight {
- declaration: Location;
- references: Location[];
-}
-
-/**
- * A rule for computing the symbol highlighting of the source code
- *
- * We use an ESLint rule as we need to access declared variables which
- * are only available only through the rule context.
- */
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- let variables: Set;
-
- /*
- Remove TypeAnnotation part from location of identifier for purpose of symbol highlighting.
- This was motivated by following code
-
- var XMLHttpRequest: {
- new(): XMLHttpRequest; // this is reference to var, not interface
- };
- interface XMLHttpRequest {}
-
- where XMLHttpRequest is both type and variable name. Issue type annotation inside the variable declaration
- is reference to the variable (this is likely a bug in parser), which causes overlap between declaration and
- reference, which makes SQ API fail with RuntimeException. As a workaround we remove TypeAnnotation part of
- identifier node from its location, so no overlap is possible (arguably this is also better UX for symbol
- highlighting).
- */
- function identifierLocation(node: TSESTree.Node) {
- const source = context.getSourceCode();
- const loc = {
- start: node.loc.start,
- end:
- node.type === 'Identifier' && node.typeAnnotation
- ? source.getLocFromIndex(node.typeAnnotation.range[0])
- : node.loc.end,
- };
- return convertLocation(loc);
- }
-
- return {
- Program() {
- // clear "variables" for each file
- variables = new Set();
- },
- '*': (node: estree.Node) => {
- context.getDeclaredVariables(node).forEach(v => variables.add(v));
- },
- 'Program:exit': (node: estree.Node) => {
- const result: SymbolHighlight[] = [];
- variables.forEach(v => {
- // if variable is initialized during declaration it is part of references as well
- // so we merge declarations and references to remove duplicates and take the earliest in the file as the declaration
- const allRef = [
- ...new Set([...v.defs.map(d => d.name), ...v.references.map(r => r.identifier)]),
- ]
- .filter(i => !!i.loc)
- .sort((a, b) => a.loc!.start.line - b.loc!.start.line);
- if (allRef.length === 0) {
- // defensive check, this should never happen
- return;
- }
- const highlightedSymbol: SymbolHighlight = {
- declaration: identifierLocation(allRef[0] as TSESTree.Node),
- references: allRef.slice(1).map(r => identifierLocation(r as TSESTree.Node)),
- };
- result.push(highlightedSymbol);
- });
-
- const openCurlyBracesStack: AST.Token[] = [];
- const openHtmlTagsStack: AST.Token[] = [];
- extractTokensAndComments(context.getSourceCode()).tokens.forEach(token => {
- switch (token.type) {
- case 'Punctuator':
- if (token.value === '{') {
- openCurlyBracesStack.push(token);
- } else if (token.value === '}') {
- const highlightedSymbol: SymbolHighlight = {
- declaration: convertLocation(openCurlyBracesStack.pop()!.loc),
- references: [convertLocation(token.loc)],
- };
- result.push(highlightedSymbol);
- }
- break;
- case 'HTMLTagOpen':
- openHtmlTagsStack.push(token);
- break;
- case 'HTMLSelfClosingTagClose':
- openHtmlTagsStack.pop();
- break;
- case 'HTMLEndTagOpen':
- const openHtmlTag = openHtmlTagsStack.pop();
- if (openHtmlTag) {
- const highlightedSymbol: SymbolHighlight = {
- declaration: convertLocation(openHtmlTag.loc),
- references: [convertLocation(token.loc)],
- };
- result.push(highlightedSymbol);
- }
- break;
- }
- });
-
- // as issues are the only communication channel of a rule
- // we pass data as serialized json as an issue message
- context.report({ node, message: JSON.stringify(result) });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/syntax-highlighting.ts b/eslint-bridge/src/linting/eslint/linter/visitors/syntax-highlighting.ts
deleted file mode 100644
index 5bb58d13ddd..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/syntax-highlighting.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import * as ESTree from 'estree';
-import { AST } from 'vue-eslint-parser';
-import { extractTokensAndComments, Location } from './metrics/helpers';
-
-/**
- * A syntax highlight
- *
- * A syntax highlight is used by SonarQube to display a source code
- * with syntax highlighting.
- *
- * @param location the highlight location
- * @param textType the highlight type
- */
-export interface SyntaxHighlight {
- location: Location;
- textType: TextType;
-}
-
-/**
- * Denotes a highlight type of a token
- *
- * The set of possible values for a token highlight is defined by SonarQube, which
- * uses this value to decide how to highlight a token.
- */
-export type TextType = 'CONSTANT' | 'COMMENT' | 'STRUCTURED_COMMENT' | 'KEYWORD' | 'STRING';
-
-/**
- * Computes the syntax highlighting of an ESLint source code
- * @param sourceCode the source code to highlight
- * @returns a list of highlighted tokens
- */
-export function getSyntaxHighlighting(sourceCode: SourceCode) {
- const { tokens, comments } = extractTokensAndComments(sourceCode);
- const highlights: SyntaxHighlight[] = [];
- for (const token of tokens) {
- switch (token.type as any) {
- case 'HTMLTagOpen':
- case 'HTMLTagClose':
- case 'HTMLEndTagOpen':
- case 'HTMLSelfClosingTagClose':
- case 'Keyword':
- highlight(token, 'KEYWORD', highlights);
- break;
- case 'HTMLLiteral':
- case 'String':
- case 'Template':
- case 'RegularExpression':
- highlight(token, 'STRING', highlights);
- break;
- case 'Numeric':
- highlight(token, 'CONSTANT', highlights);
- break;
- }
- }
- for (const comment of comments) {
- if (
- (comment.type === 'Block' && comment.value.startsWith('*')) ||
- comment.type === 'HTMLBogusComment'
- ) {
- highlight(comment, 'STRUCTURED_COMMENT', highlights);
- } else {
- highlight(comment, 'COMMENT', highlights);
- }
- }
- return { highlights };
-}
-
-function highlight(
- node: AST.Token | ESTree.Comment,
- highlightKind: TextType,
- highlights: SyntaxHighlight[],
-) {
- if (!node.loc) {
- return;
- }
- const startPosition = node.loc.start;
- const endPosition = node.loc.end;
- highlights.push({
- location: {
- startLine: startPosition.line,
- startCol: startPosition.column,
- endLine: endPosition.line,
- endCol: endPosition.column,
- },
- textType: highlightKind,
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/visitors/visitor.ts b/eslint-bridge/src/linting/eslint/linter/visitors/visitor.ts
deleted file mode 100644
index 2e011ed0ee6..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/visitors/visitor.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { SourceCode } from 'eslint';
-
-/**
- * Visits the abstract syntax tree of an ESLint source code
- * @param sourceCode the source code to visit
- * @param callback a callback function invoked at each node visit
- */
-export function visit(sourceCode: SourceCode, callback: (node: estree.Node) => void): void {
- const stack: estree.Node[] = [sourceCode.ast];
- while (stack.length) {
- const node = stack.pop() as estree.Node;
- callback(node);
- stack.push(...childrenOf(node, sourceCode.visitorKeys).reverse());
- }
-}
-
-/**
- * Returns the direct children of a node
- * @param node the node to get the children
- * @param visitorKeys the visitor keys provided by the source code
- * @returns the node children
- */
-export function childrenOf(node: estree.Node, visitorKeys: SourceCode.VisitorKeys): estree.Node[] {
- const keys = visitorKeys[node.type];
- const children = [];
- if (keys) {
- for (const key of keys) {
- /**
- * A node's child may be a node or an array of nodes, e.g., `body` in `estree.Program`.
- * If it's an array, we extract all the nodes from it; if not, we just add the node.
- */
- const child = (node as any)[key];
- if (Array.isArray(child)) {
- children.push(...child);
- } else {
- children.push(child);
- }
- }
- }
- return children.filter(Boolean);
-}
diff --git a/eslint-bridge/src/linting/eslint/linter/wrapper.ts b/eslint-bridge/src/linting/eslint/linter/wrapper.ts
deleted file mode 100644
index e247daade44..00000000000
--- a/eslint-bridge/src/linting/eslint/linter/wrapper.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import { loadBundles, loadCustomRules } from './bundle-loader';
-import { createLinterConfig, RuleConfig } from './config';
-import { FileType } from 'helpers';
-import { transformMessages, LintingResult } from './issues';
-import { CustomRule } from './custom-rules';
-
-/**
- * Wrapper's constructor initializer. All the parameters are optional,
- * having the option to create a Linter without any additional rules
- * loaded, aside of the preexisting ESLint core rules.
- *
- * @param inputRules the quality profile rules, enabled rules
- * @param environments the JavaScript environments
- * @param globals the global variables
- * @param ruleBundles the bundles of rules to load in the linter
- * @param customRules array of rules to load in the linter
- */
-export interface WrapperOptions {
- inputRules?: RuleConfig[];
- environments?: string[];
- globals?: string[];
- ruleBundles?: string[];
- customRules?: CustomRule[];
-}
-
-/**
- * When a linter is created, by default all these bundles of rules will
- * be loaded into the linter internal rules map. This behaviour can be
- * adjusted by passing which bundles, if any, should be loaded instead.
- * The order of this array is important here. Rules from a previous bundle
- * will be overridden by the implementation of the same rule key in a
- * subsequent bundle.
- */
-const defaultRuleBundles = [
- 'externalRules',
- 'pluginRules',
- 'internalRules',
- 'contextRules',
- 'internalCustomRules',
-];
-
-/**
- * A wrapper of ESLint linter
- *
- * The purpose of the wrapper is to configure the behaviour of ESLint linter,
- * which includes:
- *
- * - defining the rules that should be used during linting,
- * - declaring globals that need to be considered as such
- * - defining the environments bringing a set of predefined variables
- *
- * Because some rules target main files while other target test files (or even
- * both), the wrapper relies on two linting configurations to decide which set
- * of rules should be considered during linting.
- *
- * Last but not least, the linter wrapper eventually turns ESLint problems,
- * also known as messages, into SonarQube issues.
- */
-export class LinterWrapper {
- /** The wrapper's internal ESLint linter instance */
- readonly linter: Linter;
-
- /** The wrapper's linting configuration */
- readonly config: { [key in FileType]: Linter.Config };
-
- /**
- * Constructs an ESLint linter wrapper
- *
- * Constructing a linter wrapper consists in building the rule database
- * the internal ESLint linter shall consider during linting. Furthermore,
- * it creates a linting configuration that configures which rules should
- * be used on linting based on the active quality profile and file type.
- *
- * The order of defining rules is important here because internal rules
- * and external ones might share the same name by accident, which would
- * unexpectedly overwrite the behaviour of the internal one in favor of
- * the external one. This is why some internal rules are named with the
- * prefix `sonar-`, e.g., `sonar-no-fallthrough`.
- *
- * @param options the wrapper's options
- */
- constructor(options: WrapperOptions = {}) {
- this.linter = new Linter();
- loadBundles(this.linter, options.ruleBundles ?? defaultRuleBundles);
- loadCustomRules(this.linter, options.customRules);
- this.config = this.createConfig(options);
- }
-
- /**
- * Lints an ESLint source code instance
- *
- * Linting a source code implies using ESLint linting functionality to find
- * problems in the code. It selects which linting configuration needs to be
- * considered during linting based on the file type.
- *
- * @param sourceCode the ESLint source code
- * @param filePath the path of the source file
- * @param fileType the type of the source file
- * @returns the linting result
- */
- lint(sourceCode: SourceCode, filePath: string, fileType: FileType = 'MAIN'): LintingResult {
- const fileTypeConfig = this.config[fileType];
- const config = { ...fileTypeConfig, settings: { ...fileTypeConfig.settings, fileType } };
- const options = { filename: filePath, allowInlineConfig: false };
- const messages = this.linter.verify(sourceCode, config, options);
- return transformMessages(messages, { sourceCode, rules: this.linter.getRules() });
- }
-
- /**
- * Creates the wrapper's linting configuration
- *
- * The wrapper's linting configuration actually includes two
- * ESLint configurations: one per file type.
- *
- * @returns the wrapper's linting configuration
- */
- private createConfig(options: WrapperOptions) {
- const mainRules: RuleConfig[] = [];
- const testRules: RuleConfig[] = [];
- for (const inputRule of options.inputRules ?? []) {
- if (inputRule.fileTypeTarget.includes('MAIN')) {
- mainRules.push(inputRule);
- }
- if (inputRule.fileTypeTarget.includes('TEST')) {
- testRules.push(inputRule);
- }
- }
- const linterRules = this.linter.getRules();
- const mainConfig = createLinterConfig(
- mainRules,
- linterRules,
- options.environments ?? [],
- options.globals ?? [],
- );
- const testConfig = createLinterConfig(
- testRules,
- linterRules,
- options.environments ?? [],
- options.globals ?? [],
- );
- return { ['MAIN']: mainConfig, ['TEST']: testConfig };
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/anchor-precedence.ts b/eslint-bridge/src/linting/eslint/rules/anchor-precedence.ts
deleted file mode 100644
index d920c14fb18..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/anchor-precedence.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5850/javascript
-
-import { Rule } from 'eslint';
-import { AST } from 'regexpp';
-import { createRegExpRule } from './helpers/regex';
-
-enum Position {
- BEGINNING,
- END,
-}
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- return {
- onPatternEnter: (pattern: AST.Pattern) => {
- const { alternatives } = pattern;
- if (
- alternatives.length > 1 &&
- (anchoredAt(alternatives, Position.BEGINNING) || anchoredAt(alternatives, Position.END)) &&
- notAnchoredElseWhere(alternatives)
- ) {
- context.reportRegExpNode({
- message:
- 'Group parts of the regex together to make the intended operator precedence explicit.',
- node: context.node,
- regexpNode: pattern,
- });
- }
- },
- };
-});
-
-function anchoredAt(alternatives: AST.Alternative[], position: Position): boolean {
- const itemIndex = position === Position.BEGINNING ? 0 : alternatives.length - 1;
- const firstOrLast = alternatives[itemIndex];
- return isAnchored(firstOrLast, position);
-}
-
-function notAnchoredElseWhere(alternatives: AST.Alternative[]): boolean {
- if (
- isAnchored(alternatives[0], Position.END) ||
- isAnchored(alternatives[alternatives.length - 1], Position.BEGINNING)
- ) {
- return false;
- }
- for (const alternative of alternatives.slice(1, alternatives.length - 1)) {
- if (isAnchored(alternative, Position.BEGINNING) || isAnchored(alternative, Position.END)) {
- return false;
- }
- }
- return true;
-}
-
-function isAnchored(alternative: AST.Alternative, position: Position): boolean {
- const { elements } = alternative;
- if (elements.length === 0) {
- return false;
- }
- const index = position === Position.BEGINNING ? 0 : elements.length - 1;
- const firstOrLast = elements[index];
- return isAnchor(firstOrLast);
-}
-
-function isAnchor(element: AST.Element) {
- return element.type === 'Assertion' && (element.kind === 'start' || element.kind === 'end');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/argument-type.ts b/eslint-bridge/src/linting/eslint/rules/argument-type.ts
deleted file mode 100644
index dcb8e81afae..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/argument-type.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3782/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getTypeFromTreeNode, isRequiredParserServices } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import ts, { SyntaxKind } from 'typescript';
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- const tc = services.program.getTypeChecker();
-
- function isBuiltInMethod(symbol: ts.Symbol) {
- const parent = symbol.valueDeclaration?.parent;
- if (!parent || parent.kind !== SyntaxKind.InterfaceDeclaration) {
- return false;
- }
- const parentSymbol = tc.getSymbolAtLocation((parent as ts.InterfaceDeclaration).name);
- if (!parentSymbol) {
- return false;
- }
- const fqn = tc.getFullyQualifiedName(parentSymbol);
- // some of the built-in objects are deliberately excluded, because they generate many FPs
- // and no relevant TP, e.g. RegExp, Function
- return ['String', 'Math', 'Array', 'Number', 'Date'].includes(fqn);
- }
-
- function isVarArg(param: ts.ParameterDeclaration) {
- return !!param.dotDotDotToken;
- }
-
- function isTypeParameter(type: ts.Type) {
- return type.getFlags() & ts.TypeFlags.TypeParameter;
- }
-
- function declarationMismatch(
- declaration: ts.SignatureDeclaration,
- callExpression: estree.CallExpression,
- ) {
- const parameters = declaration.parameters;
- for (let i = 0; i < Math.min(parameters.length, callExpression.arguments.length); i++) {
- const parameterType = parameters[i].type;
- if (!parameterType) {
- return null;
- }
- const declaredType = tc.getTypeFromTypeNode(parameterType);
- const actualType = getTypeFromTreeNode(callExpression.arguments[i], services);
- if (
- // @ts-ignore private API, see https://github.com/microsoft/TypeScript/issues/9879
- !tc.isTypeAssignableTo(actualType, declaredType) &&
- !isTypeParameter(declaredType) &&
- !ts.isFunctionTypeNode(parameterType) &&
- !isVarArg(parameters[i])
- ) {
- return { actualType, declaredType, node: callExpression.arguments[i] };
- }
- }
- return null;
- }
-
- function typeToString(type: ts.Type) {
- return tc.typeToString(tc.getBaseTypeOfLiteralType(type));
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const tsCallExpr = services.esTreeNodeToTSNodeMap.get(
- callExpression.callee as TSESTree.Node,
- );
- const symbol = tc.getSymbolAtLocation(tsCallExpr);
-
- if (symbol && symbol.declarations && isBuiltInMethod(symbol)) {
- let mismatch: {
- actualType: ts.Type;
- declaredType: ts.Type;
- node: estree.Node;
- } | null = null;
- for (const declaration of symbol.declarations) {
- mismatch = declarationMismatch(declaration as ts.SignatureDeclaration, callExpression);
- if (!mismatch) {
- return;
- }
- }
- if (mismatch) {
- context.report({
- node: mismatch.node,
- message: `Verify that argument is of correct type: expected '${typeToString(
- mismatch.declaredType,
- )}' instead of '${typeToString(mismatch.actualType)}'.`,
- });
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/arguments-order.ts b/eslint-bridge/src/linting/eslint/rules/arguments-order.ts
deleted file mode 100644
index 8d5448e0f97..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/arguments-order.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2234/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { EncodedMessage } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { isIdentifier } from 'eslint-plugin-sonarjs/lib/utils/nodes';
-import {
- FunctionNodeType,
- isRequiredParserServices,
- isFunctionNode,
- resolveFromFunctionReference,
- getSignatureFromCallee,
- getTypeAsString,
- resolveIdentifiers,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-interface FunctionSignature {
- params: Array;
- declaration?: FunctionNodeType;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- const canResolveType = isRequiredParserServices(services);
-
- function checkArguments(functionCall: estree.CallExpression) {
- const resolvedFunction = resolveFunctionDeclaration(functionCall);
- if (!resolvedFunction) {
- return;
- }
-
- const { params: functionParameters, declaration: functionDeclaration } = resolvedFunction;
- const argumentNames = functionCall.arguments.map(arg => {
- const argument = arg as TSESTree.Node;
- return isIdentifier(argument) ? argument.name : undefined;
- });
-
- for (let argumentIndex = 0; argumentIndex < argumentNames.length; argumentIndex++) {
- const argumentName = argumentNames[argumentIndex];
- if (argumentName) {
- const swappedArgumentName = getSwappedArgumentName(
- argumentNames,
- functionParameters,
- argumentName,
- argumentIndex,
- functionCall,
- );
- if (swappedArgumentName && !areComparedArguments([argumentName, swappedArgumentName])) {
- raiseIssue(argumentName, swappedArgumentName, functionDeclaration, functionCall);
- return;
- }
- }
- }
- }
-
- function areComparedArguments(argumentNames: string[]): boolean {
- function getName(node: estree.Node): string | undefined {
- switch (node.type) {
- case 'Identifier':
- return node.name;
- case 'CallExpression':
- return getName(node.callee);
- case 'MemberExpression':
- return getName(node.object);
- default:
- return undefined;
- }
- }
- function checkComparedArguments(lhs: estree.Node, rhs: estree.Node): boolean {
- return (
- [lhs, rhs].map(getName).filter(name => name && argumentNames.includes(name)).length ===
- argumentNames.length
- );
- }
- const maybeIfStmt = context
- .getAncestors()
- .reverse()
- .find(ancestor => ancestor.type === 'IfStatement');
- if (maybeIfStmt) {
- const { test } = maybeIfStmt as estree.IfStatement;
- switch (test.type) {
- case 'BinaryExpression':
- const binExpr = test;
- if (['==', '!=', '===', '!==', '<', '<=', '>', '>='].includes(binExpr.operator)) {
- const { left: lhs, right: rhs } = binExpr;
- return checkComparedArguments(lhs, rhs);
- }
- break;
- case 'CallExpression':
- const callExpr = test;
- if (callExpr.arguments.length === 1 && callExpr.callee.type === 'MemberExpression') {
- const [lhs, rhs] = [callExpr.callee.object, callExpr.arguments[0]];
- return checkComparedArguments(lhs, rhs);
- }
- break;
- }
- }
- return false;
- }
-
- function resolveFunctionDeclaration(node: estree.CallExpression): FunctionSignature | null {
- if (canResolveType) {
- return resolveFromTSSignature(node);
- }
-
- let functionDeclaration: FunctionNodeType | null = null;
-
- if (isFunctionNode(node.callee)) {
- functionDeclaration = node.callee;
- } else if (node.callee.type === 'Identifier') {
- functionDeclaration = resolveFromFunctionReference(context, node.callee);
- }
-
- if (!functionDeclaration) {
- return null;
- }
-
- return {
- params: extractFunctionParameters(functionDeclaration),
- declaration: functionDeclaration,
- };
- }
-
- function resolveFromTSSignature(node: estree.CallExpression) {
- const signature = getSignatureFromCallee(node, services);
- if (signature && signature.declaration) {
- return {
- params: signature.parameters.map(param => param.name),
- declaration: services.tsNodeToESTreeNodeMap.get(signature.declaration),
- };
- }
- return null;
- }
-
- function getSwappedArgumentName(
- argumentNames: Array,
- functionParameters: Array,
- argumentName: string,
- argumentIndex: number,
- node: estree.CallExpression,
- ) {
- const indexInFunctionDeclaration = functionParameters.findIndex(
- functionParameterName => functionParameterName === argumentName,
- );
- if (indexInFunctionDeclaration >= 0 && indexInFunctionDeclaration !== argumentIndex) {
- const potentiallySwappedArgument = argumentNames[indexInFunctionDeclaration];
- if (
- potentiallySwappedArgument &&
- potentiallySwappedArgument === functionParameters[argumentIndex] &&
- haveCompatibleTypes(
- node.arguments[argumentIndex],
- node.arguments[indexInFunctionDeclaration],
- )
- ) {
- return potentiallySwappedArgument;
- }
- }
- return null;
- }
-
- function haveCompatibleTypes(arg1: estree.Node, arg2: estree.Node) {
- if (canResolveType) {
- const type1 = normalizeType(getTypeAsString(arg1, services));
- const type2 = normalizeType(getTypeAsString(arg2, services));
- return type1 === type2;
- }
- return true;
- }
-
- function raiseIssue(
- arg1: string,
- arg2: string,
- functionDeclaration: FunctionNodeType | undefined,
- node: estree.CallExpression,
- ) {
- const primaryMessage = `Arguments '${arg1}' and '${arg2}' have the same names but not the same order as the function parameters.`;
- const encodedMessage: EncodedMessage = {
- message: primaryMessage,
- secondaryLocations: getSecondaryLocations(functionDeclaration),
- };
-
- context.report({
- message: JSON.stringify(encodedMessage),
- loc: getParametersClauseLocation(node.arguments),
- });
- }
-
- return {
- NewExpression: (node: estree.Node) => {
- checkArguments(node as estree.NewExpression);
- },
- CallExpression: (node: estree.Node) => {
- checkArguments(node as estree.CallExpression);
- },
- };
- },
-};
-
-function extractFunctionParameters(functionDeclaration: FunctionNodeType) {
- return functionDeclaration.params.map(param => {
- const identifiers = resolveIdentifiers(param as TSESTree.Node);
- if (identifiers.length === 1 && identifiers[0]) {
- return identifiers[0].name;
- }
- return undefined;
- });
-}
-
-function getSecondaryLocations(functionDeclaration: FunctionNodeType | undefined) {
- if (functionDeclaration && functionDeclaration.params && functionDeclaration.params.length > 0) {
- const { start, end } = getParametersClauseLocation(functionDeclaration.params);
- return [
- {
- message: 'Formal parameters',
- line: start.line,
- column: start.column,
- endLine: end.line,
- endColumn: end.column,
- },
- ];
- }
- return [];
-}
-
-function getParametersClauseLocation(parameters: Array) {
- const firstParam = parameters[0] as TSESTree.Node;
- const lastParam = parameters[parameters.length - 1] as TSESTree.Node;
- return { start: firstParam.loc.start, end: lastParam.loc.end };
-}
-
-function normalizeType(typeAsString: string) {
- switch (typeAsString) {
- case 'String':
- return 'string';
- case 'Boolean':
- return 'boolean';
- case 'Number':
- return 'number';
- default:
- return typeAsString;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/arguments-usage.ts b/eslint-bridge/src/linting/eslint/rules/arguments-usage.ts
deleted file mode 100644
index a85517f1466..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/arguments-usage.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3513/javascript
-
-import { Rule, Scope } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = "Use the rest syntax to declare this function's arguments.";
-const SECONDARY_MESSAGE = 'Replace this reference to "arguments".';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- // Ignore root scope containing global variables
- 'Program:exit': () =>
- context
- .getScope()
- .childScopes.forEach(child => checkArgumentsUsageInScopeRecursively(context, child)),
- };
- },
-};
-
-function checkArgumentsUsageInScopeRecursively(
- context: Rule.RuleContext,
- scope: Scope.Scope,
-): void {
- scope.variables
- .filter(variable => variable.name === 'arguments')
- .forEach(variable => checkArgumentsVariableWithoutDefinition(context, variable));
- scope.childScopes.forEach(child => checkArgumentsUsageInScopeRecursively(context, child));
-}
-
-function checkArgumentsVariableWithoutDefinition(
- context: Rule.RuleContext,
- variable: Scope.Variable,
-): void {
- // if variable is a parameter, variable.defs contains one ParameterDefinition with a type: 'Parameter'
- // if variable is a local variable, variable.defs contains one Definition with a type: 'Variable'
- // but if variable is the function arguments, variable.defs is just empty without other hint
- const isLocalVariableOrParameter = variable.defs.length > 0;
- const references = variable.references.filter(ref => !isFollowedByLengthProperty(ref));
- if (!isLocalVariableOrParameter && references.length > 0) {
- const firstReference = references[0];
- const secondaryLocations = references.slice(1).map(ref => ref.identifier) as TSESTree.Node[];
- context.report({
- node: firstReference.identifier,
- message: toEncodedMessage(
- MESSAGE,
- secondaryLocations,
- Array(secondaryLocations.length).fill(SECONDARY_MESSAGE),
- ),
- });
- }
-}
-
-function isFollowedByLengthProperty(reference: Scope.Reference): boolean {
- const parent = (reference.identifier as TSESTree.Node).parent;
- return (
- !!parent &&
- parent.type === 'MemberExpression' &&
- parent.property.type === 'Identifier' &&
- parent.property.name === 'length'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/array-callback-without-return.ts b/eslint-bridge/src/linting/eslint/rules/array-callback-without-return.ts
deleted file mode 100644
index 4c2f9aa5a45..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/array-callback-without-return.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3796/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import {
- isArray,
- RequiredParserServices,
- isRequiredParserServices,
- isMemberExpression,
- RuleContext,
-} from './helpers';
-
-const message = `Add a "return" statement to this callback.`;
-
-const methodsWithCallback = [
- 'every',
- 'filter',
- 'find',
- 'findIndex',
- 'map',
- 'reduce',
- 'reduceRight',
- 'some',
- 'sort',
-];
-
-function hasCallBackWithoutReturn(argument: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- const type = checker.getTypeAtLocation(
- services.esTreeNodeToTSNodeMap.get(argument as TSESTree.Node),
- );
- const signatures = type.getCallSignatures();
- return (
- signatures.length > 0 &&
- signatures.every(sig => checker.typeToString(sig.getReturnType()) === 'void')
- );
-}
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- return {
- 'CallExpression[callee.type="MemberExpression"]'(node: estree.Node) {
- const callExpression = node as estree.CallExpression;
- const args = callExpression.arguments;
- const memberExpression = callExpression.callee as estree.MemberExpression;
- const { property, object } = memberExpression;
- if (memberExpression.computed || property.type !== 'Identifier' || args.length === 0) {
- return;
- }
- if (
- methodsWithCallback.includes(property.name) &&
- isArray(object, services) &&
- hasCallBackWithoutReturn(args[0], services)
- ) {
- context.report({
- message,
- ...getNodeToReport(args[0], node, context),
- });
- } else if (
- isMemberExpression(callExpression.callee, 'Array', 'from') &&
- args.length > 1 &&
- hasCallBackWithoutReturn(args[1], services)
- ) {
- context.report({
- message,
- ...getNodeToReport(args[1], node, context),
- });
- }
- },
- };
- },
-};
-
-function getNodeToReport(node: estree.Node, parent: estree.Node, context: Rule.RuleContext) {
- if (
- node.type === 'FunctionDeclaration' ||
- node.type === 'FunctionExpression' ||
- node.type === 'ArrowFunctionExpression'
- ) {
- return {
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- parent as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- };
- }
- return {
- node,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/array-constructor.ts b/eslint-bridge/src/linting/eslint/rules/array-constructor.ts
deleted file mode 100644
index ed65aa46af9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/array-constructor.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1528/javascript
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- function checkNewExpression(node: estree.Node) {
- const newExpression = node as estree.NewExpression;
- if (newExpression.callee.type === 'Identifier' && newExpression.callee.name === 'Array') {
- let message = 'Use either a literal or "Array.from()" instead of the "Array" constructor.';
- if (
- newExpression.arguments.length === 1 &&
- newExpression.arguments[0].type === 'Literal' &&
- typeof newExpression.arguments[0].value === 'number'
- ) {
- message = 'Use "Array.from()" instead of the "Array" constructor.';
- }
- context.report({ node, message });
- }
- }
-
- return {
- NewExpression: checkNewExpression,
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/arrow-function-convention.ts b/eslint-bridge/src/linting/eslint/rules/arrow-function-convention.ts
deleted file mode 100644
index a212805be50..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/arrow-function-convention.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3524/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-const MESSAGE_ADD_PARAMETER = 'Add parentheses around the parameter of this arrow function.';
-const MESSAGE_REMOVE_PARAMETER = 'Remove parentheses around the parameter of this arrow function.';
-const MESSAGE_ADD_BODY = 'Add curly braces and "return" to this arrow function body.';
-const MESSAGE_REMOVE_BODY = 'Remove curly braces and "return" from this arrow function body.';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- type: 'object',
- properties: {
- requireParameterParentheses: {
- type: 'boolean',
- },
- requireBodyBraces: {
- type: 'boolean',
- },
- },
- additionalProperties: false,
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const options = context.options[0] || {};
- const requireParameterParentheses = !!options.requireParameterParentheses;
- const requireBodyBraces = !!options.requireBodyBraces;
- return {
- ArrowFunctionExpression(node: estree.Node) {
- const arrowFunction = node as estree.ArrowFunctionExpression;
- checkParameters(context, requireParameterParentheses, arrowFunction);
- checkBody(context, requireBodyBraces, arrowFunction);
- },
- };
- },
-};
-
-function checkParameters(
- context: Rule.RuleContext,
- requireParameterParentheses: boolean,
- arrowFunction: estree.ArrowFunctionExpression,
-) {
- if (arrowFunction.params.length !== 1) {
- return;
- }
- const parameter = arrowFunction.params[0];
- // Looking at the closing parenthesis after the parameter to avoid problems with cases like
- // `functionTakingCallbacks(x => {...})` where the opening parenthesis before `x` isn't part
- // of the function literal
- const tokenAfterParameter = context.getSourceCode().getTokenAfter(parameter);
- const hasParameterParentheses = tokenAfterParameter && tokenAfterParameter.value === ')';
-
- if (requireParameterParentheses && !hasParameterParentheses) {
- context.report({ node: parameter, message: MESSAGE_ADD_PARAMETER });
- } else if (
- !requireParameterParentheses &&
- !hasGeneric(context, arrowFunction) &&
- hasParameterParentheses
- ) {
- const arrowFunctionComments = context.getSourceCode().getCommentsInside(arrowFunction);
- const arrowFunctionBodyComments = context.getSourceCode().getCommentsInside(arrowFunction.body);
- // parameters comments inside parentheses are not available, so use the following subtraction:
- const hasArrowFunctionParamsComments =
- arrowFunctionComments.filter(comment => !arrowFunctionBodyComments.includes(comment)).length >
- 0;
- if (
- parameter.type === 'Identifier' &&
- !hasArrowFunctionParamsComments &&
- !(parameter as TSESTree.Identifier).typeAnnotation &&
- !(arrowFunction as TSESTree.ArrowFunctionExpression).returnType
- ) {
- context.report({ node: parameter, message: MESSAGE_REMOVE_PARAMETER });
- }
- }
-}
-
-function hasGeneric(context: Rule.RuleContext, arrowFunction: estree.ArrowFunctionExpression) {
- const offset = arrowFunction.async ? 1 : 0;
- const firstTokenIgnoreAsync = context.getSourceCode().getFirstToken(arrowFunction, offset);
- return firstTokenIgnoreAsync && firstTokenIgnoreAsync.value === '<';
-}
-
-function checkBody(
- context: Rule.RuleContext,
- requireBodyBraces: boolean,
- arrowFunction: estree.ArrowFunctionExpression,
-) {
- const hasBodyBraces = arrowFunction.body.type === 'BlockStatement';
- if (requireBodyBraces && !hasBodyBraces) {
- context.report({ node: arrowFunction.body, message: MESSAGE_ADD_BODY });
- } else if (!requireBodyBraces && hasBodyBraces) {
- const statements = (arrowFunction.body as estree.BlockStatement).body;
- if (statements.length === 1) {
- const statement = statements[0];
- if (isRemovableReturn(statement)) {
- context.report({ node: arrowFunction.body, message: MESSAGE_REMOVE_BODY });
- }
- }
- }
-}
-
-function isRemovableReturn(statement: estree.Statement) {
- if (statement.type === 'ReturnStatement') {
- const returnStatement = statement;
- const returnExpression = returnStatement.argument;
- if (returnExpression && returnExpression.type !== 'ObjectExpression') {
- const location = returnExpression.loc;
- return location && location.start.line === location.end.line;
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/assertions-in-tests.ts b/eslint-bridge/src/linting/eslint/rules/assertions-in-tests.ts
deleted file mode 100644
index 29990e80c79..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/assertions-in-tests.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2699/javascript
-import { Rule, SourceCode } from 'eslint';
-import * as estree from 'estree';
-import { childrenOf } from 'linting/eslint';
-import { Chai, isFunctionCall, Mocha, resolveFunction } from './helpers';
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- const testCases: Mocha.TestCase[] = [];
- return {
- 'CallExpression:exit': (node: estree.Node) => {
- const testCase = Mocha.extractTestCase(node);
- if (testCase !== null) {
- testCases.push(testCase);
- }
- },
- 'Program:exit': () => {
- if (Chai.isImported(context)) {
- testCases.forEach(testCase => checkAssertions(testCase, context));
- }
- },
- };
- },
-};
-
-function checkAssertions(testCase: Mocha.TestCase, context: Rule.RuleContext) {
- const { node, callback } = testCase;
- const visitor = new TestCaseAssertionVisitor(context);
- visitor.visit(callback.body);
- if (visitor.missingAssertions()) {
- context.report({ node, message: 'Add at least one assertion to this test case.' });
- }
-}
-
-class TestCaseAssertionVisitor {
- private readonly visitorKeys: SourceCode.VisitorKeys;
- private hasAssertions: boolean;
-
- constructor(private readonly context: Rule.RuleContext) {
- this.visitorKeys = context.getSourceCode().visitorKeys;
- this.hasAssertions = false;
- }
-
- visit(node: estree.Node) {
- if (this.hasAssertions) {
- return;
- }
- if (Chai.isAssertion(node)) {
- this.hasAssertions = true;
- return;
- }
- if (isFunctionCall(node)) {
- const functionDef = resolveFunction(this.context, node.callee);
- if (functionDef) {
- this.visit(functionDef.body);
- }
- }
- for (const child of childrenOf(node, this.visitorKeys)) {
- this.visit(child);
- }
- }
-
- missingAssertions() {
- return !this.hasAssertions;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-apigateway-public-api.ts b/eslint-bridge/src/linting/eslint/rules/aws-apigateway-public-api.ts
deleted file mode 100644
index 287582c316f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-apigateway-public-api.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6333/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate, normalizeFQN } from './helpers/aws/cdk';
-import { CallExpression, MemberExpression, NewExpression, Node } from 'estree';
-import { getResultOfExpression } from './helpers/result';
-import {
- getFullyQualifiedName,
- getUniqueWriteUsageOrNode,
- isMemberWithProperty,
- isMethodCall,
-} from './helpers';
-
-const REST_API_PROPERTIES_POSITION = 2;
-const RESOURCE_ADD_RESOURCE_PROPERTIES_POSITION = 1;
-const RESOURCE_ADD_METHOD_POSITION = 2;
-
-const REST_API_ROOT_PROPERTY = 'root';
-
-const DEFAULT_METHOD_OPTIONS = 'defaultMethodOptions';
-
-const AUTHORIZATION_TYPE = 'authorizationType';
-const NONE_AUTHORIZATION_TYPE = 'aws_cdk_lib.aws_apigateway.AuthorizationType.NONE';
-
-const ADD_METHOD = 'addMethod';
-const ADD_RESOURCE = 'addResource';
-const GET_RESOURCE = 'getResource';
-const PARENT_RESOURCE = 'parentResource';
-
-const messages = {
- publicApi: 'Make sure that creating public APIs is safe here.',
- omittedAuthorizationType:
- 'Omitting "authorizationType" disables authentication. Make sure it is safe here.',
-};
-
-const apigatewayChecker = AwsCdkCheckArguments(
- ['omittedAuthorizationType', 'publicApi'],
- true,
- AUTHORIZATION_TYPE,
- { primitives: { invalid: ['NONE'] } },
-);
-
-function consumersFactory(ctx: Rule.RuleContext) {
- const defaultAuthorizationTypes = new Map();
- const restApiDefaultCollector = defaultsCollector(REST_API_PROPERTIES_POSITION);
- const resourceDefaultCollector = defaultsCollector(RESOURCE_ADD_RESOURCE_PROPERTIES_POSITION);
-
- return {
- 'aws_cdk_lib.aws_apigateway.CfnMethod': apigatewayChecker,
- 'aws_cdk_lib.aws_apigatewayv2.CfnRoute': apigatewayChecker,
- 'aws_cdk_lib.aws_apigateway.RestApi': restApiDefaultCollector,
- 'aws_cdk_lib.aws_apigateway.RestApi.root': {
- methods: [ADD_METHOD, ADD_RESOURCE, GET_RESOURCE, PARENT_RESOURCE],
-
- callExpression: (expr: CallExpression, _ctx: Rule.RuleContext, fqn: string) => {
- if (fqn.endsWith(ADD_METHOD)) {
- checkResourceMethod(expr);
- } else if (fqn.endsWith(ADD_RESOURCE)) {
- resourceDefaultCollector(expr);
- }
- },
- },
- };
-
- function checkResourceMethod(expr: CallExpression) {
- const properties = getResultOfExpression(ctx, expr).getArgument(RESOURCE_ADD_METHOD_POSITION);
- const authorizationType = properties.getProperty(AUTHORIZATION_TYPE);
- if (authorizationType.isFound && isSensitiveAuthorizationType(authorizationType.node)) {
- ctx.report({
- messageId: 'publicApi',
- node: authorizationType.node,
- });
- } else if (authorizationType.isMissing) {
- const defaultAuthorizationType = getDefaultAuthorizationType(expr.callee);
- if (defaultAuthorizationType == null) {
- ctx.report({
- messageId: 'omittedAuthorizationType',
- node: authorizationType.node,
- });
- } else if (isSensitiveAuthorizationType(defaultAuthorizationType)) {
- ctx.report({
- messageId: 'publicApi',
- node: expr,
- });
- }
- }
- }
-
- function getDefaultAuthorizationType(node: Node): Node | undefined {
- const resource = getUniqueWriteUsageOrNode(ctx, node);
- if (defaultAuthorizationTypes.has(resource)) {
- return defaultAuthorizationTypes.get(resource);
- } else if (isDefaultFromCallee(resource)) {
- return getDefaultAuthorizationType(resource.callee);
- } else if (isDefaultFromObject(resource, ADD_METHOD, ADD_RESOURCE, REST_API_ROOT_PROPERTY)) {
- return getDefaultAuthorizationType(resource.object);
- } else {
- return undefined;
- }
- }
-
- function defaultsCollector(position: number) {
- return (expr: NewExpression | CallExpression) => {
- const properties = getResultOfExpression(ctx, expr).getArgument(position);
- const defaultMethodOptions = properties.getProperty(DEFAULT_METHOD_OPTIONS);
- const authorizationType = defaultMethodOptions.getProperty(AUTHORIZATION_TYPE);
- if (authorizationType.isFound) {
- defaultAuthorizationTypes.set(expr, authorizationType.node);
- }
- };
- }
-
- function isSensitiveAuthorizationType(node: Node) {
- const fqn = normalizeFQN(getFullyQualifiedName(ctx, node));
- return fqn === NONE_AUTHORIZATION_TYPE;
- }
-}
-
-function isDefaultFromObject(node: Node, ...names: string[]): node is MemberExpression {
- return node.type === 'MemberExpression' && names.some(name => isMemberWithProperty(node, name));
-}
-
-function isDefaultFromCallee(node: Node): node is CallExpression {
- return node.type === 'CallExpression' && isMethodCall(node);
-}
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(consumersFactory, { meta: { messages } });
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-ec2-rds-dms-public.ts b/eslint-bridge/src/linting/eslint/rules/aws-ec2-rds-dms-public.ts
deleted file mode 100644
index ffb96f6d772..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-ec2-rds-dms-public.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6329/javascript
-
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Node } from 'estree';
-import { getResultOfExpression, Result } from './helpers/result';
-import { getFullyQualifiedName, isCallingMethod } from './helpers';
-
-const PROPERTIES_POSITION = 2;
-
-const PRIVATE_SUBNETS = [
- 'aws_cdk_lib.aws_ec2.SubnetType.PRIVATE_ISOLATED',
- 'aws_cdk_lib.aws_ec2.SubnetType.PRIVATE_WITH_EGRESS',
- 'aws_cdk_lib.aws_ec2.SubnetType.PRIVATE_WITH_NAT',
-];
-
-const PUBLIC_SUBNET = 'aws_cdk_lib.aws_ec2.SubnetType.PUBLIC';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws-ec2.Instance': AwsCdkCheckArguments(
- 'publicNetwork',
- false,
- ['vpcSubnets', 'subnetType'],
- { fqns: { invalid: [PUBLIC_SUBNET] } },
- ),
- 'aws-cdk-lib.aws-ec2.CfnInstance': checkCfnInstance,
- 'aws-cdk-lib.aws_rds.DatabaseInstance': checkDatabaseInstance,
- 'aws-cdk-lib.aws_rds.CfnDBInstance': AwsCdkCheckArguments(
- 'publicNetwork',
- false,
- 'publiclyAccessible',
- { primitives: { invalid: [true] } },
- ),
- 'aws-cdk-lib.aws_dms.CfnReplicationInstance': AwsCdkCheckArguments(
- 'publicNetwork',
- true,
- 'publiclyAccessible',
- { primitives: { invalid: [true] } },
- ),
- },
- {
- meta: {
- messages: {
- publicNetwork: 'Make sure allowing public network access is safe here.',
- },
- },
- },
-);
-
-function checkCfnInstance(expr: estree.NewExpression, ctx: Rule.RuleContext) {
- const properties = getResultOfExpression(ctx, expr).getArgument(PROPERTIES_POSITION);
- const networkInterfaces = properties.getProperty('networkInterfaces');
- const sensitiveNetworkInterface = networkInterfaces.findInArray(result =>
- getSensitiveNetworkInterface(result, ctx),
- );
-
- if (sensitiveNetworkInterface.isFound) {
- ctx.report({
- messageId: 'publicNetwork',
- node: sensitiveNetworkInterface.node,
- });
- }
-}
-
-function getSensitiveNetworkInterface(networkInterface: Result, ctx: Rule.RuleContext) {
- const associatePublicIpAddress = networkInterface.getProperty('associatePublicIpAddress');
- if (associatePublicIpAddress.isTrue && !isFoundPrivateSubnet(networkInterface, ctx)) {
- return associatePublicIpAddress;
- } else {
- return null;
- }
-}
-
-function isFoundPrivateSubnet(networkInterface: Result, ctx: Rule.RuleContext) {
- const subnetId = networkInterface.getProperty('subnetId');
- const selectSubnetsCall = getSelectSubnetsCall(subnetId);
- const argument = selectSubnetsCall.getArgument(0);
- const subnetType = argument.getProperty('subnetType');
- return subnetType.isFound && isPrivateSubnet(subnetType.node, ctx);
-}
-
-function getSelectSubnetsCall(subnetId: Result) {
- let current = subnetId;
- while (current.ofType('MemberExpression')) {
- current = current.getMemberObject();
- }
- return current.filter(n => n.type === 'CallExpression' && isCallingMethod(n, 1, 'selectSubnets'));
-}
-
-function checkDatabaseInstance(expr: estree.NewExpression, ctx: Rule.RuleContext) {
- const properties = getResultOfExpression(ctx, expr).getArgument(PROPERTIES_POSITION);
- const vpcSubnets = properties.getProperty('vpcSubnets');
- const subnetType = vpcSubnets.getProperty('subnetType');
- const publiclyAccessible = properties.getProperty('publiclyAccessible');
-
- if (subnetType.isFound && isPrivateSubnet(subnetType.node, ctx)) {
- return;
- }
-
- if (publiclyAccessible.isTrue) {
- ctx.report({
- messageId: 'publicNetwork',
- node: publiclyAccessible.node,
- });
- } else if (
- !publiclyAccessible.isFound &&
- subnetType.isFound &&
- isPublicSubnet(subnetType.node, ctx)
- ) {
- ctx.report({
- messageId: 'publicNetwork',
- node: subnetType.node,
- });
- }
-}
-
-function isPrivateSubnet(node: Node, ctx: Rule.RuleContext) {
- return PRIVATE_SUBNETS.some(net => net === getFullyQualifiedName(ctx, node)?.replace(/-/g, '_'));
-}
-
-function isPublicSubnet(node: Node, ctx: Rule.RuleContext) {
- return PUBLIC_SUBNET === getFullyQualifiedName(ctx, node)?.replace(/-/g, '_');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-ec2-unencrypted-ebs-volume.ts b/eslint-bridge/src/linting/eslint/rules/aws-ec2-unencrypted-ebs-volume.ts
deleted file mode 100644
index 1ed050ca8f1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-ec2-unencrypted-ebs-volume.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6275/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws-ec2.Volume': AwsCdkCheckArguments(
- ['encryptionOmitted', 'encryptionDisabled'],
- true,
- 'encrypted',
- { primitives: { invalid: [false] } },
- ),
- },
- {
- meta: {
- messages: {
- encryptionDisabled: 'Make sure that using unencrypted volumes is safe here.',
- encryptionOmitted:
- 'Omitting "encrypted" disables volumes encryption. Make sure it is safe here.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-efs-unencrypted.ts b/eslint-bridge/src/linting/eslint/rules/aws-efs-unencrypted.ts
deleted file mode 100644
index b103a32f946..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-efs-unencrypted.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6332/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws_efs.FileSystem': AwsCdkCheckArguments(
- 'FSEncryptionDisabled',
- false,
- 'encrypted',
- { primitives: { invalid: [false] } },
- ),
- 'aws-cdk-lib.aws_efs.CfnFileSystem': AwsCdkCheckArguments(
- ['CFSEncryptionOmitted', 'CFSEncryptionDisabled'],
- true,
- 'encrypted',
- { primitives: { valid: [true] } },
- ),
- },
- {
- meta: {
- messages: {
- FSEncryptionDisabled: 'Make sure that using unencrypted file systems is safe here.',
- CFSEncryptionDisabled: 'Make sure that using unencrypted file systems is safe here.',
- CFSEncryptionOmitted:
- 'Omitting "encrypted" disables EFS encryption. Make sure it is safe here.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-iam-all-privileges.ts b/eslint-bridge/src/linting/eslint/rules/aws-iam-all-privileges.ts
deleted file mode 100644
index 52570668e02..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-iam-all-privileges.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6302/javascript
-
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-import { toEncodedMessage } from './helpers';
-import { getResultOfExpression, Result } from './helpers/result';
-import {
- AwsIamPolicyTemplate,
- getSensitiveEffect,
- isAnyLiteral,
- PolicyCheckerOptions,
-} from './helpers/aws/iam';
-
-const MESSAGES = {
- message: 'Make sure granting all privileges is safe here.',
- secondary: 'Related effect',
-};
-
-export const rule: Rule.RuleModule = AwsIamPolicyTemplate(allPrivilegesStatementChecker);
-
-function allPrivilegesStatementChecker(
- expr: Node,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const properties = getResultOfExpression(ctx, expr);
- const effect = getSensitiveEffect(properties, ctx, options);
- const action = getSensitiveAction(properties, options);
-
- if (effect.isMissing && action) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message),
- node: action,
- });
- } else if (effect.isFound && action) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message, [effect.node], [MESSAGES.secondary]),
- node: action,
- });
- }
-}
-
-function getSensitiveAction(properties: Result, options: PolicyCheckerOptions) {
- return getActionLiterals(properties, options).find(isAnyLiteral);
-}
-
-function getActionLiterals(properties: Result, options: PolicyCheckerOptions) {
- return properties.getProperty(options.actions.property).asStringLiterals();
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-iam-all-resources-accessible.ts b/eslint-bridge/src/linting/eslint/rules/aws-iam-all-resources-accessible.ts
deleted file mode 100644
index cd0e9e9f24f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-iam-all-resources-accessible.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6304/javascript
-
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-import { StringLiteral, toEncodedMessage } from './helpers';
-import { getResultOfExpression, Result } from './helpers/result';
-import {
- AwsIamPolicyTemplate,
- getSensitiveEffect,
- isAnyLiteral,
- PolicyCheckerOptions,
-} from './helpers/aws/iam';
-
-const MESSAGES = {
- message: 'Make sure granting access to all resources is safe here.',
- secondary: 'Related effect',
-};
-
-const KMS_PREFIX = 'kms:';
-
-export const rule: Rule.RuleModule = AwsIamPolicyTemplate(allResourcesAccessibleStatementCheck);
-
-function allResourcesAccessibleStatementCheck(
- expr: Node,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const properties = getResultOfExpression(ctx, expr);
- const effect = getSensitiveEffect(properties, ctx, options);
- const resource = getSensitiveResource(properties, options);
-
- if (isException(properties, options)) {
- return;
- }
-
- if (effect.isMissing && resource) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message),
- node: resource,
- });
- } else if (effect.isFound && resource) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message, [effect.node], [MESSAGES.secondary]),
- node: resource,
- });
- }
-}
-
-function isException(properties: Result, options: PolicyCheckerOptions) {
- return properties.getProperty(options.actions.property).everyStringLiteral(isKmsAction);
-}
-
-function isKmsAction(action: StringLiteral) {
- return action.value.startsWith(KMS_PREFIX);
-}
-
-function getSensitiveResource(properties: Result, options: PolicyCheckerOptions) {
- return getSensitiveResources(properties, options).find(isAnyLiteral);
-}
-
-function getSensitiveResources(properties: Result, options: PolicyCheckerOptions) {
- return properties.getProperty(options.resources.property).asStringLiterals();
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-iam-privilege-escalation.ts b/eslint-bridge/src/linting/eslint/rules/aws-iam-privilege-escalation.ts
deleted file mode 100644
index 48a173b6669..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-iam-privilege-escalation.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6317/javascript
-
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-import { StringLiteral, toEncodedMessage } from './helpers';
-import { getResultOfExpression, Result } from './helpers/result';
-import { AwsIamPolicyTemplate, getSensitiveEffect, PolicyCheckerOptions } from './helpers/aws/iam';
-
-const SENSITIVE_RESOURCE = /^(\*|arn:[^:]*:[^:]*:[^:]*:[^:]*:(role|user|group)\/\*)$/;
-
-const SENSITIVE_ACTIONS = [
- 'cloudformation:CreateStack',
- 'datapipeline:CreatePipeline',
- 'datapipeline:PutPipelineDefinition',
- 'ec2:RunInstances',
- 'glue:CreateDevEndpoint',
- 'glue:UpdateDevEndpoint',
- 'iam:AddUserToGroup',
- 'iam:AttachGroupPolicy',
- 'iam:AttachRolePolicy',
- 'iam:AttachUserPolicy',
- 'iam:CreateAccessKey',
- 'iam:CreateLoginProfile',
- 'iam:CreatePolicyVersion',
- 'iam:PassRole',
- 'iam:PutGroupPolicy',
- 'iam:PutRolePolicy',
- 'iam:PutUserPolicy',
- 'iam:SetDefaultPolicyVersion',
- 'iam:UpdateAssumeRolePolicy',
- 'iam:UpdateLoginProfile',
- 'lambda:AddPermission',
- 'lambda:CreateEventSourceMapping',
- 'lambda:CreateFunction',
- 'lambda:InvokeFunction',
- 'lambda:UpdateFunctionCode',
- 'sts:AssumeRole',
-];
-
-const MESSAGES = {
- message: (attackVectorName: string) =>
- `This policy is vulnerable to the "${attackVectorName}" privilege escalation vector. ` +
- 'Remove permissions or restrict the set of resources they apply to.',
- secondary: 'Permissions are granted on all resources.',
-};
-
-export const rule: Rule.RuleModule = AwsIamPolicyTemplate(privilegeEscalationStatementChecker);
-
-function privilegeEscalationStatementChecker(
- expr: Node,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const properties = getResultOfExpression(ctx, expr);
- const effect = getSensitiveEffect(properties, ctx, options);
- const resource = getSensitiveResource(properties, options);
- const action = getSensitiveAction(properties, options);
-
- if (
- !hasExceptionProperties(properties, options) &&
- (effect.isFound || effect.isMissing) &&
- resource &&
- action
- ) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message(action.value), [action], [MESSAGES.secondary]),
- node: resource,
- });
- }
-}
-
-function getSensitiveAction(properties: Result, options: PolicyCheckerOptions) {
- const actions = properties.getProperty(options.actions.property);
- return actions.asStringLiterals().find(isSensitiveAction);
-}
-
-function getSensitiveResource(properties: Result, options: PolicyCheckerOptions) {
- const resources = properties.getProperty(options.resources.property);
- return resources.asStringLiterals().find(isSensitiveResource);
-}
-
-function isSensitiveAction(action: StringLiteral) {
- return SENSITIVE_ACTIONS.includes(action.value);
-}
-
-function isSensitiveResource(resource: StringLiteral) {
- return SENSITIVE_RESOURCE.test(resource.value);
-}
-
-function hasExceptionProperties(properties: Result, options: PolicyCheckerOptions) {
- const exceptionProperties = [options.principals.property, options.conditions.property];
- return exceptionProperties.some(prop => !properties.getProperty(prop).isMissing);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-iam-public-access.ts b/eslint-bridge/src/linting/eslint/rules/aws-iam-public-access.ts
deleted file mode 100644
index ffa9b8de182..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-iam-public-access.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6270/javascript
-
-import { Rule } from 'eslint';
-import { NewExpression, Node } from 'estree';
-import {
- getFullyQualifiedName,
- isArrayExpression,
- isStringLiteral,
- StringLiteral,
- toEncodedMessage,
-} from './helpers';
-import { getResultOfExpression, Result } from './helpers/result';
-import {
- AwsIamPolicyTemplate,
- getSensitiveEffect,
- isAnyLiteral,
- PolicyCheckerOptions,
-} from './helpers/aws/iam';
-import { normalizeFQN } from './helpers/aws/cdk';
-
-const AWS_PRINCIPAL_PROPERTY = 'AWS';
-
-const ARN_PRINCIPAL = 'aws_cdk_lib.aws_iam.ArnPrincipal';
-
-const MESSAGES = {
- message: 'Make sure granting public access is safe here.',
- secondary: 'Related effect',
-};
-
-export const rule: Rule.RuleModule = AwsIamPolicyTemplate(publicAccessStatementChecker);
-
-function publicAccessStatementChecker(
- expr: Node,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const properties = getResultOfExpression(ctx, expr);
- const effect = getSensitiveEffect(properties, ctx, options);
- const principal = getSensitivePrincipal(properties, ctx, options);
-
- if (effect.isMissing && principal) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message),
- node: principal,
- });
- } else if (effect.isFound && principal) {
- ctx.report({
- message: toEncodedMessage(MESSAGES.message, [effect.node], [MESSAGES.secondary]),
- node: principal,
- });
- }
-}
-
-function getSensitivePrincipal(
- properties: Result,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const principal = properties.getProperty(options.principals.property);
- if (!principal.isFound) {
- return null;
- } else if (options.principals.type === 'FullyQualifiedName') {
- return getSensitivePrincipalFromFullyQualifiedName(ctx, principal.node, options);
- } else {
- return getSensitivePrincipalFromJson(ctx, principal.node);
- }
-}
-
-function getSensitivePrincipalFromFullyQualifiedName(
- ctx: Rule.RuleContext,
- node: Node,
- options: PolicyCheckerOptions,
-) {
- return getPrincipalNewExpressions(node).find(expr =>
- isSensitivePrincipalNewExpression(ctx, expr, options),
- );
-}
-
-function getPrincipalNewExpressions(node: Node) {
- const newExpressions: NewExpression[] = [];
-
- if (isArrayExpression(node)) {
- for (const element of node.elements) {
- if (element?.type === 'NewExpression') {
- newExpressions.push(element);
- }
- }
- }
-
- return newExpressions;
-}
-
-function getSensitivePrincipalFromJson(ctx: Rule.RuleContext, node: Node) {
- return getPrincipalLiterals(node, ctx).find(isAnyLiteral);
-}
-
-function isSensitivePrincipalNewExpression(
- ctx: Rule.RuleContext,
- newExpression: NewExpression,
- options: PolicyCheckerOptions,
-) {
- return (options.principals.anyValues ?? []).some(anyValue => {
- if (anyValue === ARN_PRINCIPAL) {
- const argument = newExpression.arguments[0];
- return isStringLiteral(argument) && isAnyLiteral(argument);
- } else {
- return anyValue === normalizeFQN(getFullyQualifiedName(ctx, newExpression.callee));
- }
- });
-}
-
-function getPrincipalLiterals(node: Node, ctx: Rule.RuleContext) {
- const literals: StringLiteral[] = [];
-
- if (isStringLiteral(node)) {
- literals.push(node);
- } else {
- const awsLiterals = getResultOfExpression(ctx, node)
- .getProperty(AWS_PRINCIPAL_PROPERTY)
- .asStringLiterals();
- literals.push(...awsLiterals);
- }
-
- return literals;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-opensearchservice-domain.ts b/eslint-bridge/src/linting/eslint/rules/aws-opensearchservice-domain.ts
deleted file mode 100644
index 86f643feb16..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-opensearchservice-domain.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6308/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkTemplate } from './helpers/aws/cdk';
-import { NewExpression, Node } from 'estree';
-import { getFullyQualifiedName, isBooleanLiteral, isStringLiteral } from './helpers';
-import { getResultOfExpression } from './helpers/result';
-
-const DOMAIN_PROPS_POSITION = 2;
-const ENABLED_PROPERTY = 'enabled';
-const OPEN_SEARCH = 'OpenSearch';
-const ELASTIC_SEARCH = 'Elasticsearch';
-
-interface DomainCheckerOptions {
- encryptionProperty: string;
- version: {
- valueType: 'ElasticsearchVersion' | 'EngineVersion' | 'string';
- property: string;
- defaultValue: typeof OPEN_SEARCH | typeof ELASTIC_SEARCH;
- };
-}
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws-opensearchservice.Domain': domainChecker({
- encryptionProperty: 'encryptionAtRest',
- version: {
- valueType: 'EngineVersion',
- property: 'version',
- defaultValue: OPEN_SEARCH,
- },
- }),
- 'aws-cdk-lib.aws-opensearchservice.CfnDomain': domainChecker({
- encryptionProperty: 'encryptionAtRestOptions',
- version: {
- valueType: 'string',
- property: 'engineVersion',
- defaultValue: OPEN_SEARCH,
- },
- }),
- 'aws-cdk-lib.aws-elasticsearch.Domain': domainChecker({
- encryptionProperty: 'encryptionAtRest',
- version: {
- valueType: 'ElasticsearchVersion',
- property: 'version',
- defaultValue: ELASTIC_SEARCH,
- },
- }),
- 'aws-cdk-lib.aws-elasticsearch.CfnDomain': domainChecker({
- encryptionProperty: 'encryptionAtRestOptions',
- version: {
- valueType: 'string',
- property: 'elasticsearchVersion',
- defaultValue: ELASTIC_SEARCH,
- },
- }),
- },
- {
- meta: {
- messages: {
- encryptionDisabled: 'Make sure that using unencrypted {{search}} domains is safe here.',
- encryptionOmitted:
- 'Omitting {{encryptionPropertyName}} causes encryption of data at rest to be ' +
- 'disabled for this {{search}} domain. Make sure it is safe here.',
- },
- },
- },
-);
-
-function domainChecker(options: DomainCheckerOptions) {
- return (expr: NewExpression, ctx: Rule.RuleContext) => {
- const call = getResultOfExpression(ctx, expr);
- const argument = call.getArgument(DOMAIN_PROPS_POSITION);
- const encryption = argument.getProperty(options.encryptionProperty);
- const version = argument.getProperty(options.version.property);
- const isEnabled = encryption.getProperty(ENABLED_PROPERTY);
- const search = version.map(getSearchEngine) ?? options.version.defaultValue;
-
- if (isEnabled.isMissing) {
- ctx.report({
- messageId: 'encryptionOmitted',
- node: isEnabled.node,
- data: {
- encryptionPropertyName: options.encryptionProperty,
- search,
- },
- });
- } else if (isEnabled.isFound && isUnencrypted(isEnabled.node)) {
- ctx.report({
- messageId: 'encryptionDisabled',
- node: isEnabled.node,
- data: {
- search,
- },
- });
- }
-
- function isUnencrypted(node: Node) {
- return isBooleanLiteral(node) && !node.value;
- }
-
- function getSearchEngine(node: Node) {
- let version: string | null;
-
- if (options.version.valueType === 'string' && isStringLiteral(node)) {
- version = `${options.version.property}.${node.value}`;
- } else {
- version = getFullyQualifiedName(ctx, node);
- }
-
- for (const name of version?.toLowerCase().split('.').reverse() ?? []) {
- if (name.includes('opensearch')) {
- return OPEN_SEARCH;
- } else if (name.includes('elasticsearch')) {
- return ELASTIC_SEARCH;
- }
- }
-
- return null;
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-rds-unencrypted-databases.ts b/eslint-bridge/src/linting/eslint/rules/aws-rds-unencrypted-databases.ts
deleted file mode 100644
index 03b2b36a9fc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-rds-unencrypted-databases.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6303/javascript
-
-import { Rule } from 'eslint';
-import {
- getFullyQualifiedName,
- getProperty,
- getUniqueWriteUsageOrNode,
- getValueOfExpression,
- isFalseLiteral,
- isUndefined,
-} from './helpers';
-
-import * as estree from 'estree';
-import { AwsCdkTemplate, normalizeFQN } from './helpers/aws/cdk';
-
-const CfnDBCluster = 'CfnDBCluster';
-const CfnDBInstance = 'CfnDBInstance';
-const DatabaseCluster = 'DatabaseCluster';
-const DatabaseClusterFromSnapshot = 'DatabaseClusterFromSnapshot';
-const DatabaseInstance = 'DatabaseInstance';
-const DatabaseInstanceReadReplica = 'DatabaseInstanceReadReplica';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws_rds.CfnDBCluster': checkStorage(CfnDBCluster),
- 'aws-cdk-lib.aws_rds.CfnDBInstance': checkStorage(CfnDBInstance),
- 'aws-cdk-lib.aws_rds.DatabaseCluster': checkStorage(DatabaseCluster),
- 'aws-cdk-lib.aws_rds.DatabaseClusterFromSnapshot': checkStorage(DatabaseClusterFromSnapshot),
- 'aws-cdk-lib.aws_rds.DatabaseInstance': checkStorage(DatabaseInstance),
- 'aws-cdk-lib.aws_rds.DatabaseInstanceReadReplica': checkStorage(DatabaseInstanceReadReplica),
- },
- {
- meta: {
- messages: {
- unsafe: 'Make sure that using unencrypted storage is safe here.',
- omitted: 'Omitting storageEncrypted disables RDS encryption. Make sure it is safe here.',
- },
- },
- },
-);
-
-const PROPS_ARGUMENT_POSITION = 2;
-
-function checkStorage(storage: string) {
- return (expr: estree.NewExpression, ctx: Rule.RuleContext) => {
- const argument = expr.arguments[PROPS_ARGUMENT_POSITION];
-
- const props = getValueOfExpression(ctx, argument, 'ObjectExpression');
- if (isUnresolved(argument, props)) {
- return;
- }
-
- if (props === undefined) {
- report(expr.callee, 'omitted');
- return;
- }
-
- if (isException(storage, props)) {
- return;
- }
-
- const propertyKey = getProperty(props, 'storageEncrypted', ctx);
- if (propertyKey === null) {
- report(props, 'omitted');
- }
-
- if (!propertyKey) {
- return;
- }
-
- const propertyValue = getUniqueWriteUsageOrNode(ctx, propertyKey.value);
- if (isFalseLiteral(propertyValue)) {
- report(propertyKey.value, 'unsafe');
- return;
- }
-
- function isUnresolved(node: estree.Node | undefined, value: estree.Node | undefined | null) {
- return node?.type === 'Identifier' && !isUndefined(node) && value === undefined;
- }
-
- function isException(storage: string, props: estree.ObjectExpression) {
- if (
- ![
- DatabaseCluster,
- DatabaseClusterFromSnapshot,
- DatabaseInstance,
- DatabaseInstanceReadReplica,
- ].includes(storage)
- ) {
- return false;
- }
-
- const exceptionKey = getProperty(props, 'storageEncryptionKey', ctx);
- if (exceptionKey == null) {
- return false;
- }
-
- const exceptionValue = getUniqueWriteUsageOrNode(ctx, exceptionKey.value);
- if (exceptionValue.type !== 'NewExpression') {
- return false;
- }
-
- const fqn = normalizeFQN(getFullyQualifiedName(ctx, exceptionValue.callee));
- return fqn === 'aws_cdk_lib.aws_kms.Key' || fqn === 'aws_cdk_lib.aws_kms.Alias';
- }
-
- function report(node: estree.Node, messageId: string) {
- ctx.report({
- messageId,
- node,
- });
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-restricted-ip-admin-access.ts b/eslint-bridge/src/linting/eslint/rules/aws-restricted-ip-admin-access.ts
deleted file mode 100644
index 0b5bdf8b964..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-restricted-ip-admin-access.ts
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6321/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- AwsCdkCheckArguments,
- AwsCdkConsumer,
- AwsCdkTemplate,
- FullyQualifiedName,
- getLiteralValue,
- normalizeFQN,
-} from './helpers/aws/cdk';
-import {
- getFullyQualifiedName,
- getProperty,
- getUniqueWriteUsageOrNode,
- getValueOfExpression,
- isUndefined,
- isUnresolved,
- reduceToIdentifier,
-} from './helpers';
-
-const TYPES_WITH_CONNECTIONS = [
- 'aws_cdk_lib.aws_docdb.DatabaseCluster.connections',
- 'aws_cdk_lib.aws_lambdaPythonAlpha.PythonFunction.connections',
- 'aws_cdk_lib.aws_batchAlpha.ComputeEnvironment.connections',
- 'aws_cdk_lib.aws_efs.FileSystem.connections',
- 'aws_cdk_lib.aws_lambdaGoAlpha.GoFunction.connections',
- 'aws_cdk_lib.aws_ecs.ExternalService.connections',
- 'aws_cdk_lib.aws_ecs.FargateService.connections',
- 'aws_cdk_lib.aws_ecs.Cluster.connections',
- 'aws_cdk_lib.aws_ecs.Ec2Service.connections',
- 'aws_cdk_lib.aws_elasticsearch.Domain.connections',
- 'aws_cdk_lib.aws_neptuneAlpha.DatabaseCluster.connections',
- 'aws_cdk_lib.aws_eks.FargateCluster.connections',
- 'aws_cdk_lib.aws_eks.Cluster.connections',
- 'aws_cdk_lib.aws_codebuild.PipelineProject.connections',
- 'aws_cdk_lib.aws_codebuild.Project.connections',
- 'aws_cdk_lib.aws_rds.DatabaseInstance.connections',
- 'aws_cdk_lib.aws_rds.DatabaseInstanceReadReplica.connections',
- 'aws_cdk_lib.aws_rds.DatabaseCluster.connections',
- 'aws_cdk_lib.aws_rds.ServerlessClusterFromSnapshot.connections',
- 'aws_cdk_lib.aws_rds.DatabaseProxy.connections',
- 'aws_cdk_lib.aws_rds.DatabaseInstanceFromSnapshot.connections',
- 'aws_cdk_lib.aws_rds.ServerlessCluster.connections',
- 'aws_cdk_lib.aws_rds.DatabaseClusterFromSnapshot.connections',
- 'aws_cdk_lib.aws_lambdaNodejs.NodejsFunction.connections',
- 'aws_cdk_lib.aws_fsx.LustreFileSystem.connections',
- 'aws_cdk_lib.aws_ec2.BastionHostLinux.connections',
- 'aws_cdk_lib.aws_ec2.ClientVpnEndpoint.connections',
- 'aws_cdk_lib.aws_ec2.Instance.connections',
- 'aws_cdk_lib.aws_ec2.LaunchTemplate.connections',
- 'aws_cdk_lib.aws_ec2.SecurityGroup.connections',
- 'aws_cdk_lib.aws_kinesisfirehoseAlpha.DeliveryStream.connections',
- 'aws_cdk_lib.aws_stepfunctionsTasks.SageMakerCreateTrainingJob.connections',
- 'aws_cdk_lib.aws_stepfunctionsTasks.SageMakerCreateModel.connections',
- 'aws_cdk_lib.aws_stepfunctionsTasks.EcsRunTask.connections',
- 'aws_cdk_lib.aws_redshiftAlpha.Cluster.connections',
- 'aws_cdk_lib.aws_opensearchservice.Domain.connections',
- 'aws_cdk_lib.aws_secretsmanager.HostedRotation.connections',
- 'aws_cdk_lib.aws_mskAlpha.Cluster.connections',
- 'aws_cdk_lib.triggers.TriggerFunction.connections',
- 'aws_cdk_lib.aws_autoscaling.AutoScalingGroup.connections',
- 'aws_cdk_lib.aws_syntheticsAlpha.Canary.connections',
- 'aws_cdk_lib.aws_cloudfront.experimental.EdgeFunction.connections',
- 'aws_cdk_lib.aws_lambda.Function.connections',
- 'aws_cdk_lib.aws_lambda.DockerImageFunction.connections',
- 'aws_cdk_lib.aws_lambda.SingletonFunction.connections',
- 'aws_cdk_lib.aws_lambda.Alias.connections',
- 'aws_cdk_lib.aws_lambda.Version.connections',
- 'aws_cdk_lib.aws_ec2.Connections',
-];
-
-const badPorts: number[] = [22, 3389];
-const badIpsV4: string[] = ['0.0.0.0/0'];
-const badIpsV6: string[] = ['::/0'];
-const badFQNProtocols: string[] = [
- 'aws_cdk_lib.aws_ec2.Protocol.ALL',
- 'aws_cdk_lib.aws_ec2.Protocol.TCP',
-];
-const badProtocols: string[] = ['6', 'tcp', 'TCP'];
-
-const templateCallback: { [key: FullyQualifiedName]: AwsCdkConsumer } = {};
-for (const type of TYPES_WITH_CONNECTIONS) {
- templateCallback[`${type}.allowFrom`] = { callExpression: checkAllowFrom };
- templateCallback[`${type}.allowFromAnyIpv4`] = { callExpression: checkAllowFromAnyIpv4 };
-}
-
-templateCallback['aws_cdk_lib.aws_ec2.Connections.allowDefaultPortFrom'] = {
- callExpression: (expr: estree.CallExpression, ctx: Rule.RuleContext) => {
- if (isBadEc2Peer(ctx, expr.arguments[0])) {
- checkConstructorDefaultPort(ctx, expr);
- }
- },
-};
-templateCallback['aws_cdk_lib.aws_ec2.Connections.allowDefaultPortFromAnyIpv4'] = {
- callExpression: (expr: estree.CallExpression, ctx: Rule.RuleContext) => {
- checkConstructorDefaultPort(ctx, expr);
- },
-};
-templateCallback['aws_cdk_lib.aws_ec2.SecurityGroup.addIngressRule'] = {
- callExpression: checkAllowFrom,
-};
-
-templateCallback['aws_cdk_lib.aws_ec2.CfnSecurityGroup'] = (
- expr: estree.NewExpression,
- ctx: Rule.RuleContext,
-) => {
- const params = expr.arguments[2];
- const objExpr = getValueOfExpression(ctx, params, 'ObjectExpression', true);
- if (!objExpr) {
- return;
- }
-
- const ingressProp = getProperty(objExpr, 'securityGroupIngress', ctx);
-
- if (!ingressProp) {
- return;
- }
-
- const arrExpr = getValueOfExpression(ctx, ingressProp.value, 'ArrayExpression', true);
-
- if (arrExpr) {
- for (const ingressGroup of arrExpr.elements) {
- if (ingressGroup) {
- checkIngressObject(ctx, ingressGroup);
- }
- }
- }
-};
-
-templateCallback['aws_cdk_lib.aws_ec2.CfnSecurityGroupIngress'] = (
- expr: estree.NewExpression,
- ctx: Rule.RuleContext,
-) => {
- checkIngressObject(ctx, expr.arguments[2]);
-};
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(templateCallback, {
- meta: {
- messages: {
- allowFromAnyIpv4:
- 'Change this method for "allowFrom" and set "other" to a subset of trusted IP addresses.',
- allowFrom: 'Change this IP range to a subset of trusted IP addresses.',
- },
- },
-});
-
-const invalidDefaultPortChecker = AwsCdkCheckArguments(
- 'allowFrom',
- false,
- 'defaultPort',
- { customChecker: isBadEc2Port },
- true,
- 0,
-);
-
-function checkConstructorDefaultPort(ctx: Rule.RuleContext, node: estree.CallExpression) {
- const newExpr = getValueOfExpression(ctx, reduceToIdentifier(node.callee), 'NewExpression', true);
- if (newExpr && invalidDefaultPortChecker(newExpr, ctx)) {
- ctx.report({ messageId: 'allowFromAnyIpv4', node: node.callee });
- }
-}
-
-function checkAllowFrom(expr: estree.CallExpression, ctx: Rule.RuleContext) {
- const badPeer = isBadEc2Peer(ctx, expr.arguments[0]);
- const badPort = isBadEc2Port(ctx, expr.arguments[1]);
-
- if (badPort && badPeer) {
- ctx.report({ messageId: 'allowFrom', node: expr.arguments[0] });
- }
-}
-
-function checkAllowFromAnyIpv4(expr: estree.CallExpression, ctx: Rule.RuleContext) {
- const badPort = isBadEc2Port(ctx, expr.arguments[0]);
-
- if (badPort) {
- ctx.report({ messageId: 'allowFromAnyIpv4', node: expr.callee });
- }
-}
-
-function checkIngressObject(ctx: Rule.RuleContext, node: estree.Node) {
- const objExpr = getValueOfExpression(ctx, node, 'ObjectExpression', true);
- if (!objExpr) {
- return;
- }
-
- const ipPropertyV4 = getPropertyValue(ctx, objExpr, 'cidrIp');
- const ipPropertyV6 = getPropertyValue(ctx, objExpr, 'cidrIpv6');
-
- const ipProtocol = getPropertyValue(ctx, objExpr, 'ipProtocol')?.value as string;
- const cidrIpV4 = ipPropertyV4?.value as string;
- const cidrIpV6 = ipPropertyV6?.value as string;
- const fromPort = Number.parseInt(getPropertyValue(ctx, objExpr, 'fromPort')?.value as string);
- const toPort = Number.parseInt(getPropertyValue(ctx, objExpr, 'toPort')?.value as string);
-
- if (
- disallowedIpV4(cidrIpV4) &&
- (ipProtocol === '-1' || (disallowedProtocol(ipProtocol) && disallowedPort(fromPort, toPort)))
- ) {
- ctx.report({ messageId: 'allowFrom', node: ipPropertyV4! });
- }
-
- if (
- disallowedIpV6(cidrIpV6) &&
- (ipProtocol === '-1' || (disallowedProtocol(ipProtocol) && disallowedPort(fromPort, toPort)))
- ) {
- ctx.report({ messageId: 'allowFrom', node: ipPropertyV6! });
- }
-}
-
-function disallowedPortObject(ctx: Rule.RuleContext, node: estree.Node) {
- const objExpr = getValueOfExpression(ctx, node, 'ObjectExpression', true);
- if (!objExpr) {
- return false;
- }
- const protocol = getProperty(objExpr, 'protocol', ctx);
-
- if (!protocol) {
- return false;
- }
-
- const protocolValue = getUniqueWriteUsageOrNode(ctx, protocol.value, true);
-
- if (isUnresolved(protocolValue, ctx) || isUndefined(protocolValue)) {
- return false;
- }
- const protocolFQN = normalizeFQN(getFullyQualifiedName(ctx, protocolValue));
- if (protocolFQN && badFQNProtocols.includes(protocolFQN)) {
- const fromPort = Number.parseInt(getPropertyValue(ctx, objExpr, 'fromPort')?.value as string);
- const toPort = Number.parseInt(getPropertyValue(ctx, objExpr, 'toPort')?.value as string);
- return disallowedPort(fromPort, toPort);
- }
- return false;
-}
-
-function isBadEc2Peer(ctx: Rule.RuleContext, node: estree.Node): boolean {
- const fqn = normalizeFQN(getFullyQualifiedName(ctx, node));
- if (fqn === 'aws_cdk_lib.aws_ec2.Peer.anyIpv4' || fqn === 'aws_cdk_lib.aws_ec2.Peer.anyIpv6') {
- return true;
- }
- if (fqn === 'aws_cdk_lib.aws_ec2.Peer.ipv4') {
- return disallowedIpV4(getArgumentValue(ctx, node)?.value as string);
- }
- if (fqn === 'aws_cdk_lib.aws_ec2.Peer.ipv6') {
- return disallowedIpV6(getArgumentValue(ctx, node)?.value as string);
- }
- return false;
-}
-
-function isBadEc2Port(ctx: Rule.RuleContext, node: estree.Node): boolean {
- const fqn = normalizeFQN(getFullyQualifiedName(ctx, node));
- if (fqn === 'aws_cdk_lib.aws_ec2.Port.allTcp' || fqn === 'aws_cdk_lib.aws_ec2.Port.allTraffic') {
- return true;
- }
- if (fqn === 'aws_cdk_lib.aws_ec2.Port.tcp') {
- return disallowedPort(getArgumentValue(ctx, node)?.value as number);
- }
- if (fqn === 'aws_cdk_lib.aws_ec2.Port.tcpRange') {
- const startRange = getArgumentValue(ctx, node)?.value as number;
- const endRange = getArgumentValue(ctx, node, 1)?.value as number;
- return disallowedPort(startRange, endRange);
- }
- if (fqn === 'aws_cdk_lib.aws_ec2.Port') {
- const portParams = getArgument(ctx, node);
- if (portParams) {
- return disallowedPortObject(ctx, portParams);
- }
- }
- return false;
-}
-
-function getArgument(
- ctx: Rule.RuleContext,
- node: estree.Node,
- position = 0,
-): estree.Node | undefined {
- if (!node || isUndefined(node) || isUnresolved(node, ctx)) {
- return undefined;
- }
-
- const callExpr = getUniqueWriteUsageOrNode(ctx, node, true);
-
- if (
- isUnresolved(callExpr, ctx) ||
- isUndefined(callExpr) ||
- (callExpr.type !== 'CallExpression' && callExpr.type !== 'NewExpression')
- ) {
- return undefined;
- }
-
- const argument = callExpr.arguments[position];
-
- const argumentValue = getUniqueWriteUsageOrNode(ctx, argument, true);
-
- if (isUnresolved(argumentValue, ctx) || isUndefined(argumentValue)) {
- return undefined;
- }
-
- return argumentValue;
-}
-
-function getArgumentValue(
- ctx: Rule.RuleContext,
- node: estree.Node,
- position = 0,
-): estree.Literal | undefined {
- const argument = getArgument(ctx, node, position);
- return argument ? getLiteralValue(ctx, argument) : undefined;
-}
-
-export function getPropertyValue(
- ctx: Rule.RuleContext,
- node: estree.ObjectExpression,
- propertyName: string,
-): estree.Literal | undefined {
- const property = getProperty(node, propertyName, ctx);
-
- if (!property) {
- return undefined;
- }
-
- const propertyValue = getUniqueWriteUsageOrNode(ctx, property.value, true);
-
- if (isUnresolved(propertyValue, ctx) || isUndefined(propertyValue)) {
- return undefined;
- }
-
- return getLiteralValue(ctx, propertyValue);
-}
-
-function disallowedPort(startRange?: number, endRange?: number): boolean {
- if (startRange != null && endRange != null) {
- return badPorts.some(port => port >= startRange && port <= endRange);
- }
- if (startRange != null && endRange == null) {
- return badPorts.some(port => port === startRange);
- }
- return false;
-}
-
-function disallowedIpV4(ip?: string): boolean {
- return ip ? badIpsV4.includes(ip) : false;
-}
-
-function disallowedIpV6(ip?: string): boolean {
- return ip ? badIpsV6.includes(ip) : false;
-}
-
-function disallowedProtocol(protocol?: string): boolean {
- return protocol ? badProtocols.includes(protocol) : false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-granted-access.ts b/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-granted-access.ts
deleted file mode 100644
index 5f5a5a53ae3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-granted-access.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6265/javascript
-
-import { Rule } from 'eslint';
-import estree from 'estree';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { mergeRules } from './decorators/helpers';
-import {
- getFullyQualifiedName,
- getUniqueWriteUsageOrNode,
- getValueOfExpression,
- isIdentifier,
- isMethodCall,
- toEncodedMessage,
-} from './helpers';
-import { normalizeFQN } from './helpers/aws/cdk';
-import {
- S3BucketTemplate,
- isS3BucketDeploymentConstructor,
- findPropagatedSetting,
- isS3BucketConstructor,
- getProperty,
-} from './helpers/aws/s3';
-
-const messages = {
- accessLevel: (param: string) => `Make sure granting ${param} access is safe here.`,
- unrestricted: 'Make sure allowing unrestricted access to objects from this bucket is safe here.',
-};
-
-const ACCESS_CONTROL_KEY = 'accessControl';
-const INVALID_ACCESS_CONTROL_VALUES = ['PUBLIC_READ', 'PUBLIC_READ_WRITE', 'AUTHENTICATED_READ'];
-
-const PUBLIC_READ_ACCESS_KEY = 'publicReadAccess';
-const INVALID_PUBLIC_READ_ACCESS_VALUE = true;
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return mergeRules(
- s3BucketConstructorRule.create(context),
- s3BucketDeploymentConstructorRule.create(context),
- handleGrantPublicAccess.create(context),
- );
- },
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-};
-
-const s3BucketConstructorRule: Rule.RuleModule = S3BucketTemplate((bucketConstructor, context) => {
- for (const value of INVALID_ACCESS_CONTROL_VALUES) {
- checkConstantParam(context, bucketConstructor, ACCESS_CONTROL_KEY, [
- 'BucketAccessControl',
- value,
- ]);
- }
- checkBooleanParam(
- context,
- bucketConstructor,
- PUBLIC_READ_ACCESS_KEY,
- INVALID_PUBLIC_READ_ACCESS_VALUE,
- );
-});
-
-const s3BucketDeploymentConstructorRule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- NewExpression: (node: estree.NewExpression) => {
- if (isS3BucketDeploymentConstructor(context, node)) {
- for (const value of INVALID_ACCESS_CONTROL_VALUES) {
- checkConstantParam(context, node, ACCESS_CONTROL_KEY, ['BucketAccessControl', value]);
- }
- }
- },
- };
- },
-};
-
-function checkBooleanParam(
- context: Rule.RuleContext,
- bucketConstructor: estree.NewExpression,
- propName: string,
- propValue: boolean,
-) {
- const property = getProperty(context, bucketConstructor, propName);
- if (property == null) {
- return;
- }
- const propertyLiteralValue = getValueOfExpression(context, property.value, 'Literal');
- if (propertyLiteralValue?.value === propValue) {
- const secondary = findPropagatedSetting(property, propertyLiteralValue);
- context.report({
- message: toEncodedMessage(messages.unrestricted, secondary.locations, secondary.messages),
- node: property,
- });
- }
-}
-
-function checkConstantParam(
- context: Rule.RuleContext,
- bucketConstructor: estree.NewExpression,
- propName: string,
- paramQualifiers: string[],
-) {
- const property = getProperty(context, bucketConstructor, propName);
- if (property == null) {
- return;
- }
- const propertyLiteralValue = getValueOfExpression(context, property.value, 'MemberExpression');
- if (
- propertyLiteralValue !== undefined &&
- normalizeFQN(getFullyQualifiedName(context, propertyLiteralValue)) ===
- `aws_cdk_lib.aws_s3.${paramQualifiers.join('.')}`
- ) {
- const secondary = findPropagatedSetting(property, propertyLiteralValue);
- context.report({
- message: toEncodedMessage(
- messages.accessLevel(paramQualifiers[paramQualifiers.length - 1]),
- secondary.locations,
- secondary.messages,
- ),
- node: property,
- });
- }
-}
-
-const handleGrantPublicAccess: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.CallExpression) => {
- if (!isMethodCall(node)) {
- return;
- }
- const { object, property } = node.callee;
- const isGrantPublicAccessMethodCall = isIdentifier(property, 'grantPublicAccess');
- if (!isGrantPublicAccessMethodCall) {
- return;
- }
- const variableAssignment = getUniqueWriteUsageOrNode(context, object);
- const isS3bucketInstance =
- variableAssignment.type === 'NewExpression' &&
- isS3BucketConstructor(context, variableAssignment);
- if (!isS3bucketInstance) {
- return;
- }
- context.report({
- message: toEncodedMessage(messages.unrestricted),
- node: property,
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-insecure-http.ts b/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-insecure-http.ts
deleted file mode 100644
index 8fd672677d8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-insecure-http.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6249/javascript
-
-import { Rule } from 'eslint';
-import { getValueOfExpression } from './helpers';
-import { getProperty, S3BucketTemplate } from './helpers/aws/s3';
-
-const ENFORCE_SSL_KEY = 'enforceSSL';
-
-const messages = {
- authorized: 'Make sure authorizing HTTP requests is safe here.',
- omitted: "Omitting 'enforceSSL' authorizes HTTP requests. Make sure it is safe here.",
-};
-
-export const rule: Rule.RuleModule = S3BucketTemplate((bucket, context) => {
- const enforceSSLProperty = getProperty(context, bucket, ENFORCE_SSL_KEY);
- if (enforceSSLProperty == null) {
- context.report({
- message: messages['omitted'],
- node: bucket.callee,
- });
- return;
- }
-
- const enforceSSLValue = getValueOfExpression(context, enforceSSLProperty.value, 'Literal');
- if (enforceSSLValue?.value === false) {
- context.report({
- message: messages['authorized'],
- node: enforceSSLProperty,
- });
- }
-});
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-public-access.ts b/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-public-access.ts
deleted file mode 100644
index 48b4c58d792..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-public-access.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6281/javascript
-
-import { Rule } from 'eslint';
-import { NewExpression, ObjectExpression, Property } from 'estree';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import {
- getFullyQualifiedName,
- getValueOfExpression,
- isIdentifier,
- isProperty,
- toEncodedMessage,
-} from './helpers';
-import { normalizeFQN } from './helpers/aws/cdk';
-import { findPropagatedSetting, getProperty, S3BucketTemplate } from './helpers/aws/s3';
-
-const BLOCK_PUBLIC_ACCESS_KEY = 'blockPublicAccess';
-const BLOCK_PUBLIC_ACCESS_PROPERTY_KEYS = [
- 'blockPublicAcls',
- 'blockPublicPolicy',
- 'ignorePublicAcls',
- 'restrictPublicBuckets',
-];
-
-const messages = {
- omitted:
- 'No Public Access Block configuration prevents public ACL/policies ' +
- 'to be set on this S3 bucket. Make sure it is safe here.',
- public: 'Make sure allowing public ACL/policies to be set is safe here.',
-};
-
-export const rule: Rule.RuleModule = S3BucketTemplate(
- (bucket, context) => {
- const blockPublicAccess = getProperty(context, bucket, BLOCK_PUBLIC_ACCESS_KEY);
- if (blockPublicAccess == null) {
- context.report({
- message: toEncodedMessage(messages['omitted']),
- node: bucket.callee,
- });
- } else {
- checkBlockPublicAccessValue(blockPublicAccess);
- checkBlockPublicAccessConstructor(blockPublicAccess);
- }
-
- /** Checks `blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS` sensitive pattern */
- function checkBlockPublicAccessValue(blockPublicAccess: Property) {
- const blockPublicAccessMember = getValueOfExpression(
- context,
- blockPublicAccess.value,
- 'MemberExpression',
- );
- if (
- blockPublicAccessMember !== undefined &&
- normalizeFQN(getFullyQualifiedName(context, blockPublicAccessMember)) ===
- 'aws_cdk_lib.aws_s3.BlockPublicAccess.BLOCK_ACLS'
- ) {
- const propagated = findPropagatedSetting(blockPublicAccess, blockPublicAccessMember);
- context.report({
- message: toEncodedMessage(messages['public'], propagated.locations, propagated.messages),
- node: blockPublicAccess,
- });
- }
- }
-
- /** Checks `blockPublicAccess: new s3.BlockPublicAccess({...})` sensitive pattern */
- function checkBlockPublicAccessConstructor(blockPublicAccess: Property) {
- const blockPublicAccessNew = getValueOfExpression(
- context,
- blockPublicAccess.value,
- 'NewExpression',
- );
- if (
- blockPublicAccessNew !== undefined &&
- isS3BlockPublicAccessConstructor(blockPublicAccessNew)
- ) {
- const blockPublicAccessConfig = getValueOfExpression(
- context,
- blockPublicAccessNew.arguments[0],
- 'ObjectExpression',
- );
- if (blockPublicAccessConfig === undefined) {
- context.report({
- message: toEncodedMessage(messages['omitted']),
- node: blockPublicAccessNew,
- });
- } else {
- BLOCK_PUBLIC_ACCESS_PROPERTY_KEYS.forEach(key =>
- checkBlockPublicAccessConstructorProperty(blockPublicAccessConfig, key),
- );
- }
- }
-
- function checkBlockPublicAccessConstructorProperty(
- blockPublicAccessConfig: ObjectExpression,
- key: string,
- ) {
- const blockPublicAccessProperty = blockPublicAccessConfig.properties.find(
- property => isProperty(property) && isIdentifier(property.key, key),
- ) as Property | undefined;
- if (blockPublicAccessProperty !== undefined) {
- const blockPublicAccessValue = getValueOfExpression(
- context,
- blockPublicAccessProperty.value,
- 'Literal',
- );
- if (blockPublicAccessValue?.value === false) {
- const propagated = findPropagatedSetting(
- blockPublicAccessProperty,
- blockPublicAccessValue,
- );
- context.report({
- message: toEncodedMessage(
- messages['public'],
- propagated.locations,
- propagated.messages,
- ),
- node: blockPublicAccessProperty,
- });
- }
- }
- }
-
- function isS3BlockPublicAccessConstructor(expr: NewExpression) {
- return (
- expr.callee.type === 'MemberExpression' &&
- normalizeFQN(getFullyQualifiedName(context, expr.callee)) ===
- 'aws_cdk_lib.aws_s3.BlockPublicAccess'
- );
- }
- }
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-server-encryption.ts b/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-server-encryption.ts
deleted file mode 100644
index a8276316208..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-server-encryption.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6245/javascript
-
-import { Rule } from 'eslint';
-import { MemberExpression } from 'estree';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { getFullyQualifiedName, getValueOfExpression, toEncodedMessage } from './helpers';
-import { normalizeFQN } from './helpers/aws/cdk';
-import { findPropagatedSetting, getProperty, S3BucketTemplate } from './helpers/aws/s3';
-
-const ENCRYPTED_KEY = 'encryption';
-
-const messages = {
- unencrypted: 'Objects in the bucket are not encrypted. Make sure it is safe here.',
- omitted: 'Omitting "encryption" disables server-side encryption. Make sure it is safe here.',
-};
-
-export const rule: Rule.RuleModule = S3BucketTemplate(
- (bucket, context) => {
- const encryptedProperty = getProperty(context, bucket, ENCRYPTED_KEY);
- if (encryptedProperty == null) {
- context.report({
- message: toEncodedMessage(messages['omitted'], [], []),
- node: bucket.callee,
- });
- return;
- }
-
- const encryptedValue = getValueOfExpression(
- context,
- encryptedProperty.value,
- 'MemberExpression',
- );
- if (encryptedValue && isUnencrypted(encryptedValue)) {
- const propagated = findPropagatedSetting(encryptedProperty, encryptedValue);
- context.report({
- message: toEncodedMessage(
- messages['unencrypted'],
- propagated.locations,
- propagated.messages,
- ),
- node: encryptedProperty,
- });
- }
-
- function isUnencrypted(encrypted: MemberExpression) {
- return (
- normalizeFQN(getFullyQualifiedName(context, encrypted)) ===
- 'aws_cdk_lib.aws_s3.BucketEncryption.UNENCRYPTED'
- );
- }
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-versioning.ts b/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-versioning.ts
deleted file mode 100644
index af12f8dfc24..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-s3-bucket-versioning.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6252/javascript
-
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { getValueOfExpression, toEncodedMessage, getNodeParent } from './helpers';
-import { getProperty, S3BucketTemplate } from './helpers/aws/s3';
-
-const VERSIONED_KEY = 'versioned';
-
-const messages = {
- unversioned: 'Make sure using unversioned S3 bucket is safe here.',
- omitted:
- 'Omitting the "versioned" argument disables S3 bucket versioning. Make sure it is safe here.',
- secondary: 'Propagated setting',
-};
-
-export const rule: Rule.RuleModule = S3BucketTemplate(
- (bucketConstructor, context) => {
- const versionedProperty = getProperty(context, bucketConstructor, VERSIONED_KEY);
- if (versionedProperty == null) {
- context.report({
- message: toEncodedMessage(messages.omitted),
- node: bucketConstructor.callee,
- });
- return;
- }
- const propertyLiteralValue = getValueOfExpression(context, versionedProperty.value, 'Literal');
-
- if (propertyLiteralValue?.value === false) {
- const secondary = { locations: [] as Node[], messages: [] as string[] };
- const isPropagatedProperty = versionedProperty.value !== propertyLiteralValue;
- if (isPropagatedProperty) {
- secondary.locations = [getNodeParent(propertyLiteralValue)];
- secondary.messages = [messages.secondary];
- }
- context.report({
- message: toEncodedMessage(messages.unversioned, secondary.locations, secondary.messages),
- node: versionedProperty,
- });
- }
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-sagemaker-unencrypted-notebook.ts b/eslint-bridge/src/linting/eslint/rules/aws-sagemaker-unencrypted-notebook.ts
deleted file mode 100644
index 88cc606fda8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-sagemaker-unencrypted-notebook.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6319/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws_sagemaker.CfnNotebookInstance': AwsCdkCheckArguments(
- 'CfnNotebookInstance',
- true,
- 'kmsKeyId',
- ),
- },
- {
- meta: {
- messages: {
- CfnNotebookInstance:
- 'Omitting "kmsKeyId" disables encryption of SageMaker notebook instances. Make sure it is safe here.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-sns-unencrypted-topics.ts b/eslint-bridge/src/linting/eslint/rules/aws-sns-unencrypted-topics.ts
deleted file mode 100644
index 43a358f615d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-sns-unencrypted-topics.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6327/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws_sns.Topic': AwsCdkCheckArguments('SNSTopic', true, 'masterKey'),
- 'aws-cdk-lib.aws_sns.CfnTopic': AwsCdkCheckArguments('SNSCfnTopic', true, 'kmsMasterKeyId'),
- },
- {
- meta: {
- messages: {
- SNSTopic: 'Omitting "masterKey" disables SNS topics encryption. Make sure it is safe here.',
- SNSCfnTopic:
- 'Omitting "kmsMasterKeyId" disables SNS topics encryption. Make sure it is safe here.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/aws-sqs-unencrypted-queue.ts b/eslint-bridge/src/linting/eslint/rules/aws-sqs-unencrypted-queue.ts
deleted file mode 100644
index d6d10945dd5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/aws-sqs-unencrypted-queue.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6308/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws-sqs.Queue': AwsCdkCheckArguments(
- ['OmittedQueue', 'DisabledQueue'],
- true,
- 'encryption',
- { fqns: { invalid: ['aws-cdk-lib.aws-sqs.QueueEncryption.UNENCRYPTED'] } },
- ),
- 'aws-cdk-lib.aws-sqs.CfnQueue': AwsCdkCheckArguments('CfnQueue', true, 'kmsMasterKeyId'),
- },
- {
- meta: {
- messages: {
- CfnQueue:
- 'Omitting "kmsMasterKeyId" disables SQS queues encryption. Make sure it is safe here.',
- OmittedQueue:
- 'Omitting "encryption" disables SQS queues encryption. Make sure it is safe here.',
- DisabledQueue:
- 'Setting "encryption" to "QueueEncryption.UNENCRYPTED" disables SQS queues encryption.' +
- 'Make sure it is safe here.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/bitwise-operators.ts b/eslint-bridge/src/linting/eslint/rules/bitwise-operators.ts
deleted file mode 100644
index 5b97aaeb5af..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/bitwise-operators.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1529/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { getTypeFromTreeNode } from './helpers';
-
-const BITWISE_AND_OR = ['&', '|'];
-const BITWISE_OPERATORS = [
- '&',
- '|',
- '^',
- '~',
- '<<',
- '>>',
- '>>>',
- '&=',
- '|=',
- '^=',
- '<<=',
- '>>=',
- '>>>=',
-];
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- const isNumeric = getNumericTypeChecker(context);
- let lonelyBitwiseAndOr: null | estree.BinaryExpression = null;
- let lonelyBitwiseAndOrAncestors: estree.Node[] = [];
- let fileContainsSeveralBitwiseOperations = false;
- return {
- BinaryExpression(node: estree.Node) {
- const expression = node as estree.BinaryExpression;
- if (
- !lonelyBitwiseAndOr &&
- BITWISE_AND_OR.includes(expression.operator) &&
- !isNumeric(expression.left) &&
- !isNumeric(expression.right)
- ) {
- lonelyBitwiseAndOr = expression;
- lonelyBitwiseAndOrAncestors = [...context.getAncestors()];
- } else if (BITWISE_OPERATORS.includes(expression.operator)) {
- fileContainsSeveralBitwiseOperations = true;
- }
- },
- 'Program:exit': function () {
- if (
- !fileContainsSeveralBitwiseOperations &&
- lonelyBitwiseAndOr &&
- insideCondition(lonelyBitwiseAndOr, lonelyBitwiseAndOrAncestors)
- ) {
- const op = lonelyBitwiseAndOr.operator;
- const operatorToken = context.getSourceCode().getTokenAfter(lonelyBitwiseAndOr.left);
- if (operatorToken) {
- context.report({
- loc: operatorToken.loc,
- message: `Review this use of bitwise "${op}" operator; conditional "${op}${op}" might have been intended.`,
- });
- }
- }
- },
- };
- },
-};
-
-function insideCondition(node: estree.Node, ancestors: estree.Node[]) {
- let child = node;
- for (let i = ancestors.length - 1; i >= 0; i--) {
- const parent = ancestors[i];
- if (
- parent.type === 'IfStatement' ||
- parent.type === 'ForStatement' ||
- parent.type === 'WhileStatement' ||
- parent.type === 'DoWhileStatement' ||
- parent.type === 'ConditionalExpression'
- ) {
- return parent.test === child;
- }
- child = parent;
- }
- return false;
-}
-
-type NumericTypeChecker = (node: estree.Node) => boolean;
-
-function getNumericTypeChecker(context: Rule.RuleContext): NumericTypeChecker {
- const services = context.parserServices;
- if (!!services && !!services.program && !!services.esTreeNodeToTSNodeMap) {
- return (node: estree.Node) => isNumericType(getTypeFromTreeNode(node, services));
- } else {
- const numericTypes = ['number', 'bigint'];
- return (node: estree.Node) =>
- node.type === 'Literal' ? numericTypes.includes(typeof node.value) : false;
- }
-
- function isNumericType(type: ts.Type): boolean {
- return (
- (type.getFlags() & (ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike)) !== 0 ||
- (type.isUnionOrIntersection() && !!type.types.find(isNumericType))
- );
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/bool-param-default.ts b/eslint-bridge/src/linting/eslint/rules/bool-param-default.ts
deleted file mode 100644
index 543f571e4a8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/bool-param-default.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4798/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-type FunctionLike =
- | TSESTree.FunctionDeclaration
- | TSESTree.FunctionExpression
- | TSESTree.ArrowFunctionExpression;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- provideDefault:
- "Provide a default value for '{{parameter}}' so that " +
- 'the logic of the function is more evident when this parameter is missing. ' +
- 'Consider defining another function if providing default value is not possible.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'FunctionDeclaration, FunctionExpression, ArrowFunctionExpression': (node: estree.Node) => {
- const functionLike = node as FunctionLike;
- for (const param of functionLike.params) {
- if (param.type === 'Identifier' && isOptionalBoolean(param)) {
- context.report({
- messageId: 'provideDefault',
- data: {
- parameter: param.name,
- },
- node: param as estree.Node,
- });
- }
- }
- },
- };
- },
-};
-
-function isOptionalBoolean(node: TSESTree.Identifier): boolean {
- return usesQuestionOptionalSyntax(node) || usesUnionUndefinedOptionalSyntax(node);
-}
-
-/**
- * Matches "param?: boolean"
- */
-function usesQuestionOptionalSyntax(node: TSESTree.Identifier): boolean {
- return (
- !!node.optional &&
- !!node.typeAnnotation &&
- node.typeAnnotation.typeAnnotation.type === 'TSBooleanKeyword'
- );
-}
-
-/**
- * Matches "boolean | undefined"
- */
-function usesUnionUndefinedOptionalSyntax(node: TSESTree.Identifier): boolean {
- if (!!node.typeAnnotation && node.typeAnnotation.typeAnnotation.type === 'TSUnionType') {
- const types = node.typeAnnotation.typeAnnotation.types;
- return (
- types.length === 2 &&
- types.some(tp => tp.type === 'TSBooleanKeyword') &&
- types.some(tp => tp.type === 'TSUndefinedKeyword')
- );
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/call-argument-line.ts b/eslint-bridge/src/linting/eslint/rules/call-argument-line.ts
deleted file mode 100644
index e0d40ee05b4..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/call-argument-line.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1472/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- moveArguments: 'Make those call arguments start on line {{line}}.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) => {
- const call = node as estree.CallExpression;
- if (call.callee.type !== 'CallExpression' && call.arguments.length === 1) {
- const sourceCode = context.getSourceCode();
- const parenthesis = sourceCode.getLastTokenBetween(
- call.callee,
- call.arguments[0],
- token => token.type === 'Punctuator' && token.value === ')',
- );
- const calleeLastLine = (parenthesis ? parenthesis : sourceCode.getLastToken(call.callee))!
- .loc.end.line;
- const { start } = sourceCode.getTokenAfter(call.callee)!.loc;
- if (calleeLastLine !== start.line) {
- const { end } = sourceCode.getLastToken(call)!.loc;
- if (end.line !== start.line) {
- //If arguments span multiple lines, we only report the first one
- reportIssue(start, calleeLastLine, context);
- } else {
- reportIssue({ start, end }, calleeLastLine, context);
- }
- }
- }
- },
- };
- },
-};
-
-function reportIssue(
- loc: { start: estree.Position; end: estree.Position } | estree.Position,
- line: number,
- context: Rule.RuleContext,
-) {
- context.report({
- messageId: 'moveArguments',
- data: {
- line: line.toString(),
- },
- loc,
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/certificate-transparency.ts b/eslint-bridge/src/linting/eslint/rules/certificate-transparency.ts
deleted file mode 100644
index b820f808c91..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/certificate-transparency.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5742/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, getFullyQualifiedName, getPropertyWithValue } from './helpers';
-
-const HELMET = 'helmet';
-const EXPECT_CERTIFICATE_TRANSPARENCY = 'expectCt';
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findFalseCertificateTransparencyPropertyFromHelmet,
- `Make sure disabling Certificate Transparency monitoring is safe here.`,
-);
-
-/**
- * Looks for property `expectCt: false` in node looking
- * somewhat similar to `helmet(?)`, and returns it.
- */
-function findFalseCertificateTransparencyPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- let sensitive: estree.Property | undefined;
- const { callee, arguments: args } = node;
- if (
- getFullyQualifiedName(context, callee) === HELMET &&
- args.length === 1 &&
- args[0].type === 'ObjectExpression'
- ) {
- sensitive = getPropertyWithValue(context, args[0], EXPECT_CERTIFICATE_TRANSPARENCY, false);
- }
- return sensitive ? [sensitive] : [];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/chai-determinate-assertion.ts b/eslint-bridge/src/linting/eslint/rules/chai-determinate-assertion.ts
deleted file mode 100644
index 9a53add244e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/chai-determinate-assertion.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6092/javascript
-
-import { Rule } from 'eslint';
-import { Chai, isDotNotation, isIdentifier } from './helpers';
-import * as estree from 'estree';
-
-const message = 'Refactor this uncertain assertion; it can succeed for multiple reasons.';
-
-type ChainElement = {
- identifier: estree.Identifier;
- arguments?: estree.Node[];
-};
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- if (!Chai.isImported(context)) {
- return {};
- }
- return {
- ExpressionStatement: (node: estree.ExpressionStatement) => {
- const elements: ChainElement[] = retrieveAssertionChainElements(node.expression);
-
- if (
- elements.length > 1 &&
- (isIdentifier(elements[0].identifier, 'expect') ||
- getElementIndex(elements, 'should') >= 0)
- ) {
- checkNotThrow(context, elements);
- checkNotInclude(context, elements);
- checkNotHaveProperty(context, elements);
- checkNotHaveOwnPropertyDescriptor(context, elements);
- checkNotHaveMembers(context, elements);
- checkChangeBy(context, elements);
- checkNotIncDec(context, elements);
- checkNotBy(context, elements);
- checkNotFinite(context, elements);
- }
- },
- };
- },
-};
-
-function checkNotThrow(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'throw', args => !!args && args.length > 0);
-}
-
-function checkNotInclude(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(
- context,
- elements,
- 'not',
- 'include',
- args => !!args && args.length > 0 && args[0].type === 'ObjectExpression',
- );
-}
-
-function checkNotHaveProperty(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'property', args => !!args && args.length > 1);
-}
-
-function checkNotHaveOwnPropertyDescriptor(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(
- context,
- elements,
- 'not',
- 'ownPropertyDescriptor',
- args => !!args && args.length > 1,
- );
-}
-
-function checkNotHaveMembers(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'members');
-}
-
-function checkChangeBy(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'change', 'by');
-}
-
-function checkNotIncDec(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'increase');
- checkWithCondition(context, elements, 'not', 'decrease');
-}
-
-function checkNotBy(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'by');
-}
-
-function checkNotFinite(context: Rule.RuleContext, elements: ChainElement[]) {
- checkWithCondition(context, elements, 'not', 'finite');
-}
-
-function checkWithCondition(
- context: Rule.RuleContext,
- elements: ChainElement[],
- first: string,
- second: string,
- condition: (args?: estree.Node[]) => boolean = () => true,
-) {
- const firstIndex = getElementIndex(elements, first);
- const firstElement = elements[firstIndex];
-
- const secondIndex = getElementIndex(elements, second);
- const secondElement = elements[secondIndex];
-
- if (
- firstElement &&
- secondElement &&
- neighborIndexes(firstIndex, secondIndex, elements) &&
- condition(secondElement.arguments)
- ) {
- context.report({
- message,
- loc: locFromTwoNodes(firstElement.identifier, secondElement.identifier),
- });
- }
-}
-
-// first element is not applied to second if between them function call (e.g. fist.foo().second())
-function neighborIndexes(firstIndex: number, secondIndex: number, elements: ChainElement[]) {
- if (firstIndex === secondIndex - 2) {
- return !elements[firstIndex + 1].arguments;
- }
-
- return firstIndex === secondIndex - 1;
-}
-
-function retrieveAssertionChainElements(node: estree.Expression) {
- let currentNode: estree.Node = node;
- const result: ChainElement[] = [];
- let currentArguments: estree.Node[] | undefined = undefined;
-
- while (true) {
- if (isDotNotation(currentNode)) {
- result.push({ identifier: currentNode.property, arguments: currentArguments });
- currentNode = currentNode.object;
- currentArguments = undefined;
- } else if (currentNode.type === 'CallExpression') {
- currentArguments = currentNode.arguments;
- currentNode = currentNode.callee;
- } else if (isIdentifier(currentNode)) {
- result.push({ identifier: currentNode, arguments: currentArguments });
- break;
- } else {
- break;
- }
- }
-
- return result.reverse();
-}
-
-function getElementIndex(elements: ChainElement[], name: string) {
- return elements.findIndex(element => isIdentifier(element.identifier, name));
-}
-
-function locFromTwoNodes(start: estree.Node, end: estree.Node) {
- return {
- start: start.loc!.start,
- end: end.loc!.end,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/class-name.ts b/eslint-bridge/src/linting/eslint/rules/class-name.ts
deleted file mode 100644
index c92cee8d2a1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/class-name.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S101/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-type ClassOrInterfaceDeclaration = TSESTree.ClassDeclaration | TSESTree.TSInterfaceDeclaration;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- renameClass: 'Rename {{symbolType}} "{{symbol}}" to match the regular expression {{format}}.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- ClassDeclaration: (node: estree.Node) =>
- checkName(node as ClassOrInterfaceDeclaration, 'class', context),
- TSInterfaceDeclaration: (node: estree.Node) =>
- checkName(node as ClassOrInterfaceDeclaration, 'interface', context),
- };
- },
-};
-
-function checkName(
- node: ClassOrInterfaceDeclaration,
- declarationType: string,
- context: Rule.RuleContext,
-) {
- const [{ format }] = context.options;
- if (node.id) {
- const name = node.id.name;
- if (!name.match(format)) {
- context.report({
- messageId: 'renameClass',
- data: {
- symbol: name,
- symbolType: declarationType,
- format,
- },
- node: node.id,
- });
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/class-prototype.ts b/eslint-bridge/src/linting/eslint/rules/class-prototype.ts
deleted file mode 100644
index 83e0c6a6f56..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/class-prototype.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3525/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { getTypeFromTreeNode, isRequiredParserServices, RequiredParserServices } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- declareClass:
- 'Declare a "{{class}}" class and move this declaration of "{{declaration}}" into it.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- const isFunction = isRequiredParserServices(services) ? isFunctionType : isFunctionLike;
- return {
- AssignmentExpression: (node: estree.Node) => {
- const { left, right } = node as estree.AssignmentExpression;
- if (left.type === 'MemberExpression' && isFunction(right, services)) {
- const [member, prototype] = [left.object, left.property];
- if (member.type === 'MemberExpression' && prototype.type === 'Identifier') {
- const [klass, property] = [member.object, member.property];
- if (
- klass.type === 'Identifier' &&
- property.type === 'Identifier' &&
- property.name === 'prototype'
- ) {
- context.report({
- messageId: 'declareClass',
- data: {
- class: klass.name,
- declaration: prototype.name,
- },
- node: left,
- });
- }
- }
- }
- },
- };
- },
-};
-
-function isFunctionType(node: estree.Node, services: RequiredParserServices) {
- const type = getTypeFromTreeNode(node, services);
- return type.symbol && (type.symbol.flags & ts.SymbolFlags.Function) !== 0;
-}
-
-function isFunctionLike(node: estree.Node, _services: RequiredParserServices) {
- return ['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'].includes(
- node.type,
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/code-eval.ts b/eslint-bridge/src/linting/eslint/rules/code-eval.ts
deleted file mode 100644
index 324a5e8616d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/code-eval.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1523/javascript
-// SQ key 'eval'
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeCode: 'Make sure that this dynamic injection or execution of code is safe.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) =>
- checkCallExpression(node as estree.CallExpression, context),
- NewExpression: (node: estree.Node) =>
- checkCallExpression(node as estree.CallExpression, context),
- };
- },
-};
-
-function checkCallExpression(node: estree.CallExpression, context: Rule.RuleContext) {
- if (node.callee.type === 'Identifier') {
- const { name } = node.callee;
- if ((name === 'eval' || name === 'Function') && hasAtLeastOneVariableArgument(node.arguments)) {
- context.report({
- messageId: 'safeCode',
- node: node.callee,
- });
- }
- }
-}
-
-function hasAtLeastOneVariableArgument(args: Array) {
- return !!args.find(arg => !isLiteral(arg));
-}
-
-function isLiteral(node: estree.Node) {
- if (node.type === 'Literal') {
- return true;
- }
-
- if (node.type === 'TemplateLiteral') {
- return node.expressions.length === 0;
- }
-
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/comma-or-logical-or-case.ts b/eslint-bridge/src/linting/eslint/rules/comma-or-logical-or-case.ts
deleted file mode 100644
index ab7c9d525a2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/comma-or-logical-or-case.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3616/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isLiteral } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- specifyCase: `Explicitly specify {{nesting}} separate cases that fall through; currently this case clause only works for "{{expression}}".`,
- },
- },
- create(context: Rule.RuleContext) {
- function reportIssue(node: estree.Node, clause: estree.Node, nestingLvl: number) {
- context.report({
- messageId: 'specifyCase',
- data: {
- nesting: nestingLvl.toString(),
- expression: String(getTextFromNode(clause)),
- },
- node,
- });
- }
-
- function getTextFromNode(node: estree.Node) {
- if (node.type === 'Literal') {
- return node.value;
- } else {
- return context.getSourceCode().getText(node);
- }
- }
-
- return {
- 'SwitchCase > SequenceExpression': function (node: estree.Node) {
- const expressions = (node as estree.SequenceExpression).expressions;
- reportIssue(node, expressions[expressions.length - 1], expressions.length);
- },
- 'SwitchCase > LogicalExpression': function (node: estree.Node) {
- if (!isSwitchTrue(getEnclosingSwitchStatement(context))) {
- const firstElemAndNesting = getFirstElementAndNestingLevel(
- node as estree.LogicalExpression,
- 0,
- );
- if (firstElemAndNesting) {
- reportIssue(node, firstElemAndNesting[0], firstElemAndNesting[1] + 1);
- }
- }
- },
- };
- },
-};
-
-function getEnclosingSwitchStatement(context: Rule.RuleContext): estree.SwitchStatement {
- const ancestors = context.getAncestors();
- for (let i = ancestors.length - 1; i >= 0; i--) {
- if (ancestors[i].type === 'SwitchStatement') {
- return ancestors[i] as estree.SwitchStatement;
- }
- }
- throw new Error('A switch case should have an enclosing switch statement');
-}
-
-function isSwitchTrue(node: estree.SwitchStatement) {
- return isLiteral(node.discriminant) && node.discriminant.value === true;
-}
-
-function getFirstElementAndNestingLevel(
- logicalExpression: estree.LogicalExpression,
- currentLvl: number,
-): [estree.Node, number] | undefined {
- if (logicalExpression.operator === '||') {
- if (logicalExpression.left.type === 'LogicalExpression') {
- return getFirstElementAndNestingLevel(logicalExpression.left, currentLvl + 1);
- } else {
- return [logicalExpression.left, currentLvl + 1];
- }
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/comment-regex.ts b/eslint-bridge/src/linting/eslint/rules/comment-regex.ts
deleted file mode 100644
index 0197ec9f3d8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/comment-regex.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S124/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- type: 'object',
- properties: {
- regularExpression: {
- type: 'string',
- },
- message: {
- type: 'string',
- },
- flags: {
- type: 'string',
- },
- },
- additionalProperties: false,
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const options = context.options[0] || {};
- const flags = options.flags || '';
- const cleanedFlags = 'gimusy'
- .split('')
- .filter(c => flags.includes(c))
- .join('');
- const pattern = options.regularExpression
- ? new RegExp(options.regularExpression, cleanedFlags)
- : undefined;
- const message = options.message || 'The regular expression matches this comment.';
-
- return {
- 'Program:exit': () => {
- (context.getSourceCode().getAllComments() as TSESTree.Comment[]).forEach(comment => {
- const rawTextTrimmed = comment.value.trim();
- if (pattern && pattern.test(rawTextTrimmed)) {
- context.report({
- message,
- loc: comment.loc,
- });
- }
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/concise-regex.ts b/eslint-bridge/src/linting/eslint/rules/concise-regex.ts
deleted file mode 100644
index cc35e7abd8d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/concise-regex.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6353/javascript
-
-import { Rule } from 'eslint';
-import { CharacterClass, Flags, Quantifier, RegExpLiteral } from 'regexpp/ast';
-import { createRegExpRule, RegexRuleContext } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- let flags: Flags;
- return {
- onRegExpLiteralEnter: (node: RegExpLiteral) => {
- ({ flags } = node);
- },
- onCharacterClassEnter: (node: CharacterClass) => {
- checkBulkyAnyCharacterClass(node, flags, context);
- checkBulkyNumericCharacterClass(node, context);
- checkBulkyAlphaNumericCharacterClass(node, context);
- },
- onQuantifierEnter: (node: Quantifier) => {
- checkBulkyQuantifier(node, context);
- },
- };
-});
-
-function checkBulkyAnyCharacterClass(
- node: CharacterClass,
- flags: Flags,
- context: RegexRuleContext,
-) {
- if (node.negate || node.elements.length !== 2) {
- return;
- }
- let hasLowerEscapeW = false;
- let hasUpperEscapeW = false;
- let hasLowerEscapeD = false;
- let hasUpperEscapeD = false;
- let hasLowerEscapeS = false;
- let hasUpperEscapeS = false;
- node.elements.forEach(element => {
- hasLowerEscapeW ||=
- element.type === 'CharacterSet' && element.kind === 'word' && !element.negate;
- hasUpperEscapeW ||=
- element.type === 'CharacterSet' && element.kind === 'word' && element.negate;
- hasLowerEscapeD ||=
- element.type === 'CharacterSet' && element.kind === 'digit' && !element.negate;
- hasUpperEscapeD ||=
- element.type === 'CharacterSet' && element.kind === 'digit' && element.negate;
- hasLowerEscapeS ||=
- element.type === 'CharacterSet' && element.kind === 'space' && !element.negate;
- hasUpperEscapeS ||=
- element.type === 'CharacterSet' && element.kind === 'space' && element.negate;
- });
- const isBulkyAnyCharacterClass =
- (hasLowerEscapeW && hasUpperEscapeW) ||
- (hasLowerEscapeD && hasUpperEscapeD) ||
- (hasLowerEscapeS && hasUpperEscapeS && flags.dotAll);
- if (isBulkyAnyCharacterClass) {
- context.reportRegExpNode({
- message: `Use concise character class syntax '.' instead of '${node.raw}'.`,
- node: context.node,
- regexpNode: node,
- });
- }
-}
-
-function checkBulkyNumericCharacterClass(node: CharacterClass, context: RegexRuleContext) {
- if (node.elements.length === 1) {
- const [element] = node.elements;
- const hasDigit = element.type === 'CharacterClassRange' && element.raw === '0-9';
- if (hasDigit) {
- const expected = node.negate ? '\\D' : '\\d';
- const actual = node.raw;
- context.reportRegExpNode({
- message: `Use concise character class syntax '${expected}' instead of '${actual}'.`,
- node: context.node,
- regexpNode: node,
- });
- }
- }
-}
-
-function checkBulkyAlphaNumericCharacterClass(node: CharacterClass, context: RegexRuleContext) {
- if (node.elements.length === 4) {
- let hasDigit = false,
- hasLowerCase = false,
- hasUpperCase = false,
- hasUnderscore = false;
- for (const element of node.elements) {
- hasDigit ||= element.type === 'CharacterClassRange' && element.raw === '0-9';
- hasLowerCase ||= element.type === 'CharacterClassRange' && element.raw === 'a-z';
- hasUpperCase ||= element.type === 'CharacterClassRange' && element.raw === 'A-Z';
- hasUnderscore ||= element.type === 'Character' && element.raw === '_';
- }
- if (hasDigit && hasLowerCase && hasUpperCase && hasUnderscore) {
- const expected = node.negate ? '\\W' : '\\w';
- const actual = node.raw;
- context.reportRegExpNode({
- message: `Use concise character class syntax '${expected}' instead of '${actual}'.`,
- node: context.node,
- regexpNode: node,
- });
- }
- }
-}
-
-function checkBulkyQuantifier(node: Quantifier, context: RegexRuleContext) {
- const { raw } = node;
- let message: string | undefined;
- let bulkyQuantifier: { concise: string; verbose: string } | undefined;
-
- if (/\{0,1\}\??$/.test(raw)) {
- bulkyQuantifier = { concise: '?', verbose: '{0,1}' };
- } else if (/\{0,0\}\??$/.test(raw)) {
- message = `Remove redundant ${node.element.raw}{0,0}.`;
- } else if (/\{0\}\??$/.test(raw)) {
- message = `Remove redundant ${node.element.raw}{0}.`;
- } else if (/\{1,1\}\??$/.test(raw)) {
- message = 'Remove redundant quantifier {1,1}.';
- } else if (/\{1\}\??$/.test(raw)) {
- message = 'Remove redundant quantifier {1}.';
- } else if (/\{0,\}\??$/.test(raw)) {
- bulkyQuantifier = { concise: '*', verbose: '{0,}' };
- } else if (/\{1,\}\??$/.test(raw)) {
- bulkyQuantifier = { concise: '+', verbose: '{1,}' };
- } else if (/\{(\d+),\1\}\??$/.test(raw)) {
- bulkyQuantifier = { concise: `{${node.min}}`, verbose: `{${node.min},${node.min}}` };
- }
-
- if (bulkyQuantifier) {
- message = `Use concise quantifier syntax '${bulkyQuantifier.concise}' instead of '${bulkyQuantifier.verbose}'.`;
- }
-
- if (message) {
- context.reportRegExpNode({
- message,
- node: context.node,
- regexpNode: node,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/conditional-indentation.ts b/eslint-bridge/src/linting/eslint/rules/conditional-indentation.ts
deleted file mode 100644
index 55107474c17..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/conditional-indentation.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3973/javascript
-
-import { Rule, AST, SourceCode } from 'eslint';
-import * as estree from 'estree';
-import { getParent, LoopLike, toEncodedMessage } from './helpers';
-import { TSESLint } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- return {
- IfStatement: (node: estree.Node) => {
- const ifStatement = node as estree.IfStatement;
- const parent = getParent(context);
- if (parent && parent.type !== 'IfStatement') {
- const firstToken = sourceCode.getFirstToken(node);
- checkIndentation(firstToken, ifStatement.consequent, context);
- }
-
- if (ifStatement.alternate) {
- const elseToken = sourceCode.getTokenBefore(
- ifStatement.alternate,
- token => token.type === 'Keyword' && token.value === 'else',
- );
- const alternate = ifStatement.alternate;
- if (alternate.type === 'IfStatement') {
- //case with "else if", we have to check the consequent of the next if
- checkIndentation(elseToken, alternate.consequent, context);
- } else {
- checkIndentation(
- getPrecedingBrace(elseToken, sourceCode) || elseToken,
- alternate,
- context,
- elseToken,
- );
- }
- }
- },
- 'WhileStatement, ForStatement, ForInStatement, ForOfStatement': (node: estree.Node) => {
- const firstToken = sourceCode.getFirstToken(node);
- checkIndentation(firstToken, (node as LoopLike).body, context);
- },
- };
- },
-};
-
-function checkIndentation(
- firstToken: AST.Token | null,
- statement: estree.Statement,
- context: Rule.RuleContext,
- tokenToReport = firstToken,
-) {
- if (firstToken && tokenToReport && statement.type !== 'BlockStatement') {
- const firstStatementToken = context.getSourceCode().getFirstToken(statement);
- if (
- firstStatementToken &&
- firstToken.loc.start.column >= firstStatementToken.loc.start.column
- ) {
- const message =
- `Use curly braces or indentation to denote the code conditionally ` +
- `executed by this "${tokenToReport.value}".`;
- context.report({
- message: toEncodedMessage(message, [firstStatementToken as TSESLint.AST.Token]),
- loc: tokenToReport.loc,
- });
- }
- }
-}
-
-function getPrecedingBrace(elseToken: AST.Token | null, sourceCode: SourceCode) {
- if (elseToken) {
- const tokenBeforeElse = sourceCode.getTokenBefore(elseToken);
- if (
- tokenBeforeElse?.value === '}' &&
- tokenBeforeElse.loc.start.line === elseToken.loc.start.line
- ) {
- return tokenBeforeElse;
- }
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/confidential-information-logging.ts b/eslint-bridge/src/linting/eslint/rules/confidential-information-logging.ts
deleted file mode 100644
index fd9d062f268..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/confidential-information-logging.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5757/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import {
- getValueOfExpression,
- getObjectExpressionProperty,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = 'Make sure confidential information is not logged here.';
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression: (node: estree.Node) => {
- const newExpression = node as estree.NewExpression;
- const { callee } = newExpression;
- if (getFullyQualifiedName(context, callee) !== 'signale.Signale') {
- return;
- }
- if (newExpression.arguments.length === 0) {
- context.report({ node: callee, message: toEncodedMessage(MESSAGE, []) });
- return;
- }
- const firstArgument = getValueOfExpression(
- context,
- newExpression.arguments[0],
- 'ObjectExpression',
- );
- if (!firstArgument) {
- // Argument exists but its value is unknown
- return;
- }
- const secrets = getObjectExpressionProperty(firstArgument, 'secrets');
- if (
- secrets &&
- secrets.value.type === 'ArrayExpression' &&
- secrets.value.elements.length === 0
- ) {
- context.report({
- node: callee,
- message: toEncodedMessage(MESSAGE, [secrets as TSESTree.Node]),
- });
- } else if (!secrets) {
- context.report({
- node: callee,
- message: toEncodedMessage(MESSAGE, [firstArgument as TSESTree.Node]),
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/constructor-for-side-effects.ts b/eslint-bridge/src/linting/eslint/rules/constructor-for-side-effects.ts
deleted file mode 100644
index 99a5c8292f3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/constructor-for-side-effects.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1848/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName, isTestCode } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeInstantiationOf:
- 'Either remove this useless object instantiation of "{{constructor}}" or use it.',
- removeInstantiation: 'Either remove this useless object instantiation or use it.',
- },
- },
- create(context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- return {
- 'ExpressionStatement > NewExpression': (node: estree.NewExpression) => {
- if (isTestCode(context) || isTryable(node, context)) {
- return;
- }
- const callee = (node as estree.NewExpression).callee;
- if (callee.type === 'Identifier' || callee.type === 'MemberExpression') {
- const calleeText = sourceCode.getText(callee);
- if (isException(context, callee, calleeText)) {
- return;
- }
- const reportLocation = {
- start: node.loc!.start,
- end: callee.loc!.end,
- };
- reportIssue(reportLocation, `${calleeText}`, 'removeInstantiationOf', context);
- } else {
- const newToken = sourceCode.getFirstToken(node);
- reportIssue(newToken!.loc, '', 'removeInstantiation', context);
- }
- },
- };
- },
-};
-
-function isTryable(node: estree.Node, context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- let parent = undefined;
- let child = node;
- while ((parent = ancestors.pop()) !== undefined) {
- if (parent.type === 'TryStatement' && parent.block === child) {
- return true;
- }
- child = parent;
- }
- return false;
-}
-
-function reportIssue(
- loc: { start: estree.Position; end: estree.Position },
- objectText: string,
- messageId: string,
- context: Rule.RuleContext,
-) {
- context.report({
- messageId,
- data: {
- constructor: objectText,
- },
- loc,
- });
-}
-
-/**
- * These exceptions are based on community requests and Peach
- */
-function isException(
- context: Rule.RuleContext,
- node: estree.Identifier | estree.MemberExpression,
- name: string,
-) {
- if (name === 'Notification') {
- return true;
- }
-
- const fqn = getFullyQualifiedName(context, node);
- return fqn === 'vue' || fqn === '@ag-grid-community.core.Grid';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/content-length.ts b/eslint-bridge/src/linting/eslint/rules/content-length.ts
deleted file mode 100644
index 77ece6e449b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/content-length.ts
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5693/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { getVariablePropertyFromAssignment } from './file-uploads';
-import { parse } from 'bytes';
-import {
- getLhsVariable,
- getValueOfExpression,
- getObjectExpressionProperty,
- getFullyQualifiedName,
-} from './helpers';
-
-const FORMIDABLE_MODULE = 'formidable';
-const MAX_FILE_SIZE = 'maxFileSize';
-const FORMIDABLE_DEFAULT_SIZE = 200 * 1024 * 1024;
-
-const MULTER_MODULE = 'multer';
-const LIMITS_OPTION = 'limits';
-const FILE_SIZE_OPTION = 'fileSize';
-
-const BODY_PARSER_MODULE = 'body-parser';
-const BODY_PARSER_DEFAULT_SIZE = parse('100kb');
-
-const formidableObjects: Map =
- new Map();
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeLimit: 'Make sure the content length limit is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression(node: estree.Node) {
- checkCallExpression(context, node as estree.NewExpression);
- },
- CallExpression(node: estree.Node) {
- checkCallExpression(context, node as estree.CallExpression);
- },
- AssignmentExpression(node: estree.Node) {
- visitAssignment(context, node as estree.AssignmentExpression);
- },
- Program() {
- formidableObjects.clear();
- },
- 'Program:exit'() {
- formidableObjects.forEach(value => report(context, value.nodeToReport, value.maxFileSize));
- },
- };
- },
-};
-
-function checkCallExpression(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- const { callee } = callExpression;
- let identifierFromModule: estree.Identifier;
- if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier') {
- identifierFromModule = callee.object;
- } else if (callee.type === 'Identifier') {
- identifierFromModule = callee;
- } else {
- return;
- }
-
- const fqn = getFullyQualifiedName(context, identifierFromModule);
- if (!fqn) {
- return;
- }
- const [moduleName] = fqn.split('.');
-
- if (moduleName === FORMIDABLE_MODULE) {
- checkFormidable(context, callExpression);
- }
-
- if (moduleName === MULTER_MODULE) {
- checkMulter(context, callExpression);
- }
-
- if (moduleName === BODY_PARSER_MODULE) {
- checkBodyParser(context, callExpression);
- }
-}
-
-function checkFormidable(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- if (callExpression.arguments.length === 0) {
- // options will be set later through member assignment
- const formVariable = getLhsVariable(context);
- if (formVariable) {
- formidableObjects.set(formVariable, {
- maxFileSize: FORMIDABLE_DEFAULT_SIZE,
- nodeToReport: callExpression,
- });
- }
- return;
- }
-
- const options = getValueOfExpression(context, callExpression.arguments[0], 'ObjectExpression');
- if (options) {
- const property = getObjectExpressionProperty(options, MAX_FILE_SIZE);
- checkSize(context, callExpression, property, FORMIDABLE_DEFAULT_SIZE);
- }
-}
-
-function checkMulter(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- if (callExpression.arguments.length === 0) {
- report(context, callExpression.callee);
- return;
- }
- const multerOptions = getValueOfExpression(
- context,
- callExpression.arguments[0],
- 'ObjectExpression',
- );
-
- if (!multerOptions) {
- return;
- }
-
- const limitsPropertyValue = getObjectExpressionProperty(multerOptions, LIMITS_OPTION)?.value;
- if (limitsPropertyValue && limitsPropertyValue.type === 'ObjectExpression') {
- const fileSizeProperty = getObjectExpressionProperty(limitsPropertyValue, FILE_SIZE_OPTION);
- checkSize(context, callExpression, fileSizeProperty);
- }
-
- if (!limitsPropertyValue) {
- report(context, callExpression.callee);
- }
-}
-
-function checkBodyParser(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- if (callExpression.arguments.length === 0) {
- checkSize(context, callExpression, undefined, BODY_PARSER_DEFAULT_SIZE, true);
- return;
- }
- const options = getValueOfExpression(context, callExpression.arguments[0], 'ObjectExpression');
-
- if (!options) {
- return;
- }
-
- const limitsProperty = getObjectExpressionProperty(options, LIMITS_OPTION);
- checkSize(context, callExpression, limitsProperty, BODY_PARSER_DEFAULT_SIZE, true);
-}
-
-function checkSize(
- context: Rule.RuleContext,
- callExpr: estree.CallExpression,
- property?: estree.Property,
- defaultLimit?: number,
- useStandardSizeLimit = false,
-) {
- if (property) {
- const maxFileSizeValue = getSizeValue(context, property.value);
- if (maxFileSizeValue) {
- report(context, property, maxFileSizeValue, useStandardSizeLimit);
- }
- } else {
- report(context, callExpr, defaultLimit, useStandardSizeLimit);
- }
-}
-
-function visitAssignment(context: Rule.RuleContext, assignment: estree.AssignmentExpression) {
- const variableProperty = getVariablePropertyFromAssignment(context, assignment);
- if (!variableProperty) {
- return;
- }
-
- const { objectVariable, property } = variableProperty;
-
- if (formidableObjects.has(objectVariable) && property === MAX_FILE_SIZE) {
- const formOptions = formidableObjects.get(objectVariable)!;
- const rhsValue = getSizeValue(context, assignment.right);
- if (rhsValue !== undefined) {
- formOptions.maxFileSize = rhsValue;
- formOptions.nodeToReport = assignment;
- } else {
- formidableObjects.delete(objectVariable);
- }
- }
-}
-
-function getSizeValue(context: Rule.RuleContext, node: estree.Node): number | undefined {
- const literal = getValueOfExpression(context, node, 'Literal');
- if (literal) {
- if (typeof literal.value === 'number') {
- return literal.value;
- } else if (typeof literal.value === 'string') {
- return parse(literal.value);
- }
- }
- return undefined;
-}
-
-function report(
- context: Rule.RuleContext,
- nodeToReport: estree.Node,
- size?: number,
- useStandardSizeLimit = false,
-) {
- const [fileUploadSizeLimit, standardSizeLimit] = context.options;
- const limitToCompare = useStandardSizeLimit ? standardSizeLimit : fileUploadSizeLimit;
- if (!size || size > limitToCompare) {
- context.report({
- messageId: 'safeLimit',
- node: nodeToReport,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/content-security-policy.ts b/eslint-bridge/src/linting/eslint/rules/content-security-policy.ts
deleted file mode 100644
index 6dd6d9cca8b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/content-security-policy.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5728/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, getFullyQualifiedName, getPropertyWithValue } from './helpers';
-
-const HELMET = 'helmet';
-const CONTENT_SECURITY_POLICY = 'contentSecurityPolicy';
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findFalseContentSecurityPolicyPropertyFromHelmet,
- `Make sure not enabling content security policy fetch directives is safe here.`,
-);
-
-/**
- * Looks for property `contentSecurityPolicy: false` in node looking
- * somewhat similar to `helmet(?)`, and returns it.
- */
-function findFalseContentSecurityPolicyPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- let sensitive: estree.Property | undefined;
- const { callee, arguments: args } = node;
- if (
- getFullyQualifiedName(context, callee) === HELMET &&
- args.length === 1 &&
- args[0].type === 'ObjectExpression'
- ) {
- sensitive = getPropertyWithValue(context, args[0], CONTENT_SECURITY_POLICY, false);
- }
- return sensitive ? [sensitive] : [];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/cookie-flag-check.ts b/eslint-bridge/src/linting/eslint/rules/cookie-flag-check.ts
deleted file mode 100644
index 4fef5edf676..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/cookie-flag-check.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isIdentifier,
- getValueOfExpression,
- getObjectExpressionProperty,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-
-export class CookieFlagCheck {
- issueMessage: string;
-
- constructor(readonly context: Rule.RuleContext, readonly flag: 'httpOnly' | 'secure') {
- this.issueMessage = `Make sure creating this cookie without the "${flag}" flag is safe.`;
- }
-
- private checkCookieSession(callExpression: estree.CallExpression) {
- // Sensitive argument for cookie session is first one
- this.checkSensitiveCookieArgument(callExpression, 0);
- }
-
- private checkCookiesMethodCall(callExpression: estree.CallExpression) {
- if (!isIdentifier((callExpression.callee as estree.MemberExpression).property, 'set')) {
- return;
- }
- // Sensitive argument is third argument for "cookies.set" calls
- this.checkSensitiveCookieArgument(callExpression, 2);
- }
-
- private checkCsurf(callExpression: estree.CallExpression) {
- // Sensitive argument is first for csurf
- const cookieProperty = this.checkSensitiveObjectArgument(callExpression, 0);
- if (cookieProperty) {
- // csurf cookie property can be passed as a boolean literal,
- // in which case neither "secure" nor "httponly" are enabled by default
- const cookiePropertyLiteral = getValueOfExpression(
- this.context,
- cookieProperty.value,
- 'Literal',
- );
- if (cookiePropertyLiteral?.value === true) {
- this.context.report({
- node: callExpression.callee,
- message: toEncodedMessage(this.issueMessage, [cookiePropertyLiteral as TSESTree.Node]),
- });
- }
- }
- }
-
- private checkExpressSession(callExpression: estree.CallExpression) {
- // Sensitive argument is first for express-session
- this.checkSensitiveObjectArgument(callExpression, 0);
- }
-
- private checkSensitiveCookieArgument(
- callExpression: estree.CallExpression,
- sensitiveArgumentIndex: number,
- ) {
- if (callExpression.arguments.length < sensitiveArgumentIndex + 1) {
- return;
- }
- const sensitiveArgument = callExpression.arguments[sensitiveArgumentIndex];
- const cookieObjectExpression = getValueOfExpression(
- this.context,
- sensitiveArgument,
- 'ObjectExpression',
- );
- if (!cookieObjectExpression) {
- return;
- }
- this.checkFlagOnCookieExpression(
- cookieObjectExpression,
- sensitiveArgument,
- cookieObjectExpression,
- callExpression,
- );
- }
-
- private checkSensitiveObjectArgument(
- callExpression: estree.CallExpression,
- argumentIndex: number,
- ): estree.Property | undefined {
- if (callExpression.arguments.length < argumentIndex + 1) {
- return;
- }
- const firstArgument = callExpression.arguments[argumentIndex];
- const objectExpression = getValueOfExpression(this.context, firstArgument, 'ObjectExpression');
- if (!objectExpression) {
- return;
- }
- const cookieProperty = getObjectExpressionProperty(objectExpression, 'cookie');
- if (!cookieProperty) {
- return;
- }
- const cookiePropertyValue = getValueOfExpression(
- this.context,
- cookieProperty.value,
- 'ObjectExpression',
- );
- if (cookiePropertyValue) {
- this.checkFlagOnCookieExpression(
- cookiePropertyValue,
- firstArgument,
- objectExpression,
- callExpression,
- );
- return;
- }
- return cookieProperty;
- }
-
- private checkFlagOnCookieExpression(
- cookiePropertyValue: estree.ObjectExpression,
- firstArgument: estree.Node,
- objectExpression: estree.ObjectExpression,
- callExpression: estree.CallExpression,
- ) {
- const flagProperty = getObjectExpressionProperty(cookiePropertyValue, this.flag);
- if (flagProperty) {
- const flagPropertyValue = getValueOfExpression(this.context, flagProperty.value, 'Literal');
- if (flagPropertyValue?.value === false) {
- const secondaryLocations: estree.Node[] = [flagPropertyValue];
- if (firstArgument !== objectExpression) {
- secondaryLocations.push(objectExpression);
- }
- this.context.report({
- node: callExpression.callee,
- message: toEncodedMessage(this.issueMessage, secondaryLocations as TSESTree.Node[]),
- });
- }
- }
- }
-
- public checkCookiesFromCallExpression(node: estree.Node) {
- const callExpression = node as estree.CallExpression;
- const { callee } = callExpression;
- const fqn = getFullyQualifiedName(this.context, callee);
- if (fqn === 'cookie-session') {
- this.checkCookieSession(callExpression);
- return;
- }
- if (fqn === 'csurf') {
- this.checkCsurf(callExpression);
- return;
- }
- if (fqn === 'express-session') {
- this.checkExpressSession(callExpression);
- return;
- }
- if (callee.type === 'MemberExpression') {
- const objectValue = getValueOfExpression(this.context, callee.object, 'NewExpression');
- if (objectValue && getFullyQualifiedName(this.context, objectValue.callee) === 'cookies') {
- this.checkCookiesMethodCall(callExpression);
- }
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/cookie-no-httponly.ts b/eslint-bridge/src/linting/eslint/rules/cookie-no-httponly.ts
deleted file mode 100644
index 0e860136e09..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/cookie-no-httponly.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3330/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { CookieFlagCheck } from './cookie-flag-check';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) =>
- new CookieFlagCheck(context, 'httpOnly').checkCookiesFromCallExpression(node),
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/cookies.ts b/eslint-bridge/src/linting/eslint/rules/cookies.ts
deleted file mode 100644
index 5ef57939a96..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/cookies.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2255/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeCookie: 'Make sure that cookie is written safely here.',
- },
- },
- create(context: Rule.RuleContext) {
- let usingExpressFramework = false;
-
- return {
- Program() {
- // init flag for each file
- usingExpressFramework = false;
- },
-
- Literal(node: estree.Node) {
- if ((node as estree.Literal).value === 'express') {
- usingExpressFramework = true;
- }
- },
-
- AssignmentExpression(node: estree.Node) {
- const { left } = node as estree.AssignmentExpression;
- if (left.type === 'MemberExpression') {
- const { object, property } = left;
- if (isIdentifier(object, 'document') && isIdentifier(property, 'cookie')) {
- context.report({
- messageId: 'safeCookie',
- node: left,
- });
- }
- }
- },
-
- CallExpression(node: estree.Node) {
- const { callee, arguments: args } = node as estree.CallExpression;
- if (
- callee.type === 'MemberExpression' &&
- usingExpressFramework &&
- isIdentifier(callee.property, 'cookie', 'cookies')
- ) {
- context.report({
- messageId: 'safeCookie',
- node,
- });
- }
-
- if (
- callee.type === 'MemberExpression' &&
- isIdentifier(callee.property, 'setHeader') &&
- isLiteral(args[0], 'Set-Cookie')
- ) {
- context.report({
- messageId: 'safeCookie',
- node: callee,
- });
- }
- },
- };
- },
-};
-
-function isLiteral(node: estree.Node | undefined, value: string) {
- return node && node.type === 'Literal' && node.value === value;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/core/index.ts b/eslint-bridge/src/linting/eslint/rules/core/index.ts
deleted file mode 100755
index 707660a7281..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/core/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter } from 'eslint';
-/**
- * ESLint core rules.
- */
-export const eslintRules = Object.fromEntries(new Linter().getRules());
diff --git a/eslint-bridge/src/linting/eslint/rules/cors.ts b/eslint-bridge/src/linting/eslint/rules/cors.ts
deleted file mode 100644
index dc4f2656a4f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/cors.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5122/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getUniqueWriteUsage,
- getObjectExpressionProperty,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { isLiteral } from 'eslint-plugin-sonarjs/lib/utils/nodes';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = `Make sure that enabling CORS is safe here.`;
-
-const CORS_HEADER = 'Access-Control-Allow-Origin';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- function report(node: estree.Node, ...secondaryLocations: estree.Node[]) {
- const message = toEncodedMessage(MESSAGE, secondaryLocations as TSESTree.Node[]);
- context.report({ message, node });
- }
-
- function isCorsCall(call: estree.CallExpression) {
- return getFullyQualifiedName(context, call) === 'cors';
- }
-
- return {
- CallExpression(node: estree.Node) {
- const call = node as estree.CallExpression;
-
- if (isCorsCall(call)) {
- if (call.arguments.length === 0) {
- report(call);
- return;
- }
- const [arg] = call.arguments;
- let sensitiveCorsProperty = getSensitiveCorsProperty(arg);
- if (sensitiveCorsProperty) {
- report(sensitiveCorsProperty);
- }
- if (arg?.type === 'Identifier') {
- const usage = getUniqueWriteUsage(context, arg.name);
- sensitiveCorsProperty = getSensitiveCorsProperty(usage);
- if (sensitiveCorsProperty) {
- report(sensitiveCorsProperty, arg);
- }
- }
- }
-
- if (isSettingCorsHeader(call)) {
- report(call);
- }
- },
-
- ObjectExpression(node: estree.Node) {
- const objProperty = getObjectExpressionProperty(node, CORS_HEADER);
- if (objProperty && isAnyDomain(objProperty.value)) {
- report(objProperty);
- }
- },
- };
- },
-};
-
-function isCorsHeader(node: estree.Node) {
- const header = node as TSESTree.Node;
- return isLiteral(header) && header.value === CORS_HEADER;
-}
-
-function isAnyDomain(node: estree.Node) {
- const domain = node as TSESTree.Node;
- return isLiteral(domain) && domain.value === '*';
-}
-
-function getSensitiveCorsProperty(
- node: estree.Node | undefined | null,
-): estree.Property | undefined {
- const originProperty = getObjectExpressionProperty(node, 'origin');
- if (originProperty && isAnyDomain(originProperty.value)) {
- return originProperty;
- }
- return undefined;
-}
-
-function isSettingCorsHeader(call: estree.CallExpression) {
- return isCorsHeader(call.arguments[0]) && isAnyDomain(call.arguments[1]);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/csrf.ts b/eslint-bridge/src/linting/eslint/rules/csrf.ts
deleted file mode 100644
index 2dc9f76935e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/csrf.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4502/javascript
-
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isIdentifier,
- isLiteral,
- getObjectExpressionProperty,
- flattenArgs,
- toEncodedMessage,
- getFullyQualifiedName,
- isRequireModule,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const CSURF_MODULE = 'csurf';
-const SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let globalCsrfProtection = false;
- let importedCsrfMiddleware = false;
-
- function checkIgnoredMethods(node: estree.Property) {
- if (node.value.type === 'ArrayExpression') {
- const arrayExpr = node.value;
- const unsafeMethods = arrayExpr.elements
- .filter(isLiteral)
- .filter(e => typeof e.value === 'string' && !SAFE_METHODS.includes(e.value));
- if (unsafeMethods.length > 0) {
- const [first, ...rest] = unsafeMethods;
- context.report({
- message: toEncodedMessage(
- 'Make sure disabling CSRF protection is safe here.',
- rest as TSESTree.Node[],
- ),
- node: first,
- });
- }
- }
- }
-
- function isCsurfMiddleware(node: estree.Node | undefined) {
- return node && getFullyQualifiedName(context, node) === CSURF_MODULE;
- }
-
- function checkCallExpression(callExpression: estree.CallExpression) {
- const { callee } = callExpression;
-
- // require('csurf')
- if (isRequireModule(callExpression, CSURF_MODULE)) {
- importedCsrfMiddleware = true;
- }
-
- // csurf(...)
- if (getFullyQualifiedName(context, callee) === CSURF_MODULE) {
- const [args] = callExpression.arguments;
- const ignoredMethods = getObjectExpressionProperty(args, 'ignoreMethods');
- if (ignoredMethods) {
- checkIgnoredMethods(ignoredMethods);
- }
- }
-
- // app.use(csurf(...))
- if (callee.type === 'MemberExpression') {
- if (
- isIdentifier(callee.property, 'use') &&
- flattenArgs(context, callExpression.arguments).find(isCsurfMiddleware)
- ) {
- globalCsrfProtection = true;
- }
- if (
- isIdentifier(callee.property, 'post', 'put', 'delete', 'patch') &&
- !globalCsrfProtection &&
- importedCsrfMiddleware &&
- !callExpression.arguments.some(arg => isCsurfMiddleware(arg))
- ) {
- context.report({
- message: toEncodedMessage('Make sure not using CSRF protection is safe here.', []),
- node: callee,
- });
- }
- }
- }
-
- return {
- Program() {
- globalCsrfProtection = false;
- },
- CallExpression(node: estree.Node) {
- checkCallExpression(node as estree.CallExpression);
- },
- ImportDeclaration(node: estree.Node) {
- if ((node as estree.ImportDeclaration).source.value === CSURF_MODULE) {
- importedCsrfMiddleware = true;
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/cyclomatic-complexity.ts b/eslint-bridge/src/linting/eslint/rules/cyclomatic-complexity.ts
deleted file mode 100644
index 5d31485f931..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/cyclomatic-complexity.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1541/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import {
- EncodedMessage,
- IssueLocation,
- getMainFunctionTokenLocation,
-} from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { FunctionNodeType, isFunctionNode, getParent, RuleContext } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { childrenOf } from 'linting/eslint';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- { type: 'integer' },
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const [threshold] = context.options;
- let functionsWithParent: Map;
- let functionsDefiningModule: estree.Node[];
- let functionsImmediatelyInvoked: estree.Node[];
- return {
- Program: () => {
- functionsWithParent = new Map();
- functionsDefiningModule = [];
- functionsImmediatelyInvoked = [];
- },
- 'Program:exit': () => {
- functionsWithParent.forEach((parent, func) => {
- if (
- !functionsDefiningModule.includes(func) &&
- !functionsImmediatelyInvoked.includes(func)
- ) {
- raiseOnUnauthorizedComplexity(func as FunctionNodeType, parent, threshold, context);
- }
- });
- },
- 'FunctionDeclaration, FunctionExpression, ArrowFunctionExpression': (node: estree.Node) =>
- functionsWithParent.set(node, getParent(context)),
- "CallExpression[callee.type='Identifier'][callee.name='define'] FunctionExpression": (
- node: estree.Node,
- ) => functionsDefiningModule.push(node),
- "NewExpression[callee.type='FunctionExpression'], CallExpression[callee.type='FunctionExpression']":
- (node: estree.Node) =>
- functionsImmediatelyInvoked.push((node as estree.NewExpression).callee),
- };
- },
-};
-
-function raiseOnUnauthorizedComplexity(
- node: FunctionNodeType,
- parent: estree.Node | undefined,
- threshold: number,
- context: Rule.RuleContext,
-): void {
- const tokens = computeCyclomaticComplexity(node, parent, context);
- const complexity = tokens.length;
- if (complexity > threshold) {
- context.report({
- message: toEncodedMessage(complexity, threshold, tokens),
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- parent as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
-}
-
-function toEncodedMessage(
- complexity: number,
- threshold: number,
- tokens: ComplexityToken[],
-): string {
- const encodedMessage: EncodedMessage = {
- message: `Function has a complexity of ${complexity} which is greater than ${threshold} authorized.`,
- cost: complexity - threshold,
- secondaryLocations: tokens.map(toSecondaryLocation),
- };
- return JSON.stringify(encodedMessage);
-}
-
-function toSecondaryLocation(token: ComplexityToken): IssueLocation {
- return {
- line: token.loc.start.line,
- column: token.loc.start.column,
- endLine: token.loc.end.line,
- endColumn: token.loc.end.column,
- message: '+1',
- };
-}
-
-function computeCyclomaticComplexity(
- node: estree.Node,
- parent: estree.Node | undefined,
- context: Rule.RuleContext,
-): ComplexityToken[] {
- const visitor = new FunctionComplexityVisitor(node, parent, context);
- visitor.visit();
- return visitor.getComplexityTokens();
-}
-
-interface ComplexityToken {
- loc: AST.SourceLocation;
-}
-
-class FunctionComplexityVisitor {
- private readonly tokens: ComplexityToken[] = [];
-
- constructor(
- private readonly root: estree.Node,
- private readonly parent: estree.Node | undefined,
- private readonly context: Rule.RuleContext,
- ) {}
-
- visit() {
- const visitNode = (node: estree.Node) => {
- let token: ComplexityToken | undefined | null;
-
- if (isFunctionNode(node)) {
- if (node !== this.root) {
- return;
- } else {
- token = {
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- this.parent as TSESTree.Node,
- this.context as unknown as RuleContext,
- ),
- };
- }
- } else {
- switch (node.type) {
- case 'ConditionalExpression':
- token = this.context
- .getSourceCode()
- .getFirstTokenBetween(node.test, node.consequent, token => token.value === '?');
- break;
- case 'SwitchCase':
- // ignore default case
- if (!node.test) {
- break;
- }
- case 'IfStatement':
- case 'ForStatement':
- case 'ForInStatement':
- case 'ForOfStatement':
- case 'WhileStatement':
- case 'DoWhileStatement':
- token = this.context.getSourceCode().getFirstToken(node);
- break;
- case 'LogicalExpression':
- token = this.context
- .getSourceCode()
- .getTokenAfter(
- node.left,
- token => ['||', '&&'].includes(token.value) && token.type === 'Punctuator',
- );
- break;
- }
- }
-
- if (token) {
- this.tokens.push(token);
- }
-
- childrenOf(node, this.context.getSourceCode().visitorKeys).forEach(visitNode);
- };
-
- visitNode(this.root);
- }
-
- getComplexityTokens() {
- return this.tokens;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/declarations-in-global-scope.ts b/eslint-bridge/src/linting/eslint/rules/declarations-in-global-scope.ts
deleted file mode 100644
index c02b11fa68e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/declarations-in-global-scope.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3798/javascript
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- defineLocally:
- 'Define this declaration in a local scope or bind explicitly the property to the global object.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- Program() {
- const scope = context.getScope();
- // As we parse every file with "module" source type, we find user defined global variables in the module scope
- const moduleScope = findModuleScope(context);
- moduleScope?.variables.forEach(variable => {
- if (scope.variables.find(global => global.name === variable.name)) {
- // Avoid reporting on redefinitions of actual global variables
- return;
- }
- for (const def of variable.defs) {
- const defNode = def.node;
- if (
- def.type === 'FunctionName' ||
- (def.type === 'Variable' && def.parent?.kind === 'var' && !isRequire(def.node.init))
- ) {
- context.report({
- node: defNode,
- messageId: 'defineLocally',
- });
- return;
- }
- }
- });
- },
- };
- },
-};
-
-function findModuleScope(context: Rule.RuleContext) {
- return context.getSourceCode().scopeManager.scopes.find(s => s.type === 'module');
-}
-
-function isRequire(node: estree.Node | null | undefined) {
- return (
- node?.type === 'CallExpression' &&
- node.arguments.length === 1 &&
- isIdentifier(node.callee, 'require')
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/accessor-pairs-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/accessor-pairs-decorator.ts
deleted file mode 100644
index 8de06202c0c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/accessor-pairs-decorator.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { interceptReport } from './helpers';
-
-export function decorateAccessorPairs(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isDecoratedSetterWithAngularInput));
-}
-
-function reportExempting(
- exemptionCondition: (def: TSESTree.MethodDefinition) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const def = reportDescriptor['node'] as TSESTree.MethodDefinition;
- if (!exemptionCondition(def)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function isDecoratedSetterWithAngularInput(def: TSESTree.MethodDefinition) {
- const { kind, decorators } = def;
- return (
- kind === 'set' &&
- decorators !== undefined &&
- decorators.some(
- decorator =>
- decorator.expression.type === 'CallExpression' &&
- decorator.expression.callee.type === 'Identifier' &&
- decorator.expression.callee.name === 'Input',
- )
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/brace-style-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/brace-style-decorator.ts
deleted file mode 100644
index 0fbd4e925a5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/brace-style-decorator.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1105/javascript
-
-import { Rule } from 'eslint';
-import { interceptReport } from './helpers';
-
-export function decorateBraceStyle(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isOpeningBracket));
-}
-
-function reportExempting(
- exemptionCondition: (messageId: string) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if (exemptionCondition((reportDescriptor as any).messageId)) {
- context.report(reportDescriptor);
- }
- };
-}
-
-function isOpeningBracket(messageId: string) {
- return messageId !== 'nextLineClose';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/default-param-last-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/default-param-last-decorator.ts
deleted file mode 100644
index 0f44fbebe50..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/default-param-last-decorator.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1788/javascript
-
-import { Rule } from 'eslint';
-import { AssignmentPattern, BaseFunction } from 'estree';
-import { isIdentifier } from 'linting/eslint/rules/helpers';
-import { interceptReport } from './helpers';
-
-const NUM_ARGS_REDUX_REDUCER = 2;
-
-export function decorateDefaultParamLast(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isReduxReducer));
-}
-
-function reportExempting(
- exemptionCondition: (enclosingFunction: BaseFunction) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const node = reportDescriptor['node'] as AssignmentPattern;
- const scope = context.getScope();
- const variable = scope.variables.find(value => isIdentifier(node.left, value.name));
- const enclosingFunction = variable?.defs?.[0]?.node as BaseFunction;
- if (enclosingFunction && !exemptionCondition(enclosingFunction)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function isReduxReducer(enclosingFunction: BaseFunction) {
- if (enclosingFunction.params.length === NUM_ARGS_REDUX_REDUCER) {
- const [firstParam, secondParam] = enclosingFunction.params;
- return (
- firstParam.type === 'AssignmentPattern' &&
- isIdentifier(firstParam.left, 'state') &&
- isIdentifier(secondParam, 'action')
- );
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/index.ts b/eslint-bridge/src/linting/eslint/rules/decorators/helpers/index.ts
deleted file mode 100644
index 8fcece92051..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './interceptor';
-export * from './merger';
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/interceptor.ts b/eslint-bridge/src/linting/eslint/rules/decorators/helpers/interceptor.ts
deleted file mode 100644
index c05b143674f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/interceptor.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-const NUM_ARGS_NODE_MESSAGE = 2;
-
-export type ReportOverrider = (
- context: Rule.RuleContext,
- reportDescriptor: Rule.ReportDescriptor,
-) => void;
-export type ContextOverrider = (
- context: Rule.RuleContext,
- onReport: ReportOverrider,
-) => Rule.RuleContext;
-
-/**
- * Modifies the behavior of `context.report(descriptor)` for a given rule.
- *
- * Useful for performing additional checks before reporting an issue.
- *
- * @param rule the original rule
- * @param onReport replacement for `context.report(descr)`
- * invocations used inside of the rule
- * @param contextOverrider optional function to change the default context overridding mechanism
- */
-export function interceptReport(
- rule: Rule.RuleModule,
- onReport: ReportOverrider,
- contextOverrider?: ContextOverrider,
-): Rule.RuleModule {
- return {
- // meta should be defined only when it's defined on original rule, otherwise RuleTester will fail
- ...(!!rule.meta && { meta: rule.meta }),
- create(originalContext: Rule.RuleContext) {
- let interceptingContext: Rule.RuleContext;
- if (contextOverrider == null) {
- interceptingContext = {
- id: originalContext.id,
- options: originalContext.options,
- settings: originalContext.settings,
- parserPath: originalContext.parserPath,
- parserOptions: originalContext.parserOptions,
- parserServices: originalContext.parserServices,
-
- getCwd(): string {
- return originalContext.getCwd();
- },
-
- getPhysicalFilename(): string {
- return originalContext.getPhysicalFilename();
- },
-
- getAncestors() {
- return originalContext.getAncestors();
- },
-
- getDeclaredVariables(node: estree.Node) {
- return originalContext.getDeclaredVariables(node);
- },
-
- getFilename() {
- return originalContext.getFilename();
- },
-
- getScope() {
- return originalContext.getScope();
- },
-
- getSourceCode() {
- return originalContext.getSourceCode();
- },
-
- markVariableAsUsed(name: string) {
- return originalContext.markVariableAsUsed(name);
- },
-
- report(...args: any[]): void {
- let descr: Rule.ReportDescriptor | undefined = undefined;
- if (args.length === 1) {
- descr = args[0] as Rule.ReportDescriptor;
- } else if (args.length === NUM_ARGS_NODE_MESSAGE && typeof args[1] === 'string') {
- // not declared in the `.d.ts`, but used in practice by rules written in JS
- descr = {
- node: args[0] as estree.Node,
- message: args[1],
- };
- }
- if (descr) {
- onReport(originalContext, descr);
- }
- },
- };
- } else {
- interceptingContext = contextOverrider(originalContext, onReport);
- }
- return rule.create(interceptingContext);
- },
- };
-}
-
-// interceptReport() by default doesn't work with the React plugin
-// as the rules fail to find the context getFirstTokens() function.
-export function interceptReportForReact(rule: Rule.RuleModule, onReport: ReportOverrider) {
- return interceptReport(rule, onReport, contextOverriderForReact);
-}
-
-function contextOverriderForReact(
- context: Rule.RuleContext,
- onReport: (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void,
-): Rule.RuleContext {
- const overriddenReportContext = {
- report(reportDescriptor: Rule.ReportDescriptor) {
- onReport(context, reportDescriptor);
- },
- };
-
- Object.setPrototypeOf(overriddenReportContext, context);
-
- return overriddenReportContext as Rule.RuleContext;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/merger.ts b/eslint-bridge/src/linting/eslint/rules/decorators/helpers/merger.ts
deleted file mode 100644
index db8457ee83f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/helpers/merger.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-
-/**
- * Merges the listeners of an arbitrary number of ESLint-based rules
- *
- * The purpose of this helper function is to merge the behaviour of a
- * variable number of rules. An ESLint rule "listens to" node visits based
- * on a node selector. If the node selector matches, the listener then
- * invokes a callback to proceed further with the node being visited.
- *
- * One needs to pay special attention when merging multiple rules that
- * their respective listeners don't overlap with one another, e.g., two
- * rules listen to `CallExpression` node vists. Unexpected behaviours
- * could happen otherwise.
- *
- * @param rules rules to merge
- * @returns the merge of the rules' listeners
- */
-export function mergeRules(...rules: Rule.RuleListener[]): Rule.RuleListener {
- const merged = Object.assign({}, ...rules);
-
- for (const listener of Object.keys(merged)) {
- merged[listener] = mergeListeners(...rules.map(rule => rule[listener]));
- }
- return merged;
-}
-
-function mergeListeners(...listeners: (Function | undefined)[]) {
- return (...args: any[]) => {
- for (const listener of listeners) {
- if (listener) {
- listener(...args);
- }
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/index.ts b/eslint-bridge/src/linting/eslint/rules/decorators/index.ts
deleted file mode 100644
index 17812ba32a3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/index.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-
-import { decorateAccessorPairs } from './accessor-pairs-decorator';
-import { decorateBraceStyle } from './brace-style-decorator';
-import { decorateDefaultParamLast } from './default-param-last-decorator';
-import { decorateJsxKey } from './jsx-key-decorator';
-import { decorateJsxNoConstructedContextValues } from './jsx-no-constructed-context-values';
-import { decorateNoDupeKeys } from './no-dupe-keys-decorator';
-import { decorateNoDuplicateImports } from './no-duplicate-imports-decorator';
-import { decorateNoEmpty } from './no-empty-decorator';
-import { decorateNoEmptyFunction } from './no-empty-function-decorator';
-import { decorateNoExtraSemi } from './no-extra-semi-decorator';
-import { decorateNoRedeclare } from './no-redeclare-decorator';
-import { decorateNoThisAlias } from './no-this-alias-decorator';
-import { decorateNoThrowLiteral } from './no-throw-literal-decorator';
-import { decorateNoUnreachable } from './no-unreachable-decorator';
-import { decorateNoUnstableNestedComponents } from './no-unstable-nested-components';
-import { decorateNoUnusedExpressions } from './no-unused-expressions-decorator';
-import { decorateObjectShorthand } from './object-shorthand-decorator';
-import { decoratePreferForOf } from './prefer-for-of-decorator';
-import { decoratePreferTemplate } from './prefer-template-decorator';
-import { decorateSemi } from './semi-decorator';
-import { decorateUseIsNan } from './use-isnan-decorator';
-import { decorateNoVar } from './no-var-decorator';
-
-/**
- * A decorator of an ESLint rule
- *
- * The purpose of a decorator is to refine the behaviour of external
- * ESLint rules. These refinements can include reducing the noise by
- * adding exceptions, extending the scope of the rule, adding quick fixes, etc.
- */
-export type RuleDecorator = (rule: Rule.RuleModule) => Rule.RuleModule;
-
-/**
- * The set of internal ESLint rule decorators
- *
- * Once declared here, these decorators are automatically applied
- * to the corresponding rule definitions by the linter's wrapper.
- * There is no further setup required to enable them, except when
- * one needs to test them using ESLint's rule tester.
- */
-export const decorators: Record = {
- 'accessor-pairs': decorateAccessorPairs,
- 'brace-style': decorateBraceStyle,
- 'default-param-last': decorateDefaultParamLast,
- 'jsx-key': decorateJsxKey,
- 'jsx-no-constructed-context-values': decorateJsxNoConstructedContextValues,
- 'no-dupe-keys': decorateNoDupeKeys,
- 'no-duplicate-imports': decorateNoDuplicateImports,
- 'no-empty': decorateNoEmpty,
- 'no-empty-function': decorateNoEmptyFunction,
- 'no-extra-semi': decorateNoExtraSemi,
- 'no-redeclare': decorateNoRedeclare,
- 'no-this-alias': decorateNoThisAlias,
- 'no-throw-literal': decorateNoThrowLiteral,
- 'no-unreachable': decorateNoUnreachable,
- 'no-unstable-nested-components': decorateNoUnstableNestedComponents,
- 'no-unused-expressions': decorateNoUnusedExpressions,
- 'no-var': decorateNoVar,
- 'object-shorthand': decorateObjectShorthand,
- 'prefer-for-of': decoratePreferForOf,
- 'prefer-template': decoratePreferTemplate,
- semi: decorateSemi,
- 'use-isnan': decorateUseIsNan,
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/jsx-key-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/jsx-key-decorator.ts
deleted file mode 100644
index 239e901ef4c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/jsx-key-decorator.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import { interceptReportForReact } from './helpers';
-
-export function decorateJsxKey(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReportForReact(rule, reportExempting(hasSpreadOperator));
-}
-
-function reportExempting(exemptionCondition: (property: TSESTree.Node) => boolean) {
- return (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => {
- // check if node has attribute containing spread operator
- if ('node' in reportDescriptor) {
- const { node, ...rest } = reportDescriptor;
- if (exemptionCondition(node as TSESTree.Node)) {
- return;
- }
- context.report({
- node,
- ...rest,
- });
- }
- };
-}
-
-function hasSpreadOperator(node: TSESTree.Node) {
- return (
- node.type === 'JSXElement' &&
- node.openingElement.attributes.some(attribute => attribute.type === 'JSXSpreadAttribute')
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/jsx-no-constructed-context-values.ts b/eslint-bridge/src/linting/eslint/rules/decorators/jsx-no-constructed-context-values.ts
deleted file mode 100644
index 58e67575c78..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/jsx-no-constructed-context-values.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6481/javascript
-
-import { Rule } from 'eslint';
-
-export function decorateJsxNoConstructedContextValues(rule: Rule.RuleModule): Rule.RuleModule {
- return changeRuleMessagesWith(rule, lineRemover());
-}
-
-function changeRuleMessagesWith(
- rule: Rule.RuleModule,
- messageChanger: (message: string) => string,
-) {
- if (rule.meta?.messages) {
- const messages = rule.meta.messages;
- const newMessages = Object.fromEntries(
- Object.entries(messages).map(([key, value]) => [key, messageChanger(value)]),
- );
- rule.meta.messages = newMessages;
- }
- return rule;
-}
-
-function lineRemover() {
- const lineRegexp = / \(at line [^)]+\)/g;
- return (message: string) => message.replace(lineRegexp, '');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-dupe-keys-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-dupe-keys-decorator.ts
deleted file mode 100644
index 38a049f953e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-dupe-keys-decorator.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1534/javascript
-
-import { Rule, AST } from 'eslint';
-import { interceptReport } from './helpers';
-import * as estree from 'estree';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoDupeKeys(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- context.report({
- ...reportDescriptor,
- suggest: [
- {
- desc: 'Remove this duplicate property',
- fix(fixer) {
- const propertyToRemove = getPropertyNode(reportDescriptor, context)!;
- const commaAfter = context
- .getSourceCode()
- .getTokenAfter(propertyToRemove, token => token.value === ',');
- const commaBefore = context
- .getSourceCode()
- .getTokenBefore(propertyToRemove, token => token.value === ',')!;
-
- let start = commaBefore.range[1];
- let end = propertyToRemove.range![1];
- if (commaAfter) {
- end = commaAfter.range[1];
- } else {
- start = commaBefore.range[0];
- }
- return fixer.removeRange([start, end]);
- },
- },
- ],
- });
- });
-}
-
-function getPropertyNode(reportDescriptor: Rule.ReportDescriptor, context: Rule.RuleContext) {
- if ('node' in reportDescriptor && 'loc' in reportDescriptor) {
- const objectLiteral = reportDescriptor['node'] as estree.ObjectExpression;
- const loc = reportDescriptor['loc'] as AST.SourceLocation;
-
- const transformPosToIndex = (p: estree.Position) => context.getSourceCode().getIndexFromLoc(p);
- return objectLiteral.properties.find(
- property =>
- transformPosToIndex(property.loc?.start!) <= transformPosToIndex(loc?.start) &&
- transformPosToIndex(property.loc?.end!) >= transformPosToIndex(loc?.end),
- );
- } else {
- throw new Error('Missing properties in report descriptor for rule S1534');
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-duplicate-imports-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-duplicate-imports-decorator.ts
deleted file mode 100644
index ec922734ff2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-duplicate-imports-decorator.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3863/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { removeNodeWithLeadingWhitespaces } from 'linting/eslint/rules/helpers';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoDuplicateImports(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const duplicateDecl = (reportDescriptor as any).node as estree.ImportDeclaration;
- context.report({
- ...reportDescriptor,
- suggest: getSuggestion(duplicateDecl, context),
- });
- });
-}
-
-function getSuggestion(
- duplicateDecl: estree.ImportDeclaration,
- context: Rule.RuleContext,
-): Rule.SuggestionReportDescriptor[] {
- const module = getModule(duplicateDecl);
- const importDecl = getFirstMatchingImportDeclaration(module, context);
- if (!importDecl) {
- return [];
- }
- const newSpecifiersText = mergeSpecifiers(importDecl, duplicateDecl, context);
- const oldSpecifiersRange = getSpecifiersRange(importDecl, context);
- return [
- {
- desc: `Merge this import into the first import from "${module}"`,
- fix: fixer => [
- fixer.replaceTextRange(oldSpecifiersRange, newSpecifiersText),
- removeNodeWithLeadingWhitespaces(context, duplicateDecl, fixer),
- ],
- },
- ];
-}
-
-function mergeSpecifiers(
- toDecl: estree.ImportDeclaration,
- fromDecl: estree.ImportDeclaration,
- context: Rule.RuleContext,
-) {
- const specifiers = [...toDecl.specifiers, ...fromDecl.specifiers];
- if (specifiers.length === 0) {
- return '';
- }
-
- let defaultSpecifierText = '';
- let namespaceSpecifierText = '';
- const importSpecifiersTexts: string[] = [];
- for (const specifier of specifiers) {
- const specifierText = context.getSourceCode().getText(specifier);
- switch (specifier.type) {
- case 'ImportDefaultSpecifier':
- defaultSpecifierText = specifierText;
- break;
- case 'ImportNamespaceSpecifier':
- namespaceSpecifierText = specifierText;
- break;
- case 'ImportSpecifier':
- importSpecifiersTexts.push(specifierText);
- break;
- }
- }
-
- let importSpecifiersText = '';
- if (importSpecifiersTexts.length > 0) {
- const multiline = isMultiline(toDecl) || isMultiline(fromDecl);
- const [separator, prefix, suffix] = multiline ? [',\n', '{\n', '\n}'] : [', ', '{ ', ' }'];
- importSpecifiersText = importSpecifiersTexts
- .map(text => (multiline ? ' ' + text : text))
- .join(separator);
- importSpecifiersText = `${prefix}${importSpecifiersText}${suffix}`;
- }
-
- return [defaultSpecifierText, namespaceSpecifierText, importSpecifiersText]
- .filter(text => text.length > 0)
- .join(', ');
-}
-
-function getSpecifiersRange(
- decl: estree.ImportDeclaration,
- context: Rule.RuleContext,
-): [number, number] {
- const sourceCode = context.getSourceCode();
- const importDecl = decl as TSESTree.ImportDeclaration;
- const importOrType = importDecl.importKind === 'type' ? 'type' : 'import';
- const importOrTypeToken = sourceCode.getFirstToken(decl, token => token.value === importOrType)!;
- const fromToken = sourceCode.getLastToken(decl, token => token.value === 'from');
- const begin = importOrTypeToken.range[1] + 1;
- const end = fromToken ? fromToken.range[0] - 1 : importOrTypeToken.range[1] + 1;
- return [begin, end];
-}
-
-function isMultiline(node: estree.Node): boolean {
- return node.loc!.start.line !== node.loc!.end.line;
-}
-
-function getModule(decl: estree.ImportDeclaration): string {
- return (decl.source.value as string).trim();
-}
-
-function getFirstMatchingImportDeclaration(
- module: string,
- context: Rule.RuleContext,
-): estree.ImportDeclaration | undefined {
- return context
- .getSourceCode()
- .ast.body.find(node => node.type === 'ImportDeclaration' && module === getModule(node)) as
- | estree.ImportDeclaration
- | undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-decorator.ts
deleted file mode 100644
index 0a403fe51ad..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-decorator.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S108/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoEmpty(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const node = (reportDescriptor as any).node as estree.Node;
- const type = reportDescriptor.data!.type;
- let openingBrace: AST.Token;
- if (node.type === 'SwitchStatement') {
- openingBrace = context
- .getSourceCode()
- .getTokenAfter(node.discriminant, token => token.value === '{')!;
- } /* BlockStatement */ else {
- openingBrace = context.getSourceCode().getFirstToken(node)!;
- }
- const closingBrace = context.getSourceCode().getLastToken(node)!;
- suggestEmptyBlockQuickFix(context, reportDescriptor, type, openingBrace, closingBrace);
- });
-}
-
-export function suggestEmptyBlockQuickFix(
- context: Rule.RuleContext,
- descriptor: Rule.ReportDescriptor,
- blockType: string,
- openingBrace: AST.Token,
- closingBrace: AST.Token,
-) {
- let commentPlaceholder: string;
- if (openingBrace.loc.start.line === closingBrace.loc.start.line) {
- commentPlaceholder = ` /* TODO document why this ${blockType} is empty */ `;
- } else {
- const columnOffset = closingBrace.loc.start.column;
- const padding = ' '.repeat(columnOffset);
- commentPlaceholder = `\n${padding} // TODO document why this ${blockType} is empty\n${padding}`;
- }
- context.report({
- ...descriptor,
- suggest: [
- {
- desc: 'Insert placeholder comment',
- fix: fixer => fixer.insertTextAfter(openingBrace, commentPlaceholder),
- },
- ],
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-function-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-function-decorator.ts
deleted file mode 100644
index 92fb85ff7da..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-empty-function-decorator.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1186/javascript
-
-import * as estree from 'estree';
-import { Rule } from 'eslint';
-import { interceptReport } from './helpers';
-import { suggestEmptyBlockQuickFix } from './no-empty-decorator';
-import { FunctionNodeType, isFunctionNode, isIdentifier } from '../helpers';
-
-type RuleFunctionNode = FunctionNodeType & Rule.Node;
-
-function isRuleFunctionNode(node: estree.Node): node is RuleFunctionNode {
- return isFunctionNode(node) && 'parent' in node;
-}
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoEmptyFunction(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, reportWithQuickFixIfApplicable);
-}
-
-export function reportWithQuickFixIfApplicable(
- context: Rule.RuleContext,
- reportDescriptor: Rule.ReportDescriptor,
-) {
- if (!('node' in reportDescriptor) || !isRuleFunctionNode(reportDescriptor.node)) {
- return;
- }
-
- const functionNode = reportDescriptor.node;
- if (isApplicable(functionNode)) {
- reportWithQuickFix(context, reportDescriptor, functionNode);
- }
-}
-
-// This function limits the issues to variable/function/method declarations which name is not like /^on[A-Z].
-// Any lambda expression or arrow function is thus ignored.
-function isApplicable(functionNode: RuleFunctionNode) {
- // Matches identifiers like onClick and more generally onXxx
- function isCallbackIdentifier(node: estree.Node | null) {
- return node !== null && isIdentifier(node) && /^on[A-Z]/.test(node.name);
- }
-
- // Matches: function foo() {}
- // But not: function onClose() {}
- function isFunctionDeclaration() {
- return functionNode.type === 'FunctionDeclaration' && !isCallbackIdentifier(functionNode.id);
- }
-
- // Matches: class A { foo() {} }
- // But not: class A { onClose() {} }
- function isMethodDefinition() {
- const methodNode = functionNode.parent;
- return (
- methodNode.type === 'MethodDefinition' &&
- methodNode.value === functionNode &&
- !isCallbackIdentifier(methodNode.key)
- );
- }
-
- // Matches: const foo = () => {};
- // But not: const onClose = () => {};
- function isVariableDeclarator() {
- const variableNode = functionNode.parent;
- return (
- variableNode.type === 'VariableDeclarator' &&
- variableNode.init === functionNode &&
- !isCallbackIdentifier(variableNode.id)
- );
- }
-
- return isFunctionDeclaration() || isMethodDefinition() || isVariableDeclarator();
-}
-
-function reportWithQuickFix(
- context: Rule.RuleContext,
- reportDescriptor: Rule.ReportDescriptor,
- func: FunctionNodeType,
-) {
- const name = reportDescriptor.data!.name;
- const openingBrace = context.getSourceCode().getFirstToken(func.body)!;
- const closingBrace = context.getSourceCode().getLastToken(func.body)!;
- suggestEmptyBlockQuickFix(context, reportDescriptor, name, openingBrace, closingBrace);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-extra-semi-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-extra-semi-decorator.ts
deleted file mode 100644
index da5f4a88289..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-extra-semi-decorator.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { AST, Rule } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-
-type NullableToken = AST.Token | null | undefined;
-type NodeCondition = (context: Rule.RuleContext, node: estree.Node) => boolean;
-
-// core implementation of this rule raises issues when using semicolon-free style and
-// using semicolon to protect code on purpose.
-export function decorateNoExtraSemi(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isProtectionSemicolon));
-}
-
-function reportExempting(exemptionCondition: NodeCondition) {
- return (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor): void => {
- if ('node' in reportDescriptor && !exemptionCondition(context, reportDescriptor.node)) {
- context.report(reportDescriptor);
- }
- };
-}
-
-// Checks that a node is a semicolon inserted to prevent the compiler from merging the
-// following statement with the previous.
-export function isProtectionSemicolon(context: Rule.RuleContext, node: estree.Node): boolean {
- if (node.type !== 'EmptyStatement') {
- return false;
- }
-
- // This checks the semicolon is on a new line compared to the previous token if it exists.
- const previousToken = context.getSourceCode().getTokenBefore(node);
- if (!isNodeOnNewLineAfterToken(node, previousToken)) {
- return false;
- }
-
- const nextToken = context.getSourceCode().getTokenAfter(node);
- return isParenOrBracket(nextToken);
-}
-
-function isNodeOnNewLineAfterToken(node: estree.Node, token: NullableToken): boolean {
- if (node.loc == null) {
- return false;
- } else if (token == null) {
- return true;
- } else {
- return token.loc.end.line < node.loc.start.line;
- }
-}
-
-function isParenOrBracket(token: NullableToken): boolean {
- return token?.type === 'Punctuator' && (token.value === '[' || token.value === '(');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-redeclare-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-redeclare-decorator.ts
deleted file mode 100644
index f3ca24b3306..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-redeclare-decorator.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-// core implementation of this rule raises issues on type exports
-export function decorateNoRedeclare(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isTypeDeclaration));
-}
-
-function reportExempting(
- exemptionCondition: (node: estree.Identifier) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const node = reportDescriptor['node'];
- if (node.type === 'Identifier' && !exemptionCondition(node)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function isTypeDeclaration(node: estree.Identifier) {
- return (node as TSESTree.Node).parent?.type === 'TSTypeAliasDeclaration';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-this-alias-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-this-alias-decorator.ts
deleted file mode 100644
index afcb6b6e419..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-this-alias-decorator.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { getVariableFromName } from '../helpers';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule raises false positives for generators
-export function decorateNoThisAlias(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isReferencedInsideGenerators));
-}
-
-function reportExempting(
- exemptionCondition: (context: Rule.RuleContext, node: estree.Identifier) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const node = reportDescriptor['node'] as estree.Identifier;
- if (!exemptionCondition(context, node)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function isReferencedInsideGenerators(context: Rule.RuleContext, node: estree.Identifier) {
- const variable = getVariableFromName(context, node.name);
- if (variable) {
- for (const reference of variable.references) {
- let scope: Scope.Scope | null = reference.from;
- while (scope !== null && !scope.variables.includes(variable)) {
- if (isGenerator(scope.block)) {
- return true;
- }
- scope = scope.upper;
- }
- }
- }
- return false;
-
- function isGenerator(node: estree.Node) {
- return (
- (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
- node.generator === true
- );
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-throw-literal-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-throw-literal-decorator.ts
deleted file mode 100644
index a22235c3ab5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-throw-literal-decorator.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3696/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isBinaryPlus, isStringLiteral } from 'linting/eslint/rules/helpers';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoThrowLiteral(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const suggest: Rule.SuggestionReportDescriptor[] = [];
- if ('node' in reportDescriptor) {
- const { argument: thrown } = reportDescriptor.node as estree.ThrowStatement;
- if (isStringLike(thrown)) {
- const thrownText = context.getSourceCode().getText(thrown);
- suggest.push({
- desc: 'Throw an error object',
- fix: fixer => fixer.replaceText(thrown, `new Error(${thrownText})`),
- });
- }
- }
- context.report({
- ...reportDescriptor,
- suggest,
- });
- });
-}
-
-function isStringLike(node: estree.Node): boolean {
- return isStringLiteral(node) || isStringConcatenation(node);
-}
-
-function isStringConcatenation(node: estree.Node): boolean {
- return isBinaryPlus(node) && (isStringLike(node.left) || isStringLike(node.right));
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-unreachable-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-unreachable-decorator.ts
deleted file mode 100644
index d6abdaa6d7c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-unreachable-decorator.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1763/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-import { removeNodeWithLeadingWhitespaces } from 'linting/eslint/rules/helpers';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateNoUnreachable(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const loc = (reportDescriptor as any).loc as AST.SourceLocation;
- const node = (reportDescriptor as any).node as estree.Node;
- context.report({
- ...reportDescriptor,
- suggest: [
- {
- desc: 'Remove unreachable code',
- fix: fixer =>
- removeNodeWithLeadingWhitespaces(
- context,
- node,
- fixer,
- context.getSourceCode().getIndexFromLoc(loc.end),
- ),
- },
- ],
- });
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-unstable-nested-components.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-unstable-nested-components.ts
deleted file mode 100644
index ba2c94ea740..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-unstable-nested-components.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6478/javascript
-
-import { Rule } from 'eslint';
-import { interceptReportForReact } from './helpers';
-
-export function decorateNoUnstableNestedComponents(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReportForReact(rule, changeMessageWith(urlRemover()));
-}
-
-function changeMessageWith(messageChanger: (message: string) => string) {
- return (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => {
- const report = reportDescriptor as { message?: string };
- if (report.message) {
- report.message = messageChanger(report.message);
- }
- context.report(reportDescriptor);
- };
-}
-
-function urlRemover() {
- const urlRegexp = / \(https:[^)]+\)/;
- return (message: string) => message.replace(urlRegexp, '');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-unused-expressions-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-unused-expressions-decorator.ts
deleted file mode 100644
index 227b9cdefc5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-unused-expressions-decorator.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { interceptReport } from './helpers';
-
-export function decorateNoUnusedExpressions(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(
- rule,
- reportExempting(
- expr =>
- isNegatedIife(expr) ||
- containsChaiExpect(expr) ||
- containsValidChaiShould(expr) ||
- isAuraLightningComponent(expr) ||
- isSequenceWithSideEffects(expr),
- ),
- );
-}
-
-function reportExempting(
- exemptionCondition: (expr: estree.Expression) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const n: estree.Node = reportDescriptor['node'];
- const expr = (n as estree.ExpressionStatement).expression;
- if (!exemptionCondition(expr)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function containsChaiExpect(node: estree.Node): boolean {
- if (node.type === 'CallExpression') {
- if (node.callee.type === 'Identifier' && node.callee.name === 'expect') {
- return true;
- } else {
- return containsChaiExpect(node.callee);
- }
- } else if (node.type === 'MemberExpression') {
- return containsChaiExpect(node.object);
- }
- return false;
-}
-
-function containsValidChaiShould(node: estree.Node, isSubexpr = false): boolean {
- if (node.type === 'CallExpression') {
- return containsValidChaiShould(node.callee, true);
- } else if (node.type === 'MemberExpression') {
- if (node.property && node.property.type === 'Identifier' && node.property.name === 'should') {
- // Expressions like `x.should` are valid only as subexpressions, not on top level
- return isSubexpr;
- } else {
- return containsValidChaiShould(node.object, true);
- }
- }
- return false;
-}
-
-function isNegatedIife(node: estree.Node): boolean {
- return node.type === 'UnaryExpression' && node.operator === '!' && isIife(node.argument);
-}
-
-function isIife(node: estree.Node): boolean {
- return (
- node.type === 'CallExpression' &&
- (node.callee.type === 'FunctionExpression' || node.callee.type === 'ArrowFunctionExpression')
- );
-}
-
-function isSequenceWithSideEffects(node: estree.Node): boolean {
- return (
- node.type === 'SequenceExpression' &&
- node.expressions[node.expressions.length - 1].type === 'AssignmentExpression'
- );
-}
-
-function isAuraLightningComponent(node: estree.Node): boolean {
- return (
- node.type === 'ObjectExpression' &&
- node.properties.length > 0 &&
- (node as TSESTree.Node).parent?.parent?.type === 'Program'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/no-var-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/no-var-decorator.ts
deleted file mode 100644
index 4ecf5cea96b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/no-var-decorator.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { interceptReport } from './helpers';
-import estree from 'estree';
-
-export function decorateNoVar(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const { node, ...rest } = reportDescriptor;
- const {
- declarations: [firstDecl, ..._],
- } = node as estree.VariableDeclaration;
-
- const varToken = context.getSourceCode().getTokenBefore(firstDecl.id);
- const identifierEnd = firstDecl.id.loc!.end;
- if (varToken == null) {
- // impossible
- return;
- }
- context.report({
- loc: {
- start: varToken.loc.start,
- end: identifierEnd,
- },
- ...rest,
- });
- }
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/object-shorthand-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/object-shorthand-decorator.ts
deleted file mode 100644
index e4a326debfa..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/object-shorthand-decorator.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3498/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule raises issues on aura lightning components
-export function decorateObjectShorthand(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isAuraLightningComponent));
-}
-
-function reportExempting(
- exemptionCondition: (property: TSESTree.Property) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const property = reportDescriptor['node'] as TSESTree.Property;
- if (!exemptionCondition(property)) {
- context.report({ ...reportDescriptor, node: property.key as estree.Node });
- }
- }
- };
-}
-
-function isAuraLightningComponent(property: TSESTree.Property) {
- const { parent, value } = property;
- return (
- parent!.parent!.type === 'ExpressionStatement' &&
- parent!.parent!.parent!.type === 'Program' &&
- value.type === 'FunctionExpression'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/prefer-for-of-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/prefer-for-of-decorator.ts
deleted file mode 100644
index 8d135b90541..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/prefer-for-of-decorator.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4138/javascript
-
-import { Rule, AST, Scope } from 'eslint';
-import { interceptReport } from './helpers';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-const element = 'element';
-
-// core implementation of this rule does not provide quick fixes
-export function decoratePreferForOf(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const forStmt = (reportDescriptor as any).node as estree.ForStatement;
- const suggest: Rule.SuggestionReportDescriptor[] = [];
- if (isFixable(context.getScope())) {
- suggest.push({
- desc: 'Replace with "for of" loop',
- fix: fixer => rewriteForStatement(forStmt, context, fixer),
- });
- }
- context.report({
- ...reportDescriptor,
- suggest,
- });
- });
-}
-
-function isFixable(scope: Scope.Scope): boolean {
- return (
- scope.references.every(reference => reference.identifier.name !== element) &&
- scope.childScopes.every(isFixable)
- );
-}
-
-function rewriteForStatement(
- forStmt: estree.ForStatement,
- context: Rule.RuleContext,
- fixer: Rule.RuleFixer,
-) {
- const fixes: Rule.Fix[] = [];
-
- /* rewrite `for` header: `(init; test; update)` -> `(const element of ) ` */
- const openingParenthesis = context
- .getSourceCode()
- .getFirstToken(forStmt, token => token.value === '(')!;
- const closingParenthesis = context
- .getSourceCode()
- .getTokenBefore(forStmt.body, token => token.value === ')')!;
-
- const arrayExpr = extractArrayExpression(forStmt);
- const arrayText = context.getSourceCode().getText(arrayExpr);
-
- const headerRange: AST.Range = [openingParenthesis.range[1], closingParenthesis.range[0]];
- const headerText = `const ${element} of ${arrayText}`;
- fixes.push(fixer.replaceTextRange(headerRange, headerText));
-
- /* rewrite `for` body: `[]` -> `element` */
- const [indexVar] = context.getDeclaredVariables(forStmt.init!);
- for (const reference of indexVar.references) {
- const id = reference.identifier;
- if (contains(forStmt.body, id)) {
- const arrayAccess = (id as TSESTree.Node).parent as estree.Node;
- fixes.push(fixer.replaceText(arrayAccess, element));
- }
- }
-
- return fixes;
-}
-
-function extractArrayExpression(forStmt: estree.ForStatement) {
- return ((forStmt.test as estree.BinaryExpression).right as estree.MemberExpression).object;
-}
-
-function contains(outer: estree.Node, inner: estree.Node) {
- return outer.range![0] <= inner.range![0] && outer.range![1] >= inner.range![1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/prefer-template-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/prefer-template-decorator.ts
deleted file mode 100644
index 59475b6c7b2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/prefer-template-decorator.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule raises issues on binary expressions with string literal operand(s)
-export function decoratePreferTemplate(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, reportExempting(isTwoOperands));
-}
-
-function reportExempting(
- exemptionCondition: (node: estree.BinaryExpression) => boolean,
-): (context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) => void {
- return (context, reportDescriptor) => {
- if ('node' in reportDescriptor) {
- const expr = reportDescriptor['node'] as estree.BinaryExpression;
- if (!exemptionCondition(expr)) {
- context.report(reportDescriptor);
- }
- }
- };
-}
-
-function isTwoOperands(node: estree.BinaryExpression) {
- return node.right.type !== 'BinaryExpression' && node.left.type !== 'BinaryExpression';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/semi-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/semi-decorator.ts
deleted file mode 100644
index a51510e4a6c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/semi-decorator.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1438/javascript
-
-import { Rule } from 'eslint';
-import { interceptReport } from './helpers';
-
-export function decorateSemi(rule: Rule.RuleModule): Rule.RuleModule {
- return interceptReport(rule, fixLocation);
-}
-
-function fixLocation(context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor) {
- const report = reportDescriptor as any;
- if (report.loc?.start && report.messageId === 'missingSemi') {
- report.loc = report.loc.start;
- }
- context.report(reportDescriptor);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/decorators/use-isnan-decorator.ts b/eslint-bridge/src/linting/eslint/rules/decorators/use-isnan-decorator.ts
deleted file mode 100644
index 1a89bc85663..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/decorators/use-isnan-decorator.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2688/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isMemberExpression } from 'linting/eslint/rules/helpers';
-import { interceptReport } from './helpers';
-
-// core implementation of this rule does not provide quick fixes
-export function decorateUseIsNan(rule: Rule.RuleModule): Rule.RuleModule {
- rule.meta!.hasSuggestions = true;
- return interceptReport(rule, (context, reportDescriptor) => {
- const suggest: Rule.SuggestionReportDescriptor[] = [];
- const node = (reportDescriptor as any).node as estree.Node;
- if (node.type === 'BinaryExpression') {
- const { left, operator, right } = node;
- let negate: boolean | null = null;
- switch (operator) {
- case '!=':
- case '!==':
- negate = true;
- break;
- case '==':
- case '===':
- negate = false;
- break;
- }
- if (negate !== null) {
- const arg = isNaNIdentifier(left) ? right : left;
- const argText = context.getSourceCode().getText(arg);
- const prefix = negate ? '!' : '';
- suggest.push(
- {
- desc: 'Use "isNaN()"',
- fix: fixer => fixer.replaceText(node, `${prefix}isNaN(${argText})`),
- },
- {
- desc: 'Use "Number.isNaN()"',
- fix: fixer => fixer.replaceText(node, `${prefix}Number.isNaN(${argText})`),
- },
- );
- }
- }
- context.report({ ...reportDescriptor, suggest });
- });
-}
-
-function isNaNIdentifier(node: estree.Node) {
- return isIdentifier(node, 'NaN') || isMemberExpression(node, 'Number', 'NaN');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/deprecation.ts b/eslint-bridge/src/linting/eslint/rules/deprecation.ts
deleted file mode 100644
index bb1c051d960..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/deprecation.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1874/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as estree from 'estree';
-import { getParent, isRequiredParserServices, RequiredParserServices } from './helpers';
-import * as ts from 'typescript';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- deprecation: "'{{symbol}}' is deprecated. {{reason}}",
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- Identifier: (node: estree.Node) => {
- const parent = getParent(context);
- if (isShortHandProperty(parent) && parent.key === node) {
- // to not report twice
- return;
- }
- if (isObjectExpressionProperty(node, context)) {
- return;
- }
- const id = node as estree.Identifier;
- const insideImportExport = context.getAncestors().some(anc => anc.type.includes('Import'));
- if (insideImportExport || isDeclaration(id, context)) {
- return;
- }
-
- const deprecation = getDeprecation(id, services, context);
- if (deprecation) {
- context.report({
- node,
- messageId: 'deprecation',
- data: {
- symbol: id.name,
- reason: deprecation.reason,
- },
- });
- }
- },
- };
- },
-};
-
-function isDeclaration(id: estree.Identifier, context: Rule.RuleContext) {
- const parent = getParent(context);
- if (isShortHandProperty(parent) && parent.value === id) {
- return false;
- }
-
- const variable = context.getScope().variables.find(v => v.name === id.name);
- if (variable) {
- return variable.defs.some(def => def.name === id);
- }
-
- const declarationTypes = [
- 'PropertyDefinition',
- 'TSPropertySignature',
- 'TSDeclareFunction',
- 'FunctionDeclaration',
- 'MethodDefinition',
- 'TSMethodSignature',
- ];
- return parent && declarationTypes.includes(parent.type);
-}
-
-function getDeprecation(
- id: estree.Identifier,
- services: RequiredParserServices,
- context: Rule.RuleContext,
-): Deprecation | undefined {
- const tc = services.program.getTypeChecker();
- const callExpression = getCallExpression(context, id);
-
- if (callExpression) {
- const tsCallExpression = services.esTreeNodeToTSNodeMap.get(callExpression as TSESTree.Node);
- const signature = tc.getResolvedSignature(tsCallExpression as ts.CallLikeExpression);
- if (signature) {
- const deprecation = getJsDocDeprecation(signature.getJsDocTags());
- if (deprecation) {
- return deprecation;
- }
- }
- }
- const symbol = getSymbol(id, services, context, tc);
-
- if (!symbol) {
- return undefined;
- }
- if (callExpression && isFunction(symbol)) {
- return undefined;
- }
-
- return getJsDocDeprecation(symbol.getJsDocTags());
-}
-
-function getSymbol(
- id: estree.Identifier,
- services: RequiredParserServices,
- context: Rule.RuleContext,
- tc: ts.TypeChecker,
-) {
- let symbol: ts.Symbol | undefined;
- const tsId = services.esTreeNodeToTSNodeMap.get(id as TSESTree.Node) as ts.Identifier;
- const parent = services.esTreeNodeToTSNodeMap.get(getParent(context) as TSESTree.Node) as ts.Node;
- if (parent.kind === ts.SyntaxKind.BindingElement) {
- symbol = tc.getTypeAtLocation(parent.parent).getProperty(tsId.text);
- } else if (
- (isPropertyAssignment(parent) && parent.name === tsId) ||
- (isShorthandPropertyAssignment(parent) && parent.name === tsId)
- ) {
- try {
- symbol = tc.getPropertySymbolOfDestructuringAssignment(tsId);
- } catch (e) {
- // do nothing, we are in object literal, not destructuring
- // no obvious easy way to check that in advance
- }
- } else {
- symbol = tc.getSymbolAtLocation(tsId);
- }
-
- if (symbol && (symbol.flags & ts.SymbolFlags.Alias) !== 0) {
- return tc.getAliasedSymbol(symbol);
- }
- return symbol;
-}
-
-function getCallExpression(
- context: Rule.RuleContext,
- id: estree.Node,
-): estree.CallExpression | estree.TaggedTemplateExpression | undefined {
- const ancestors = context.getAncestors();
- let callee = id;
- let parent = ancestors.length > 0 ? ancestors[ancestors.length - 1] : undefined;
-
- if (parent && parent.type === 'MemberExpression' && parent.property === id) {
- callee = parent;
- parent = ancestors.length > 1 ? ancestors[ancestors.length - 2] : undefined;
- }
-
- if (isCallExpression(parent, callee)) {
- return parent;
- }
-}
-
-function isCallExpression(
- node: estree.Node | undefined,
- callee: estree.Node,
-): node is estree.CallExpression | estree.TaggedTemplateExpression {
- if (node) {
- if (node.type === 'NewExpression' || node.type === 'CallExpression') {
- return node.callee === callee;
- } else if (node.type === 'TaggedTemplateExpression') {
- return node.tag === callee;
- }
- }
- return false;
-}
-
-function getJsDocDeprecation(tags: ts.JSDocTagInfo[]): Deprecation | undefined {
- for (const tag of tags) {
- if (tag.name === 'deprecated') {
- return tag.text ? { reason: tag.text.map(e => e.text).join(' ') } : new Deprecation();
- }
- }
- return undefined;
-}
-
-function isFunction(symbol: ts.Symbol) {
- const { declarations } = symbol;
- if (declarations === undefined || declarations.length === 0) {
- return false;
- }
- switch (declarations[0].kind) {
- case ts.SyntaxKind.MethodDeclaration:
- case ts.SyntaxKind.FunctionDeclaration:
- case ts.SyntaxKind.FunctionExpression:
- case ts.SyntaxKind.MethodSignature:
- return true;
- default:
- return false;
- }
-}
-
-function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment {
- return node.kind === ts.SyntaxKind.PropertyAssignment;
-}
-
-function isShorthandPropertyAssignment(node: ts.Node): node is ts.ShorthandPropertyAssignment {
- return node.kind === ts.SyntaxKind.ShorthandPropertyAssignment;
-}
-
-function isShortHandProperty(parent: estree.Node | undefined): parent is estree.Property {
- return !!parent && parent.type === 'Property' && parent.shorthand;
-}
-
-function isObjectExpressionProperty(node: estree.Node, context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- const parent = ancestors.pop();
- const grandparent = ancestors.pop();
- return (
- parent?.type === 'Property' &&
- !parent.computed &&
- !parent.shorthand &&
- parent.key === node &&
- grandparent?.type === 'ObjectExpression'
- );
-}
-
-class Deprecation {
- reason = '';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/destructuring-assignment-syntax.ts b/eslint-bridge/src/linting/eslint/rules/destructuring-assignment-syntax.ts
deleted file mode 100644
index f0d18677510..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/destructuring-assignment-syntax.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3514/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as estree from 'estree';
-import { findFirstMatchingAncestor, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MAX_INDEX = 4;
-const isAllowedIndex = (idx: number) => idx >= 0 && idx <= MAX_INDEX;
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- function visitStatements(statements: Array) {
- const declarationsByObject: Map = new Map();
-
- for (const statement of statements) {
- if (statement.type === 'VariableDeclaration') {
- visitDeclarations(declarationsByObject, statement.declarations);
- } else {
- checkDeclarationsBlock(declarationsByObject);
- declarationsByObject.clear();
- }
- }
- checkDeclarationsBlock(declarationsByObject);
- }
-
- function visitDeclarations(
- declarationsByObject: Map,
- declarations: Array,
- ) {
- for (const declaration of declarations) {
- const id = declaration.id;
- if (declaration.init && id.type === 'Identifier') {
- const varName = id.name;
- const expression = declaration.init;
- if (expression.type !== 'MemberExpression') {
- continue;
- }
- const property = expression.property;
- if (property.type === 'Identifier' && property.name === varName) {
- addDeclaration(declarationsByObject, expression.object, declaration);
- } else if (
- property.type === 'Literal' &&
- typeof property.value === 'number' &&
- isAllowedIndex(property.value)
- ) {
- addDeclaration(declarationsByObject, expression.object, declaration);
- }
- }
- }
- }
-
- function addDeclaration(
- declarationsByObject: Map,
- object: estree.Node,
- declaration: estree.VariableDeclarator,
- ) {
- const key = context.getSourceCode().getText(object);
- const value = declarationsByObject.get(key);
- if (value) {
- value.push(declaration);
- } else {
- declarationsByObject.set(key, [declaration]);
- }
- }
-
- function checkDeclarationsBlock(
- declarationsByObject: Map,
- ) {
- declarationsByObject.forEach((declarations: estree.VariableDeclarator[], key: string) => {
- if (declarations.length > 1) {
- const firstKind = getKind(declarations[0]);
- const tail = declarations.slice(1);
- if (tail.every(decl => getKind(decl) === firstKind)) {
- context.report({
- node: declarations[0],
- message: toEncodedMessage(
- `Use destructuring syntax for these assignments from "${key}".`,
- tail as TSESTree.Node[],
- Array(tail.length).fill('Replace this assignment.'),
- ),
- });
- }
- }
- });
- }
-
- return {
- BlockStatement: (node: estree.Node) => {
- visitStatements((node as estree.BlockStatement).body);
- },
- SwitchCase: (node: estree.Node) => {
- visitStatements((node as estree.SwitchCase).consequent);
- },
- Program: (node: estree.Node) => {
- visitStatements((node as estree.Program).body);
- },
- };
- },
-};
-
-function getKind(declarator: estree.VariableDeclarator) {
- const declaration = findFirstMatchingAncestor(
- declarator as TSESTree.Node,
- n => n.type === 'VariableDeclaration',
- ) as estree.VariableDeclaration | undefined;
- return declaration && declaration.kind;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/different-types-comparison.ts b/eslint-bridge/src/linting/eslint/rules/different-types-comparison.ts
deleted file mode 100644
index 21da76613c4..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/different-types-comparison.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3403/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isRequiredParserServices, getTypeFromTreeNode, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- function isComparableTo(lhs: estree.Node, rhs: estree.Node) {
- const checker = services.program.getTypeChecker();
- const lhsType = checker.getBaseTypeOfLiteralType(getTypeFromTreeNode(lhs, services));
- const rhsType = checker.getBaseTypeOfLiteralType(getTypeFromTreeNode(rhs, services));
- // @ts-ignore private API
- return (
- checker.isTypeAssignableTo(lhsType, rhsType) || checker.isTypeAssignableTo(rhsType, lhsType)
- );
- }
-
- return {
- BinaryExpression: (node: estree.Node) => {
- const { left, operator, right } = node as estree.BinaryExpression;
- if (['===', '!=='].includes(operator) && !isComparableTo(left, right)) {
- const [actual, expected, outcome] =
- operator === '===' ? ['===', '==', 'false'] : ['!==', '!=', 'true'];
- const operatorToken = context
- .getSourceCode()
- .getTokensBetween(left, right)
- .find(token => token.type === 'Punctuator' && token.value === operator)!;
- context.report({
- message: toEncodedMessage(
- `Remove this "${actual}" check; it will always be ${outcome}. Did you mean to use "${expected}"?`,
- [left, right],
- ),
- loc: operatorToken.loc,
- suggest: [
- {
- desc: `Replace "${actual}" with "${expected}"`,
- fix: fixer => fixer.replaceText(operatorToken, expected),
- },
- ],
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/disabled-auto-escaping.ts b/eslint-bridge/src/linting/eslint/rules/disabled-auto-escaping.ts
deleted file mode 100644
index c37c1c3db31..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/disabled-auto-escaping.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5247/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isIdentifier,
- getValueOfExpression,
- isRequiredParserServices,
- resolveFromFunctionReference,
- checkSensitiveCall,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = 'Make sure disabling auto-escaping feature is safe here.';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- function isEmptySanitizerFunction(
- sanitizerFunction:
- | estree.FunctionExpression
- | estree.FunctionDeclaration
- | estree.ArrowFunctionExpression,
- ) {
- if (sanitizerFunction.params.length !== 1) {
- return false;
- }
- const firstParam = sanitizerFunction.params[0];
- if (firstParam.type !== 'Identifier') {
- return false;
- }
- const firstParamName = firstParam.name;
- if (sanitizerFunction.body.type !== 'BlockStatement') {
- return (
- sanitizerFunction.body.type === 'Identifier' &&
- sanitizerFunction.body.name === firstParamName
- );
- }
- const { body } = sanitizerFunction.body;
- if (body.length !== 1) {
- return false;
- }
- const onlyStatement = body[0];
- if (
- onlyStatement.type === 'ReturnStatement' &&
- onlyStatement.argument &&
- isIdentifier(onlyStatement.argument, firstParamName)
- ) {
- return true;
- }
- return false;
- }
-
- function isInvalidSanitizerFunction(node: estree.Node) {
- type AssignedFunction =
- | estree.FunctionDeclaration
- | estree.FunctionExpression
- | estree.ArrowFunctionExpression
- | undefined
- | null;
- let assignedFunction: AssignedFunction =
- getValueOfExpression(context, node, 'FunctionExpression') ??
- getValueOfExpression(context, node, 'ArrowFunctionExpression');
- if (!assignedFunction && node.type === 'Identifier' && isRequiredParserServices(services)) {
- assignedFunction = resolveFromFunctionReference(context, node);
- }
- if (!!assignedFunction) {
- return isEmptySanitizerFunction(assignedFunction);
- }
- return false;
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- if (fqn === 'handlebars.compile') {
- checkSensitiveCall(context, callExpression, 1, 'noEscape', true, MESSAGE);
- }
- if (fqn === 'marked.setOptions') {
- checkSensitiveCall(context, callExpression, 0, 'sanitize', false, MESSAGE);
- }
- if (fqn === 'markdown-it') {
- checkSensitiveCall(context, callExpression, 0, 'html', true, MESSAGE);
- }
- },
- NewExpression: (node: estree.Node) => {
- const newExpression = node as estree.NewExpression;
- if (getFullyQualifiedName(context, newExpression) === 'kramed.Renderer') {
- checkSensitiveCall(context, newExpression, 0, 'sanitize', false, MESSAGE);
- }
- },
- AssignmentExpression: (node: estree.Node) => {
- const assignmentExpression = node as estree.AssignmentExpression;
- const { left, right } = assignmentExpression;
- if (left.type !== 'MemberExpression') {
- return;
- }
- if (
- !(
- getFullyQualifiedName(context, left) === 'mustache.escape' ||
- (isMustacheIdentifier(left.object) && isIdentifier(left.property, 'escape'))
- )
- ) {
- return;
- }
- if (isInvalidSanitizerFunction(right)) {
- context.report({
- node: left,
- message: toEncodedMessage(MESSAGE),
- });
- }
- },
- };
- },
-};
-
-function isMustacheIdentifier(node: estree.Node) {
- return isIdentifier(node, 'Mustache');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/disabled-resource-integrity.ts b/eslint-bridge/src/linting/eslint/rules/disabled-resource-integrity.ts
deleted file mode 100644
index 0812601be90..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/disabled-resource-integrity.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5725/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Variable } from 'eslint-scope';
-import { isIdentifier, isRequiredParserServices, getTypeAsString } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeResource: 'Make sure not using resource integrity feature is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- function shouldReport(assignedVariable: Variable) {
- let nbSrcAssignment = 0;
- let hasUnsafeSrcAssignment = false;
- let hasIntegrityAssignment = false;
- assignedVariable.references.forEach(ref => {
- const parentNode = (ref.identifier as TSESTree.Node).parent;
- if (!parentNode) {
- return;
- }
- nbSrcAssignment += isSrcAssignment(parentNode) ? 1 : 0;
- hasUnsafeSrcAssignment = hasUnsafeSrcAssignment || isUnsafeSrcAssignment(parentNode);
- hasIntegrityAssignment = hasIntegrityAssignment || isIntegrityAssignment(parentNode);
- });
- return nbSrcAssignment === 1 && hasUnsafeSrcAssignment && !hasIntegrityAssignment;
- }
-
- function isIntegrityAssignment(memberExpression: TSESTree.Node): boolean {
- if (memberExpression.type !== 'MemberExpression') {
- return false;
- }
- return (
- memberExpression.property.type === 'Identifier' &&
- memberExpression.property.name === 'integrity'
- );
- }
-
- function isSrcAssignment(memberExpression: TSESTree.Node): boolean {
- if (memberExpression.type !== 'MemberExpression') {
- return false;
- }
- if (
- memberExpression.property.type !== 'Identifier' ||
- memberExpression.property.name !== 'src'
- ) {
- return false;
- }
- const assignmentExpression = memberExpression.parent;
- if (assignmentExpression?.type !== 'AssignmentExpression') {
- return false;
- }
- return true;
- }
-
- function isUnsafeSrcAssignment(memberExpression: TSESTree.Node): boolean {
- if (!isSrcAssignment(memberExpression)) {
- return false;
- }
- const right = (memberExpression.parent as estree.AssignmentExpression).right;
- if (right.type !== 'Literal') {
- return false;
- }
- return !!right.raw && (!!right.raw.match('^"http') || !!right.raw.match('^"//'));
- }
-
- return {
- 'VariableDeclarator[init.type="CallExpression"]': (node: estree.Node) => {
- const variableDeclarator = node as estree.VariableDeclarator;
- const callExpression = variableDeclarator.init as estree.CallExpression;
- const left = variableDeclarator.id;
- const { callee } = callExpression;
- if (left.type !== 'Identifier') {
- return;
- }
- if (callee.type !== 'MemberExpression') {
- return;
- }
- const typeName = getTypeAsString(left, services);
- if (
- !isIdentifier(callee.object, 'document') ||
- !isIdentifier(callee.property, 'createElement') ||
- typeName !== 'HTMLScriptElement'
- ) {
- return;
- }
- const scope = context.getScope();
- const assignedVariable = scope.variables.find(v => v.name === left.name);
- if (!assignedVariable) {
- return;
- }
- if (shouldReport(assignedVariable)) {
- context.report({
- node: variableDeclarator,
- messageId: 'safeResource',
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/disabled-timeout.ts b/eslint-bridge/src/linting/eslint/rules/disabled-timeout.ts
deleted file mode 100644
index ed496012f3f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/disabled-timeout.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6080/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- Chai,
- getUniqueWriteUsageOrNode,
- isIdentifier,
- isMethodCall,
- isNumberLiteral,
- isThisExpression,
- Mocha,
-} from './helpers';
-
-const MESSAGE =
- 'Set this timeout to 0 if you want to disable it, otherwise use a value lower than 2147483648.';
-const MAX_DELAY_VALUE = 2_147_483_647;
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- if (!Chai.isImported(context)) {
- return {};
- }
- const constructs: estree.Node[] = [];
- return {
- CallExpression: (node: estree.Node) => {
- if (Mocha.isTestConstruct(node)) {
- constructs.push(node);
- return;
- }
- if (constructs.length > 0) {
- checkTimeoutDisabling(node as estree.CallExpression, context);
- }
- },
- 'CallExpression:exit': (node: estree.Node) => {
- if (Mocha.isTestConstruct(node)) {
- constructs.pop();
- }
- },
- };
- },
-};
-
-function checkTimeoutDisabling(node: estree.CallExpression, context: Rule.RuleContext) {
- if (isMethodCall(node) && node.arguments.length > 0) {
- const {
- callee: { object, property },
- arguments: [value],
- } = node;
- if (
- isThisExpression(object) &&
- isIdentifier(property, 'timeout') &&
- isDisablingTimeout(value, context)
- ) {
- context.report({
- message: MESSAGE,
- node: value,
- });
- }
- }
-}
-
-function isDisablingTimeout(timeout: estree.Node, context: Rule.RuleContext) {
- const usage = getUniqueWriteUsageOrNode(context, timeout);
- return isNumberLiteral(usage) && usage.value > MAX_DELAY_VALUE;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/dns-prefetching.ts b/eslint-bridge/src/linting/eslint/rules/dns-prefetching.ts
deleted file mode 100644
index 12e18784745..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/dns-prefetching.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5743/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { checkSensitiveCall, getFullyQualifiedName } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = 'Make sure allowing browsers to perform DNS prefetching is safe here.';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- if (fqn === 'helmet.dnsPrefetchControl') {
- checkSensitiveCall(context, callExpression, 0, 'allow', true, MESSAGE);
- }
- if (fqn === 'helmet') {
- checkSensitiveCall(context, callExpression, 0, 'dnsPrefetchControl', false, MESSAGE);
- }
- if (fqn === 'dns-prefetch-control') {
- checkSensitiveCall(context, callExpression, 0, 'allow', true, MESSAGE);
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/duplicates-in-character-class.ts b/eslint-bridge/src/linting/eslint/rules/duplicates-in-character-class.ts
deleted file mode 100644
index 61fd9f33306..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/duplicates-in-character-class.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5869/javascript
-
-import { Rule } from 'eslint';
-import { CharacterClass, Flags, Node, RegExpLiteral } from 'regexpp/ast';
-import { toEncodedMessage } from './helpers';
-import {
- createRegExpRule,
- getRegexpLocation,
- SimplifiedRegexCharacterClass,
-} from './helpers/regex';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = createRegExpRule(
- context => {
- let flags: Flags;
- return {
- onRegExpLiteralEnter: (node: RegExpLiteral) => {
- flags = node.flags;
- },
- onCharacterClassEnter: (node: CharacterClass) => {
- const duplicates = new Set();
- const characterClass = new SimplifiedRegexCharacterClass(flags);
- node.elements.forEach(element => {
- const intersections = new SimplifiedRegexCharacterClass(flags, element).findIntersections(
- characterClass,
- );
- if (intersections.length > 0) {
- intersections.forEach(intersection => duplicates.add(intersection));
- duplicates.add(element);
- }
- characterClass.add(element);
- });
- if (duplicates.size > 0) {
- const [primary, ...secondaries] = duplicates;
- context.reportRegExpNode({
- message: toEncodedMessage(
- 'Remove duplicates in this character class.',
- secondaries.map(snd => ({ loc: getRegexpLocation(context.node, snd, context) })),
- secondaries.map(_ => 'Additional duplicate'),
- ),
- node: context.node,
- regexpNode: primary,
- });
- }
- },
- };
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/empty-string-repetition.ts b/eslint-bridge/src/linting/eslint/rules/empty-string-repetition.ts
deleted file mode 100644
index d591133569b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/empty-string-repetition.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5842/javascript
-
-import { Rule } from 'eslint';
-import { Node, Quantifier } from 'regexpp/ast';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- return {
- onQuantifierEnter: (node: Quantifier) => {
- const { element } = node;
- if (matchEmptyString(element)) {
- context.reportRegExpNode({
- message: `Rework this part of the regex to not match the empty string.`,
- node: context.node,
- regexpNode: element,
- });
- }
- },
- };
-});
-
-function matchEmptyString(node: Node): boolean {
- switch (node.type) {
- case 'Alternative':
- return node.elements.every(matchEmptyString);
- case 'Assertion':
- return true;
- case 'CapturingGroup':
- case 'Group':
- case 'Pattern':
- return node.alternatives.some(matchEmptyString);
- case 'Quantifier':
- return node.min === 0;
- default:
- return false;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/encryption-secure-mode.ts b/eslint-bridge/src/linting/eslint/rules/encryption-secure-mode.ts
deleted file mode 100644
index efb9cb1b581..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/encryption-secure-mode.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5542/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName, getValueOfExpression } from './helpers';
-
-const aliases: string[] = [
- 'AES128',
- 'AES192',
- 'AES256',
- 'BF',
- 'blowfish',
- 'CAMELLIA128',
- 'CAMELLIA192',
- 'CAMELLIA256',
- 'CAST',
- 'DES',
- 'DES-EDE',
- 'DES-EDE3',
- 'DES3',
- 'DESX',
- 'RC2',
- 'RC2-40',
- 'RC2-64',
- 'RC2-128',
- 'SEED',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- useSecureMode: 'Use a secure mode and padding scheme.',
- },
- },
- create(context: Rule.RuleContext) {
- const patterns: RegExp[] = [new RegExp('CBC', 'i'), new RegExp('ECB', 'i')];
- aliases.forEach(alias => patterns.push(new RegExp(`^${alias}$`, 'i')));
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- if (getFullyQualifiedName(context, callExpression) !== 'crypto.createCipheriv') {
- return;
- }
- const sensitiveArgument = callExpression.arguments[0];
- const sensitiveArgumentValue = getValueOfExpression(context, sensitiveArgument, 'Literal');
- if (!sensitiveArgumentValue) {
- return;
- }
- const { value } = sensitiveArgumentValue;
- if (typeof value !== 'string') {
- return;
- }
- if (patterns.some(pattern => pattern.test(value))) {
- context.report({
- messageId: 'useSecureMode',
- node: sensitiveArgument,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/encryption.ts b/eslint-bridge/src/linting/eslint/rules/encryption.ts
deleted file mode 100644
index 500daf82d28..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/encryption.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4787/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isMemberWithProperty, getFullyQualifiedName } from './helpers';
-
-const getEncryptionRuleModule = (
- clientSideMethods: string[],
- serverSideMethods: string[],
-): Rule.RuleModule => ({
- meta: {
- messages: {
- safeEncryption: 'Make sure that encrypting data is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- // for client side
- let usingCryptoInFile = false;
-
- return {
- Program() {
- // init flag for each file
- usingCryptoInFile = false;
- },
-
- MemberExpression(node: estree.Node) {
- // detect 'SubtleCrypto' object
- // which can be retrieved by 'crypto.subtle' or 'window.crypto.subtle'
- const { object, property } = node as estree.MemberExpression;
- if (
- isIdentifier(property, 'subtle') &&
- (isIdentifier(object, 'crypto') || isMemberWithProperty(object, 'crypto'))
- ) {
- usingCryptoInFile = true;
- }
- },
-
- 'CallExpression:exit'(node: estree.Node) {
- const { callee } = node as estree.CallExpression;
-
- if (usingCryptoInFile) {
- // e.g.: crypto.subtle.encrypt()
- checkForClientSide(callee, context, clientSideMethods);
- }
-
- // e.g.
- // const crypto = require("crypto");
- // const cipher = crypto.createCipher(alg, key);
- checkForServerSide(callee, context, serverSideMethods);
- },
- };
- },
-});
-
-function checkForServerSide(
- callee: estree.Node,
- context: Rule.RuleContext,
- serverSideMethods: string[],
-) {
- const fqn = getFullyQualifiedName(context, callee);
- if (serverSideMethods.some(method => fqn === `crypto.${method}`)) {
- context.report({
- messageId: 'safeEncryption',
- node: callee,
- });
- }
-}
-
-function checkForClientSide(
- callee: estree.Node,
- context: Rule.RuleContext,
- clientSideMethods: string[],
-) {
- if (
- isIdentifier(callee, ...clientSideMethods) ||
- isMemberWithProperty(callee, ...clientSideMethods)
- ) {
- context.report({
- messageId: 'safeEncryption',
- node: callee,
- });
- }
-}
-
-const clientSideEncryptMethods = ['encrypt', 'decrypt'];
-const serverSideEncryptMethods = [
- 'createCipher',
- 'createCipheriv',
- 'createDecipher',
- 'createDecipheriv',
- 'publicEncrypt',
- 'publicDecrypt',
- 'privateEncrypt',
- 'privateDecrypt',
-];
-
-export const rule: Rule.RuleModule = getEncryptionRuleModule(
- clientSideEncryptMethods,
- serverSideEncryptMethods,
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/existing-groups.ts b/eslint-bridge/src/linting/eslint/rules/existing-groups.ts
deleted file mode 100644
index f708a7af298..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/existing-groups.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6328/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import { RegExpLiteral } from 'regexpp/ast';
-import { isRequiredParserServices } from './helpers';
-import {
- GroupReference,
- extractReferences,
- getParsedRegex,
- isStringReplaceCall,
-} from './helpers/regex';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- nonExistingGroup: 'Referencing non-existing group{{groups}}.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- CallExpression: (call: estree.CallExpression) => {
- if (isStringReplaceCall(call, services)) {
- const [pattern, substr] = call.arguments;
- const regex = getParsedRegex(pattern, context);
- if (regex !== null) {
- const groups = extractGroups(regex);
- const references = extractReferences(substr);
- const invalidReferences = references.filter(
- ref => !isReferencingExistingGroup(ref, groups),
- );
- if (invalidReferences.length > 0) {
- const groups = `${invalidReferences.length > 1 ? 's' : ''}: ${invalidReferences
- .map(ref => ref.raw)
- .join(', ')}`;
- context.report({
- node: substr,
- messageId: 'nonExistingGroup',
- data: {
- groups,
- },
- });
- }
- }
- }
- },
- };
- },
-};
-
-class CapturingGroups {
- private readonly names = new Set();
- private groups = 0;
-
- public add(name: string | null): void {
- if (name !== null) {
- this.names.add(name);
- }
- this.groups++;
- }
-
- public has(name: string): boolean {
- return this.names.has(name);
- }
-
- public count(): number {
- return this.groups;
- }
-}
-
-function extractGroups(regex: RegExpLiteral) {
- const groups = new CapturingGroups();
- regexpp.visitRegExpAST(regex, {
- onCapturingGroupEnter: group => groups.add(group.name),
- });
- return groups;
-}
-
-function isReferencingExistingGroup(reference: GroupReference, groups: CapturingGroups) {
- if (!isNaN(Number(reference.value))) {
- const index = Number(reference.value);
- return index >= 1 && index <= groups.count();
- } else {
- const name = reference.value;
- return groups.has(name);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/expression-complexity.ts b/eslint-bridge/src/linting/eslint/rules/expression-complexity.ts
deleted file mode 100644
index 8adad043fc8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/expression-complexity.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1067/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- { type: 'integer' },
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const [max] = context.options;
- const statementLevel: ExpressionComplexity[] = [new ExpressionComplexity()];
- return {
- '*': (node: estree.Node) => {
- const tree = node as TSESTree.Node;
- if (isConditionalLike(tree)) {
- const expr = statementLevel[statementLevel.length - 1];
- expr.incrementNestedExprLevel();
- expr.addOperator(getOperatorToken(tree, context));
- } else if (isScopeLike(tree)) {
- statementLevel.push(new ExpressionComplexity());
- }
- },
- '*:exit': (node: estree.Node) => {
- const tree = node as TSESTree.Node;
- if (isConditionalLike(tree)) {
- const expr = statementLevel[statementLevel.length - 1];
- expr.decrementNestedExprLevel();
- if (expr.isOnFirstExprLevel()) {
- const operators = expr.getComplexityOperators();
- if (operators.length > max) {
- reportIssue(tree, operators, max, context);
- }
- expr.resetExpressionComplexityOperators();
- }
- } else if (isScopeLike(tree)) {
- statementLevel.pop();
- }
- },
- };
- },
-};
-
-class ExpressionComplexity {
- nestedLevel = 0;
- operators: AST.Token[] = [];
-
- addOperator(operator: AST.Token) {
- this.operators.push(operator);
- }
-
- incrementNestedExprLevel() {
- this.nestedLevel++;
- }
-
- decrementNestedExprLevel() {
- this.nestedLevel--;
- }
-
- isOnFirstExprLevel() {
- return this.nestedLevel === 0;
- }
-
- getComplexityOperators() {
- return this.operators;
- }
-
- resetExpressionComplexityOperators() {
- this.operators = [];
- }
-}
-
-function isScopeLike(node: TSESTree.Node) {
- return (
- node.type === 'FunctionExpression' ||
- (node.type === 'FunctionDeclaration' && node.generator) ||
- node.type === 'ObjectExpression' ||
- node.type === 'CallExpression' ||
- node.type === 'JSXElement'
- );
-}
-
-function isConditionalLike(node: TSESTree.Node) {
- return node.type === 'ConditionalExpression' || node.type === 'LogicalExpression';
-}
-
-function getOperatorToken(node: TSESTree.Node, context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- if (node.type === 'ConditionalExpression') {
- return sourceCode.getTokenAfter(
- node.test as estree.Node,
- token => token.type === 'Punctuator' && token.value === '?',
- )!;
- } else {
- const expr = node as estree.LogicalExpression;
- return sourceCode.getTokenAfter(
- expr.left,
- token => token.type === 'Punctuator' && token.value === expr.operator,
- )!;
- }
-}
-
-function reportIssue(
- node: TSESTree.Node,
- operators: AST.Token[],
- max: number,
- context: Rule.RuleContext,
-) {
- const complexity = operators.length;
- const message = `Reduce the number of conditional operators (${complexity}) used in the expression (maximum allowed ${max}).`;
- const secondaryLocationsHolder = operators;
- const secondaryMessages = Array(complexity).fill('+1');
- const cost = complexity - max;
- context.report({
- node: node as estree.Node,
- message: toEncodedMessage(message, secondaryLocationsHolder, secondaryMessages, cost),
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/file-header.ts b/eslint-bridge/src/linting/eslint/rules/file-header.ts
deleted file mode 100644
index 20cd5df41bc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/file-header.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1451/javascript
-
-import { Rule } from 'eslint';
-
-let cached: {
- headerFormat: string;
- isRegularExpression: boolean;
- expectedLines?: string[];
- searchPattern?: RegExp;
- failedToCompile?: boolean;
-};
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- fixHeader: 'Add or update the header of this file.',
- },
- },
- create(context: Rule.RuleContext) {
- updateCache(context.options);
-
- if (cached.failedToCompile) {
- // don't visit anything
- return {};
- }
-
- return {
- 'Program:exit': function () {
- if (cached.isRegularExpression) {
- checkRegularExpression(cached.searchPattern!, context);
- } else {
- checkPlainText(cached.expectedLines!, context);
- }
- },
- };
- },
-};
-
-function checkPlainText(expectedLines: string[], context: Rule.RuleContext) {
- let matches = false;
- const lines = context.getSourceCode().lines;
-
- if (expectedLines.length <= lines.length) {
- matches = true;
-
- let i = 0;
- for (const expectedLine of expectedLines) {
- const line = lines[i];
- i++;
- if (line !== expectedLine) {
- matches = false;
- break;
- }
- }
- }
-
- if (!matches) {
- addFileIssue(context);
- }
-}
-
-function checkRegularExpression(searchPattern: RegExp, context: Rule.RuleContext) {
- const fileContent = context.getSourceCode().getText();
- const match = searchPattern.exec(fileContent);
- if (!match || match.index !== 0) {
- addFileIssue(context);
- }
-}
-
-function addFileIssue(context: Rule.RuleContext) {
- context.report({
- messageId: 'fixHeader',
- loc: { line: 0, column: 0 },
- });
-}
-
-function updateCache(options: any[]) {
- const [{ headerFormat, isRegularExpression }] = options;
-
- if (
- !cached ||
- cached.headerFormat !== headerFormat ||
- cached.isRegularExpression !== isRegularExpression
- ) {
- cached = {
- headerFormat,
- isRegularExpression,
- };
-
- if (isRegularExpression) {
- try {
- cached.searchPattern = new RegExp(headerFormat, 's');
- cached.failedToCompile = false;
- } catch (e) {
- console.error(`Failed to compile regular expression for rule S1451 (${e.message})`);
- cached.failedToCompile = true;
- }
- } else {
- cached.expectedLines = headerFormat.split(/(?:\r)?\n|\r/);
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/file-name-differ-from-class.ts b/eslint-bridge/src/linting/eslint/rules/file-name-differ-from-class.ts
deleted file mode 100644
index 8f0bdb7d1c0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/file-name-differ-from-class.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3317/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import path from 'path';
-import { getVariableFromName } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- renameFile: 'Rename this file to "{{exported}}"',
- },
- },
- create(context: Rule.RuleContext) {
- let isOnlyExport = true;
- let nameOfExported: string | undefined = undefined;
-
- return {
- ExportDefaultDeclaration: (node: estree.Node) => {
- const declaration = (node as estree.ExportDefaultDeclaration).declaration;
- if (declaration.type === 'Identifier') {
- const variable = getVariableFromName(context, declaration.name);
- if (variable && variable.defs.length === 1) {
- const def = variable.defs[0];
- if (def.type === 'ClassName' || def.type === 'FunctionName' || isConst(def)) {
- nameOfExported = declaration.name;
- }
- }
- } else if (
- declaration.type === 'ClassDeclaration' ||
- declaration.type === 'FunctionDeclaration'
- ) {
- if (declaration.id) {
- nameOfExported = declaration.id.name;
- }
- }
- },
- 'ExportAllDeclaration, ExportNamedDeclaration': () => {
- isOnlyExport = false;
- },
- 'Program:exit': () => {
- if (isOnlyExport && nameOfExported) {
- const fileName = path.parse(context.getFilename()).name;
- if (
- 'index' !== fileName &&
- !sameName(nameOfExported, fileName) &&
- !sameName(nameOfExported, sliceOffPostfix(fileName))
- ) {
- context.report({
- messageId: 'renameFile',
- data: {
- exported: nameOfExported,
- },
- loc: { line: 0, column: 0 },
- });
- }
- }
- },
- };
- },
-};
-
-function sameName(nameOfExported: string, fileName: string) {
- const normalizedFileName = fileName.replace(/_/g, '').replace(/-/g, '').replace(/\./g, '');
- const normalizedNameOfExported = nameOfExported.replace(/_/g, '').replace(/-/g, '');
- return normalizedNameOfExported.toLowerCase() === normalizedFileName.toLowerCase();
-}
-
-function isConst(def: Scope.Definition) {
- return def.type === 'Variable' && def.parent && def.parent.kind === 'const';
-}
-
-function sliceOffPostfix(fileName: string) {
- return fileName.slice(0, fileName.lastIndexOf('.'));
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/file-permissions.ts b/eslint-bridge/src/linting/eslint/rules/file-permissions.ts
deleted file mode 100644
index 0c4659fbafd..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/file-permissions.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2612/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isIdentifier,
- isMemberExpression,
- getUniqueWriteUsage,
- getFullyQualifiedName,
-} from './helpers';
-
-const chmodLikeFunction = ['chmod', 'chmodSync', 'fchmod', 'fchmodSync', 'lchmod', 'lchmodSync'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safePermission: 'Make sure this permission is safe.',
- },
- },
- create(context: Rule.RuleContext) {
- function isChmodLikeFunction(node: estree.CallExpression) {
- const { callee } = node;
- if (callee.type !== 'MemberExpression') {
- return false;
- }
- // to support fs promises we are only checking the name of the function
- return isIdentifier(callee.property, ...chmodLikeFunction);
- }
-
- function modeFromLiteral(modeExpr: estree.Literal) {
- const modeValue = modeExpr.value;
- let mode = null;
- if (typeof modeValue === 'string') {
- mode = Number.parseInt(modeValue, 8);
- } else if (typeof modeValue === 'number') {
- const raw = modeExpr.raw;
- // ts parser interprets number starting with 0 as decimal, we need to parse it as octal value
- if (raw && raw.startsWith('0') && !raw.startsWith('0o')) {
- mode = Number.parseInt(raw, 8);
- } else {
- mode = modeValue;
- }
- }
- return mode;
- }
-
- // fs.constants have these value only when running on linux, we need to hardcode them to be able to test on win
- const FS_CONST: Record = {
- S_IRWXU: 0o700,
- S_IRUSR: 0o400,
- S_IWUSR: 0o200,
- S_IXUSR: 0o100,
- S_IRWXG: 0o70,
- S_IRGRP: 0o40,
- S_IWGRP: 0o20,
- S_IXGRP: 0o10,
- S_IRWXO: 0o7,
- S_IROTH: 0o4,
- S_IWOTH: 0o2,
- S_IXOTH: 0o1,
- };
-
- function modeFromMemberExpression(modeExpr: estree.MemberExpression): number | null {
- const { object, property } = modeExpr;
- if (isMemberExpression(object, 'fs', 'constants') && property.type === 'Identifier') {
- return FS_CONST[property.name];
- }
- return null;
- }
-
- function modeFromExpression(
- expr: estree.Node | undefined,
- visited: Set,
- ): number | null {
- if (!expr) {
- return null;
- }
- if (expr.type === 'MemberExpression') {
- return modeFromMemberExpression(expr);
- } else if (expr.type === 'Literal') {
- return modeFromLiteral(expr);
- } else if (expr.type === 'Identifier') {
- const usage = getUniqueWriteUsage(context, expr.name);
- if (usage && !visited.has(usage)) {
- visited.add(usage);
- return modeFromExpression(usage, visited);
- }
- } else if (expr.type === 'BinaryExpression') {
- const { left, operator, right } = expr;
- if (operator === '|') {
- const leftValue = modeFromExpression(left, visited);
- const rightValue = modeFromExpression(right, visited);
- if (leftValue && rightValue) {
- return leftValue | rightValue;
- }
- }
- }
- return null;
- }
-
- function checkModeArgument(node: estree.Node, moduloTest: number) {
- const visited = new Set();
- const mode = modeFromExpression(node, visited);
- if (mode !== null && !isNaN(mode) && mode % 8 !== moduloTest) {
- context.report({
- node,
- messageId: 'safePermission',
- });
- }
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- if (isChmodLikeFunction(callExpression)) {
- checkModeArgument(callExpression.arguments[0], 0);
- checkModeArgument(callExpression.arguments[1], 0);
- } else if (getFullyQualifiedName(context, callExpression) === 'process.umask') {
- checkModeArgument(callExpression.arguments[0], 7);
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/file-uploads.ts b/eslint-bridge/src/linting/eslint/rules/file-uploads.ts
deleted file mode 100644
index 9e84af887fb..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/file-uploads.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2598/javascript
-
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import {
- getLhsVariable,
- getValueOfExpression,
- getObjectExpressionProperty,
- getVariableFromName,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const FORMIDABLE_MODULE = 'formidable';
-const KEEP_EXTENSIONS = 'keepExtensions';
-const UPLOAD_DIR = 'uploadDir';
-
-const MULTER_MODULE = 'multer';
-const STORAGE_OPTION = 'storage';
-const DESTINATION_OPTION = 'destination';
-
-const formidableObjects: Map<
- Scope.Variable,
- { uploadDirSet: boolean; keepExtensions: boolean; callExpression: estree.CallExpression }
-> = new Map();
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression(node: estree.Node) {
- checkCallExpression(context, node as estree.NewExpression);
- },
- CallExpression(node: estree.Node) {
- checkCallExpression(context, node as estree.CallExpression);
- },
- AssignmentExpression(node: estree.Node) {
- visitAssignment(context, node as estree.AssignmentExpression);
- },
- Program() {
- formidableObjects.clear();
- },
- 'Program:exit'() {
- formidableObjects.forEach(value =>
- report(context, value.uploadDirSet, value.keepExtensions, value.callExpression),
- );
- },
- };
- },
-};
-
-function checkCallExpression(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- const { callee } = callExpression;
- if (callee.type !== 'Identifier') {
- return;
- }
-
- const fqn = getFullyQualifiedName(context, callee);
- if (!fqn) {
- return;
- }
- const [moduleName] = fqn.split('.');
-
- if (moduleName === FORMIDABLE_MODULE) {
- checkFormidable(context, callExpression);
- }
-
- if (moduleName === MULTER_MODULE) {
- checkMulter(context, callExpression);
- }
-}
-
-function checkFormidable(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- if (callExpression.arguments.length === 0) {
- const formVariable = getLhsVariable(context);
- if (formVariable) {
- formidableObjects.set(formVariable, {
- uploadDirSet: false,
- keepExtensions: false,
- callExpression,
- });
- }
- return;
- }
-
- const options = getValueOfExpression(context, callExpression.arguments[0], 'ObjectExpression');
- if (options) {
- report(
- context,
- !!getObjectExpressionProperty(options, UPLOAD_DIR),
- keepExtensionsValue(getObjectExpressionProperty(options, KEEP_EXTENSIONS)?.value),
- callExpression,
- );
- }
-}
-
-function checkMulter(context: Rule.RuleContext, callExpression: estree.CallExpression) {
- if (callExpression.arguments.length === 0) {
- return;
- }
- const multerOptions = getValueOfExpression(
- context,
- callExpression.arguments[0],
- 'ObjectExpression',
- );
-
- if (!multerOptions) {
- return;
- }
-
- const storagePropertyValue = getObjectExpressionProperty(multerOptions, STORAGE_OPTION)?.value;
- if (storagePropertyValue) {
- const storageValue = getValueOfExpression(context, storagePropertyValue, 'CallExpression');
-
- if (storageValue) {
- const diskStorageCallee = getDiskStorageCalleeIfUnsafeStorage(context, storageValue);
- if (diskStorageCallee) {
- report(context, false, false, callExpression, {
- node: diskStorageCallee,
- message: 'no destination specified',
- });
- }
- }
- }
-}
-
-function getDiskStorageCalleeIfUnsafeStorage(
- context: Rule.RuleContext,
- storageCreation: estree.CallExpression,
-) {
- const { arguments: args, callee } = storageCreation;
- if (args.length > 0 && isMemberWithProperty(callee, 'diskStorage')) {
- const storageOptions = getValueOfExpression(context, args[0], 'ObjectExpression');
- if (storageOptions && !getObjectExpressionProperty(storageOptions, DESTINATION_OPTION)) {
- return callee;
- }
- }
-
- return false;
-}
-
-function isMemberWithProperty(expr: estree.Node, property: string) {
- return (
- expr.type === 'MemberExpression' &&
- expr.property.type === 'Identifier' &&
- expr.property.name === property
- );
-}
-
-function keepExtensionsValue(extensionValue?: estree.Node): boolean {
- if (
- extensionValue &&
- extensionValue.type === 'Literal' &&
- typeof extensionValue.value === 'boolean'
- ) {
- return extensionValue.value;
- }
-
- return false;
-}
-
-function visitAssignment(context: Rule.RuleContext, assignment: estree.AssignmentExpression) {
- const variableProperty = getVariablePropertyFromAssignment(context, assignment);
- if (!variableProperty) {
- return;
- }
-
- const { objectVariable, property } = variableProperty;
-
- if (formidableObjects.has(objectVariable)) {
- const formOptions = formidableObjects.get(objectVariable)!;
- if (property === UPLOAD_DIR) {
- formOptions.uploadDirSet = true;
- }
-
- if (property === KEEP_EXTENSIONS) {
- formOptions.keepExtensions = keepExtensionsValue(assignment.right);
- }
- }
-}
-
-/**
- * for `x.foo = 42` returns 'x' variable and 'foo' property string
- */
-export function getVariablePropertyFromAssignment(
- context: Rule.RuleContext,
- assignment: estree.AssignmentExpression,
-): { objectVariable: Scope.Variable; property: string } | undefined {
- if (assignment.left.type !== 'MemberExpression') {
- return undefined;
- }
-
- const memberExpr = assignment.left;
- if (memberExpr.object.type === 'Identifier' && memberExpr.property.type === 'Identifier') {
- const objectVariable = getVariableFromName(context, memberExpr.object.name);
- if (objectVariable) {
- return { objectVariable, property: memberExpr.property.name };
- }
- }
-
- return undefined;
-}
-
-function report(
- context: Rule.RuleContext,
- uploadDirSet: boolean,
- keepExtensions: boolean,
- callExpression: estree.CallExpression,
- secondaryLocation?: { node: estree.Node; message: string },
-) {
- let message;
-
- if (keepExtensions && uploadDirSet) {
- message = 'Restrict the extension of uploaded files.';
- } else if (!keepExtensions && !uploadDirSet) {
- message = 'Restrict folder destination of uploaded files.';
- } else if (keepExtensions && !uploadDirSet) {
- message = 'Restrict the extension and folder destination of uploaded files.';
- }
-
- if (message) {
- if (secondaryLocation) {
- message = toEncodedMessage(
- message,
- [secondaryLocation.node as TSESTree.Node],
- [secondaryLocation.message],
- );
- } else {
- message = toEncodedMessage(message, []);
- }
-
- context.report({
- message,
- node: callExpression.callee,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/fixme-tag.ts b/eslint-bridge/src/linting/eslint/rules/fixme-tag.ts
deleted file mode 100644
index 636e9f65764..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/fixme-tag.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1134/javascript
-
-import { Rule } from 'eslint';
-import { reportPatternInComment } from './todo-tag';
-
-const fixmePattern = 'fixme';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- fixme: 'Take the required action to fix the issue indicated by this comment.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'Program:exit': () => {
- reportPatternInComment(context, fixmePattern, 'fixme');
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/for-in.ts b/eslint-bridge/src/linting/eslint/rules/for-in.ts
deleted file mode 100644
index 4ed5fd64635..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/for-in.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1535/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- restrictLoop: 'Restrict what this loop acts on by testing each property.',
- },
- },
- create(context: Rule.RuleContext) {
- function isAttrCopy(statement: estree.Node) {
- if (statement.type !== 'ExpressionStatement') {
- return false;
- }
- const expression = statement.expression;
- return (
- expression.type === 'AssignmentExpression' &&
- expression.left.type === 'MemberExpression' &&
- expression.left.computed
- );
- }
-
- return {
- ForInStatement(node) {
- const forInStatement = node as estree.ForInStatement;
- const body = forInStatement.body;
-
- if (body.type === 'BlockStatement') {
- if (body.body.length === 0) {
- return;
- }
- const firstStatement = body.body[0];
- if (firstStatement.type === 'IfStatement' || isAttrCopy(firstStatement)) {
- return;
- }
- }
-
- if (body.type === 'EmptyStatement' || body.type === 'IfStatement' || isAttrCopy(body)) {
- return;
- }
-
- context.report({
- node: forInStatement,
- messageId: 'restrictLoop',
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/for-loop-increment-sign.ts b/eslint-bridge/src/linting/eslint/rules/for-loop-increment-sign.ts
deleted file mode 100644
index a51339565cb..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/for-loop-increment-sign.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2251/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { toEncodedMessage } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- ForStatement: (node: estree.Node) => {
- const forStatement: estree.ForStatement = node as estree.ForStatement;
- const test = forStatement.test;
- const loopIncrement: ForLoopIncrement | null =
- ForLoopIncrement.findInLoopUpdate(forStatement);
- if (test == null || loopIncrement == null || forStatement.update == null) {
- return;
- }
- const wrongDirection = getWrongDirection(test, loopIncrement);
- if (wrongDirection !== 0 && wrongDirection === loopIncrement.direction) {
- const movement: string = wrongDirection > 0 ? 'incremented' : 'decremented';
- const message = toEncodedMessage(
- `"${loopIncrement.identifier.name}" is ${movement} and will never reach its stop condition.`,
- [test as TSESTree.Node],
- );
- context.report({
- message,
- node: forStatement.update,
- });
- }
- },
- };
- },
-};
-
-class ForLoopIncrement {
- increment: estree.Expression;
- identifier: estree.Identifier;
- direction: number;
-
- constructor(increment: estree.Expression, identifier: estree.Identifier, direction: number) {
- this.increment = increment;
- this.identifier = identifier;
- this.direction = direction;
- }
-
- static findInLoopUpdate(forStatement: estree.ForStatement) {
- let result = null;
- const expression = forStatement.update;
- if (!expression) {
- return null;
- }
- if (expression.type === 'UpdateExpression') {
- const updateExpression: estree.UpdateExpression = expression;
- const direction: number = updateExpression.operator === '++' ? 1 : -1;
- result = ForLoopIncrement.increment(updateExpression, updateExpression.argument, direction);
- }
- if (expression.type === 'AssignmentExpression') {
- const assignmentExpression: estree.AssignmentExpression = expression;
- if (
- assignmentExpression.operator === '+=' &&
- assignmentExpression.left.type === 'Identifier'
- ) {
- result = ForLoopIncrement.increment(
- expression,
- assignmentExpression.left,
- directionFromValue(assignmentExpression.right),
- );
- }
- if (
- assignmentExpression.operator === '-=' &&
- assignmentExpression.left.type === 'Identifier'
- ) {
- result = ForLoopIncrement.increment(
- expression,
- assignmentExpression.left,
- -directionFromValue(assignmentExpression.right),
- );
- }
- if (assignmentExpression.operator === '=') {
- result = ForLoopIncrement.assignmentIncrement(assignmentExpression);
- }
- }
- return result;
- }
-
- private static increment(
- increment: estree.Expression,
- expression: estree.Expression,
- direction: number,
- ) {
- if (expression.type === 'Identifier') {
- return new ForLoopIncrement(increment, expression, direction);
- }
- return null;
- }
-
- private static assignmentIncrement(assignmentExpression: estree.AssignmentExpression) {
- const lhs = assignmentExpression.left;
- const rhs = assignmentExpression.right;
- if (
- lhs.type === 'Identifier' &&
- rhs.type === 'BinaryExpression' &&
- (rhs.operator === '+' || rhs.operator === '-')
- ) {
- let incrementDirection = directionFromValue(rhs.right);
- if (incrementDirection !== null && isSameIdentifier(rhs.left, lhs)) {
- incrementDirection = rhs.operator === '-' ? -incrementDirection : incrementDirection;
- return ForLoopIncrement.increment(assignmentExpression, lhs, incrementDirection);
- }
- }
- return null;
- }
-}
-
-function directionFromValue(expression: estree.Expression): number {
- if (expression.type === 'Literal') {
- const value = Number(expression.raw);
- if (isNaN(value) || value === 0) {
- return 0;
- }
- return value > 0 ? 1 : -1;
- }
- if (expression.type === 'UnaryExpression') {
- const unaryExpression: estree.UnaryExpression = expression;
- if (unaryExpression.operator === '+') {
- return directionFromValue(unaryExpression.argument);
- }
- if (unaryExpression.operator === '-') {
- return -directionFromValue(unaryExpression.argument);
- }
- }
- return 0;
-}
-
-function getWrongDirection(
- condition: estree.Expression,
- forLoopIncrement: ForLoopIncrement,
-): number {
- if (condition.type !== 'BinaryExpression') {
- return 0;
- }
- if (isSameIdentifier(condition.left, forLoopIncrement.identifier)) {
- if (condition.operator === '<' || condition.operator === '<=') {
- return -1;
- }
- if (condition.operator === '>' || condition.operator === '>=') {
- return +1;
- }
- } else if (isSameIdentifier(condition.right, forLoopIncrement.identifier)) {
- if (condition.operator === '<' || condition.operator === '<=') {
- return +1;
- }
- if (condition.operator === '>' || condition.operator === '>=') {
- return -1;
- }
- }
- return 0;
-}
-
-function isSameIdentifier(expression: estree.Expression, identifier: estree.Identifier) {
- return expression.type === 'Identifier' && expression.name === identifier.name;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/frame-ancestors.ts b/eslint-bridge/src/linting/eslint/rules/frame-ancestors.ts
deleted file mode 100644
index 7eb840db629..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/frame-ancestors.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5732/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, getFullyQualifiedName, getObjectExpressionProperty } from './helpers';
-
-const HELMET = 'helmet';
-const HELMET_CSP = 'helmet-csp';
-const DIRECTIVES = 'directives';
-const NONE = "'none'";
-const CONTENT_SECURITY_POLICY = 'contentSecurityPolicy';
-const FRAME_ANCESTORS_CAMEL = 'frameAncestors';
-const FRAME_ANCESTORS_HYPHEN = 'frame-ancestors';
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findDirectivesWithSensitiveFrameAncestorsPropertyFromHelmet,
- `Make sure disabling content security policy frame-ancestors directive is safe here.`,
-);
-
-function findDirectivesWithSensitiveFrameAncestorsPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- const { arguments: args } = node;
- if (isValidHelmetModuleCall(context, node) && args.length === 1) {
- const [options] = args;
- const maybeDirectives = getObjectExpressionProperty(options, DIRECTIVES);
- if (maybeDirectives) {
- const maybeFrameAncestors = getFrameAncestorsProperty(maybeDirectives);
- if (!maybeFrameAncestors) {
- return [maybeDirectives];
- }
- if (isSetNoneFrameAncestorsProperty(maybeFrameAncestors)) {
- return [maybeFrameAncestors];
- }
- }
- }
- return [];
-}
-
-function isValidHelmetModuleCall(context: Rule.RuleContext, callExpr: estree.CallExpression) {
- /* csp(options) or helmet.contentSecurityPolicy(options) */
- const fqn = getFullyQualifiedName(context, callExpr);
- return fqn === HELMET_CSP || fqn === `${HELMET}.${CONTENT_SECURITY_POLICY}`;
-}
-
-function isSetNoneFrameAncestorsProperty(frameAncestors: estree.Property): boolean {
- const { value } = frameAncestors;
- return (
- value.type === 'ArrayExpression' &&
- Boolean(
- value.elements.find(
- v => v?.type === 'Literal' && typeof v.value === 'string' && v.value === NONE,
- ),
- )
- );
-}
-
-function getFrameAncestorsProperty(directives: estree.Property): estree.Property | undefined {
- const propertyKeys = [FRAME_ANCESTORS_CAMEL, FRAME_ANCESTORS_HYPHEN];
- for (const propertyKey of propertyKeys) {
- const maybeProperty = getObjectExpressionProperty(directives.value, propertyKey);
- if (maybeProperty) {
- return maybeProperty;
- }
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/function-inside-loop.ts b/eslint-bridge/src/linting/eslint/rules/function-inside-loop.ts
deleted file mode 100644
index a11e02ebd93..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/function-inside-loop.ts
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1515/javascript
-
-import { AST, Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import {
- findFirstMatchingAncestor,
- getParent,
- LoopLike,
- RuleContext,
- toEncodedMessage,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const message = 'Make sure this function is not called after the loop completes.';
-
-const loopLike = 'WhileStatement,DoWhileStatement,ForStatement,ForOfStatement,ForInStatement';
-
-const functionLike = 'FunctionDeclaration,FunctionExpression,ArrowFunctionExpression';
-
-const allowedCallbacks = [
- 'replace',
- 'forEach',
- 'filter',
- 'map',
- 'find',
- 'findIndex',
- 'every',
- 'some',
- 'reduce',
- 'reduceRight',
- 'sort',
- 'each',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- function getLocalEnclosingLoop(node: estree.Node) {
- return findFirstMatchingAncestor(node as TSESTree.Node, n => loopLike.includes(n.type));
- }
-
- return {
- [functionLike]: (node: estree.Node) => {
- const loopNode = getLocalEnclosingLoop(node) as LoopLike;
- if (loopNode) {
- if (
- !isIIEF(node, context) &&
- !isAllowedCallbacks(context) &&
- context.getScope().through.some(ref => !isSafe(ref, loopNode))
- ) {
- context.report({
- message: toEncodedMessage(message, [getMainLoopToken(loopNode, context)]),
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
- }
- },
- };
- },
-};
-
-function isIIEF(node: estree.Node, context: Rule.RuleContext) {
- const parent = getParent(context);
- return (
- parent &&
- ((parent.type === 'CallExpression' && parent.callee === node) ||
- (parent.type === 'MemberExpression' && parent.object === node))
- );
-}
-
-function isAllowedCallbacks(context: Rule.RuleContext) {
- const parent = getParent(context);
- if (parent && parent.type === 'CallExpression') {
- const callee = parent.callee;
- if (callee.type === 'MemberExpression') {
- return (
- callee.property.type === 'Identifier' && allowedCallbacks.includes(callee.property.name)
- );
- }
- }
- return false;
-}
-
-function isSafe(ref: Scope.Reference, loopNode: LoopLike) {
- const variable = ref.resolved;
- if (variable) {
- const definition = variable.defs[0];
- const declaration = definition && definition.parent;
- const kind = declaration && declaration.type === 'VariableDeclaration' ? declaration.kind : '';
-
- if (kind !== 'let' && kind !== 'const') {
- return hasConstValue(variable, loopNode);
- }
- }
-
- return true;
-}
-
-function hasConstValue(variable: Scope.Variable, loopNode: LoopLike): boolean {
- for (const ref of variable.references) {
- if (ref.isWrite()) {
- //Check if write is in the scope of the loop
- if (ref.from.type === 'block' && ref.from.block === loopNode.body) {
- return false;
- }
-
- const refRange = ref.identifier.range;
- const range = getLoopTestRange(loopNode);
- //Check if value change in the header of the loop
- if (refRange && range && refRange[0] >= range[0] && refRange[1] <= range[1]) {
- return false;
- }
- }
- }
- return true;
-}
-
-function getLoopTestRange(loopNode: LoopLike) {
- const bodyRange = loopNode.body.range;
- if (bodyRange) {
- switch (loopNode.type) {
- case 'ForStatement':
- if (loopNode.test && loopNode.test.range) {
- return [loopNode.test.range[0], bodyRange[0]];
- }
- break;
- case 'WhileStatement':
- case 'DoWhileStatement':
- return loopNode.test.range;
- case 'ForOfStatement':
- case 'ForInStatement':
- const leftRange = loopNode.range;
- if (leftRange) {
- return [leftRange[0], bodyRange[0]];
- }
- }
- }
-}
-
-function getMainLoopToken(loop: LoopLike, context: Rule.RuleContext): AST.Token {
- const sourceCode = context.getSourceCode();
- let token: AST.Token | null;
- switch (loop.type) {
- case 'WhileStatement':
- case 'DoWhileStatement':
- token = sourceCode.getTokenBefore(
- loop.test,
- t => t.type === 'Keyword' && t.value === 'while',
- );
- break;
- case 'ForStatement':
- case 'ForOfStatement':
- default:
- token = sourceCode.getFirstToken(loop, t => t.type === 'Keyword' && t.value === 'for');
- }
- return token!;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/function-name.ts b/eslint-bridge/src/linting/eslint/rules/function-name.ts
deleted file mode 100644
index 1693054e631..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/function-name.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S100/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { last, functionLike } from './helpers';
-
-interface FunctionKnowledge {
- node: estree.Identifier;
- func: estree.Function;
- returnsJSX: boolean;
-}
-
-const functionExitSelector = [
- ':matches(',
- ['FunctionExpression', 'ArrowFunctionExpression', 'FunctionDeclaration'].join(','),
- ')',
- ':exit',
-].join('');
-
-const functionExpressionProperty = [
- 'Property',
- '[key.type="Identifier"]',
- ':matches(',
- ['[value.type="FunctionExpression"]', '[value.type="ArrowFunctionExpression"]'].join(','),
- ')',
-].join('');
-
-const functionExpressionVariable = [
- 'VariableDeclarator',
- '[id.type="Identifier"]',
- ':matches(',
- ['[init.type="FunctionExpression"]', '[init.type="ArrowFunctionExpression"]'].join(','),
- ')',
-].join('');
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- renameFunction:
- "Rename this '{{function}}' function to match the regular expression '{{format}}'.",
- },
- },
- create(context: Rule.RuleContext) {
- const [{ format }] = context.options;
- const knowledgeStack: FunctionKnowledge[] = [];
- return {
- [functionExpressionProperty]: (node: estree.Property) => {
- knowledgeStack.push({
- node: node.key as estree.Identifier,
- func: node.value as estree.Function,
- returnsJSX: returnsJSX(node.value as estree.Function),
- });
- },
- [functionExpressionVariable]: (node: estree.VariableDeclarator) => {
- knowledgeStack.push({
- node: node.id as estree.Identifier,
- func: node.init as estree.Function,
- returnsJSX: returnsJSX(node.init as estree.Function),
- });
- },
- 'MethodDefinition[key.type="Identifier"]': (node: estree.MethodDefinition) => {
- knowledgeStack.push({
- node: node.key as estree.Identifier,
- func: node.value as estree.Function,
- returnsJSX: false,
- });
- },
- 'FunctionDeclaration[id.type="Identifier"]': (node: estree.FunctionDeclaration) => {
- knowledgeStack.push({
- node: node.id as estree.Identifier,
- func: node as estree.Function,
- returnsJSX: false,
- });
- },
- [functionExitSelector]: (func: estree.Function) => {
- if (func === last(knowledgeStack)?.func) {
- const knowledge = knowledgeStack.pop();
- if (knowledge && !knowledge.returnsJSX) {
- const { node } = knowledge;
- if (!node.name.match(format)) {
- context.report({
- messageId: 'renameFunction',
- data: {
- function: node.name,
- format,
- },
- node,
- });
- }
- }
- }
- },
- ReturnStatement: (node: estree.ReturnStatement) => {
- const knowledge = last(knowledgeStack);
- const ancestors = context.getAncestors();
-
- for (let i = ancestors.length - 1; i >= 0; i--) {
- if (functionLike.has(ancestors[i].type)) {
- const enclosingFunction = ancestors[i];
- if (
- knowledge &&
- knowledge.func === enclosingFunction &&
- node.argument &&
- (node.argument as any).type.startsWith('JSX')
- ) {
- knowledge.returnsJSX = true;
- }
- return;
- }
- }
- },
- };
- },
-};
-
-//handling arrow functions without return statement
-function returnsJSX(node: estree.Function) {
- return (node.body as any).type.startsWith('JSX');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/function-return-type.ts b/eslint-bridge/src/linting/eslint/rules/function-return-type.ts
deleted file mode 100644
index eec00ff9d32..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/function-return-type.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3800/javascript
-
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import {
- getParent,
- getTypeFromTreeNode,
- isAny,
- isRequiredParserServices,
- RuleContext,
- toEncodedMessage,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-class FunctionScope {
- private readonly returnStatements: estree.ReturnStatement[] = [];
-
- getReturnStatements() {
- return this.returnStatements.slice();
- }
-
- addReturnStatement(node: estree.ReturnStatement) {
- this.returnStatements.push(node);
- }
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let scopes: FunctionScope[] = [];
-
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- const checker = services.program.getTypeChecker();
-
- function onFunctionExit(node: estree.Node) {
- const returnStatements = scopes.pop()!.getReturnStatements();
- if (returnStatements.every(retStmt => retStmt.argument?.type === 'ThisExpression')) {
- return;
- }
- const signature = checker.getSignatureFromDeclaration(
- services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node) as ts.SignatureDeclaration,
- );
- if (signature && hasMultipleReturnTypes(signature, checker)) {
- const stmts = returnStatements.filter(
- retStmt => !isNullLike(getTypeFromTreeNode(retStmt.argument!, services)),
- );
- const stmtsTypes = stmts.map(retStmt => getTypeFromTreeNode(retStmt.argument!, services));
- if (stmtsTypes.every(isAny)) {
- return;
- }
- context.report({
- message: toEncodedMessage(
- 'Refactor this function to always return the same type.',
- stmts,
- stmtsTypes.map(stmtType => `Returns ${prettyPrint(stmtType, checker)}`),
- ),
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
- }
-
- return {
- ReturnStatement: (node: estree.Node) => {
- const retStmt = node as estree.ReturnStatement;
- if (scopes.length > 0 && retStmt.argument) {
- scopes[scopes.length - 1].addReturnStatement(retStmt);
- }
- },
- ':function': () => {
- scopes.push(new FunctionScope());
- },
- ':function:exit': onFunctionExit,
- 'Program:exit': () => {
- scopes = [];
- },
- };
- },
-};
-
-function hasMultipleReturnTypes(signature: ts.Signature, checker: ts.TypeChecker) {
- const returnType = checker.getBaseTypeOfLiteralType(checker.getReturnTypeOfSignature(signature));
- return isMixingTypes(returnType, checker) && !hasReturnTypeJSDoc(signature);
-}
-
-function isMixingTypes(type: ts.Type, checker: ts.TypeChecker): boolean {
- return (
- type.isUnion() &&
- type.types
- .filter(tp => !isNullLike(tp))
- .map(tp => prettyPrint(tp, checker))
- .filter(distinct).length > 1
- );
-}
-
-function hasReturnTypeJSDoc(signature: ts.Signature) {
- return signature.getJsDocTags().some(tag => ['return', 'returns'].includes(tag.name));
-}
-
-function isObjectLikeType(type: ts.Type) {
- return !!(type.getFlags() & ts.TypeFlags.Object);
-}
-
-function distinct(value: T, index: number, self: T[]) {
- return self.indexOf(value) === index;
-}
-
-function prettyPrint(type: ts.Type, checker: ts.TypeChecker): string {
- if (type.isUnionOrIntersection()) {
- const delimiter = type.isUnion() ? ' | ' : ' & ';
- return type.types
- .map(tp => prettyPrint(tp, checker))
- .filter(distinct)
- .join(delimiter);
- }
- const typeNode = checker.typeToTypeNode(type, undefined, undefined);
- if (typeNode !== undefined) {
- if (ts.isFunctionTypeNode(typeNode)) {
- return 'function';
- }
- if (ts.isArrayTypeNode(typeNode) || isTypedArray(type, checker)) {
- return 'array';
- }
- }
- if (isObjectLikeType(type)) {
- return 'object';
- }
- return checker.typeToString(checker.getBaseTypeOfLiteralType(type));
-}
-
-function isTypedArray(type: ts.Type, checker: ts.TypeChecker) {
- return checker.typeToString(type).endsWith('Array');
-}
-
-function isNullLike(type: ts.Type) {
- return (
- (type.flags & ts.TypeFlags.Null) !== 0 ||
- (type.flags & ts.TypeFlags.Void) !== 0 ||
- (type.flags & ts.TypeFlags.Undefined) !== 0
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/future-reserved-words.ts b/eslint-bridge/src/linting/eslint/rules/future-reserved-words.ts
deleted file mode 100644
index 354ab9170ee..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/future-reserved-words.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1527/javascript
-
-import { Rule, Scope } from 'eslint';
-
-const futureReservedWords = [
- 'implements',
- 'interface',
- 'package',
- 'private',
- 'protected',
- 'public',
- 'enum',
- 'class',
- 'const',
- 'export',
- 'extends',
- 'import',
- 'super',
- 'let',
- 'static',
- 'yield',
- 'await',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- renameReserved:
- 'Rename "{{reserved}}" identifier to prevent potential conflicts with future evolutions of the JavaScript language.',
- },
- },
- create(context: Rule.RuleContext) {
- function checkVariable(variable: Scope.Variable) {
- if (variable.defs.length > 0) {
- const def = variable.defs[0].name;
- context.report({
- node: def,
- messageId: 'renameReserved',
- data: {
- reserved: variable.name,
- },
- });
- }
- }
-
- function checkVariablesByScope(scope: Scope.Scope) {
- scope.variables.filter(v => futureReservedWords.includes(v.name)).forEach(checkVariable);
-
- scope.childScopes.forEach(childScope => {
- checkVariablesByScope(childScope);
- });
- }
-
- return {
- 'Program:exit': () => {
- checkVariablesByScope(context.getScope());
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/generator-without-yield.ts b/eslint-bridge/src/linting/eslint/rules/generator-without-yield.ts
deleted file mode 100644
index fc43a6a5f7e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/generator-without-yield.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3531/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { getParent, RuleContext } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- addYield: 'Add a "yield" statement to this generator.',
- },
- },
- create(context: Rule.RuleContext) {
- const yieldStack: number[] = [];
-
- function enterFunction() {
- yieldStack.push(0);
- }
-
- function exitFunction(node: estree.Node) {
- const functionNode = node as estree.FunctionExpression | estree.FunctionDeclaration;
- const countYield = yieldStack.pop();
- if (countYield === 0 && functionNode.body.body.length > 0) {
- context.report({
- messageId: 'addYield',
- loc: getMainFunctionTokenLocation(
- functionNode as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
- }
-
- return {
- ':function[generator=true]': enterFunction,
- ':function[generator=true]:exit': exitFunction,
- YieldExpression() {
- if (yieldStack.length > 0) {
- yieldStack[yieldStack.length - 1] += 1;
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/hashing.ts b/eslint-bridge/src/linting/eslint/rules/hashing.ts
deleted file mode 100644
index 73fa8e0f797..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/hashing.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4790/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName, getUniqueWriteUsageOrNode, isStringLiteral } from './helpers';
-
-const message = 'Make sure this weak hash algorithm is not used in a sensitive context here.';
-const CRYPTO_UNSECURE_HASH_ALGORITHMS = new Set([
- 'md2',
- 'md4',
- 'md5',
- 'md6',
- 'haval128',
- 'hmacmd5',
- 'dsa',
- 'ripemd',
- 'ripemd128',
- 'ripemd160',
- 'hmacripemd160',
- 'sha1',
-]);
-const SUBTLE_UNSECURE_HASH_ALGORITHMS = new Set(['sha-1']);
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- function checkNodejsCrypto(fqn: string | null, node: estree.CallExpression) {
- // crypto#createHash
- const { callee, arguments: args } = node;
- if (fqn === 'crypto.createHash') {
- checkUnsecureAlgorithm(callee, args[0], CRYPTO_UNSECURE_HASH_ALGORITHMS);
- }
- }
-
- function checkSubtleCrypto(fqn: string | null, node: estree.CallExpression) {
- // crypto.subtle#digest
- const { callee, arguments: args } = node;
- if (fqn === 'crypto.subtle.digest') {
- checkUnsecureAlgorithm(callee, args[0], SUBTLE_UNSECURE_HASH_ALGORITHMS);
- }
- }
-
- function checkUnsecureAlgorithm(
- method: estree.Node,
- hash: estree.Node,
- unsecureAlgorithms: Set,
- ) {
- const hashAlgorithm = getUniqueWriteUsageOrNode(context, hash);
- if (
- isStringLiteral(hashAlgorithm) &&
- unsecureAlgorithms.has(hashAlgorithm.value.toLocaleLowerCase())
- ) {
- context.report({
- message,
- node: method,
- });
- }
- }
-
- return {
- 'CallExpression[arguments.length > 0]': (node: estree.Node) => {
- const callExpr = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpr);
- checkNodejsCrypto(fqn, callExpr);
- checkSubtleCrypto(fqn, callExpr);
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/ancestor.ts b/eslint-bridge/src/linting/eslint/rules/helpers/ancestor.ts
deleted file mode 100644
index f682abb7e4d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/ancestor.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-import { functionLike } from './ast';
-
-export function findFirstMatchingLocalAncestor(
- node: TSESTree.Node,
- predicate: (node: TSESTree.Node) => boolean,
-) {
- return localAncestorsChain(node).find(predicate);
-}
-
-export function findFirstMatchingAncestor(
- node: TSESTree.Node,
- predicate: (node: TSESTree.Node) => boolean,
-) {
- return ancestorsChain(node, new Set()).find(predicate);
-}
-
-export function localAncestorsChain(node: TSESTree.Node) {
- return ancestorsChain(node, functionLike);
-}
-
-export function ancestorsChain(node: TSESTree.Node, boundaryTypes: Set) {
- const chain: TSESTree.Node[] = [];
-
- let currentNode = node.parent;
- while (currentNode) {
- chain.push(currentNode);
- if (boundaryTypes.has(currentNode.type)) {
- break;
- }
- currentNode = currentNode.parent;
- }
- return chain;
-}
-
-export function getParent(context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- return ancestors.length > 0 ? ancestors[ancestors.length - 1] : undefined;
-}
-
-/**
- * Returns the parent of an ESLint node
- *
- * This function assumes that an ESLint node exposes a parent property,
- * which is always defined. However, it's better to use `getParent` if
- * it is possible to retrieve the parent based on the rule context.
- *
- * It should eventually disappear once we come up with a proper solution
- * against the conflicting typings between ESLint and TypeScript ESLint
- * when it comes to the parent of a node.
- *
- * @param node an ESLint node
- * @returns the parent node
- */
-export function getNodeParent(node: Node) {
- return (node as TSESTree.Node).parent as Node;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/ast.ts b/eslint-bridge/src/linting/eslint/rules/helpers/ast.ts
deleted file mode 100644
index ebe1046432b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/ast.ts
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { flatMap, getFullyQualifiedName, toEncodedMessage } from '.';
-
-export type Node = estree.Node | TSESTree.Node;
-
-export type LoopLike =
- | estree.WhileStatement
- | estree.DoWhileStatement
- | estree.ForStatement
- | estree.ForOfStatement
- | estree.ForInStatement;
-
-export type FunctionNodeType =
- | estree.FunctionDeclaration
- | estree.FunctionExpression
- | estree.ArrowFunctionExpression;
-
-export type StringLiteral = estree.Literal & { value: string };
-
-export const FUNCTION_NODES = [
- 'FunctionDeclaration',
- 'FunctionExpression',
- 'ArrowFunctionExpression',
-];
-
-export const functionLike = new Set([
- 'FunctionDeclaration',
- 'FunctionExpression',
- 'ArrowFunctionExpression',
- 'MethodDefinition',
-]);
-
-export function isIdentifier(
- node: Node | undefined,
- ...values: string[]
-): node is estree.Identifier {
- return (
- node?.type === 'Identifier' &&
- (values.length === 0 || values.some(value => value === node.name))
- );
-}
-
-export function isMemberWithProperty(node: estree.Node, ...values: string[]) {
- return node.type === 'MemberExpression' && isIdentifier(node.property, ...values);
-}
-
-export function isMemberExpression(
- node: estree.Node,
- objectValue: string,
- ...propertyValue: string[]
-) {
- if (node.type === 'MemberExpression') {
- const { object, property } = node;
- if (isIdentifier(object, objectValue) && isIdentifier(property, ...propertyValue)) {
- return true;
- }
- }
-
- return false;
-}
-
-export function isBinaryPlus(
- node: estree.Node,
-): node is estree.BinaryExpression & { operator: '+' } {
- return node.type === 'BinaryExpression' && node.operator === '+';
-}
-
-export function isUnaryExpression(node: estree.Node | undefined): node is estree.UnaryExpression {
- return node !== undefined && node.type === 'UnaryExpression';
-}
-
-export function isArrayExpression(node: estree.Node | undefined): node is estree.ArrayExpression {
- return node !== undefined && node.type === 'ArrayExpression';
-}
-
-export function isRequireModule(node: estree.CallExpression, ...moduleNames: string[]) {
- if (isIdentifier(node.callee, 'require') && node.arguments.length === 1) {
- const argument = node.arguments[0];
- if (argument.type === 'Literal') {
- return moduleNames.includes(String(argument.value));
- }
- }
-
- return false;
-}
-
-export function isMethodInvocation(
- callExpression: estree.CallExpression,
- objectIdentifierName: string,
- methodName: string,
- minArgs: number,
-): boolean {
- return (
- callExpression.callee.type === 'MemberExpression' &&
- isIdentifier(callExpression.callee.object, objectIdentifierName) &&
- isIdentifier(callExpression.callee.property, methodName) &&
- callExpression.callee.property.type === 'Identifier' &&
- callExpression.arguments.length >= minArgs
- );
-}
-
-export function isFunctionInvocation(
- callExpression: estree.CallExpression,
- functionName: string,
- minArgs: number,
-): boolean {
- return (
- callExpression.callee.type === 'Identifier' &&
- isIdentifier(callExpression.callee, functionName) &&
- callExpression.arguments.length >= minArgs
- );
-}
-
-export function isFunctionCall(
- node: estree.Node,
-): node is estree.CallExpression & { callee: estree.Identifier } {
- return node.type === 'CallExpression' && node.callee.type === 'Identifier';
-}
-
-export function isMethodCall(callExpr: estree.CallExpression): callExpr is estree.CallExpression & {
- callee: estree.MemberExpression & { property: estree.Identifier };
-} {
- return (
- callExpr.callee.type === 'MemberExpression' &&
- !callExpr.callee.computed &&
- callExpr.callee.property.type === 'Identifier'
- );
-}
-
-export function isCallingMethod(
- callExpr: estree.CallExpression,
- arity: number,
- ...methodNames: string[]
-): callExpr is estree.CallExpression & {
- callee: estree.MemberExpression & { property: estree.Identifier };
-} {
- return (
- isMethodCall(callExpr) &&
- callExpr.arguments.length === arity &&
- methodNames.includes(callExpr.callee.property.name)
- );
-}
-
-export function isNamespaceSpecifier(importDeclaration: estree.ImportDeclaration, name: string) {
- return importDeclaration.specifiers.some(
- ({ type, local }) => type === 'ImportNamespaceSpecifier' && local.name === name,
- );
-}
-
-export function isDefaultSpecifier(importDeclaration: estree.ImportDeclaration, name: string) {
- return importDeclaration.specifiers.some(
- ({ type, local }) => type === 'ImportDefaultSpecifier' && local.name === name,
- );
-}
-
-export function isModuleExports(node: estree.Node): boolean {
- return (
- node.type === 'MemberExpression' &&
- node.object.type === 'Identifier' &&
- node.object.name === 'module' &&
- node.property.type === 'Identifier' &&
- node.property.name === 'exports'
- );
-}
-
-export function isFunctionNode(node: estree.Node): node is FunctionNodeType {
- return FUNCTION_NODES.includes(node.type);
-}
-
-// we have similar function in eslint-plugin-sonarjs, however this one accepts null
-// eventually we should update eslint-plugin-sonarjs
-export function isLiteral(n: estree.Node | null): n is estree.Literal {
- return n != null && n.type === 'Literal';
-}
-
-export function isNullLiteral(n: estree.Node): boolean {
- return isLiteral(n) && n.value === null;
-}
-
-export function isFalseLiteral(n: estree.Node): boolean {
- return isLiteral(n) && n.value === false;
-}
-
-export function isUndefined(node: Node): boolean {
- return node.type === 'Identifier' && node.name === 'undefined';
-}
-
-/**
- * Detect expression statements like the following:
- * myArray[1] = 42;
- * myArray[1] += 42;
- * myObj.prop1 = 3;
- * myObj.prop1 += 3;
- */
-export function isElementWrite(statement: estree.ExpressionStatement, ref: Scope.Reference) {
- if (statement.expression.type === 'AssignmentExpression') {
- const assignmentExpression = statement.expression;
- const lhs = assignmentExpression.left;
- return isMemberExpressionReference(lhs, ref);
- }
- return false;
-}
-
-function isMemberExpressionReference(lhs: estree.Node, ref: Scope.Reference): boolean {
- return (
- lhs.type === 'MemberExpression' &&
- (isReferenceTo(ref, lhs.object) || isMemberExpressionReference(lhs.object, ref))
- );
-}
-
-export function isReferenceTo(ref: Scope.Reference, node: estree.Node) {
- return node.type === 'Identifier' && node === ref.identifier;
-}
-
-export function getUniqueWriteUsage(context: Rule.RuleContext, name: string) {
- const variable = getVariableFromName(context, name);
- return getUniqueWriteReference(variable);
-}
-
-export function getUniqueWriteReference(
- variable: Scope.Variable | undefined,
-): estree.Node | undefined {
- if (variable) {
- const writeReferences = variable.references.filter(reference => reference.isWrite());
- if (writeReferences.length === 1 && writeReferences[0].writeExpr) {
- return writeReferences[0].writeExpr;
- }
- }
- return undefined;
-}
-
-export function getUniqueWriteUsageOrNode(
- context: Rule.RuleContext,
- node: estree.Node,
- recursive = false,
-): estree.Node {
- if (node.type === 'Identifier') {
- const usage = getUniqueWriteUsage(context, node.name);
- if (usage) {
- return recursive ? getUniqueWriteUsageOrNode(context, usage, recursive) : usage;
- } else {
- return node;
- }
- } else {
- return node;
- }
-}
-
-export function getValueOfExpression(
- context: Rule.RuleContext,
- expr: estree.Node | undefined | null,
- type: T,
- recursive = false,
-): Extract | undefined {
- if (!expr) {
- return undefined;
- }
- if (isNodeType(expr, type)) {
- return expr;
- }
- if (expr.type === 'Identifier') {
- const usage = getUniqueWriteUsage(context, expr.name);
- if (usage) {
- if (isNodeType(usage, type)) {
- return usage;
- }
- if (recursive) {
- return getValueOfExpression(context, usage, type, true);
- }
- }
- }
-
- return undefined;
-}
-
-// see https://stackoverflow.com/questions/64262105/narrowing-return-value-of-function-based-on-argument
-function isNodeType(
- node: Node,
- type: T,
-): node is Extract {
- return node.type === type;
-}
-
-/**
- * for `x = 42` or `let x = 42` when visiting '42' returns 'x' variable
- */
-export function getLhsVariable(context: Rule.RuleContext): Scope.Variable | undefined {
- const parent = context.getAncestors()[context.getAncestors().length - 1];
- let formIdentifier: estree.Identifier | undefined;
- if (parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') {
- formIdentifier = parent.id;
- } else if (parent.type === 'AssignmentExpression' && parent.left.type === 'Identifier') {
- formIdentifier = parent.left;
- }
- if (formIdentifier) {
- return getVariableFromName(context, formIdentifier.name);
- }
-
- return undefined;
-}
-
-export function getVariableFromScope(scope: Scope.Scope | null, name: string) {
- let variable;
- while (variable == null && scope != null) {
- variable = scope.variables.find(value => value.name === name);
- scope = scope.upper;
- }
- return variable;
-}
-
-export function getVariableFromName(context: Rule.RuleContext, name: string) {
- const scope: Scope.Scope | null = context.getScope();
- return getVariableFromScope(scope, name);
-}
-
-/**
- * Takes array of arguments. Keeps following variable definitions
- * and unpacking arrays as long as possible. Returns flattened
- * array with all collected nodes.
- *
- * A usage example should clarify why this might be useful.
- * According to ExpressJs `app.use` spec, the arguments can be:
- *
- * - A middleware function.
- * - A series of middleware functions (separated by commas).
- * - An array of middleware functions.
- * - A combination of all of the above.
- *
- * This means that methods like `app.use` accept variable arguments,
- * but also arrays, or combinations thereof. This methods helps
- * to flatten out such complicated composed argument lists.
- */
-export function flattenArgs(context: Rule.RuleContext, args: estree.Node[]): estree.Node[] {
- // Invokes `getUniqueWriteUsageOrNode` at most once, from then on
- // only flattens arrays.
- function recHelper(nodePossiblyIdentifier: estree.Node): estree.Node[] {
- const n = getUniqueWriteUsageOrNode(context, nodePossiblyIdentifier);
- if (n.type === 'ArrayExpression') {
- return flatMap(n.elements as estree.Node[], recHelper);
- } else {
- return [n];
- }
- }
-
- return flatMap(args, recHelper);
-}
-
-export function resolveIdentifiers(
- node: TSESTree.Node,
- acceptShorthand = false,
-): TSESTree.Identifier[] {
- const identifiers: TSESTree.Identifier[] = [];
- resolveIdentifiersAcc(node, identifiers, acceptShorthand);
- return identifiers;
-}
-
-function resolveIdentifiersAcc(
- node: TSESTree.Node,
- identifiers: TSESTree.Identifier[],
- acceptShorthand: boolean,
-): void {
- if (!node) {
- return;
- }
- switch (node.type) {
- case 'Identifier':
- identifiers.push(node);
- break;
- case 'ObjectPattern':
- node.properties.forEach(prop => resolveIdentifiersAcc(prop, identifiers, acceptShorthand));
- break;
- case 'ArrayPattern':
- node.elements.forEach(
- elem => elem && resolveIdentifiersAcc(elem, identifiers, acceptShorthand),
- );
- break;
- case 'Property':
- if (acceptShorthand || !node.shorthand) {
- resolveIdentifiersAcc(node.value, identifiers, acceptShorthand);
- }
- break;
- case 'RestElement':
- resolveIdentifiersAcc(node.argument, identifiers, acceptShorthand);
- break;
- case 'AssignmentPattern':
- resolveIdentifiersAcc(node.left, identifiers, acceptShorthand);
- break;
- case 'TSParameterProperty':
- resolveIdentifiersAcc(node.parameter, identifiers, acceptShorthand);
- break;
- }
-}
-
-// TODO Drop this function and replace it with `getProperty`
-export function getObjectExpressionProperty(
- node: estree.Node | undefined | null,
- propertyKey: string,
-): estree.Property | undefined {
- if (node?.type === 'ObjectExpression') {
- const properties = node.properties.filter(
- p =>
- p.type === 'Property' &&
- (isIdentifier(p.key, propertyKey) || (isLiteral(p.key) && p.key.value === propertyKey)),
- ) as estree.Property[];
- // if property is duplicated, we return the last defined
- return properties[properties.length - 1];
- }
- return undefined;
-}
-
-export function getPropertyWithValue(
- context: Rule.RuleContext,
- objectExpression: estree.ObjectExpression,
- propertyName: string,
- propertyValue: estree.Literal['value'],
-): estree.Property | undefined {
- const maybeProperty = getObjectExpressionProperty(objectExpression, propertyName);
- if (maybeProperty) {
- const maybePropertyValue = getValueOfExpression(context, maybeProperty.value, 'Literal');
- if (maybePropertyValue?.value === propertyValue) {
- return maybeProperty;
- }
- }
- return undefined;
-}
-
-export function getProperty(
- expr: estree.ObjectExpression,
- key: string,
- ctx: Rule.RuleContext,
-): estree.Property | null | undefined {
- let unresolvedSpreadElement = false;
- for (let i = expr.properties.length - 1; i >= 0; --i) {
- const property = expr.properties[i];
- if (isProperty(property, key)) {
- return property;
- }
- if (property.type === 'SpreadElement') {
- const props = getValueOfExpression(ctx, property.argument, 'ObjectExpression');
- if (props !== undefined) {
- const prop = getProperty(props, key, ctx);
- if (prop !== null) {
- return prop;
- }
- } else {
- unresolvedSpreadElement = true;
- }
- }
- }
- if (unresolvedSpreadElement) {
- return undefined;
- }
- return null;
-
- function isProperty(node: estree.Node, key: string): node is estree.Property {
- return (
- node.type === 'Property' &&
- (isIdentifier(node.key, key) || (isStringLiteral(node.key) && node.key.value === key))
- );
- }
-}
-
-export function resolveFromFunctionReference(
- context: Rule.RuleContext,
- functionIdentifier: estree.Identifier,
-) {
- const { scopeManager } = context.getSourceCode();
- for (const scope of scopeManager.scopes) {
- const reference = scope.references.find(r => r.identifier === functionIdentifier);
- if (
- reference?.resolved &&
- reference.resolved.defs.length === 1 &&
- reference.resolved.defs[0].type === 'FunctionName'
- ) {
- return reference.resolved.defs[0].node;
- }
- }
- return null;
-}
-
-export function resolveFunction(
- context: Rule.RuleContext,
- node: estree.Node,
-): estree.Function | null {
- if (isFunctionNode(node)) {
- return node;
- } else if (node.type === 'Identifier') {
- return resolveFromFunctionReference(context, node);
- } else {
- return null;
- }
-}
-
-export function checkSensitiveCall(
- context: Rule.RuleContext,
- callExpression: estree.CallExpression,
- sensitiveArgumentIndex: number,
- sensitiveProperty: string,
- sensitivePropertyValue: boolean,
- message: string,
-) {
- if (callExpression.arguments.length < sensitiveArgumentIndex + 1) {
- return;
- }
- const sensitiveArgument = callExpression.arguments[sensitiveArgumentIndex];
- const options = getValueOfExpression(context, sensitiveArgument, 'ObjectExpression');
- if (!options) {
- return;
- }
- const unsafeProperty = getPropertyWithValue(
- context,
- options,
- sensitiveProperty,
- sensitivePropertyValue,
- );
- if (unsafeProperty) {
- context.report({
- node: callExpression.callee,
- message: toEncodedMessage(message, [unsafeProperty]),
- });
- }
-}
-
-export function isStringLiteral(node: estree.Node): node is StringLiteral {
- return isLiteral(node) && typeof node.value === 'string';
-}
-
-export function isBooleanLiteral(node: estree.Node): node is estree.Literal & { value: boolean } {
- return isLiteral(node) && typeof node.value === 'boolean';
-}
-
-export function isNumberLiteral(node: estree.Node): node is estree.Literal & { value: number } {
- return isLiteral(node) && typeof node.value === 'number';
-}
-
-export function isRegexLiteral(node: estree.Node): node is estree.RegExpLiteral {
- return node.type === 'Literal' && node.value instanceof RegExp;
-}
-
-export function isDotNotation(
- node: estree.Node,
-): node is estree.MemberExpression & { property: estree.Identifier } {
- return node.type === 'MemberExpression' && !node.computed && node.property.type === 'Identifier';
-}
-
-export function isObjectDestructuring(
- node: estree.Node,
-): node is
- | (estree.VariableDeclarator & { id: estree.ObjectPattern })
- | (estree.AssignmentExpression & { left: estree.ObjectPattern }) {
- return (
- (node.type === 'VariableDeclarator' && node.id.type === 'ObjectPattern') ||
- (node.type === 'AssignmentExpression' && node.left.type === 'ObjectPattern')
- );
-}
-
-export function isStaticTemplateLiteral(node: estree.Node): node is estree.TemplateLiteral {
- return (
- node.type === 'TemplateLiteral' && node.expressions.length === 0 && node.quasis.length === 1
- );
-}
-
-export function isThisExpression(node: estree.Node): node is estree.ThisExpression {
- return node.type === 'ThisExpression';
-}
-
-export function isProperty(node: estree.Node): node is estree.Property {
- return node.type === 'Property';
-}
-
-/**
- * Check if an identifier has no known value, meaning:
- *
- * - It's not imported/required
- * - Defined variable without any write references (function parameter?)
- * - Non-defined variable (a possible global?)
- *
- * @param node Node to check
- * @param ctx Rule context
- */
-export function isUnresolved(node: estree.Node | undefined | null, ctx: Rule.RuleContext): boolean {
- if (!node || getFullyQualifiedName(ctx, node) || isUndefined(node)) {
- return false;
- }
- let nodeToCheck: estree.Node = node;
- while (nodeToCheck.type === 'MemberExpression') {
- nodeToCheck = nodeToCheck.object;
- }
-
- if (nodeToCheck.type === 'Identifier') {
- const variable = getVariableFromName(ctx, nodeToCheck.name);
- const writeReferences = variable?.references.filter(reference => reference.isWrite());
- if (!variable || !writeReferences?.length) {
- return true;
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/aws/cdk.ts b/eslint-bridge/src/linting/eslint/rules/helpers/aws/cdk.ts
deleted file mode 100644
index 25fb9759f84..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/aws/cdk.ts
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName } from '../module';
-import {
- getProperty,
- getUniqueWriteUsage,
- getUniqueWriteUsageOrNode,
- isIdentifier,
- isLiteral,
- isUndefined,
- isUnresolved,
- getValueOfExpression,
-} from '../ast';
-
-const AWS_OPTIONS_ARGUMENT_POSITION = 2;
-
-/**
- * A symbol fully qualified name, e.g. `aws-cdk-lib.aws_sns.Topic`.
- */
-export type FullyQualifiedName = string;
-export type AwsCdkCallback = {
- functionName?: string;
- methods?: string[];
- callExpression(expr: estree.CallExpression, ctx: Rule.RuleContext, fqn?: string): void;
- newExpression?(expr: estree.NewExpression, ctx: Rule.RuleContext): void;
-};
-export type AwsCdkConsumer =
- | ((expr: estree.NewExpression, ctx: Rule.RuleContext) => void)
- | AwsCdkCallback;
-type AwsCdkNode = estree.NewExpression | estree.CallExpression;
-
-type Values = { invalid?: any[]; valid?: any[]; case_insensitive?: boolean };
-type ValuesByType = {
- primitives?: Values;
- fqns?: Values;
- customChecker?: (ctx: Rule.RuleContext, node: estree.Node) => boolean;
-};
-type NodeAndReport = {
- node: estree.Node;
- nodeToReport: estree.Node;
-};
-
-export type AwsCdkConsumerMap = { [key: FullyQualifiedName]: AwsCdkConsumer };
-
-/**
- * A rule template for AWS CDK resources
- *
- * @param mapOrFactory callbacks to invoke when a new expression or a call expression matches a fully qualified name
- * @param metadata the rule metadata
- * @returns the instantiated rule module
- */
-export function AwsCdkTemplate(
- mapOrFactory: AwsCdkConsumerMap | ((ctx: Rule.RuleContext) => AwsCdkConsumerMap),
- metadata: { meta: Rule.RuleMetaData } = { meta: {} },
-): Rule.RuleModule {
- return {
- ...metadata,
- create(ctx: Rule.RuleContext) {
- const consumers = typeof mapOrFactory === 'function' ? mapOrFactory(ctx) : mapOrFactory;
- return {
- 'NewExpression, CallExpression'(node: AwsCdkNode) {
- if (node.arguments.some(arg => arg.type === 'SpreadElement')) {
- return;
- }
- for (const fqn in consumers) {
- const normalizedExpectedFQN = normalizeFQN(fqn);
- const callback = consumers[fqn];
- if (typeof callback === 'object' || node.type === 'CallExpression') {
- executeIfMatching(node, normalizedExpectedFQN!, callback);
- continue;
- }
- const normalizedActualFQN = normalizeFQN(getFullyQualifiedName(ctx, node.callee));
- if (normalizedActualFQN === normalizedExpectedFQN) {
- callback(node, ctx);
- }
- }
- },
- };
-
- function executeIfMatching(node: AwsCdkNode, expected: string, callback: AwsCdkConsumer) {
- if (typeof callback === 'function') {
- return;
- }
-
- const fqn = normalizeFQN(getFullyQualifiedName(ctx, node.callee));
- if (node.type === 'NewExpression' && fqn === expected) {
- callback.newExpression?.(node, ctx);
- } else if (isMethodCall(callback, fqn, expected)) {
- callback.callExpression(node, ctx, fqn);
- }
- }
-
- function isMethodCall(callback: AwsCdkCallback, fqn: string | undefined, expected: string) {
- if (callback.functionName) {
- return fqn === `${expected}.${callback.functionName}`;
- } else if (callback.methods && fqn?.startsWith(expected)) {
- const methodNames = fqn.substring(expected.length).split('.');
- const methods = callback.methods;
- return methodNames.every(name => name === '' || methods.includes(name));
- } else {
- return fqn === expected;
- }
- }
- },
- };
-}
-
-/**
- * Get the messageId at the given position from an array. If a string is used
- * instead of an array, return it
- * @param messageId Array of messageIds or single string if only one messageId is used
- * @param pos
- */
-function getMessageAtPos(messageId: string | string[], pos = 0): string {
- if (typeof messageId === 'string') {
- return messageId;
- }
- return messageId[pos];
-}
-
-/**
- * Function to analyse arguments in a function and check for correct values. It will report if the
- * conditions are not met unless `silent = true`, in which case it will return boolean `true`
- * indicating conditions are not met.
- *
- * @param messageId Array of messageIds or single string if only one messageId is used. When an array is passed,
- * first messageId is used for omitted values and second for invalid values.
- * @param needsProps whether default (undefined) values are allowed or if it must be set
- * @param propertyName property name to search in the object (Array of strings for nested props)
- * @param values allowed or disallowed values
- * @param silent whether the function must report or just return conflicting Node when conditions are not met
- * @param position position of the argument to be analysed (3rd argument by default)
- */
-export function AwsCdkCheckArguments(
- messageId: string | string[],
- needsProps: boolean,
- propertyName: string | string[],
- values?: ValuesByType,
- silent = false,
- position = AWS_OPTIONS_ARGUMENT_POSITION,
-) {
- return (expr: estree.NewExpression, ctx: Rule.RuleContext): estree.Node | undefined => {
- const argument = expr.arguments[position];
-
- // Argument not found or undefined
- if (!argument || isUndefined(argument)) {
- if (needsProps) {
- if (silent) {
- return expr.callee;
- }
- ctx.report({ messageId: getMessageAtPos(messageId, 0), node: expr.callee });
- }
- return;
- }
-
- const properties = traverseProperties(
- { node: argument, nodeToReport: argument },
- typeof propertyName === 'string' ? [propertyName] : propertyName,
- ctx,
- getMessageAtPos(messageId, 0),
- needsProps,
- silent,
- );
-
- if (!Array.isArray(properties)) {
- return properties;
- }
-
- if (!properties?.length) {
- return;
- }
-
- for (const property of properties) {
- const propertyValue = getUniqueWriteUsageOrNode(
- ctx,
- (property.node as estree.Property).value,
- true,
- );
-
- if (isUnresolved(propertyValue, ctx)) {
- continue;
- }
-
- /* Property is undefined or an empty array, which is the undefined equivalent
- for properties with an array-form where we expect multiple nested values */
- if (
- isUndefined(propertyValue) ||
- (propertyValue.type === 'ArrayExpression' && !propertyValue.elements.length)
- ) {
- if (needsProps) {
- if (silent) {
- return getNodeToReport(property);
- }
- ctx.report({ messageId: getMessageAtPos(messageId, 0), node: getNodeToReport(property) });
- }
- continue;
- }
-
- // Value is expected to be a primitive (string, number)
- if (values?.primitives && disallowedValue(ctx, propertyValue, values.primitives)) {
- if (silent) {
- return getNodeToReport(property);
- }
- ctx.report({ messageId: getMessageAtPos(messageId, 1), node: getNodeToReport(property) });
- }
- // Value is expected to be an Identifier following a specific FQN
- if (values?.fqns && disallowedFQNs(ctx, propertyValue, values.fqns)) {
- if (silent) {
- return getNodeToReport(property);
- }
- ctx.report({ messageId: getMessageAtPos(messageId, 1), node: getNodeToReport(property) });
- }
- // The value needs to be validated with a customized function
- if (values?.customChecker && values.customChecker(ctx, propertyValue)) {
- if (silent) {
- return getNodeToReport(property);
- }
- ctx.report({ messageId: getMessageAtPos(messageId, 1), node: getNodeToReport(property) });
- }
- }
- };
-}
-
-function getNodeToReport(property: NodeAndReport): estree.Node {
- if (property.nodeToReport.type === 'Property') {
- return property.nodeToReport.value;
- }
- return property.nodeToReport;
-}
-
-/**
- * Given an object expression, check for [nested] attributes. If at some level an
- * array is found, the search for next level properties will be performed on each element
- * of the array.
- *
- * @returns an array of Nodes which have the given property path.
- *
- * @param node node to look for the next property.
- * @param propertyPath pending property paths to traverse
- * @param ctx rule context
- * @param messageId messageId to report when path cannot be met and silent = `false`
- * @param needsProp whether missing (undefined) values are allowed or if it must be set
- * @param silent whether the function must report or just return conflicting Node when conditions are not met
- */
-
-function traverseProperties(
- node: NodeAndReport,
- propertyPath: string[],
- ctx: Rule.RuleContext,
- messageId: string,
- needsProp: boolean,
- silent: boolean,
-): NodeAndReport[] | estree.Node {
- const [propertyName, ...nextElements] = propertyPath;
- const properties: NodeAndReport[] = [];
- const children: NodeAndReport[] = [];
-
- if (isUnresolved(node.node, ctx)) {
- return [];
- }
-
- const objExpr = getValueOfExpression(ctx, node.node, 'ObjectExpression', true);
-
- if (objExpr === undefined) {
- const arrayExpr = getValueOfExpression(ctx, node.node, 'ArrayExpression', true);
-
- if (arrayExpr === undefined || !arrayExpr.elements.length) {
- if (needsProp) {
- if (silent) {
- return node.nodeToReport;
- }
- ctx.report({ messageId, node: node.nodeToReport });
- }
- return [];
- }
-
- for (const element of arrayExpr.elements) {
- const elemObjExpr = getValueOfExpression(ctx, element, 'ObjectExpression', true);
- if (elemObjExpr && element) {
- children.push({ node: elemObjExpr, nodeToReport: element });
- }
- }
- } else {
- children.push({ node: objExpr, nodeToReport: node.nodeToReport });
- }
-
- for (const child of children) {
- const property = getProperty(child.node as estree.ObjectExpression, propertyName, ctx);
- if (property === undefined) {
- continue;
- }
-
- if (!property) {
- if (needsProp) {
- if (silent) {
- return node.nodeToReport;
- }
- ctx.report({ messageId, node: node.nodeToReport });
- }
- continue;
- }
-
- if (nextElements.length) {
- if (
- child.node === child.nodeToReport &&
- (child.node as estree.ObjectExpression).properties.includes(property)
- ) {
- child.nodeToReport = property.value;
- }
- child.node = property.value;
- const nextElementChildren = traverseProperties(
- child,
- nextElements,
- ctx,
- messageId,
- needsProp,
- silent,
- );
- if (!Array.isArray(nextElementChildren)) {
- return nextElementChildren;
- }
- properties.push(...nextElementChildren);
- } else {
- if (
- child.node === child.nodeToReport &&
- (child.node as estree.ObjectExpression).properties.includes(property)
- ) {
- child.nodeToReport = property;
- }
- child.node = property;
- properties.push(child);
- }
- }
- return properties;
-}
-
-function disallowedValue(ctx: Rule.RuleContext, node: estree.Node, values: Values): boolean {
- const literal = getLiteralValue(ctx, node);
- if (literal) {
- if (values.valid?.length) {
- const found = values.valid.some(value => {
- if (values.case_insensitive && typeof literal.value === 'string') {
- return value.toLowerCase() === literal.value.toLowerCase();
- }
- return value === literal.value;
- });
- if (!found) {
- return true;
- }
- }
- if (values.invalid?.length) {
- const found = values.invalid.some(value => {
- if (values.case_insensitive && typeof literal.value === 'string') {
- return value.toLowerCase() === literal.value.toLowerCase();
- }
- return value === literal.value;
- });
- if (found) {
- return true;
- }
- }
- }
- return false;
-}
-
-export function getLiteralValue(
- ctx: Rule.RuleContext,
- node: estree.Node,
-): estree.Literal | undefined {
- if (isLiteral(node)) {
- return node;
- } else if (isIdentifier(node)) {
- const usage = getUniqueWriteUsage(ctx, node.name);
- if (usage) {
- return getLiteralValue(ctx, usage);
- }
- }
- return undefined;
-}
-
-function disallowedFQNs(ctx: Rule.RuleContext, node: estree.Node, values: Values) {
- const normalizedFQN = normalizeFQN(getFullyQualifiedName(ctx, node));
-
- if (
- values.valid?.length &&
- (!normalizedFQN || !values.valid.map(normalizeFQN).includes(normalizedFQN))
- ) {
- return true;
- }
- return normalizedFQN && values.invalid?.map(normalizeFQN).includes(normalizedFQN);
-}
-
-export function normalizeFQN(fqn?: string | null) {
- return fqn?.replace(/-/g, '_');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/aws/iam.ts b/eslint-bridge/src/linting/eslint/rules/helpers/aws/iam.ts
deleted file mode 100644
index d3810463d62..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/aws/iam.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { CallExpression, NewExpression, Node } from 'estree';
-import { Rule } from 'eslint';
-import { AwsCdkTemplate, normalizeFQN } from './cdk';
-import { SONAR_RUNTIME } from '../../../linter/parameters';
-import { getResultOfExpression, Result } from '../result';
-import { flattenArgs, isStringLiteral, StringLiteral } from '../ast';
-import { getFullyQualifiedName } from '../module';
-
-export interface PolicyCheckerOptions {
- effect: {
- property: string;
- type: 'FullyQualifiedName' | 'string';
- allowValue: string;
- };
- actions: {
- property: string;
- anyValues?: string[];
- };
- resources: {
- property: string;
- };
- conditions: {
- property: string;
- };
- principals: {
- property: string;
- type: 'FullyQualifiedName' | 'json';
- anyValues?: string[];
- };
-}
-
-type StatementChecker = (expr: Node, ctx: Rule.RuleContext, options: PolicyCheckerOptions) => void;
-
-const PROPERTIES_POSITION = 0;
-
-const POLICY_DOCUMENT_STATEMENT_PROPERTY = 'Statement';
-
-const ARN_PRINCIPAL = 'aws_cdk_lib.aws_iam.ArnPrincipal';
-const STAR_PRINCIPAL = 'aws_cdk_lib.aws_iam.StarPrincipal';
-const ANY_PRINCIPAL = 'aws_cdk_lib.aws_iam.AnyPrincipal';
-
-const ANY_LITERAL = '*';
-
-const PROPERTIES_OPTIONS: PolicyCheckerOptions = {
- effect: {
- property: 'effect',
- type: 'FullyQualifiedName',
- allowValue: 'aws_cdk_lib.aws_iam.Effect.ALLOW',
- },
- actions: {
- property: 'actions',
- },
- resources: {
- property: 'resources',
- },
- conditions: {
- property: 'conditions',
- },
- principals: {
- property: 'principals',
- type: 'FullyQualifiedName',
- anyValues: [STAR_PRINCIPAL, ANY_PRINCIPAL, ARN_PRINCIPAL],
- },
-};
-
-const JSON_OPTIONS: PolicyCheckerOptions = {
- effect: {
- property: 'Effect',
- type: 'string',
- allowValue: 'Allow',
- },
- actions: {
- property: 'Action',
- },
- resources: {
- property: 'Resource',
- },
- conditions: {
- property: 'Condition',
- },
- principals: {
- property: 'Principal',
- type: 'json',
- },
-};
-
-export function AwsIamPolicyTemplate(statementChecker: StatementChecker) {
- return AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws-iam.PolicyStatement': {
- newExpression: policyStatementChecker(statementChecker, PROPERTIES_OPTIONS),
- functionName: 'fromJson',
- callExpression: policyStatementChecker(statementChecker, JSON_OPTIONS),
- },
- 'aws-cdk-lib.aws-iam.PolicyDocument': {
- functionName: 'fromJson',
- callExpression: policyDocumentChecker(statementChecker, JSON_OPTIONS),
- },
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
- );
-}
-
-export function getSensitiveEffect(
- properties: Result,
- ctx: Rule.RuleContext,
- options: PolicyCheckerOptions,
-) {
- const effect = properties.getProperty(options.effect.property);
- return effect.filter(node => {
- if (options.effect.type === 'FullyQualifiedName') {
- const fullyQualifiedName = normalizeFQN(getFullyQualifiedName(ctx, node));
- return fullyQualifiedName === options.effect.allowValue;
- } else {
- return isStringLiteral(node) && node.value === options.effect.allowValue;
- }
- });
-}
-
-export function isAnyLiteral(literal: StringLiteral) {
- return literal.value === ANY_LITERAL;
-}
-
-function policyDocumentChecker(statementChecker: StatementChecker, options: PolicyCheckerOptions) {
- return (expr: CallExpression, ctx: Rule.RuleContext) => {
- const call = getResultOfExpression(ctx, expr);
- const properties = call.getArgument(PROPERTIES_POSITION);
- const statements = properties.getProperty(POLICY_DOCUMENT_STATEMENT_PROPERTY);
-
- if (statements.isFound) {
- for (const node of flattenArgs(ctx, [statements.node])) {
- statementChecker(node, ctx, options);
- }
- }
- };
-}
-
-function policyStatementChecker(statementChecker: StatementChecker, options: PolicyCheckerOptions) {
- return (expr: CallExpression | NewExpression, ctx: Rule.RuleContext) => {
- const call = getResultOfExpression(ctx, expr);
- const properties = call.getArgument(PROPERTIES_POSITION);
-
- if (properties.isFound) {
- statementChecker(properties.node, ctx, options);
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/aws/s3.ts b/eslint-bridge/src/linting/eslint/rules/helpers/aws/s3.ts
deleted file mode 100644
index 8fc839fffbd..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/aws/s3.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getFullyQualifiedName,
- getNodeParent,
- getValueOfExpression,
- isIdentifier,
- isProperty,
-} from '..';
-import { normalizeFQN } from './cdk';
-
-/**
- * A rule template for AWS S3 Buckets
- *
- * The rule template allows to detect sensitive configuration passed on
- * the invocation of S3 Bucket's constructor from AWS CDK:
- *
- * ```new s3.Bucket(...)```
- *
- * @param callback the callback invoked on visiting S3 Bucket's instantiation
- * @param metadata the instantiated rule metadata
- * @returns the instantiated rule definition
- */
-export function S3BucketTemplate(
- callback: (bucketConstructor: estree.NewExpression, context: Rule.RuleContext) => void,
- metadata: { meta: Rule.RuleMetaData } = { meta: {} },
-): Rule.RuleModule {
- return {
- ...metadata,
- create(context: Rule.RuleContext) {
- return {
- NewExpression: (node: estree.NewExpression) => {
- if (isS3BucketConstructor(context, node)) {
- callback(node, context);
- }
- },
- };
- },
- };
-}
-
-/**
- * Detects S3 Bucket's constructor invocation from 'aws-cdk-lib/aws-s3':
- *
- * const s3 = require('aws-cdk-lib/aws-s3');
- * new s3.Bucket();
- */
-export function isS3BucketConstructor(context: Rule.RuleContext, node: estree.NewExpression) {
- return normalizeFQN(getFullyQualifiedName(context, node)) === 'aws_cdk_lib.aws_s3.Bucket';
-}
-
-/**
- * Detects S3 BucketDeployment's constructor invocation from 'aws-cdk-lib/aws-s3':
- *
- * const s3 = require('aws-cdk-lib/aws-s3');
- * new s3.BucketDeployment();
- */
-export function isS3BucketDeploymentConstructor(
- context: Rule.RuleContext,
- node: estree.NewExpression,
-) {
- return (
- normalizeFQN(getFullyQualifiedName(context, node)) === 'aws_cdk_lib.aws_s3.BucketDeployment'
- );
-}
-
-/**
- * Extracts a property from the configuration argument of S3 Bucket's constructor
- *
- * ```
- * new s3.Bucket(_, _, { // config
- * key1: value1,
- * ...
- * keyN: valueN
- * });
- * ```
- *
- * @param context the rule context
- * @param bucket the invocation of S3 Bucket's constructor
- * @param key the key of the property to extract
- * @returns the extracted property
- */
-export function getProperty(context: Rule.RuleContext, bucket: estree.NewExpression, key: string) {
- const args = bucket.arguments as estree.Expression[];
-
- const optionsArg = args[2];
- const options = getValueOfExpression(context, optionsArg, 'ObjectExpression');
- if (options == null) {
- return null;
- }
-
- return options.properties.find(
- property => isProperty(property) && isIdentifier(property.key, key),
- ) as estree.Property | undefined;
-}
-
-/**
- * Finds the propagated setting of a sensitive property
- */
-export function findPropagatedSetting(
- sensitiveProperty: estree.Property,
- propagatedValue: estree.Node,
-) {
- const propagated = { locations: [] as estree.Node[], messages: [] as string[] };
- const isPropagatedProperty = sensitiveProperty.value !== propagatedValue;
- if (isPropagatedProperty) {
- propagated.locations = [getNodeParent(propagatedValue)];
- propagated.messages = ['Propagated setting.'];
- }
- return propagated;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/chai.ts b/eslint-bridge/src/linting/eslint/rules/helpers/chai.ts
deleted file mode 100644
index 23811fe9584..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/chai.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getImportDeclarations,
- getRequireCalls,
- isFunctionInvocation,
- isIdentifier,
- isMethodCall,
- isMethodInvocation,
-} from '.';
-
-export namespace Chai {
- export function isImported(context: Rule.RuleContext): boolean {
- return (
- getRequireCalls(context).some(
- r => r.arguments[0].type === 'Literal' && r.arguments[0].value === 'chai',
- ) || getImportDeclarations(context).some(i => i.source.value === 'chai')
- );
- }
-
- export function isAssertion(node: estree.Node): boolean {
- return isAssertUsage(node) || isExpectUsage(node) || isShouldUsage(node);
- }
-
- function isAssertUsage(node: estree.Node) {
- // assert(), assert.(), chai.assert(), chai.assert.()
- return (
- node.type === 'CallExpression' &&
- (isMethodInvocation(node, 'chai', 'assert', 1) ||
- isFunctionInvocation(node, 'assert', 1) ||
- (isMethodCall(node) && isIdentifier(node.callee.object, 'assert')) ||
- (isMethodCall(node) &&
- node.callee.object.type === 'MemberExpression' &&
- isIdentifier(node.callee.object.object, 'chai') &&
- isIdentifier(node.callee.object.property, 'assert')))
- );
- }
-
- function isExpectUsage(node: estree.Node) {
- // expect(), chai.expect()
- return (
- node.type === 'CallExpression' &&
- (isMethodInvocation(node, 'chai', 'expect', 1) || isFunctionInvocation(node, 'expect', 1))
- );
- }
-
- function isShouldUsage(node: estree.Node) {
- // .should.
- return node.type === 'MemberExpression' && isIdentifier(node.property, 'should');
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/collection.ts b/eslint-bridge/src/linting/eslint/rules/helpers/collection.ts
deleted file mode 100644
index 8638f2ae118..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/collection.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export const collectionConstructor = ['Array', 'Map', 'Set', 'WeakSet', 'WeakMap'];
-
-export const writingMethods = [
- // array methods
- 'copyWithin',
- 'fill',
- 'pop',
- 'push',
- 'reverse',
- 'set',
- 'shift',
- 'sort',
- 'splice',
- 'unshift',
- // map, set methods
- 'add',
- 'clear',
- 'delete',
-];
-
-export const sortLike = ['sort', '"sort"', "'sort'"];
-
-export function flatMap(xs: A[], f: (e: A) => B[]): B[] {
- const acc: B[] = [];
- for (const x of xs) {
- acc.push(...f(x));
- }
- return acc;
-}
-
-export function last(arr: Array) {
- return arr[arr.length - 1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/express.ts b/eslint-bridge/src/linting/eslint/rules/helpers/express.ts
deleted file mode 100644
index 53288fb99e5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/express.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getFullyQualifiedName,
- isModuleExports,
- isMethodInvocation,
- flattenArgs,
- getParent,
- toEncodedMessage,
-} from '.';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-/**
- * This modules provides utilities for writing rules about Express.js.
- */
-export namespace Express {
- const EXPRESS = 'express';
-
- /**
- * Checks whether the declaration looks somewhat like ` = express()`
- * and returns `` if it matches.
- */
- export function attemptFindAppInstantiation(
- varDecl: estree.VariableDeclarator,
- context: Rule.RuleContext,
- ): estree.Identifier | undefined {
- const rhs = varDecl.init;
- if (rhs && rhs.type === 'CallExpression' && getFullyQualifiedName(context, rhs) === EXPRESS) {
- const pattern = varDecl.id;
- return pattern.type === 'Identifier' ? pattern : undefined;
- }
- return undefined;
- }
-
- /**
- * Checks whether the function injects an instantiated app and is exported like `module.exports = function(app) {}`
- * or `module.exports.property = function(app) {}`, and returns app if it matches.
- */
- export function attemptFindAppInjection(
- functionDef: estree.Function,
- context: Rule.RuleContext,
- ): estree.Identifier | undefined {
- const app = functionDef.params.find(
- param => param.type === 'Identifier' && param.name === 'app',
- ) as estree.Identifier | undefined;
- if (app) {
- const parent = getParent(context);
- if (parent?.type === 'AssignmentExpression') {
- const { left } = parent;
- if (
- left.type === 'MemberExpression' &&
- (isModuleExports(left) || isModuleExports(left.object))
- ) {
- return app;
- }
- }
- }
- return undefined;
- }
-
- /**
- * Checks whether the expression looks somewhat like `app.use(m1, [m2, m3], ..., mN)`,
- * where one of `mK`-nodes satisfies the given predicate.
- */
- export function isUsingMiddleware(
- context: Rule.RuleContext,
- callExpression: estree.CallExpression,
- app: estree.Identifier,
- middlewareNodePredicate: (n: estree.Node) => boolean,
- ): boolean {
- if (isMethodInvocation(callExpression, app.name, 'use', 1)) {
- const flattenedArgs = flattenArgs(context, callExpression.arguments);
- return Boolean(flattenedArgs.find(middlewareNodePredicate));
- }
- return false;
- }
-
- /**
- * Checks whether a node looks somewhat like `require('m')()` for
- * some middleware `m` from the list of middlewares.
- */
- export function isMiddlewareInstance(
- context: Rule.RuleContext,
- middlewares: string[],
- n: estree.Node,
- ): boolean {
- if (n.type === 'CallExpression') {
- const fqn = getFullyQualifiedName(context, n);
- return middlewares.some(middleware => middleware === fqn);
- }
- return false;
- }
-
- /**
- * Rule factory for detecting sensitive settings that are passed to
- * middlewares eventually used by Express.js applications:
- *
- * app.use(
- * middleware(settings)
- * )
- *
- * or
- *
- * app.use(
- * middleware.method(settings)
- * )
- *
- * @param sensitivePropertyFinder - a function looking for a sensitive setting on a middleware call
- * @param message - the reported message when an issue is raised
- * @returns a rule module that raises issues when a sensitive property is found
- */
- export function SensitiveMiddlewarePropertyRule(
- sensitivePropertyFinder: (
- context: Rule.RuleContext,
- middlewareCall: estree.CallExpression,
- ) => estree.Property[],
- message: string,
- ): Rule.RuleModule {
- return {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let app: estree.Identifier | null;
- let sensitiveProperties: estree.Property[];
-
- function isExposing(middlewareNode: estree.Node): boolean {
- return Boolean(sensitiveProperties.push(...findSensitiveProperty(middlewareNode)));
- }
-
- function findSensitiveProperty(middlewareNode: estree.Node): estree.Property[] {
- if (middlewareNode.type === 'CallExpression') {
- return sensitivePropertyFinder(context, middlewareNode);
- }
- return [];
- }
-
- return {
- Program: () => {
- app = null;
- sensitiveProperties = [];
- },
- CallExpression: (node: estree.Node) => {
- if (app) {
- const callExpr = node as estree.CallExpression;
- const isSafe = !isUsingMiddleware(context, callExpr, app, isExposing);
- if (!isSafe) {
- for (const sensitive of sensitiveProperties) {
- context.report({
- node: callExpr,
- message: toEncodedMessage(message, [sensitive as TSESTree.Property]),
- });
- }
- sensitiveProperties = [];
- }
- }
- },
- VariableDeclarator: (node: estree.Node) => {
- if (!app) {
- const varDecl = node as estree.VariableDeclarator;
- const instantiatedApp = attemptFindAppInstantiation(varDecl, context);
- if (instantiatedApp) {
- app = instantiatedApp;
- }
- }
- },
- ':function': (node: estree.Node) => {
- if (!app) {
- const functionDef = node as estree.Function;
- const injectedApp = attemptFindAppInjection(functionDef, context);
- if (injectedApp) {
- app = injectedApp;
- }
- }
- },
- };
- },
- };
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/file.ts b/eslint-bridge/src/linting/eslint/rules/helpers/file.ts
deleted file mode 100644
index ad73dc61656..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/file.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { FileType } from 'helpers';
-
-export function isMainCode(context: Rule.RuleContext) {
- return !isTestCode(context);
-}
-
-export function isTestCode(context: Rule.RuleContext) {
- return getFileType(context) === 'TEST';
-}
-
-function getFileType(context: Rule.RuleContext): FileType {
- return context.settings['fileType'];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/globals.ts b/eslint-bridge/src/linting/eslint/rules/helpers/globals.ts
deleted file mode 100644
index aff753a80d1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/globals.ts
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// copied from javascript-frontend/src/main/resources/org/sonar/javascript/tree/symbols/globals.json ,
-// which should be deleted once the frontend migration is over
-export const globalsByLibraries = {
- builtin: [
- 'Array',
- 'ArrayBuffer',
- 'Boolean',
- 'DataView',
- 'Date',
- 'Error',
- 'EvalError',
- 'Float32Array',
- 'Float64Array',
- 'Function',
- 'Infinity',
- 'Int16Array',
- 'Int32Array',
- 'Int8Array',
- 'JSON',
- 'Map',
- 'Math',
- 'NaN',
- 'Number',
- 'Object',
- 'Promise',
- 'Proxy',
- 'RangeError',
- 'ReferenceError',
- 'Reflect',
- 'RegExp',
- 'Set',
- 'String',
- 'Symbol',
- 'SyntaxError',
- 'TypeError',
- 'URIError',
- 'Uint16Array',
- 'Uint32Array',
- 'Uint8Array',
- 'Uint8ClampedArray',
- 'WeakMap',
- 'WeakSet',
- 'constructor',
- 'decodeURI',
- 'decodeURIComponent',
- 'encodeURI',
- 'encodeURIComponent',
- 'escape',
- 'eval',
- 'hasOwnProperty',
- 'isFinite',
- 'isNaN',
- 'isPrototypeOf',
- 'parseFloat',
- 'parseInt',
- 'propertyIsEnumerable',
- 'toLocaleString',
- 'toString',
- 'unescape',
- 'valueOf',
- ],
-
- // https://developer.mozilla.org/en-US/docs/Web/API/Window
- // https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model
- browser: [
- 'addEventListener',
- 'alert',
- 'AnalyserNode',
- 'Animation',
- 'AnimationEffectReadOnly',
- 'AnimationEffectTiming',
- 'AnimationEffectTimingReadOnly',
- 'AnimationEvent',
- 'AnimationPlaybackEvent',
- 'AnimationTimeline',
- 'applicationCache',
- 'ApplicationCache',
- 'ApplicationCacheErrorEvent',
- 'atob',
- 'Attr',
- 'Audio',
- 'AudioBuffer',
- 'AudioBufferSourceNode',
- 'AudioContext',
- 'AudioDestinationNode',
- 'AudioListener',
- 'AudioNode',
- 'AudioParam',
- 'AudioProcessingEvent',
- 'AutocompleteErrorEvent',
- 'BarProp',
- 'BatteryManager',
- 'BeforeUnloadEvent',
- 'BiquadFilterNode',
- 'Blob',
- 'blur',
- 'btoa',
- 'Cache',
- 'caches',
- 'CacheStorage',
- 'cancelAnimationFrame',
- 'CanvasGradient',
- 'CanvasPattern',
- 'CanvasRenderingContext2D',
- 'CDATASection',
- 'ChannelMergerNode',
- 'ChannelSplitterNode',
- 'CharacterData',
- 'clearInterval',
- 'clearTimeout',
- 'clientInformation',
- 'ClientRect',
- 'ClientRectList',
- 'ClipboardEvent',
- 'close',
- 'closed',
- 'CloseEvent',
- 'Comment',
- 'CompositionEvent',
- 'confirm',
- 'console',
- 'ConvolverNode',
- 'Credential',
- 'CredentialsContainer',
- 'crypto',
- 'Crypto',
- 'CryptoKey',
- 'CSS',
- 'CSSAnimation',
- 'CSSFontFaceRule',
- 'CSSImportRule',
- 'CSSKeyframeRule',
- 'CSSKeyframesRule',
- 'CSSMediaRule',
- 'CSSPageRule',
- 'CSSRule',
- 'CSSRuleList',
- 'CSSStyleDeclaration',
- 'CSSStyleRule',
- 'CSSStyleSheet',
- 'CSSSupportsRule',
- 'CSSTransition',
- 'CSSUnknownRule',
- 'CSSViewportRule',
- 'customElements',
- 'CustomEvent',
- 'DataTransfer',
- 'DataTransferItem',
- 'DataTransferItemList',
- 'Debug',
- 'defaultStatus',
- 'defaultstatus',
- 'DelayNode',
- 'DeviceMotionEvent',
- 'DeviceOrientationEvent',
- 'devicePixelRatio',
- 'dispatchEvent',
- 'document',
- 'Document',
- 'DocumentFragment',
- 'DocumentTimeline',
- 'DocumentType',
- 'DOMError',
- 'DOMException',
- 'DOMImplementation',
- 'DOMParser',
- 'DOMSettableTokenList',
- 'DOMStringList',
- 'DOMStringMap',
- 'DOMTokenList',
- 'DragEvent',
- 'DynamicsCompressorNode',
- 'Element',
- 'ElementTimeControl',
- 'ErrorEvent',
- 'event',
- 'Event',
- 'EventSource',
- 'EventTarget',
- 'external',
- 'FederatedCredential',
- 'fetch',
- 'File',
- 'FileError',
- 'FileList',
- 'FileReader',
- 'find',
- 'focus',
- 'FocusEvent',
- 'FontFace',
- 'FormData',
- 'frameElement',
- 'frames',
- 'GainNode',
- 'Gamepad',
- 'GamepadButton',
- 'GamepadEvent',
- 'getComputedStyle',
- 'getSelection',
- 'HashChangeEvent',
- 'Headers',
- 'history',
- 'History',
- 'HTMLAllCollection',
- 'HTMLAnchorElement',
- 'HTMLAppletElement',
- 'HTMLAreaElement',
- 'HTMLAudioElement',
- 'HTMLBaseElement',
- 'HTMLBlockquoteElement',
- 'HTMLBodyElement',
- 'HTMLBRElement',
- 'HTMLButtonElement',
- 'HTMLCanvasElement',
- 'HTMLCollection',
- 'HTMLContentElement',
- 'HTMLDataListElement',
- 'HTMLDetailsElement',
- 'HTMLDialogElement',
- 'HTMLDirectoryElement',
- 'HTMLDivElement',
- 'HTMLDListElement',
- 'HTMLDocument',
- 'HTMLElement',
- 'HTMLEmbedElement',
- 'HTMLFieldSetElement',
- 'HTMLFontElement',
- 'HTMLFormControlsCollection',
- 'HTMLFormElement',
- 'HTMLFrameElement',
- 'HTMLFrameSetElement',
- 'HTMLHeadElement',
- 'HTMLHeadingElement',
- 'HTMLHRElement',
- 'HTMLHtmlElement',
- 'HTMLIFrameElement',
- 'HTMLImageElement',
- 'HTMLInputElement',
- 'HTMLIsIndexElement',
- 'HTMLKeygenElement',
- 'HTMLLabelElement',
- 'HTMLLayerElement',
- 'HTMLLegendElement',
- 'HTMLLIElement',
- 'HTMLLinkElement',
- 'HTMLMapElement',
- 'HTMLMarqueeElement',
- 'HTMLMediaElement',
- 'HTMLMenuElement',
- 'HTMLMetaElement',
- 'HTMLMeterElement',
- 'HTMLModElement',
- 'HTMLObjectElement',
- 'HTMLOListElement',
- 'HTMLOptGroupElement',
- 'HTMLOptionElement',
- 'HTMLOptionsCollection',
- 'HTMLOutputElement',
- 'HTMLParagraphElement',
- 'HTMLParamElement',
- 'HTMLPictureElement',
- 'HTMLPreElement',
- 'HTMLProgressElement',
- 'HTMLQuoteElement',
- 'HTMLScriptElement',
- 'HTMLSelectElement',
- 'HTMLShadowElement',
- 'HTMLSourceElement',
- 'HTMLSpanElement',
- 'HTMLStyleElement',
- 'HTMLTableCaptionElement',
- 'HTMLTableCellElement',
- 'HTMLTableColElement',
- 'HTMLTableElement',
- 'HTMLTableRowElement',
- 'HTMLTableSectionElement',
- 'HTMLTemplateElement',
- 'HTMLTextAreaElement',
- 'HTMLTitleElement',
- 'HTMLTrackElement',
- 'HTMLUListElement',
- 'HTMLUnknownElement',
- 'HTMLVideoElement',
- 'IDBCursor',
- 'IDBCursorWithValue',
- 'IDBDatabase',
- 'IDBEnvironment',
- 'IDBFactory',
- 'IDBIndex',
- 'IDBKeyRange',
- 'IDBObjectStore',
- 'IDBOpenDBRequest',
- 'IDBRequest',
- 'IDBTransaction',
- 'IDBVersionChangeEvent',
- 'Image',
- 'ImageBitmap',
- 'ImageData',
- 'indexedDB',
- 'innerHeight',
- 'innerWidth',
- 'InputEvent',
- 'InputMethodContext',
- 'IntersectionObserver',
- 'IntersectionObserverEntry',
- 'Intl',
- 'KeyboardEvent',
- 'KeyframeEffect',
- 'KeyframeEffectReadOnly',
- 'length',
- 'localStorage',
- 'location',
- 'Location',
- 'locationbar',
- 'matchMedia',
- 'MediaElementAudioSourceNode',
- 'MediaEncryptedEvent',
- 'MediaError',
- 'MediaKeyError',
- 'MediaKeyEvent',
- 'MediaKeyMessageEvent',
- 'MediaKeys',
- 'MediaKeySession',
- 'MediaKeyStatusMap',
- 'MediaKeySystemAccess',
- 'MediaList',
- 'MediaQueryList',
- 'MediaQueryListEvent',
- 'MediaSource',
- 'MediaStream',
- 'MediaStreamAudioDestinationNode',
- 'MediaStreamAudioSourceNode',
- 'MediaStreamEvent',
- 'MediaStreamTrack',
- 'menubar',
- 'MessageChannel',
- 'MessageEvent',
- 'MessagePort',
- 'MIDIAccess',
- 'MIDIConnectionEvent',
- 'MIDIInput',
- 'MIDIInputMap',
- 'MIDIMessageEvent',
- 'MIDIOutput',
- 'MIDIOutputMap',
- 'MIDIPort',
- 'MimeType',
- 'MimeTypeArray',
- 'MouseEvent',
- 'moveBy',
- 'moveTo',
- 'MutationEvent',
- 'MutationObserver',
- 'MutationRecord',
- 'name',
- 'NamedNodeMap',
- 'navigator',
- 'Navigator',
- 'Node',
- 'NodeFilter',
- 'NodeIterator',
- 'NodeList',
- 'Notification',
- 'OfflineAudioCompletionEvent',
- 'OfflineAudioContext',
- 'offscreenBuffering',
- 'onbeforeunload',
- 'onblur',
- 'onerror',
- 'onfocus',
- 'onload',
- 'onresize',
- 'onunload',
- 'open',
- 'openDatabase',
- 'opener',
- 'opera',
- 'Option',
- 'OscillatorNode',
- 'outerHeight',
- 'outerWidth',
- 'PageTransitionEvent',
- 'pageXOffset',
- 'pageYOffset',
- 'parent',
- 'PasswordCredential',
- 'Path2D',
- 'performance',
- 'Performance',
- 'PerformanceEntry',
- 'PerformanceMark',
- 'PerformanceMeasure',
- 'PerformanceNavigation',
- 'PerformanceResourceTiming',
- 'PerformanceTiming',
- 'PeriodicWave',
- 'Permissions',
- 'PermissionStatus',
- 'personalbar',
- 'Plugin',
- 'PluginArray',
- 'PopStateEvent',
- 'postMessage',
- 'print',
- 'ProcessingInstruction',
- 'ProgressEvent',
- 'PromiseRejectionEvent',
- 'prompt',
- 'PushManager',
- 'PushSubscription',
- 'RadioNodeList',
- 'Range',
- 'ReadableByteStream',
- 'ReadableStream',
- 'removeEventListener',
- 'Request',
- 'requestAnimationFrame',
- 'requestIdleCallback',
- 'resizeBy',
- 'resizeTo',
- 'Response',
- 'RTCIceCandidate',
- 'RTCSessionDescription',
- 'RTCPeerConnection',
- 'screen',
- 'Screen',
- 'screenLeft',
- 'ScreenOrientation',
- 'screenTop',
- 'screenX',
- 'screenY',
- 'ScriptProcessorNode',
- 'scroll',
- 'scrollbars',
- 'scrollBy',
- 'scrollTo',
- 'scrollX',
- 'scrollY',
- 'SecurityPolicyViolationEvent',
- 'Selection',
- 'self',
- 'ServiceWorker',
- 'ServiceWorkerContainer',
- 'ServiceWorkerRegistration',
- 'sessionStorage',
- 'setInterval',
- 'setTimeout',
- 'ShadowRoot',
- 'SharedKeyframeList',
- 'SharedWorker',
- 'showModalDialog',
- 'SiteBoundCredential',
- 'speechSynthesis',
- 'SpeechSynthesisEvent',
- 'SpeechSynthesisUtterance',
- 'status',
- 'statusbar',
- 'stop',
- 'Storage',
- 'StorageEvent',
- 'styleMedia',
- 'StyleSheet',
- 'StyleSheetList',
- 'SubtleCrypto',
- 'SVGAElement',
- 'SVGAltGlyphDefElement',
- 'SVGAltGlyphElement',
- 'SVGAltGlyphItemElement',
- 'SVGAngle',
- 'SVGAnimateColorElement',
- 'SVGAnimatedAngle',
- 'SVGAnimatedBoolean',
- 'SVGAnimatedEnumeration',
- 'SVGAnimatedInteger',
- 'SVGAnimatedLength',
- 'SVGAnimatedLengthList',
- 'SVGAnimatedNumber',
- 'SVGAnimatedNumberList',
- 'SVGAnimatedPathData',
- 'SVGAnimatedPoints',
- 'SVGAnimatedPreserveAspectRatio',
- 'SVGAnimatedRect',
- 'SVGAnimatedString',
- 'SVGAnimatedTransformList',
- 'SVGAnimateElement',
- 'SVGAnimateMotionElement',
- 'SVGAnimateTransformElement',
- 'SVGAnimationElement',
- 'SVGCircleElement',
- 'SVGClipPathElement',
- 'SVGColor',
- 'SVGColorProfileElement',
- 'SVGColorProfileRule',
- 'SVGComponentTransferFunctionElement',
- 'SVGCSSRule',
- 'SVGCursorElement',
- 'SVGDefsElement',
- 'SVGDescElement',
- 'SVGDiscardElement',
- 'SVGDocument',
- 'SVGElement',
- 'SVGElementInstance',
- 'SVGElementInstanceList',
- 'SVGEllipseElement',
- 'SVGEvent',
- 'SVGExternalResourcesRequired',
- 'SVGFEBlendElement',
- 'SVGFEColorMatrixElement',
- 'SVGFEComponentTransferElement',
- 'SVGFECompositeElement',
- 'SVGFEConvolveMatrixElement',
- 'SVGFEDiffuseLightingElement',
- 'SVGFEDisplacementMapElement',
- 'SVGFEDistantLightElement',
- 'SVGFEDropShadowElement',
- 'SVGFEFloodElement',
- 'SVGFEFuncAElement',
- 'SVGFEFuncBElement',
- 'SVGFEFuncGElement',
- 'SVGFEFuncRElement',
- 'SVGFEGaussianBlurElement',
- 'SVGFEImageElement',
- 'SVGFEMergeElement',
- 'SVGFEMergeNodeElement',
- 'SVGFEMorphologyElement',
- 'SVGFEOffsetElement',
- 'SVGFEPointLightElement',
- 'SVGFESpecularLightingElement',
- 'SVGFESpotLightElement',
- 'SVGFETileElement',
- 'SVGFETurbulenceElement',
- 'SVGFilterElement',
- 'SVGFilterPrimitiveStandardAttributes',
- 'SVGFitToViewBox',
- 'SVGFontElement',
- 'SVGFontFaceElement',
- 'SVGFontFaceFormatElement',
- 'SVGFontFaceNameElement',
- 'SVGFontFaceSrcElement',
- 'SVGFontFaceUriElement',
- 'SVGForeignObjectElement',
- 'SVGGElement',
- 'SVGGeometryElement',
- 'SVGGlyphElement',
- 'SVGGlyphRefElement',
- 'SVGGradientElement',
- 'SVGGraphicsElement',
- 'SVGHKernElement',
- 'SVGICCColor',
- 'SVGImageElement',
- 'SVGLangSpace',
- 'SVGLength',
- 'SVGLengthList',
- 'SVGLinearGradientElement',
- 'SVGLineElement',
- 'SVGLocatable',
- 'SVGMarkerElement',
- 'SVGMaskElement',
- 'SVGMatrix',
- 'SVGMetadataElement',
- 'SVGMissingGlyphElement',
- 'SVGMPathElement',
- 'SVGNumber',
- 'SVGNumberList',
- 'SVGPaint',
- 'SVGPathElement',
- 'SVGPathSeg',
- 'SVGPathSegArcAbs',
- 'SVGPathSegArcRel',
- 'SVGPathSegClosePath',
- 'SVGPathSegCurvetoCubicAbs',
- 'SVGPathSegCurvetoCubicRel',
- 'SVGPathSegCurvetoCubicSmoothAbs',
- 'SVGPathSegCurvetoCubicSmoothRel',
- 'SVGPathSegCurvetoQuadraticAbs',
- 'SVGPathSegCurvetoQuadraticRel',
- 'SVGPathSegCurvetoQuadraticSmoothAbs',
- 'SVGPathSegCurvetoQuadraticSmoothRel',
- 'SVGPathSegLinetoAbs',
- 'SVGPathSegLinetoHorizontalAbs',
- 'SVGPathSegLinetoHorizontalRel',
- 'SVGPathSegLinetoRel',
- 'SVGPathSegLinetoVerticalAbs',
- 'SVGPathSegLinetoVerticalRel',
- 'SVGPathSegList',
- 'SVGPathSegMovetoAbs',
- 'SVGPathSegMovetoRel',
- 'SVGPatternElement',
- 'SVGPoint',
- 'SVGPointList',
- 'SVGPolygonElement',
- 'SVGPolylineElement',
- 'SVGPreserveAspectRatio',
- 'SVGRadialGradientElement',
- 'SVGRect',
- 'SVGRectElement',
- 'SVGRenderingIntent',
- 'SVGScriptElement',
- 'SVGSetElement',
- 'SVGStopElement',
- 'SVGStringList',
- 'SVGStylable',
- 'SVGStyleElement',
- 'SVGSVGElement',
- 'SVGSwitchElement',
- 'SVGSymbolElement',
- 'SVGTests',
- 'SVGTextContentElement',
- 'SVGTextElement',
- 'SVGTextPathElement',
- 'SVGTextPositioningElement',
- 'SVGTitleElement',
- 'SVGTransform',
- 'SVGTransformable',
- 'SVGTransformList',
- 'SVGTRefElement',
- 'SVGTSpanElement',
- 'SVGUnitTypes',
- 'SVGURIReference',
- 'SVGUseElement',
- 'SVGViewElement',
- 'SVGViewSpec',
- 'SVGVKernElement',
- 'SVGZoomAndPan',
- 'SVGZoomEvent',
- 'Text',
- 'TextDecoder',
- 'TextEncoder',
- 'TextEvent',
- 'TextMetrics',
- 'TextTrack',
- 'TextTrackCue',
- 'TextTrackCueList',
- 'TextTrackList',
- 'TimeEvent',
- 'TimeRanges',
- 'toolbar',
- 'top',
- 'Touch',
- 'TouchEvent',
- 'TouchList',
- 'TrackEvent',
- 'TransitionEvent',
- 'TreeWalker',
- 'UIEvent',
- 'URL',
- 'URLSearchParams',
- 'ValidityState',
- 'VTTCue',
- 'WaveShaperNode',
- 'WebGLActiveInfo',
- 'WebGLBuffer',
- 'WebGLContextEvent',
- 'WebGLFramebuffer',
- 'WebGLProgram',
- 'WebGLRenderbuffer',
- 'WebGLRenderingContext',
- 'WebGLShader',
- 'WebGLShaderPrecisionFormat',
- 'WebGLTexture',
- 'WebGLUniformLocation',
- 'WebSocket',
- 'WheelEvent',
- 'window',
- 'Window',
- 'Worker',
- 'XDomainRequest',
- 'XMLDocument',
- 'XMLHttpRequest',
- 'XMLHttpRequestEventTarget',
- 'XMLHttpRequestProgressEvent',
- 'XMLHttpRequestUpload',
- 'XMLSerializer',
- 'XPathEvaluator',
- 'XPathException',
- 'XPathExpression',
- 'XPathNamespace',
- 'XPathNSResolver',
- 'XPathResult',
- 'XSLTProcessor',
- ],
- worker: [
- 'applicationCache',
- 'atob',
- 'Blob',
- 'BroadcastChannel',
- 'btoa',
- 'Cache',
- 'caches',
- 'clearInterval',
- 'clearTimeout',
- 'close',
- 'console',
- 'fetch',
- 'FileReaderSync',
- 'FormData',
- 'Headers',
- 'IDBCursor',
- 'IDBCursorWithValue',
- 'IDBDatabase',
- 'IDBFactory',
- 'IDBIndex',
- 'IDBKeyRange',
- 'IDBObjectStore',
- 'IDBOpenDBRequest',
- 'IDBRequest',
- 'IDBTransaction',
- 'IDBVersionChangeEvent',
- 'ImageData',
- 'importScripts',
- 'indexedDB',
- 'location',
- 'MessageChannel',
- 'MessagePort',
- 'name',
- 'navigator',
- 'Notification',
- 'onclose',
- 'onconnect',
- 'onerror',
- 'onlanguagechange',
- 'onmessage',
- 'onoffline',
- 'ononline',
- 'onrejectionhandled',
- 'onunhandledrejection',
- 'performance',
- 'Performance',
- 'PerformanceEntry',
- 'PerformanceMark',
- 'PerformanceMeasure',
- 'PerformanceNavigation',
- 'PerformanceResourceTiming',
- 'PerformanceTiming',
- 'postMessage',
- 'Promise',
- 'Request',
- 'Response',
- 'self',
- 'ServiceWorkerRegistration',
- 'setInterval',
- 'setTimeout',
- 'TextDecoder',
- 'TextEncoder',
- 'URL',
- 'URLSearchParams',
- 'WebSocket',
- 'Worker',
- 'XMLHttpRequest',
- ],
-
- // https://nodejs.org/api/globals.html
- node: [
- '__dirname',
- '__filename',
- 'Buffer',
- 'clearImmediate',
- 'clearInterval',
- 'clearTimeout',
- 'console',
- 'exports',
- 'global',
- 'module',
- 'process',
- 'require',
- 'setImmediate',
- 'setInterval',
- 'setTimeout',
- ],
- commonjs: ['exports', 'module', 'require', 'global'],
- amd: ['define', 'require'],
-
- // https://mochajs.org/
- mocha: [
- 'after',
- 'afterEach',
- 'before',
- 'beforeEach',
- 'context',
- 'describe',
- 'it',
- 'mocha',
- 'run',
- 'setup',
- 'specify',
- 'suite',
- 'suiteSetup',
- 'suiteTeardown',
- 'teardown',
- 'test',
- 'xcontext',
- 'xdescribe',
- 'xit',
- 'xspecify',
- ],
-
- // https://jasmine.github.io/2.0/introduction.html
- jasmine: [
- 'afterAll',
- 'afterEach',
- 'beforeAll',
- 'beforeEach',
- 'describe',
- 'expect',
- 'fail',
- 'fdescribe',
- 'fit',
- 'it',
- 'jasmine',
- 'pending',
- 'runs',
- 'spyOn',
- 'waits',
- 'waitsFor',
- 'xdescribe',
- 'xit',
- ],
- jest: [
- 'afterAll',
- 'afterEach',
- 'beforeAll',
- 'beforeEach',
- 'check',
- 'describe',
- 'expect',
- 'gen',
- 'it',
- 'fit',
- 'jest',
- 'pit',
- 'require',
- 'test',
- 'xdescribe',
- 'xit',
- 'xtest',
- ],
- qunit: [
- 'asyncTest',
- 'deepEqual',
- 'equal',
- 'expect',
- 'module',
- 'notDeepEqual',
- 'notEqual',
- 'notOk',
- 'notPropEqual',
- 'notStrictEqual',
- 'ok',
- 'propEqual',
- 'QUnit',
- 'raises',
- 'start',
- 'stop',
- 'strictEqual',
- 'test',
- 'throws',
- ],
- phantomjs: ['console', 'exports', 'phantom', 'require', 'WebPage'],
- couch: [
- 'emit',
- 'exports',
- 'getRow',
- 'log',
- 'module',
- 'provides',
- 'require',
- 'respond',
- 'send',
- 'start',
- 'sum',
- ],
- rhino: [
- 'defineClass',
- 'deserialize',
- 'gc',
- 'help',
- 'importClass',
- 'importPackage',
- 'java',
- 'load',
- 'loadClass',
- 'Packages',
- 'print',
- 'quit',
- 'readFile',
- 'readUrl',
- 'runCommand',
- 'seal',
- 'serialize',
- 'spawn',
- 'sync',
- 'toint32',
- 'version',
- ],
- nashorn: [
- '__DIR__',
- '__FILE__',
- '__LINE__',
- 'com',
- 'edu',
- 'exit',
- 'Java',
- 'java',
- 'javafx',
- 'JavaImporter',
- 'javax',
- 'JSAdapter',
- 'load',
- 'loadWithNewGlobal',
- 'org',
- 'Packages',
- 'print',
- 'quit',
- ],
- wsh: [
- 'ActiveXObject',
- 'Enumerator',
- 'GetObject',
- 'ScriptEngine',
- 'ScriptEngineBuildVersion',
- 'ScriptEngineMajorVersion',
- 'ScriptEngineMinorVersion',
- 'VBArray',
- 'WScript',
- 'WSH',
- 'XDomainRequest',
- ],
- jquery: ['$', 'jQuery'],
- yui: ['Y', 'YUI', 'YUI_config'],
- shelljs: [
- 'cat',
- 'cd',
- 'chmod',
- 'config',
- 'cp',
- 'dirs',
- 'echo',
- 'env',
- 'error',
- 'exec',
- 'exit',
- 'find',
- 'grep',
- 'ls',
- 'ln',
- 'mkdir',
- 'mv',
- 'popd',
- 'pushd',
- 'pwd',
- 'rm',
- 'sed',
- 'set',
- 'target',
- 'tempdir',
- 'test',
- 'touch',
- 'which',
- ],
- prototypejs: [
- '$',
- '$$',
- '$A',
- '$break',
- '$continue',
- '$F',
- '$H',
- '$R',
- '$w',
- 'Abstract',
- 'Ajax',
- 'Autocompleter',
- 'Builder',
- 'Class',
- 'Control',
- 'Draggable',
- 'Draggables',
- 'Droppables',
- 'Effect',
- 'Element',
- 'Enumerable',
- 'Event',
- 'Field',
- 'Form',
- 'Hash',
- 'Insertion',
- 'ObjectRange',
- 'PeriodicalExecuter',
- 'Position',
- 'Prototype',
- 'Scriptaculous',
- 'Selector',
- 'Sortable',
- 'SortableObserver',
- 'Sound',
- 'Template',
- 'Toggle',
- 'Try',
- ],
- meteor: [
- '$',
- '_',
- 'Accounts',
- 'AccountsClient',
- 'AccountsServer',
- 'AccountsCommon',
- 'App',
- 'Assets',
- 'Blaze',
- 'check',
- 'Cordova',
- 'DDP',
- 'DDPServer',
- 'DDPRateLimiter',
- 'Deps',
- 'EJSON',
- 'Email',
- 'HTTP',
- 'Log',
- 'Match',
- 'Meteor',
- 'Mongo',
- 'MongoInternals',
- 'Npm',
- 'Package',
- 'Plugin',
- 'process',
- 'Random',
- 'ReactiveDict',
- 'ReactiveVar',
- 'Router',
- 'ServiceConfiguration',
- 'Session',
- 'share',
- 'Spacebars',
- 'Template',
- 'Tinytest',
- 'Tracker',
- 'UI',
- 'Utils',
- 'WebApp',
- 'WebAppInternals',
- ],
- mongo: [
- '_isWindows',
- '_rand',
- 'BulkWriteResult',
- 'cat',
- 'cd',
- 'connect',
- 'db',
- 'getHostName',
- 'getMemInfo',
- 'hostname',
- 'ISODate',
- 'listFiles',
- 'load',
- 'ls',
- 'md5sumFile',
- 'mkdir',
- 'Mongo',
- 'NumberInt',
- 'NumberLong',
- 'ObjectId',
- 'PlanCache',
- 'print',
- 'printjson',
- 'pwd',
- 'quit',
- 'removeFile',
- 'rs',
- 'sh',
- 'UUID',
- 'version',
- 'WriteResult',
- ],
- applescript: [
- '$',
- 'Application',
- 'Automation',
- 'console',
- 'delay',
- 'Library',
- 'ObjC',
- 'ObjectSpecifier',
- 'Path',
- 'Progress',
- 'Ref',
- ],
- serviceworker: [
- 'caches',
- 'Cache',
- 'CacheStorage',
- 'Client',
- 'clients',
- 'Clients',
- 'ExtendableEvent',
- 'ExtendableMessageEvent',
- 'FetchEvent',
- 'importScripts',
- 'registration',
- 'self',
- 'ServiceWorker',
- 'ServiceWorkerContainer',
- 'ServiceWorkerGlobalScope',
- 'ServiceWorkerMessageEvent',
- 'ServiceWorkerRegistration',
- 'skipWaiting',
- 'WindowClient',
- ],
- atomtest: [
- 'advanceClock',
- 'fakeClearInterval',
- 'fakeClearTimeout',
- 'fakeSetInterval',
- 'fakeSetTimeout',
- 'resetTimeouts',
- 'waitsForPromise',
- ],
-
- // https://guides.emberjs.com/v1.10.0/testing/test-helpers/
- embertest: [
- 'andThen',
- 'click',
- 'currentPath',
- 'currentRouteName',
- 'currentURL',
- 'fillIn',
- 'find',
- 'findWithAssert',
- 'keyEvent',
- 'pauseTest',
- 'triggerEvent',
- 'visit',
- ],
- protractor: ['$', '$$', 'browser', 'By', 'by', 'DartObject', 'element', 'protractor'],
- 'shared-node-browser': ['clearInterval', 'clearTimeout', 'console', 'setInterval', 'setTimeout'],
- webextensions: ['browser', 'chrome', 'opr'],
- greasemonkey: [
- 'GM_addStyle',
- 'GM_deleteValue',
- 'GM_getResourceText',
- 'GM_getResourceURL',
- 'GM_getValue',
- 'GM_info',
- 'GM_listValues',
- 'GM_log',
- 'GM_openInTab',
- 'GM_registerMenuCommand',
- 'GM_setClipboard',
- 'GM_setValue',
- 'GM_xmlhttpRequest',
- 'unsafeWindow',
- ],
- flow: [
- 'boolean',
- 'number',
- 'string',
- 'null',
- 'void',
- 'mixed',
- 'any',
- 'empty',
- 'Array',
- 'Class',
- '$Call',
- '$TupleMap',
- '$ObjMap',
- '$ElementType',
- '$PropertyType',
- '$Rest',
- '$Diff',
- '$Exact',
- '$ReadOnly',
- '$ReadOnlyArray',
- '$Values',
- '$Keys',
- '$SuperType',
- '$Subtype',
- 'RegExp$flags',
- 'stream$Writable',
- 'stream$Readable',
- 'tty$WriteStream',
- 'tty$ReadStream',
- ],
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/index.ts b/eslint-bridge/src/linting/eslint/rules/helpers/index.ts
deleted file mode 100644
index da3d26e2c1b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/index.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './ancestor';
-export * from './ast';
-export * from './chai';
-export * from './collection';
-export * from './express';
-export * from './file';
-export * from './globals';
-export * from './location';
-export * from './lva';
-export * from './mocha';
-export * from './module';
-export * from './quickfix';
-export * from './reaching-definitions';
-export * from './rule-detect-react';
-export * from './type';
-
-export * from 'eslint-plugin-sonarjs/lib/utils/parser-services';
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/location.ts b/eslint-bridge/src/linting/eslint/rules/helpers/location.ts
deleted file mode 100644
index 0bb9f1d4f36..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/location.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { AST } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { EncodedMessage, IssueLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-
-export type LocationHolder = AST.Token | TSESTree.Node | estree.Node | { loc: AST.SourceLocation };
-
-/**
- * Encodes an ESLint descriptor message with secondary locations
- *
- * The encoding consists in stringifying a JavaScript object with
- * `JSON.stringify` that includes the ESLint's descriptor message
- * along with second location information: message and location.
- *
- * This encoded message is eventually decoded by the linter wrapper
- * on the condition that the rule definition of the flagged problem
- * defines the internal `sonar-runtime` parameter in its schema.
- *
- * @param message the ESLint descriptor message
- * @param secondaryLocationsHolder the secondary locations
- * @param secondaryMessages the messages for each secondary location
- * @param cost the optional cost to fix
- * @returns the encoded message with secondary locations
- */
-export function toEncodedMessage(
- message: string,
- secondaryLocationsHolder: Array = [],
- secondaryMessages?: (string | undefined)[],
- cost?: number,
-): string {
- const encodedMessage: EncodedMessage = {
- message,
- cost,
- secondaryLocations: secondaryLocationsHolder.map((locationHolder, index) =>
- toSecondaryLocation(
- locationHolder,
- !!secondaryMessages ? secondaryMessages[index] : undefined,
- ),
- ),
- };
- return JSON.stringify(encodedMessage);
-}
-
-function toSecondaryLocation(locationHolder: LocationHolder, message?: string): IssueLocation {
- if (!locationHolder.loc) {
- throw new Error('Invalid secondary location');
- }
- return {
- message,
- column: locationHolder.loc.start.column,
- line: locationHolder.loc.start.line,
- endColumn: locationHolder.loc.end.column,
- endLine: locationHolder.loc.end.line,
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/lva.ts b/eslint-bridge/src/linting/eslint/rules/helpers/lva.ts
deleted file mode 100644
index 227da767262..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/lva.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, Scope } from 'eslint';
-import Variable = Scope.Variable;
-import CodePathSegment = Rule.CodePathSegment;
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/typescript-estree';
-
-export function lva(liveVariablesMap: Map) {
- const worklist = Array.from(liveVariablesMap.values(), lva => lva.segment);
- while (worklist.length > 0) {
- const current = worklist.pop()!;
- const liveVariables = liveVariablesMap.get(current.id)!;
- const liveInHasChanged = liveVariables.propagate(liveVariablesMap);
- if (liveInHasChanged) {
- current.prevSegments.forEach(prev => worklist.push(prev));
- }
- }
-}
-
-export interface ReferenceLike {
- identifier: estree.Identifier | TSESTree.JSXIdentifier;
- from: Scope.Scope;
- resolved: Scope.Variable | null;
- writeExpr: estree.Node | null;
- init: boolean;
-
- isWrite(): boolean;
-
- isRead(): boolean;
-
- isWriteOnly(): boolean;
-
- isReadOnly(): boolean;
-
- isReadWrite(): boolean;
-}
-
-export class LiveVariables {
- constructor(segment: Rule.CodePathSegment) {
- this.segment = segment;
- }
-
- segment: CodePathSegment;
-
- /**
- * variables that are being read in the block
- */
- gen = new Set();
- /**
- * variables that are being written in the block
- */
- kill = new Set();
- /**
- * variables needed by this or a successor block and are not killed in this block
- */
- in = new Set();
- /**
- * variables needed by successors
- */
- out: Variable[] = [];
-
- /**
- * collects references in order they are evaluated, set in JS maintains insertion order
- */
- references = new Set();
-
- add(ref: ReferenceLike) {
- const variable = ref.resolved;
- if (variable) {
- if (ref.isRead()) {
- this.gen.add(variable);
- }
- if (ref.isWrite()) {
- this.kill.add(variable);
- }
- this.references.add(ref);
- }
- }
-
- propagate(liveVariablesMap: Map) {
- const out: Variable[] = [];
- this.segment.nextSegments.forEach(next => {
- out.push(...liveVariablesMap.get(next.id)!.in);
- });
- const diff = difference(out, this.kill);
- this.out = out;
- if (shouldUpdate(this.in, this.gen, diff)) {
- this.in = new Set([...this.gen, ...diff]);
- return true;
- } else {
- return false;
- }
- }
-}
-
-function difference(a: T[], b: Set): T[] {
- if (b.size === 0) {
- return a;
- }
- const diff = [];
- for (const e of a) {
- if (!b.has(e)) {
- diff.push(e);
- }
- }
- return diff;
-}
-
-function shouldUpdate(inSet: Set, gen: Set, diff: Variable[]): boolean {
- for (const e of gen) {
- if (!inSet.has(e)) {
- return true;
- }
- }
- for (const e of diff) {
- if (!inSet.has(e)) {
- return true;
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/mocha.ts b/eslint-bridge/src/linting/eslint/rules/helpers/mocha.ts
deleted file mode 100644
index 25a887c9f72..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/mocha.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { FUNCTION_NODES, isIdentifier } from '.';
-
-export namespace Mocha {
- const TEST_CONSTRUCTS = [
- 'describe',
- 'context',
- 'it',
- 'specify',
- 'before',
- 'after',
- 'beforeEach',
- 'afterEach',
- ];
-
- export interface TestCase {
- node: estree.Node;
- callback: estree.Function;
- }
-
- export function isTestConstruct(
- node: estree.Node,
- constructs: string[] = TEST_CONSTRUCTS,
- ): boolean {
- return constructs.some(construct => {
- return (
- node.type === 'CallExpression' &&
- (isIdentifier(node.callee, construct) ||
- (node.callee.type === 'MemberExpression' &&
- isIdentifier(node.callee.object, construct) &&
- isIdentifier(node.callee.property, 'only', 'skip')))
- );
- });
- }
-
- export function extractTestCase(node: estree.Node): TestCase | null {
- if (isTestCase(node)) {
- const callExpr = node as estree.CallExpression;
- const [, callback] = callExpr.arguments;
- if (callback && FUNCTION_NODES.includes(callback.type)) {
- return { node: callExpr.callee, callback: callback as estree.Function };
- }
- }
- return null;
- }
-
- export function isTestCase(node: estree.Node): boolean {
- return isTestConstruct(node, ['it', 'specify']);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/module.ts b/eslint-bridge/src/linting/eslint/rules/helpers/module.ts
deleted file mode 100644
index a71c4bb7f66..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/module.ts
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Node, isIdentifier, getVariableFromScope, getUniqueWriteReference } from './ast';
-import Variable = Scope.Variable;
-
-export function getImportDeclarations(context: Rule.RuleContext) {
- const program = context.getSourceCode().ast;
- if (program.sourceType === 'module') {
- return program.body.filter(
- node => node.type === 'ImportDeclaration',
- ) as estree.ImportDeclaration[];
- }
- return [];
-}
-
-export function getRequireCalls(context: Rule.RuleContext) {
- const required: estree.CallExpression[] = [];
- const { scopeManager } = context.getSourceCode();
- scopeManager.scopes.forEach(scope =>
- scope.variables.forEach(variable =>
- variable.defs.forEach(def => {
- if (def.type === 'Variable' && def.node.init) {
- if (isRequire(def.node.init)) {
- required.push(def.node.init as estree.CallExpression);
- } else if (def.node.init.type === 'MemberExpression' && isRequire(def.node.init.object)) {
- required.push(def.node.init.object as estree.CallExpression);
- }
- }
- }),
- ),
- );
- return required;
-}
-
-function isRequire(node: Node) {
- return (
- node.type === 'CallExpression' &&
- node.callee.type === 'Identifier' &&
- node.callee.name === 'require' &&
- node.arguments.length === 1
- );
-}
-
-/**
- * Returns 'module' if `node` is a `require('module')` CallExpression
- *
- * For usage inside rules, prefer getFullyQualifiedName()
- *
- * @param node
- * @returns the module name or undefined
- */
-function getModuleNameFromRequire(node: Node): estree.Literal | undefined {
- if (isRequire(node)) {
- const moduleName = (node as estree.CallExpression).arguments[0];
- if (moduleName.type === 'Literal') {
- return moduleName;
- }
- }
- return undefined;
-}
-
-/**
- * Returns the fully qualified name of ESLint node
- *
- * This function filters out the `node:` prefix
- *
- * A fully qualified name here denotes a value that is accessed through an imported
- * symbol, e.g., `foo.bar.baz` where `foo` was imported either from a require call
- * or an import statement:
- *
- * ```
- * const foo = require('lib');
- * foo.bar.baz.qux; // matches the fully qualified name 'lib.bar.baz.qux' (not 'foo.bar.baz.qux')
- * const foo2 = require('lib').bar;
- * foo2.baz.qux; // matches the fully qualified name 'lib.bar.baz.qux'
- * ```
- *
- * Returns null when an FQN could not be found.
- *
- * @param context the rule context
- * @param node the node
- * @param fqn the already traversed FQN (for recursive calls)
- * @param scope scope to look for the variable definition, used in recursion not to
- * loop over same variable always in the lower scope
- */
-export function getFullyQualifiedName(
- context: Rule.RuleContext,
- node: estree.Node,
- fqn: string[] = [],
- scope?: Scope.Scope,
-): string | null {
- return removeNodePrefixIfExists(getFullyQualifiedNameRaw(context, node, fqn, scope));
-}
-
-/**
- * Just like getFullyQualifiedName(), but does not filter out the `node:` prefix.
- *
- * To be used for rules that need to work with the `node:` prefix.
- */
-export function getFullyQualifiedNameRaw(
- context: Rule.RuleContext,
- node: estree.Node,
- fqn: string[],
- scope?: Scope.Scope,
- visitedVars: Variable[] = [],
-): string | null {
- let nodeToCheck = reduceToIdentifier(node, fqn);
-
- if (!isIdentifier(nodeToCheck)) {
- // require chaining, e.g. `require('lib')()` or `require('lib').prop()`
- if (node.type === 'CallExpression') {
- const qualifiers: string[] = [];
- const maybeRequire = reduceTo('CallExpression', node.callee, qualifiers);
- const module = getModuleNameFromRequire(maybeRequire);
- if (typeof module?.value === 'string') {
- qualifiers.unshift(module.value);
- return qualifiers.join('.');
- }
- }
- return null;
- }
-
- const variable = getVariableFromScope(scope || context.getScope(), nodeToCheck.name);
-
- if (!variable || variable.defs.length > 1) {
- return null;
- }
-
- // built-in variable
- // ESLint marks built-in global variables with an undocumented hidden `writeable` property that should equal `false`.
- // @see https://github.com/eslint/eslint/blob/6380c87c563be5dc78ce0ddd5c7409aaf71692bb/lib/linter/linter.js#L207
- // @see https://github.com/eslint/eslint/blob/6380c87c563be5dc78ce0ddd5c7409aaf71692bb/lib/rules/no-global-assign.js#L81
- if ((variable as any).writeable === false || visitedVars.includes(variable)) {
- fqn.unshift(nodeToCheck.name);
- return fqn.join('.');
- }
-
- const definition = variable.defs.find(({ type }) => ['ImportBinding', 'Variable'].includes(type));
-
- if (!definition) {
- return null;
- }
-
- // imports
- const fqnFromImport = checkFqnFromImport(variable, definition, context, fqn, visitedVars);
- if (fqnFromImport !== null) {
- return fqnFromImport;
- }
-
- // requires
- const fqnFromRequire = checkFqnFromRequire(variable, definition, context, fqn, visitedVars);
- if (fqnFromRequire !== null) {
- return fqnFromRequire;
- }
-
- return null;
-}
-
-function checkFqnFromImport(
- variable: Scope.Variable,
- definition: Scope.Definition,
- context: Rule.RuleContext,
- fqn: string[],
- visitedVars: Variable[],
-) {
- if (definition.type === 'ImportBinding') {
- const specifier = definition.node;
- const importDeclaration = definition.parent;
- // import {default as cdk} from 'aws-cdk-lib';
- // vs.
- // import { aws_s3 as s3 } from 'aws-cdk-lib';
- if (specifier.type === 'ImportSpecifier' && specifier.imported?.name !== 'default') {
- fqn.unshift(specifier.imported?.name);
- }
- if (typeof importDeclaration.source?.value === 'string') {
- const importedQualifiers = importDeclaration.source.value.split('/');
- fqn.unshift(...importedQualifiers);
- return fqn.join('.');
- }
- // import s3 = require('aws-cdk-lib/aws-s3');
- if ((importDeclaration as TSESTree.Node).type === 'TSImportEqualsDeclaration') {
- const importedModule = (importDeclaration as unknown as TSESTree.TSImportEqualsDeclaration)
- .moduleReference;
- if (
- importedModule.type === 'TSExternalModuleReference' &&
- importedModule.expression.type === 'Literal' &&
- typeof importedModule.expression.value === 'string'
- ) {
- const importedQualifiers = importedModule.expression.value.split('/');
- fqn.unshift(...importedQualifiers);
- return fqn.join('.');
- }
- //import s3 = cdk.aws_s3;
- if (importedModule.type === 'TSQualifiedName') {
- visitedVars.push(variable);
- return getFullyQualifiedNameRaw(
- context,
- importedModule as unknown as estree.Node,
- fqn,
- variable.scope,
- visitedVars,
- );
- }
- }
- }
- return null;
-}
-
-function checkFqnFromRequire(
- variable: Scope.Variable,
- definition: Scope.Definition,
- context: Rule.RuleContext,
- fqn: string[],
- visitedVars: Variable[],
-) {
- const value = getUniqueWriteReference(variable);
- // requires
- if (definition.type === 'Variable' && value) {
- // case for `const {Bucket} = require('aws-cdk-lib/aws-s3');`
- // case for `const {Bucket: foo} = require('aws-cdk-lib/aws-s3');`
- if (definition.node.id.type === 'ObjectPattern') {
- for (const property of definition.node.id.properties) {
- if ((property as estree.Property).value === definition.name) {
- fqn.unshift(((property as estree.Property).key as estree.Identifier).name);
- }
- }
- }
- const nodeToCheck = reduceTo('CallExpression', value, fqn);
- const module = getModuleNameFromRequire(nodeToCheck)?.value;
- if (typeof module === 'string') {
- const importedQualifiers = module.split('/');
- fqn.unshift(...importedQualifiers);
- return fqn.join('.');
- } else {
- visitedVars.push(variable);
- return getFullyQualifiedNameRaw(context, nodeToCheck, fqn, variable.scope, visitedVars);
- }
- }
- return null;
-}
-
-/**
- * Removes `node:` prefix if such exists
- *
- * Node.js builtin modules can be referenced with a `node:` prefix (eg.: node:fs/promises)
- *
- * https://nodejs.org/api/esm.html#node-imports
- *
- * @param fqn Fully Qualified Name (ex.: `node:https.request`)
- * @returns `fqn` sanitized from `node:` prefix (ex.: `https.request`)
- */
-function removeNodePrefixIfExists(fqn: string | null) {
- if (fqn === null) {
- return null;
- }
- const NODE_NAMESPACE = 'node:';
- if (fqn.startsWith(NODE_NAMESPACE)) {
- return fqn.substring(NODE_NAMESPACE.length);
- }
- return fqn;
-}
-
-/**
- * Helper function for getFullyQualifiedName to handle Member expressions
- * filling in the FQN array with the accessed properties.
- * @param node the Node to traverse
- * @param fqn the array with the qualifiers
- */
-export function reduceToIdentifier(node: estree.Node, fqn: string[] = []): estree.Node {
- return reduceTo('Identifier', node, fqn);
-}
-
-/**
- * Reduce a given node through its ancestors until a given node type is found
- * filling in the FQN array with the accessed properties.
- * @param type the type of node you are looking for to be returned. Returned node still needs to be
- * checked as its type it's not guaranteed to match the passed type.
- * @param node the Node to traverse
- * @param fqn the array with the qualifiers
- */
-export function reduceTo(
- type: T,
- node: estree.Node,
- fqn: string[] = [],
-): estree.Node {
- let nodeToCheck: estree.Node = node;
-
- while (nodeToCheck.type !== type) {
- if (nodeToCheck.type === 'MemberExpression') {
- const { property } = nodeToCheck;
- if (property.type === 'Literal' && typeof property.value === 'string') {
- fqn.unshift(property.value);
- } else if (property.type === 'Identifier') {
- fqn.unshift(property.name);
- }
- nodeToCheck = nodeToCheck.object;
- } else if (nodeToCheck.type === 'CallExpression' && !getModuleNameFromRequire(nodeToCheck)) {
- nodeToCheck = nodeToCheck.callee;
- } else if (nodeToCheck.type === 'NewExpression') {
- nodeToCheck = nodeToCheck.callee;
- } else if (nodeToCheck.type === 'ChainExpression') {
- nodeToCheck = nodeToCheck.expression;
- } else if ((nodeToCheck as TSESTree.Node).type === 'TSNonNullExpression') {
- // we should migrate to use only TSESTree types everywhere to avoid casting
- nodeToCheck = (nodeToCheck as unknown as TSESTree.TSNonNullExpression)
- .expression as estree.Expression;
- } else if ((nodeToCheck as TSESTree.Node).type === 'TSQualifiedName') {
- const qualified = nodeToCheck as unknown as TSESTree.TSQualifiedName;
- fqn.unshift(qualified.right.name);
- nodeToCheck = qualified.left as estree.Node;
- } else {
- break;
- }
- }
-
- return nodeToCheck;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/quickfix.ts b/eslint-bridge/src/linting/eslint/rules/helpers/quickfix.ts
deleted file mode 100644
index f8d5c74bdcb..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/quickfix.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { Rule } from 'eslint';
-
-export function removeNodeWithLeadingWhitespaces(
- context: Rule.RuleContext,
- node: estree.Node,
- fixer: Rule.RuleFixer,
- removeUntil?: number,
-) {
- const previousComments = context.getSourceCode().getCommentsBefore(node);
- let start = 0;
- if (previousComments.length === 0) {
- const previousToken = context.getSourceCode().getTokenBefore(node);
- if (previousToken) {
- start = previousToken.range[1];
- }
- } else {
- start = previousComments[previousComments.length - 1].range![1];
- }
-
- const end = removeUntil ? removeUntil : node.range![1];
- return fixer.removeRange([start, end]);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/reaching-definitions.ts b/eslint-bridge/src/linting/eslint/rules/helpers/reaching-definitions.ts
deleted file mode 100644
index b1bb2f390ab..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/reaching-definitions.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import Variable = Scope.Variable;
-import CodePathSegment = Rule.CodePathSegment;
-import Reference = Scope.Reference;
-
-type LiteralValue = string;
-
-class AssignedValues extends Set {
- type: 'AssignedValues' = 'AssignedValues';
-}
-
-const assignedValues = (val: LiteralValue) => new AssignedValues([val]);
-interface UnknownValue {
- type: 'UnknownValue';
-}
-export const unknownValue: UnknownValue = {
- type: 'UnknownValue',
-};
-
-export type Values = AssignedValues | UnknownValue;
-
-export function reachingDefinitions(reachingDefinitionsMap: Map) {
- const worklist = Array.from(reachingDefinitionsMap.values(), defs => defs.segment);
-
- while (worklist.length > 0) {
- const current = worklist.pop()!;
- const reachingDefs = reachingDefinitionsMap.get(current.id)!;
- const outHasChanged = reachingDefs.propagate(reachingDefinitionsMap);
- if (outHasChanged) {
- current.nextSegments.forEach(next => worklist.push(next));
- }
- }
-}
-
-export class ReachingDefinitions {
- constructor(segment: Rule.CodePathSegment) {
- this.segment = segment;
- }
-
- segment: CodePathSegment;
-
- in = new Map();
-
- out = new Map();
-
- /**
- * collects references in order they are evaluated, set in JS maintains insertion order
- */
- references = new Set();
-
- add(ref: Reference) {
- const variable = ref.resolved;
- if (variable) {
- this.references.add(ref);
- }
- }
-
- propagate(reachingDefinitionsMap: Map) {
- this.in.clear();
- this.segment.prevSegments.forEach(prev => {
- this.join(reachingDefinitionsMap.get(prev.id)!.out);
- });
- const newOut = new Map(this.in);
- this.references.forEach(ref => this.updateProgramState(ref, newOut));
- if (!equals(this.out, newOut)) {
- this.out = newOut;
- return true;
- } else {
- return false;
- }
- }
-
- updateProgramState(ref: Reference, programState: Map) {
- const variable = ref.resolved;
- if (!variable || !ref.isWrite()) {
- return;
- }
- if (!ref.writeExpr) {
- programState.set(variable, unknownValue);
- return;
- }
- const rhsValues = resolveAssignedValues(variable, ref.writeExpr, programState, ref.from);
- programState.set(variable, rhsValues);
- }
-
- join(previousOut: Map) {
- for (const [key, values] of previousOut.entries()) {
- const inValues = this.in.get(key) || new AssignedValues();
- if (inValues.type === 'AssignedValues' && values.type === 'AssignedValues') {
- values.forEach(val => inValues.add(val));
- this.in.set(key, inValues);
- } else {
- this.in.set(key, unknownValue);
- }
- }
- }
-}
-
-export function resolveAssignedValues(
- lhsVariable: Variable,
- writeExpr: estree.Node | null,
- assignedValuesMap: Map,
- scope: Scope.Scope,
-): Values {
- if (!writeExpr) {
- return unknownValue;
- }
- switch (writeExpr.type) {
- case 'Literal':
- return writeExpr.raw ? assignedValues(writeExpr.raw) : unknownValue;
- case 'Identifier':
- const resolvedVar = getVariableFromIdentifier(writeExpr, scope);
- if (resolvedVar && resolvedVar !== lhsVariable) {
- const resolvedAssignedValues = assignedValuesMap.get(resolvedVar);
- return resolvedAssignedValues || unknownValue;
- }
- return unknownValue;
- default:
- return unknownValue;
- }
-}
-
-function equals(ps1: Map, ps2: Map) {
- if (ps1.size !== ps2.size) {
- return false;
- }
- for (const [variable, values1] of ps1) {
- const values2 = ps2.get(variable);
- if (!values2 || !valuesEquals(values2, values1)) {
- return false;
- }
- }
- return true;
-}
-
-function valuesEquals(a: Values, b: Values) {
- if (a.type === 'AssignedValues' && b.type === 'AssignedValues') {
- return setEquals(a, b);
- }
- return a === b;
-}
-
-function setEquals(a: Set, b: Set): boolean {
- return a.size === b.size && [...a].every(e => b.has(e));
-}
-
-export function getVariableFromIdentifier(identifier: estree.Identifier, scope: Scope.Scope) {
- let variable = scope.variables.find(value => value.name === identifier.name);
- if (!variable && scope.upper) {
- variable = scope.upper.variables.find(value => value.name === identifier.name);
- }
- return variable;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/alternation.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/alternation.ts
deleted file mode 100644
index 36773c6d134..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/alternation.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { CapturingGroup, Group, LookaroundAssertion, Pattern } from 'regexpp/ast';
-
-/**
- * An alternation is a regexpp node that has an `alternatives` field.
- */
-export type Alternation = Pattern | CapturingGroup | Group | LookaroundAssertion;
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/ast.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/ast.ts
deleted file mode 100644
index 7983e4f7685..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/ast.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { ParserServices } from '@typescript-eslint/experimental-utils';
-import * as estree from 'estree';
-import { isIdentifier, isString } from 'linting/eslint/rules/helpers';
-
-export function isRegExpConstructor(node: estree.Node): node is estree.CallExpression {
- return (
- ((node.type === 'CallExpression' || node.type === 'NewExpression') &&
- node.callee.type === 'Identifier' &&
- node.callee.name === 'RegExp' &&
- node.arguments.length > 0) ||
- isRegExpWithGlobalThis(node)
- );
-}
-
-export function isStringReplaceCall(call: estree.CallExpression, services: ParserServices) {
- return (
- call.callee.type === 'MemberExpression' &&
- call.callee.property.type === 'Identifier' &&
- !call.callee.computed &&
- ['replace', 'replaceAll'].includes(call.callee.property.name) &&
- call.arguments.length > 1 &&
- isString(call.callee.object, services)
- );
-}
-
-export function isStringRegexMethodCall(call: estree.CallExpression, services: ParserServices) {
- return (
- call.callee.type === 'MemberExpression' &&
- call.callee.property.type === 'Identifier' &&
- !call.callee.computed &&
- ['match', 'matchAll', 'search'].includes(call.callee.property.name) &&
- call.arguments.length > 0 &&
- isString(call.callee.object, services) &&
- isString(call.arguments[0], services)
- );
-}
-
-function isRegExpWithGlobalThis(node: estree.Node) {
- return (
- node.type === 'NewExpression' &&
- node.callee.type === 'MemberExpression' &&
- isIdentifier(node.callee.object, 'globalThis') &&
- isIdentifier(node.callee.property, 'RegExp') &&
- node.arguments.length > 0
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/extract.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/extract.ts
deleted file mode 100644
index f6061821b07..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/extract.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import { Rule } from 'eslint';
-import {
- getUniqueWriteUsage,
- isBinaryPlus,
- isIdentifier,
- isRegexLiteral,
- isStaticTemplateLiteral,
- isStringLiteral,
-} from 'linting/eslint/rules/helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRegExpConstructor } from './ast';
-import { getFlags } from './flags';
-
-export function getParsedRegex(
- node: estree.Node,
- context: Rule.RuleContext,
-): regexpp.AST.RegExpLiteral | null {
- const patternAndFlags = getPatternFromNode(node, context);
- if (patternAndFlags) {
- try {
- return regexpp.parseRegExpLiteral(new RegExp(patternAndFlags.pattern, patternAndFlags.flags));
- } catch {
- // do nothing for invalid regex
- }
- }
-
- return null;
-}
-
-function getPatternFromNode(
- node: estree.Node,
- context: Rule.RuleContext,
-): { pattern: string; flags: string } | null {
- if (isRegExpConstructor(node)) {
- const patternOnly = getPatternFromNode(node.arguments[0], context);
- const flags = getFlags(node);
- if (patternOnly && flags !== null) {
- return { pattern: patternOnly.pattern, flags };
- }
- } else if (isRegexLiteral(node)) {
- return node.regex;
- } else if (isStringLiteral(node)) {
- return { pattern: node.value as string, flags: '' };
- } else if (isStaticTemplateLiteral(node)) {
- return { pattern: node.quasis[0].value.raw, flags: '' };
- } else if (isIdentifier(node)) {
- const assignedExpression = getUniqueWriteUsage(context, node.name);
- if (
- assignedExpression &&
- (assignedExpression as TSESTree.Node).parent?.type === 'VariableDeclarator'
- ) {
- return getPatternFromNode(assignedExpression, context);
- }
- } else if (isBinaryPlus(node)) {
- const left = getPatternFromNode(node.left, context);
- const right = getPatternFromNode(node.right, context);
- if (left && right) {
- return { pattern: left.pattern + right.pattern, flags: '' };
- }
- }
-
- return null;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/flags.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/flags.ts
deleted file mode 100644
index b973cbc0872..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/flags.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-
-export function getFlags(callExpr: estree.CallExpression): string | null {
- if (callExpr.arguments.length < 2) {
- return '';
- }
- const flags = callExpr.arguments[1];
- if (flags.type === 'Literal' && typeof flags.value === 'string') {
- return flags.value;
- }
- return null;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/group.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/group.ts
deleted file mode 100644
index 00ead43999b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/group.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { isStringLiteral } from 'linting/eslint/rules/helpers';
-
-export interface GroupReference {
- raw: string;
- value: string;
-}
-
-export function extractReferences(node: estree.Node) {
- const references: GroupReference[] = [];
- if (isStringLiteral(node)) {
- const str = node.value as string;
- const reg = /\$(\d+)|\$\<([a-zA-Z][a-zA-Z0-9_]*)\>/g;
- let match: RegExpExecArray | null;
- while ((match = reg.exec(str)) !== null) {
- const [raw, index, name] = match;
- const value = index || name;
- references.push({ raw, value });
- }
- }
- return references;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/index.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/index.ts
deleted file mode 100644
index 439a3775213..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/index.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './alternation';
-export * from './ast';
-export * from './extract';
-export * from './flags';
-export * from './group';
-export * from './location';
-export * from './range';
-export * from './rule-template';
-export * from './simplified-regex-character-class';
-export * from './tokenizer';
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/location.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/location.ts
deleted file mode 100644
index b3358eb2d60..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/location.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { AST, Rule } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import { isRegexLiteral, isStringLiteral } from 'linting/eslint/rules/helpers';
-import { getRegexpRange } from './range';
-
-/**
- * Gets the regexp node location in the ESLint referential
- * @param node the ESLint regex node
- * @param regexpNode the regexp regex node
- * @param context the rule context
- * @param offset an offset to apply on the location
- * @returns the regexp node location in the ESLint referential
- */
-export function getRegexpLocation(
- node: estree.Node,
- regexpNode: regexpp.AST.Node,
- context: Rule.RuleContext,
- offset = [0, 0],
-): AST.SourceLocation {
- let loc: AST.SourceLocation;
- if (isRegexLiteral(node) || isStringLiteral(node)) {
- const source = context.getSourceCode();
- const [start] = node.range!;
- const [reStart, reEnd] = getRegexpRange(node, regexpNode);
- loc = {
- start: source.getLocFromIndex(start + reStart + offset[0]),
- end: source.getLocFromIndex(start + reEnd + offset[1]),
- };
- } else {
- loc = node.loc!;
- }
- return loc;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/range.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/range.ts
deleted file mode 100644
index ce9e5002901..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/range.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { AST } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import { last, isRegexLiteral, isStringLiteral } from 'linting/eslint/rules/helpers';
-import { tokenizeString } from './tokenizer';
-
-/**
- * Returns the location of regexpNode relative to the node, which is regexp string or literal. If the computation
- * of location fails, it returns the range of the whole node.
- */
-export function getRegexpRange(node: estree.Node, regexpNode: regexpp.AST.Node): AST.Range {
- if (isRegexLiteral(node)) {
- return [regexpNode.start, regexpNode.end];
- }
- if (isStringLiteral(node)) {
- if (node.value === '') {
- return [0, 2];
- }
- const s = node.raw!;
- const tokens = tokenizeString(unquote(s));
- if (regexpNode.start === regexpNode.end) {
- // this happens in case of empty alternative node like '|'
- if (regexpNode.start - 1 < tokens.length) {
- // '|' first empty alternative will have start = 1, end = 1
- // +1 is to account for string quote
- return [
- tokens[regexpNode.start - 1].range[0] + 1,
- tokens[regexpNode.start - 1].range[0] + 1,
- ];
- } else {
- // '|' second empty alternative regex node will have start = 2, end = 2
- // +1 is to account for string quote
- return [last(tokens).range[1] + 1, last(tokens).range[1] + 1];
- }
- }
- // regexpNode positions are 1 - based, we need to -1 to report as 0 - based
- // it's possible for node start to be outside of range, e.g. `a` in new RegExp('//a')
- const startToken = regexpNode.start - 1;
- if (tokens[startToken] === undefined) {
- // fallback when something is broken
- return nodeRange(node);
- }
- const start = tokens[startToken].range[0];
- // it's possible for node end to be outside of range, e.g. new RegExp('\n(|)')
- const endToken = Math.min(regexpNode.end - 2, tokens.length - 1);
- if (tokens[endToken] === undefined) {
- // fallback when something is broken
- return nodeRange(node);
- }
- const end = tokens[endToken].range[1];
- // +1 is needed to account for string quotes
- return [start + 1, end + 1];
- }
- if (node.type === 'TemplateLiteral') {
- // we don't support these properly
- return nodeRange(node);
- }
- throw new Error(`Expected regexp or string literal, got ${node.type}`);
-}
-
-function nodeRange(node: estree.Node): [number, number] {
- return [0, node.range![1] - node.range![0]];
-}
-
-function unquote(s: string): string {
- if (s.charAt(0) !== "'" && s.charAt(0) !== '"') {
- throw new Error(`invalid string to unquote: ${s}`);
- }
- return s.substring(1, s.length - 1);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/rule-template.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/rule-template.ts
deleted file mode 100644
index cb4a9d6ad99..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/rule-template.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import type { RegExpVisitor } from 'regexpp/visitor';
-import { isStringRegexMethodCall } from './ast';
-import { getParsedRegex } from './extract';
-import { getRegexpLocation } from './location';
-import { isRequiredParserServices } from '..';
-
-/**
- * Rule context for regex rules that also includes the original ESLint node
- * denoting the regular expression (string) literal.
- */
-export type RegexRuleContext = Rule.RuleContext & {
- node: estree.Node;
- reportRegExpNode: (descriptor: RegexReportDescriptor) => void;
-};
-
-type RegexReportMessage = { message: string } | { messageId: string };
-type RegexReportData = {
- regexpNode: regexpp.AST.Node;
- node: estree.Node;
- offset?: [number, number];
-};
-type RegexReportDescriptor = RegexReportData & RegexReportMessage;
-
-/**
- * Rule template to create regex rules.
- * @param handlers - the regexpp node handlers
- * @param meta - the (optional) rule metadata
- * @returns the resulting rule module
- */
-export function createRegExpRule(
- handlers: (context: RegexRuleContext) => RegExpVisitor.Handlers,
- metadata: { meta: Rule.RuleMetaData } = { meta: {} },
-): Rule.RuleModule {
- return {
- ...metadata,
- create(context: Rule.RuleContext) {
- const services = isRequiredParserServices(context.parserServices)
- ? context.parserServices
- : null;
-
- function checkRegex(node: estree.Node, regExpAST: regexpp.AST.Node | null) {
- if (!regExpAST) {
- return;
- }
- const ctx = Object.create(context) as RegexRuleContext;
- ctx.node = node;
- ctx.reportRegExpNode = reportRegExpNode;
- regexpp.visitRegExpAST(regExpAST, handlers(ctx));
- }
-
- function reportRegExpNode(descriptor: RegexReportDescriptor) {
- const { node, regexpNode, offset = [0, 0] } = descriptor;
- const loc = getRegexpLocation(node, regexpNode, context, offset);
- if ('message' in descriptor) {
- context.report({ message: descriptor.message, loc });
- } else if ('messageId' in descriptor) {
- context.report({ messageId: descriptor.messageId, loc });
- }
- }
-
- function checkLiteral(literal: estree.Literal) {
- checkRegex(literal, getParsedRegex(literal, context));
- }
-
- function checkCallExpression(callExpr: estree.CallExpression) {
- let parsedRegex = getParsedRegex(callExpr, context);
- if (!parsedRegex && services && isStringRegexMethodCall(callExpr, services)) {
- const [implicitRegex] = callExpr.arguments;
- parsedRegex = getParsedRegex(implicitRegex, context);
- }
- checkRegex(callExpr.arguments[0], parsedRegex);
- }
-
- return {
- 'Literal[regex]': checkLiteral,
- NewExpression: checkCallExpression,
- CallExpression: checkCallExpression,
- };
- },
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/simplified-regex-character-class.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/simplified-regex-character-class.ts
deleted file mode 100644
index e444abf6d84..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/simplified-regex-character-class.ts
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import {
- Character,
- CharacterClassElement,
- CharacterClassRange,
- CharacterSet,
- Flags,
- Node,
-} from 'regexpp/ast';
-import * as regexpp from 'regexpp';
-import createTree from 'functional-red-black-tree';
-
-const MAX_CODE_POINT = 0x10ffff;
-
-export class SimplifiedRegexCharacterClass {
- /**
- * This map defines the contents of the character class in the following way:
- * For any entry {@code codepoint -> tree}, all the codepoints from {@code codepoint} up to (and excluding) the next
- * entry are in the character class and belong to the given tree.
- * For any entry {@code codepoint -> null}, all the codepoints from {@code codepoint} up to (and excluding) the next
- * entry are not part of the character class.
- * So a codepoint is contained in this class if and only if {@code contents.le(codePoint).value} is
- * non-null and the tree returned by {@code value} will be the element of the character class which matches that
- * code point.
- */
- private contents = createTree();
-
- constructor(private readonly flags: Flags, element?: CharacterClassElement) {
- if (element) {
- this.add(element);
- }
- }
-
- public add(element: CharacterClassElement) {
- new SimplifiedRegexCharacterClass.Builder(this).visit(element);
- }
-
- public findIntersections(that: SimplifiedRegexCharacterClass) {
- const iter = that.contents.begin;
- const intersections: Node[] = [];
- if (iter.key === undefined) {
- return intersections;
- }
- while (iter.hasNext) {
- const { key, value } = iter;
- iter.next();
- const to = iter.value ? iter.key : iter.key - 1;
- if (value && this.hasEntryBetween(key, to)) {
- intersections.push(value);
- }
- }
- if (iter.value && this.hasEntryBetween(iter.key, MAX_CODE_POINT)) {
- intersections.push(iter.value);
- }
- return intersections;
- }
-
- hasEntryBetween(from: number, to: number) {
- const before = this.contents.le(from);
- return (before.key !== undefined && before.value) || !this.isRangeEmpty(from + 1, to + 1);
- }
-
- isRangeEmpty(from: number, to: number) {
- let isEmpty = true;
- this.contents.forEach(() => (isEmpty = false), from, to);
- return isEmpty;
- }
-
- addRange(from: number, to: number, element: CharacterClassElement) {
- const oldEntry = this.contents.le(to);
- const oldEnd = oldEntry.key === undefined ? undefined : this.contents.gt(oldEntry.key).key;
- this.contents = this.put(from, element, this.contents);
- const iterator = this.contents.begin;
- while (iterator.key !== undefined) {
- if (iterator.key > from && iterator.key <= to && iterator.value === undefined) {
- this.contents = iterator.update(element);
- }
- iterator.next();
- }
- const next = to + 1;
- if (next <= MAX_CODE_POINT) {
- if (oldEntry.key !== undefined && oldEntry.value && (oldEnd === undefined || oldEnd > next)) {
- this.contents = this.put(next, oldEntry.value, this.contents);
- } else if (this.contents.find(next).key === undefined) {
- this.contents = this.put(next, undefined, this.contents);
- }
- }
- }
-
- put(
- key: number,
- value: Node | undefined,
- tree: createTree.Tree,
- ) {
- const entry = tree.find(key);
- if (entry.valid) {
- return entry.update(value);
- }
- return tree.insert(key, value);
- }
-
- private static readonly Builder = class {
- constructor(private readonly characters: SimplifiedRegexCharacterClass) {}
-
- public visit(element: CharacterClassElement) {
- switch (element.type) {
- case 'Character':
- this.visitCharacter(element);
- break;
- case 'CharacterClassRange':
- this.visitCharacterClassRange(element);
- break;
- case 'CharacterSet':
- this.visitCharacterSet(element);
- break;
- }
- }
-
- visitCharacter(character: Character) {
- this.addRange(character.value, character.value, character);
- }
-
- visitCharacterClassRange(characterRange: CharacterClassRange) {
- this.addRange(characterRange.min.value, characterRange.max.value, characterRange);
- }
-
- visitCharacterSet(characterSet: CharacterSet) {
- switch (characterSet.kind) {
- case 'digit':
- if (characterSet.negate) {
- this.characters.addRange(0x00, this.codePoint('0') - 1, characterSet);
- if (this.characters.flags.unicode) {
- this.characters.addRange(this.codePoint('9') + 1, 0xff, characterSet);
- } else {
- this.characters.addRange(this.codePoint('9') + 1, MAX_CODE_POINT, characterSet);
- }
- } else {
- this.characters.addRange(this.codePoint('0'), this.codePoint('9'), characterSet);
- }
- break;
- case 'space':
- if (characterSet.negate) {
- this.characters.addRange(0x00, this.codePoint('\t') - 1, characterSet);
- this.characters.addRange(
- this.codePoint('\r') + 1,
- this.codePoint(' ') - 1,
- characterSet,
- );
- if (this.characters.flags.unicode) {
- this.characters.addRange(this.codePoint(' ') + 1, 0x84, characterSet);
- this.characters.addRange(0x86, 0x9f, characterSet);
- this.characters.addRange(0xa1, 0x167f, characterSet);
- this.characters.addRange(0x1681, 0x1fff, characterSet);
- this.characters.addRange(0x200b, 0x2027, characterSet);
- this.characters.addRange(0x202a, 0x202e, characterSet);
- this.characters.addRange(0x2030, 0x205e, characterSet);
- this.characters.addRange(0x2060, 0x2fff, characterSet);
- this.characters.addRange(0x3001, MAX_CODE_POINT, characterSet);
- } else {
- this.characters.addRange(this.codePoint(' ') + 1, MAX_CODE_POINT, characterSet);
- }
- } else {
- this.characters.addRange(this.codePoint('\t'), this.codePoint('\r'), characterSet);
- this.characters.addRange(this.codePoint(' '), this.codePoint(' '), characterSet);
- if (this.characters.flags.unicode) {
- this.characters.addRange(0x85, 0x85, characterSet);
- this.characters.addRange(0xa0, 0xa0, characterSet);
- this.characters.addRange(0x1680, 0x1680, characterSet);
- this.characters.addRange(0x2000, 0x200a, characterSet);
- this.characters.addRange(0x2028, 0x2029, characterSet);
- this.characters.addRange(0x202f, 0x202f, characterSet);
- this.characters.addRange(0x205f, 0x205f, characterSet);
- this.characters.addRange(0x3000, 0x3000, characterSet);
- }
- }
- break;
- case 'word':
- if (characterSet.negate) {
- this.characters.addRange(0x00, this.codePoint('0') - 1, characterSet);
- this.characters.addRange(
- this.codePoint('9') + 1,
- this.codePoint('A') - 1,
- characterSet,
- );
- this.characters.addRange(
- this.codePoint('Z') + 1,
- this.codePoint('_') - 1,
- characterSet,
- );
- this.characters.addRange(this.codePoint('`'), this.codePoint('`'), characterSet);
- if (this.characters.flags.unicode) {
- this.characters.addRange(
- this.codePoint('z') + 1,
- this.codePoint('µ') - 1,
- characterSet,
- );
- } else {
- this.characters.addRange(this.codePoint('z') + 1, MAX_CODE_POINT, characterSet);
- }
- } else {
- this.characters.addRange(this.codePoint('0'), this.codePoint('9'), characterSet);
- this.characters.addRange(this.codePoint('A'), this.codePoint('Z'), characterSet);
- this.characters.addRange(this.codePoint('_'), this.codePoint('_'), characterSet);
- this.characters.addRange(this.codePoint('a'), this.codePoint('z'), characterSet);
- }
- break;
- }
- }
-
- addRange(from: number, to: number, element: CharacterClassElement) {
- const upperCaseFrom = this.codePoint(String.fromCodePoint(from).toUpperCase());
- const upperCaseTo = this.codePoint(String.fromCodePoint(to).toUpperCase());
- const lowerCaseFrom = this.codePoint(String.fromCodePoint(upperCaseFrom).toLowerCase());
- const lowerCaseTo = this.codePoint(String.fromCodePoint(upperCaseTo).toLowerCase());
- if (
- this.characters.flags.ignoreCase &&
- lowerCaseFrom !== upperCaseFrom &&
- lowerCaseTo !== upperCaseTo &&
- ((this.isAscii(from) && this.isAscii(to)) || this.characters.flags.unicode)
- ) {
- this.characters.addRange(upperCaseFrom, upperCaseTo, element);
- this.characters.addRange(lowerCaseFrom, lowerCaseTo, element);
- } else {
- this.characters.addRange(from, to, element);
- }
- }
-
- isAscii(c: number) {
- return c < 128;
- }
-
- codePoint(c: string) {
- const cp = c.codePointAt(0);
- if (cp === undefined) {
- throw new Error(`failed to compute code point for: ${c}`);
- }
- return cp;
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/regex/tokenizer.ts b/eslint-bridge/src/linting/eslint/rules/helpers/regex/tokenizer.ts
deleted file mode 100644
index 74ce59cc0a1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/regex/tokenizer.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export interface StringLiteralToken {
- value: string;
- range: [number, number];
-}
-
-const UNICODE_ESCAPE_LENGTH = 4;
-const HEX_ESCAPE_LENGTH = 2;
-
-const CP_BACK_SLASH = cp('\\');
-const CP_FORWARD_SLASH = cp('/');
-const CP_CR = cp('\r');
-const CP_LF = cp('\n');
-const CP_n = cp('n');
-const CP_r = cp('r');
-const CP_t = cp('t');
-const CP_b = cp('b');
-const CP_v = cp('v');
-const CP_f = cp('f');
-const CP_u = cp('u');
-const CP_x = cp('x');
-
-/**
- * Parse 's' and return array of tokens with range. We assume 's' is correctly terminated because it was already parsed
- * into AST.
- *
- * Inspired by https://github.com/ota-meshi/eslint-plugin-regexp/blob/61ae9424e0f3bde62569718b597cdc036fec9f71/lib/utils/string-literal-parser/tokenizer.ts
- */
-export function tokenizeString(s: string): StringLiteralToken[] {
- const tokens: StringLiteralToken[] = [];
- let pos = 0;
-
- function next() {
- const c = cp(s, pos);
- pos = inc(pos, c);
- return c;
- }
-
- function readEscape(): string {
- const c = next();
- switch (c) {
- case CP_n:
- return '\n';
- case CP_r:
- return '\r';
- case CP_t:
- return '\t';
- case CP_b:
- return '\b';
- case CP_v:
- return '\v';
- case CP_f:
- return '\f';
- case CP_BACK_SLASH:
- return '\\';
- case CP_CR:
- if (cp(s, pos) === CP_LF) {
- pos++; // \r\n
- }
- return '';
- case CP_LF:
- return '';
- case CP_u:
- return String.fromCodePoint(readUnicode());
- case CP_x:
- return String.fromCodePoint(readHex());
- default:
- if (isOctalDigit(c)) {
- return readOctal(c);
- }
- return String.fromCodePoint(c);
- }
- }
-
- /**
- * read unicode escape like \u0061 or \u{61}
- */
- function readUnicode(): number {
- let u;
- if (s.charAt(pos) === '{') {
- pos++;
- const close = s.indexOf('}', pos);
- u = s.substring(pos, close);
- pos = close + 1;
- } else {
- u = s.substring(pos, pos + UNICODE_ESCAPE_LENGTH);
- pos += UNICODE_ESCAPE_LENGTH;
- }
- return Number.parseInt(u, 16);
- }
-
- /**
- * read hex escape like \xA9
- */
- function readHex(): number {
- const x = Number.parseInt(s.substring(pos, pos + HEX_ESCAPE_LENGTH), 16);
- pos += HEX_ESCAPE_LENGTH;
- return x;
- }
-
- /**
- * read octal escapes like \251. Octal escape sequences can have 1 - 3 digits
- * and can be padded with 0
- *
- * @param firstDigit digit on the current 'pos' position
- */
- function readOctal(firstDigit: number): string {
- let octal = String.fromCodePoint(firstDigit);
- let i = pos;
- while (isOctalDigit(cp(s, i)) && i - pos < 2) {
- octal += s.charAt(i);
- i++;
- }
- const res = Number.parseInt(octal, 8);
- pos = i;
- return String.fromCodePoint(res);
- }
-
- while (pos < s.length) {
- const start = pos;
- const c = next();
- if (c === CP_BACK_SLASH) {
- const value = readEscape();
- if (value !== '') {
- tokens.push({ value, range: [start, pos] });
- }
- } else if (c === CP_FORWARD_SLASH) {
- const forwardSlash: StringLiteralToken = {
- value: String.fromCodePoint(c),
- range: [start, pos],
- };
- tokens.push(forwardSlash);
- tokens.push(forwardSlash);
- } else {
- tokens.push({ value: String.fromCodePoint(c), range: [start, pos] });
- }
- }
- return tokens;
-}
-
-function inc(pos: number, c: number): number {
- // account for UTF-16 low surrogate
- return pos + (c >= 0x10000 ? 2 : 1);
-}
-
-function isOctalDigit(c: number | undefined): boolean {
- return c !== undefined && cp('0') <= c && c <= cp('7');
-}
-
-function cp(s: string, i = 0): number {
- return s.codePointAt(i)!;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/result.ts b/eslint-bridge/src/linting/eslint/rules/helpers/result.ts
deleted file mode 100644
index ed1b072bd5d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/result.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Node } from 'estree';
-import {
- getProperty,
- getUniqueWriteUsageOrNode,
- isArrayExpression,
- isBooleanLiteral,
- isStringLiteral,
- isUndefined,
- StringLiteral,
-} from './ast';
-import { Rule } from 'eslint';
-
-export class Result {
- constructor(
- readonly ctx: Rule.RuleContext,
- readonly node: Node,
- readonly status: 'missing' | 'unknown' | 'found',
- ) {}
-
- get isFound() {
- return this.status === 'found';
- }
-
- get isMissing() {
- return this.status === 'missing';
- }
-
- get isTrue() {
- return this.isFound && isBooleanLiteral(this.node) && this.node.value;
- }
-
- ofType(type: Node['type']) {
- return this.isFound && this.node.type === type;
- }
-
- getArgument(position: number): Result {
- if (!this.isFound) {
- return this;
- } else if (this.node.type !== 'NewExpression' && this.node.type !== 'CallExpression') {
- return unknown(this.ctx, this.node);
- }
-
- const argument = this.node.arguments[position];
- if (argument == null) {
- return missing(this.ctx, this.node);
- } else {
- return getResultOfExpression(this.ctx, argument);
- }
- }
-
- getProperty(propertyName: string): Result {
- if (!this.isFound) {
- return this;
- } else if (this.node.type !== 'ObjectExpression') {
- return unknown(this.ctx, this.node);
- }
-
- const property = getProperty(this.node, propertyName, this.ctx);
- if (property === undefined) {
- return unknown(this.ctx, this.node);
- } else if (property === null) {
- return missing(this.ctx, this.node);
- } else {
- return getResultOfExpression(this.ctx, property.value);
- }
- }
-
- getMemberObject(): Result {
- if (!this.isFound) {
- return this;
- } else if (this.node.type !== 'MemberExpression') {
- return unknown(this.ctx, this.node);
- } else {
- return getResultOfExpression(this.ctx, this.node.object).filter(n => n.type !== 'Super');
- }
- }
-
- findInArray(closure: (item: Result) => Result | null | undefined) {
- if (!this.isFound) {
- return this;
- } else if (!isArrayExpression(this.node)) {
- return unknown(this.ctx, this.node);
- }
-
- let isMissing = true;
-
- for (const element of this.node.elements) {
- const result = element != null ? closure(getResultOfExpression(this.ctx, element)) : null;
- if (result?.isFound) {
- return result;
- }
- isMissing &&= result?.isMissing ?? true;
- }
-
- return isMissing ? missing(this.ctx, this.node) : unknown(this.ctx, this.node);
- }
-
- everyStringLiteral(closure: (item: StringLiteral) => boolean) {
- if (!this.isFound) {
- return false;
- } else if (isStringLiteral(this.node)) {
- return closure(this.node);
- } else if (!isArrayExpression(this.node)) {
- return false;
- }
-
- for (const element of this.node.elements) {
- const child = element == null ? null : getResultOfExpression(this.ctx, element);
- if (!child?.isFound || !isStringLiteral(child.node) || !closure(child.node)) {
- return false;
- }
- }
-
- return true;
- }
-
- asStringLiterals() {
- if (!this.isFound) {
- return [];
- }
-
- const values: StringLiteral[] = [];
-
- if (isArrayExpression(this.node)) {
- for (const arg of this.node.elements) {
- const result = arg == null ? null : getResultOfExpression(this.ctx, arg);
- if (result?.isFound && isStringLiteral(result.node)) {
- values.push(result.node);
- }
- }
- } else if (isStringLiteral(this.node)) {
- values.push(this.node);
- }
-
- return values;
- }
-
- map(closure: (node: N) => V | null): V | null {
- return !this.isFound ? null : closure(this.node as N);
- }
-
- filter(closure: (node: N, ctx: Rule.RuleContext) => boolean): Result {
- if (!this.isFound) {
- return this;
- }
- return !closure(this.node as N, this.ctx) ? unknown(this.ctx, this.node) : this;
- }
-}
-
-function unknown(ctx: Rule.RuleContext, node: Node): Result {
- return new Result(ctx, node, 'unknown');
-}
-
-function missing(ctx: Rule.RuleContext, node: Node): Result {
- return new Result(ctx, node, 'missing');
-}
-
-function found(ctx: Rule.RuleContext, node: Node): Result {
- return new Result(ctx, node, 'found');
-}
-
-export function getResultOfExpression(ctx: Rule.RuleContext, node: Node): Result {
- const value = getUniqueWriteUsageOrNode(ctx, node, true);
- return isUndefined(value) ? missing(ctx, value) : found(ctx, value);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/rule-detect-react.ts b/eslint-bridge/src/linting/eslint/rules/helpers/rule-detect-react.ts
deleted file mode 100644
index eb87d5e9b1f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/rule-detect-react.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { Node } from 'estree';
-
-const detectReactSelector = [
- ':matches(',
- [
- 'CallExpression[callee.name="require"][arguments.0.value="react"]',
- 'CallExpression[callee.name="require"][arguments.0.value="create-react-class"]',
- 'ImportDeclaration[source.value="react"]',
- ].join(','),
- ')',
-].join('');
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- reactDetected: 'React detected',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- [detectReactSelector](node: Node) {
- context.report({
- messageId: 'reactDetected',
- node,
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/helpers/type.ts b/eslint-bridge/src/linting/eslint/rules/helpers/type.ts
deleted file mode 100644
index a0e829185dd..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/helpers/type.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import ts from 'typescript';
-import { TSESTree, TSESLint } from '@typescript-eslint/experimental-utils';
-import { RequiredParserServices } from 'eslint-plugin-sonarjs/lib/utils/parser-services';
-
-export type RuleContext = TSESLint.RuleContext;
-
-export function isArray(node: estree.Node, services: RequiredParserServices) {
- const type = getTypeFromTreeNode(node, services);
- return type.symbol && type.symbol.name === 'Array';
-}
-
-export function isString(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- const typ = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
- return (typ.getFlags() & ts.TypeFlags.StringLike) !== 0;
-}
-
-export function isNumber(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- const typ = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
- return (typ.getFlags() & ts.TypeFlags.NumberLike) !== 0;
-}
-
-export function isBigIntType(type: ts.Type) {
- return (type.getFlags() & ts.TypeFlags.BigIntLike) !== 0;
-}
-
-export function isNumberType(type: ts.Type) {
- return (type.getFlags() & ts.TypeFlags.NumberLike) !== 0;
-}
-
-export function isStringType(type: ts.Type) {
- return (type.flags & ts.TypeFlags.StringLike) > 0 || type.symbol?.name === 'String';
-}
-
-export function isFunction(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- const type = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
- return type.symbol && (type.symbol.flags & ts.SymbolFlags.Function) !== 0;
-}
-
-export function isUndefinedOrNull(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- const typ = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
- return (
- (typ.getFlags() & ts.TypeFlags.Undefined) !== 0 || (typ.getFlags() & ts.TypeFlags.Null) !== 0
- );
-}
-
-export function isThenable(node: estree.Node, services: RequiredParserServices) {
- const mapped = services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node);
- const tp = services.program.getTypeChecker().getTypeAtLocation(mapped);
- const thenProperty = tp.getProperty('then');
- return Boolean(thenProperty && thenProperty.flags & ts.SymbolFlags.Method);
-}
-
-export function isAny(type: ts.Type) {
- return type.flags === ts.TypeFlags.Any;
-}
-
-export function getTypeFromTreeNode(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- return checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
-}
-
-export function getTypeAsString(node: estree.Node, services: RequiredParserServices) {
- const { typeToString, getBaseTypeOfLiteralType } = services.program.getTypeChecker();
- return typeToString(getBaseTypeOfLiteralType(getTypeFromTreeNode(node, services)));
-}
-
-export function getSymbolAtLocation(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- return checker.getSymbolAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
-}
-
-export function getSignatureFromCallee(node: estree.Node, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- return checker.getResolvedSignature(
- services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node) as ts.CallLikeExpression,
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/hidden-files.ts b/eslint-bridge/src/linting/eslint/rules/hidden-files.ts
deleted file mode 100644
index 9197011354f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/hidden-files.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5691/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getUniqueWriteUsage, getObjectExpressionProperty, getFullyQualifiedName } from './helpers';
-
-const SERVE_STATIC = 'serve-static';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeHiddenFile: 'Make sure serving hidden files is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression(node: estree.Node) {
- // serveStatic(...)
- const { callee, arguments: args } = node as estree.CallExpression;
- if (getFullyQualifiedName(context, callee) === SERVE_STATIC && args.length > 1) {
- let options: estree.Node | undefined = args[1];
- if (options.type === 'Identifier') {
- options = getUniqueWriteUsage(context, options.name);
- }
-
- const dotfilesProperty = getObjectExpressionProperty(options, 'dotfiles');
- if (
- dotfilesProperty?.value.type === 'Literal' &&
- dotfilesProperty.value.value === 'allow'
- ) {
- context.report({ node: dotfilesProperty, messageId: 'safeHiddenFile' });
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/in-operator-type-error.ts b/eslint-bridge/src/linting/eslint/rules/in-operator-type-error.ts
deleted file mode 100644
index fe85aa3c9af..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/in-operator-type-error.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3785/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { isRequiredParserServices, getTypeFromTreeNode, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- function isPrimitive(node: estree.Node) {
- const type = getTypeFromTreeNode(node, services);
- return (
- (type.flags & ts.TypeFlags.StringLike) !== 0 ||
- (type.flags & ts.TypeFlags.NumberLike) !== 0 ||
- (type.flags & ts.TypeFlags.BooleanLike) !== 0 ||
- (type.flags & ts.TypeFlags.Null) !== 0 ||
- (type.flags & ts.TypeFlags.Undefined) !== 0
- );
- }
- return {
- 'BinaryExpression[operator="in"]': (node: estree.Node) => {
- const { left, right, operator } = node as estree.BinaryExpression;
- if (isPrimitive(right)) {
- const opToken = context
- .getSourceCode()
- .getTokensBetween(left, right)
- .find(token => token.type === 'Keyword' && token.value === operator)!;
- context.report({
- message: toEncodedMessage(
- 'TypeError can be thrown as this operand might have primitive type.',
- [opToken],
- ),
- node: right,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/inconsistent-function-call.ts b/eslint-bridge/src/linting/eslint/rules/inconsistent-function-call.ts
deleted file mode 100644
index 6d840687cec..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/inconsistent-function-call.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3686/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getVariableFromName, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const usedInNew: Map = new Map();
- const usedInCall: Map = new Map();
- const hasIssue: Scope.Variable[] = [];
-
- return {
- NewExpression: (node: estree.Node) => {
- checkExpression(
- node as estree.SimpleCallExpression,
- usedInNew,
- usedInCall,
- hasIssue,
- 'out',
- context,
- );
- },
- CallExpression: (node: estree.Node) => {
- checkExpression(
- node as estree.SimpleCallExpression,
- usedInCall,
- usedInNew,
- hasIssue,
- '',
- context,
- );
- },
- };
- },
-};
-
-function checkExpression(
- callExpression: estree.SimpleCallExpression,
- thisTypeUsageMap: Map,
- otherTypeUsageMap: Map,
- hasIssue: Scope.Variable[],
- tail: string,
- context: Rule.RuleContext,
-) {
- const variable = getVariable(callExpression, context);
- if (variable && variable.defs.length !== 0) {
- const otherTypeUsage = otherTypeUsageMap.get(variable);
- if (otherTypeUsage && otherTypeUsage.loc && !hasIssue.includes(variable)) {
- const message =
- `Correct the use of this function; ` +
- `on line ${otherTypeUsage.loc.start.line} it was called with${tail} "new".`;
-
- context.report({
- node: callExpression.callee,
- message: toEncodedMessage(message, [otherTypeUsage.callee as TSESTree.Node]),
- });
-
- hasIssue.push(variable);
- } else {
- thisTypeUsageMap.set(variable, callExpression);
- }
- }
-}
-
-function getVariable(node: estree.SimpleCallExpression, context: Rule.RuleContext) {
- if (node.callee.type === 'Identifier') {
- return getVariableFromName(context, node.callee.name);
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/index-of-compare-to-positive-number.ts b/eslint-bridge/src/linting/eslint/rules/index-of-compare-to-positive-number.ts
deleted file mode 100644
index 3ad8a6c729b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/index-of-compare-to-positive-number.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2692/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isArray, isRequiredParserServices, RequiredParserServices } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- considerIncludes:
- "This check ignores index 0; consider using 'includes' method to make this check safe and explicit.",
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- BinaryExpression(node: estree.Node) {
- const expression = node as estree.BinaryExpression;
- if (
- expression.operator === '>' &&
- isZero(expression.right) &&
- isArrayIndexOfCall(expression.left, services)
- ) {
- context.report({ node, messageId: 'considerIncludes' });
- }
- },
- };
- },
-};
-
-function isZero(node: estree.Expression): boolean {
- return node.type === 'Literal' && node.value === 0;
-}
-
-function isArrayIndexOfCall(node: estree.Expression, services: RequiredParserServices): boolean {
- return (
- node.type === 'CallExpression' &&
- node.arguments.length === 1 &&
- node.callee.type === 'MemberExpression' &&
- node.callee.property.type === 'Identifier' &&
- node.callee.property.name === 'indexOf' &&
- isArray(node.callee.object, services)
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/index.ts b/eslint-bridge/src/linting/eslint/rules/index.ts
deleted file mode 100644
index 3b6f413614d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/index.ts
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-
-import { rule as anchorPrecedence } from './anchor-precedence';
-import { rule as argumentType } from './argument-type';
-import { rule as argumentsOrder } from './arguments-order';
-import { rule as argumentsUsage } from './arguments-usage';
-import { rule as arrayCallBackWithoutReturn } from './array-callback-without-return';
-import { rule as arrayConstructor } from './array-constructor';
-import { rule as arrowFunctionConvention } from './arrow-function-convention';
-import { rule as assertionsInTests } from './assertions-in-tests';
-import { rule as awsApigatewayPublicApi } from './aws-apigateway-public-api';
-import { rule as awsEc2RdsDmsPublic } from './aws-ec2-rds-dms-public';
-import { rule as awsEc2UnencryptedEbsVolume } from './aws-ec2-unencrypted-ebs-volume';
-import { rule as awsEfsUnencrypted } from './aws-efs-unencrypted';
-import { rule as awsIamAllPrivileges } from './aws-iam-all-privileges';
-import { rule as awsIamAllResourcesAccessible } from './aws-iam-all-resources-accessible';
-import { rule as awsIamPrivilegeEscalation } from './aws-iam-privilege-escalation';
-import { rule as awsIamPublicAccess } from './aws-iam-public-access';
-import { rule as awsOpensearchserviceDomain } from './aws-opensearchservice-domain';
-import { rule as awsRdsUnencryptedDatabases } from './aws-rds-unencrypted-databases';
-import { rule as awsRestrictedIpAdminAccess } from './aws-restricted-ip-admin-access';
-import { rule as awsS3BucketGrantedAccess } from './aws-s3-bucket-granted-access';
-import { rule as awsS3BucketInsecureHttp } from './aws-s3-bucket-insecure-http';
-import { rule as awsS3BucketPublicAccess } from './aws-s3-bucket-public-access';
-import { rule as awsS3BucketServerEncryption } from './aws-s3-bucket-server-encryption';
-import { rule as awsS3BucketVersioning } from './aws-s3-bucket-versioning';
-import { rule as awsSagemakerUnencryptedNotebook } from './aws-sagemaker-unencrypted-notebook';
-import { rule as awsSnsUnencryptedTopics } from './aws-sns-unencrypted-topics';
-import { rule as awsSqsUnencryptedQueue } from './aws-sqs-unencrypted-queue';
-import { rule as bitwiseOperators } from './bitwise-operators';
-import { rule as boolParamDefault } from './bool-param-default';
-import { rule as callArgumentLine } from './call-argument-line';
-import { rule as certificateTransparency } from './certificate-transparency';
-import { rule as chaiDeterminateAssertion } from './chai-determinate-assertion';
-import { rule as className } from './class-name';
-import { rule as classPrototype } from './class-prototype';
-import { rule as codeEval } from './code-eval';
-import { rule as commaOrLogicalOrCase } from './comma-or-logical-or-case';
-import { rule as commentRegex } from './comment-regex';
-import { rule as conciseRegex } from './concise-regex';
-import { rule as conditionalIndentation } from './conditional-indentation';
-import { rule as confidentialInformationLogging } from './confidential-information-logging';
-import { rule as constructorForSideEffects } from './constructor-for-side-effects';
-import { rule as contentLength } from './content-length';
-import { rule as contentSecurityPolicy } from './content-security-policy';
-import { rule as cookieNoHttpOnly } from './cookie-no-httponly';
-import { rule as cookies } from './cookies';
-import { rule as cors } from './cors';
-import { rule as csrf } from './csrf';
-import { rule as cyclomaticComplexity } from './cyclomatic-complexity';
-import { rule as declarationsInGlobalScope } from './declarations-in-global-scope';
-import { rule as deprecation } from './deprecation';
-import { rule as destructuringAssignmentSyntax } from './destructuring-assignment-syntax';
-import { rule as differentTypesComparison } from './different-types-comparison';
-import { rule as disabledAutoEscaping } from './disabled-auto-escaping';
-import { rule as disabledResourceIntegrity } from './disabled-resource-integrity';
-import { rule as disabledTimeout } from './disabled-timeout';
-import { rule as dnsPrefetching } from './dns-prefetching';
-import { rule as duplicatesInCharacterClass } from './duplicates-in-character-class';
-import { rule as emptyStringRepetition } from './empty-string-repetition';
-import { rule as encryption } from './encryption';
-import { rule as encryptionSecureMode } from './encryption-secure-mode';
-import { rule as existingGroups } from './existing-groups';
-import { rule as expressionComplexity } from './expression-complexity';
-import { rule as fileHeader } from './file-header';
-import { rule as fileNameDifferFromClass } from './file-name-differ-from-class';
-import { rule as filePermissions } from './file-permissions';
-import { rule as fileUploads } from './file-uploads';
-import { rule as fixmeTag } from './fixme-tag';
-import { rule as forIn } from './for-in';
-import { rule as forLoopIncrementSign } from './for-loop-increment-sign';
-import { rule as frameAncestors } from './frame-ancestors';
-import { rule as functionInsideLoop } from './function-inside-loop';
-import { rule as functionName } from './function-name';
-import { rule as functionReturnType } from './function-return-type';
-import { rule as futureReservedWords } from './future-reserved-words';
-import { rule as generatorWithoutYield } from './generator-without-yield';
-import { rule as hashing } from './hashing';
-import { rule as hiddenFiles } from './hidden-files';
-import { rule as inOperatorTypeError } from './in-operator-type-error';
-import { rule as inconsistentFunctionCall } from './inconsistent-function-call';
-import { rule as indexOfCompareToPositiveNumber } from './index-of-compare-to-positive-number';
-import { rule as insecureCookie } from './insecure-cookie';
-import { rule as insecureJwtToken } from './insecure-jwt-token';
-import { rule as invertedAssertionArguments } from './inverted-assertion-arguments';
-import { rule as labelPosition } from './label-position';
-import { rule as linkWithTargetBlank } from './link-with-target-blank';
-import { rule as maxUnionSize } from './max-union-size';
-import { rule as misplacedLoopCounter } from './misplaced-loop-counter';
-import { rule as nestedControlFlow } from './nested-control-flow';
-import { rule as newOperatorMisuse } from './new-operator-misuse';
-import { rule as noAccessorFieldMismatch } from './no-accessor-field-mismatch';
-import { rule as noAlphabeticalSort } from './no-alphabetical-sort';
-import { rule as noAngularBypassSanitization } from './no-angular-bypass-sanitization';
-import { rule as noArrayDelete } from './no-array-delete';
-import { rule as noAssociativeArrays } from './no-associative-arrays';
-import { rule as noBuiltInOverride } from './no-built-in-override';
-import { rule as noCaseLabelInSwitch } from './no-case-label-in-switch';
-import { rule as noClearTextProtocols } from './no-clear-text-protocols';
-import { rule as noCodeAfterDone } from './no-code-after-done';
-import { rule as noCommentedCode } from './no-commented-code';
-import { rule as noDeadStore } from './no-dead-store';
-import { rule as noDeleteVar } from './no-delete-var';
-import { rule as noDuplicateInComposite } from './no-duplicate-in-composite';
-import { rule as noEmptyAfterReluctant } from './no-empty-after-reluctant';
-import { rule as noEmptyAlternatives } from './no-empty-alternatives';
-import { rule as noEmptyGroup } from './no-empty-group';
-import { rule as noEqualsInForTermination } from './no-equals-in-for-termination';
-import { rule as noExclusiveTests } from './no-exclusive-tests';
-import { rule as noForInIterable } from './no-for-in-iterable';
-import { rule as noFunctionDeclarationInBlock } from './no-function-declaration-in-block';
-import { rule as noGlobalThis } from './no-global-this';
-import { rule as noGlobalsShadowing } from './no-globals-shadowing';
-import { rule as noHardcodedCredentials } from './no-hardcoded-credentials';
-import { rule as noHardcodedIp } from './no-hardcoded-ip';
-import { rule as noHookSetterInBody } from './no-hook-setter-in-body';
-import { rule as noImplicitDependencies } from './no-implicit-dependencies';
-import { rule as noImplicitGlobal } from './no-implicit-global';
-import { rule as noInMisuse } from './no-in-misuse';
-import { rule as noIncompleteAssertions } from './no-incomplete-assertions';
-import { rule as noInconsistentReturns } from './no-inconsistent-returns';
-import { rule as noIncorrectStringConcat } from './no-incorrect-string-concat';
-import { rule as noInfiniteLoop } from './no-infinite-loop';
-import { rule as noIntrusivePermissions } from './no-intrusive-permissions';
-import { rule as noInvalidAwait } from './no-invalid-await';
-import { rule as noInvariantReturns } from './no-invariant-returns';
-import { rule as noIpForward } from './no-ip-forward';
-import { rule as noLabels } from './no-labels';
-import { rule as noMimeSniff } from './no-mime-sniff';
-import { rule as noMisleadingArrayReverse } from './no-misleading-array-reverse';
-import { rule as noMixedContent } from './no-mixed-content';
-import { rule as noNestedAssignment } from './no-nested-assignment';
-import { rule as noNestedConditional } from './no-nested-conditional';
-import { rule as noNestedIncDec } from './no-nested-incdec';
-import { rule as noNewSymbol } from './no-new-symbol';
-import { rule as noOsCommandFromPath } from './no-os-command-from-path';
-import { rule as noParameterReassignment } from './no-parameter-reassignment';
-import { rule as noPrimitiveWrappers } from './no-primitive-wrappers';
-import { rule as noRedundantAssignments } from './no-redundant-assignments';
-import { rule as noRedundantOptional } from './no-redundant-optional';
-import { rule as noRedundantParentheses } from './no-redundant-parentheses';
-import { rule as noReferenceError } from './no-reference-error';
-import { rule as noReferrerPolicy } from './no-referrer-policy';
-import { rule as noRequireOrDefine } from './no-require-or-define';
-import { rule as noReturnTypeAny } from './no-return-type-any';
-import { rule as noSameArgumentAssert } from './no-same-argument-assert';
-import { rule as noTab } from './no-tab';
-import { rule as noTryPromise } from './no-try-promise';
-import { rule as noUndefinedArgument } from './no-undefined-argument';
-import { rule as noUndefinedAssignment } from './no-undefined-assignment';
-import { rule as noUnenclosedMultilineBlock } from './no-unenclosed-multiline-block';
-import { rule as noUniqKey } from './no-uniq-key';
-import { rule as noUnsafeUnzip } from './no-unsafe-unzip';
-import { rule as noUnthrownError } from './no-unthrown-error';
-import { rule as noUnusedFunctionArgument } from './no-unused-function-argument';
-import { rule as noUselessIncrement } from './no-useless-increment';
-import { rule as noUselessIntersection } from './no-useless-intersection';
-import { rule as noUselessReactSetstate } from './no-useless-react-setstate';
-import { rule as noVariableUsageBeforeDeclaration } from './no-variable-usage-before-declaration';
-import { rule as noVueBypassSanitization } from './no-vue-bypass-sanitization';
-import { rule as noWeakCipher } from './no-weak-cipher';
-import { rule as noWeakKeys } from './no-weak-keys';
-import { rule as noWildcardImport } from './no-wildcard-import';
-import { rule as nonNumberInArithmeticExpression } from './non-number-in-arithmetic-expression';
-import { rule as nullDereference } from './null-dereference';
-import { rule as operationReturningNan } from './operation-returning-nan';
-import { rule as osCommand } from './os-command';
-import { rule as postMessage } from './post-message';
-import { rule as preferDefaultLast } from './prefer-default-last';
-import { rule as preferPromiseShorthand } from './prefer-promise-shorthand';
-import { rule as preferTypeGuard } from './prefer-type-guard';
-import { rule as processArgv } from './process-argv';
-import { rule as productionDebug } from './production-debug';
-import { rule as pseudoRandom } from './pseudo-random';
-import { rule as publiclyWrittableDirectories } from './publicly-writable-directories';
-import { rule as regexComplexity } from './regex-complexity';
-import { rule as regularExpr } from './regular-expr';
-import { rule as rulesOfHooks } from './rules-of-hooks';
-import { rule as sessionRegeneration } from './session-regeneration';
-import { rule as shorthandPropertyGrouping } from './shorthand-property-grouping';
-import { rule as singleCharInCharacterClasses } from './single-char-in-character-classes';
-import { rule as singleCharacterAlternative } from './single-character-alternation';
-import { rule as slowRegex } from './slow-regex';
-import { rule as sockets } from './sockets';
-import { rule as sonarBlockScopedVar } from './sonar-block-scoped-var';
-import { rule as sonarJsxNoLeakedRender } from './sonar-jsx-no-leaked-render';
-import { rule as sonarMaxLines } from './sonar-max-lines';
-import { rule as sonarMaxLinesPerFunction } from './sonar-max-lines-per-function';
-import { rule as sonarMaxParams } from './sonar-max-params';
-import { rule as sonarNoControlRegex } from './sonar-no-control-regex';
-import { rule as sonarNoDupeKeys } from './sonar-no-dupe-keys';
-import { rule as sonarNoFallthrough } from './sonar-no-fallthrough';
-import { rule as sonarNoInvalidRegexp } from './sonar-no-invalid-regexp';
-import { rule as sonarNoMisleadingCharacterClass } from './sonar-no-misleading-character-class';
-import { rule as sonarNoRegexSpaces } from './sonar-no-regex-spaces';
-import { rule as sonarNoUnusedClassComponentMethods } from './sonar-no-unused-class-component-methods';
-import { rule as sonarNoUnusedVars } from './sonar-no-unused-vars';
-import { rule as sqlQueries } from './sql-queries';
-import { rule as standardInput } from './standard-input';
-import { rule as statefulRegex } from './stateful-regex';
-import { rule as strictTransportSecurity } from './strict-transport-security';
-import { rule as stringsComparison } from './strings-comparison';
-import { rule as superInvocation } from './super-invocation';
-import { rule as switchWithoutDefault } from './switch-without-default';
-import { rule as testCheckException } from './test-check-exception';
-import { rule as todoTag } from './todo-tag';
-import { rule as tooManyBreakOrContinueInLoop } from './too-many-break-or-continue-in-loop';
-import { rule as unicodeAwareRegex } from './unicode-aware-regex';
-import { rule as unusedImport } from './unused-import';
-import { rule as unusedNamedGroups } from './unused-named-groups';
-import { rule as unverifiedCertificate } from './unverified-certificate';
-import { rule as unverifiedHostname } from './unverified-hostname';
-import { rule as updatedConstVar } from './updated-const-var';
-import { rule as updatedLoopCounter } from './updated-loop-counter';
-import { rule as useTypeAlias } from './use-type-alias';
-import { rule as uselessStringOperation } from './useless-string-operation';
-import { rule as valuesNotConvertibleToNumbers } from './values-not-convertible-to-numbers';
-import { rule as variableName } from './variable-name';
-import { rule as voidUse } from './void-use';
-import { rule as weakSsl } from './weak-ssl';
-import { rule as webSqlDatabase } from './web-sql-database';
-import { rule as xPoweredBy } from './x-powered-by';
-import { rule as xmlParserXXE } from './xml-parser-xxe';
-import { rule as xpath } from './xpath';
-
-/**
- * The set of internal ESLint-based rules
- */
-const rules: { [key: string]: Rule.RuleModule } = {};
-
-/**
- * Maps ESLint rule keys declared in the JavaScript checks to rule implementations
- */
-rules['anchor-precedence'] = anchorPrecedence;
-rules['argument-type'] = argumentType;
-rules['arguments-order'] = argumentsOrder;
-rules['arguments-usage'] = argumentsUsage;
-rules['array-callback-without-return'] = arrayCallBackWithoutReturn;
-rules['array-constructor'] = arrayConstructor;
-rules['arrow-function-convention'] = arrowFunctionConvention;
-rules['assertions-in-tests'] = assertionsInTests;
-rules['aws-apigateway-public-api'] = awsApigatewayPublicApi;
-rules['aws-ec2-rds-dms-public'] = awsEc2RdsDmsPublic;
-rules['aws-ec2-unencrypted-ebs-volume'] = awsEc2UnencryptedEbsVolume;
-rules['aws-efs-unencrypted'] = awsEfsUnencrypted;
-rules['aws-iam-all-privileges'] = awsIamAllPrivileges;
-rules['aws-iam-all-resources-accessible'] = awsIamAllResourcesAccessible;
-rules['aws-iam-privilege-escalation'] = awsIamPrivilegeEscalation;
-rules['aws-iam-public-access'] = awsIamPublicAccess;
-rules['aws-opensearchservice-domain'] = awsOpensearchserviceDomain;
-rules['aws-rds-unencrypted-databases'] = awsRdsUnencryptedDatabases;
-rules['aws-restricted-ip-admin-access'] = awsRestrictedIpAdminAccess;
-rules['aws-s3-bucket-granted-access'] = awsS3BucketGrantedAccess;
-rules['aws-s3-bucket-insecure-http'] = awsS3BucketInsecureHttp;
-rules['aws-s3-bucket-public-access'] = awsS3BucketPublicAccess;
-rules['aws-s3-bucket-server-encryption'] = awsS3BucketServerEncryption;
-rules['aws-s3-bucket-versioning'] = awsS3BucketVersioning;
-rules['aws-sagemaker-unencrypted-notebook'] = awsSagemakerUnencryptedNotebook;
-rules['aws-sns-unencrypted-topics'] = awsSnsUnencryptedTopics;
-rules['aws-sqs-unencrypted-queue'] = awsSqsUnencryptedQueue;
-rules['bitwise-operators'] = bitwiseOperators;
-rules['bool-param-default'] = boolParamDefault;
-rules['call-argument-line'] = callArgumentLine;
-rules['certificate-transparency'] = certificateTransparency;
-rules['chai-determinate-assertion'] = chaiDeterminateAssertion;
-rules['class-name'] = className;
-rules['class-prototype'] = classPrototype;
-rules['code-eval'] = codeEval;
-rules['comma-or-logical-or-case'] = commaOrLogicalOrCase;
-rules['comment-regex'] = commentRegex;
-rules['concise-regex'] = conciseRegex;
-rules['conditional-indentation'] = conditionalIndentation;
-rules['confidential-information-logging'] = confidentialInformationLogging;
-rules['constructor-for-side-effects'] = constructorForSideEffects;
-rules['content-length'] = contentLength;
-rules['content-security-policy'] = contentSecurityPolicy;
-rules['cookie-no-httponly'] = cookieNoHttpOnly;
-rules['cookies'] = cookies;
-rules['cors'] = cors;
-rules['csrf'] = csrf;
-rules['cyclomatic-complexity'] = cyclomaticComplexity;
-rules['declarations-in-global-scope'] = declarationsInGlobalScope;
-rules['deprecation'] = deprecation;
-rules['destructuring-assignment-syntax'] = destructuringAssignmentSyntax;
-rules['different-types-comparison'] = differentTypesComparison;
-rules['disabled-auto-escaping'] = disabledAutoEscaping;
-rules['disabled-resource-integrity'] = disabledResourceIntegrity;
-rules['disabled-timeout'] = disabledTimeout;
-rules['dns-prefetching'] = dnsPrefetching;
-rules['duplicates-in-character-class'] = duplicatesInCharacterClass;
-rules['empty-string-repetition'] = emptyStringRepetition;
-rules['encryption'] = encryption;
-rules['encryption-secure-mode'] = encryptionSecureMode;
-rules['existing-groups'] = existingGroups;
-rules['expression-complexity'] = expressionComplexity;
-rules['file-header'] = fileHeader;
-rules['file-name-differ-from-class'] = fileNameDifferFromClass;
-rules['file-permissions'] = filePermissions;
-rules['file-uploads'] = fileUploads;
-rules['fixme-tag'] = fixmeTag;
-rules['for-in'] = forIn;
-rules['for-loop-increment-sign'] = forLoopIncrementSign;
-rules['frame-ancestors'] = frameAncestors;
-rules['function-inside-loop'] = functionInsideLoop;
-rules['function-name'] = functionName;
-rules['function-return-type'] = functionReturnType;
-rules['future-reserved-words'] = futureReservedWords;
-rules['generator-without-yield'] = generatorWithoutYield;
-rules['hashing'] = hashing;
-rules['hidden-files'] = hiddenFiles;
-rules['in-operator-type-error'] = inOperatorTypeError;
-rules['inconsistent-function-call'] = inconsistentFunctionCall;
-rules['index-of-compare-to-positive-number'] = indexOfCompareToPositiveNumber;
-rules['insecure-cookie'] = insecureCookie;
-rules['insecure-jwt-token'] = insecureJwtToken;
-rules['inverted-assertion-arguments'] = invertedAssertionArguments;
-rules['label-position'] = labelPosition;
-rules['link-with-target-blank'] = linkWithTargetBlank;
-rules['max-union-size'] = maxUnionSize;
-rules['misplaced-loop-counter'] = misplacedLoopCounter;
-rules['nested-control-flow'] = nestedControlFlow;
-rules['new-operator-misuse'] = newOperatorMisuse;
-rules['no-accessor-field-mismatch'] = noAccessorFieldMismatch;
-rules['no-alphabetical-sort'] = noAlphabeticalSort;
-rules['no-angular-bypass-sanitization'] = noAngularBypassSanitization;
-rules['no-array-delete'] = noArrayDelete;
-rules['no-associative-arrays'] = noAssociativeArrays;
-rules['no-built-in-override'] = noBuiltInOverride;
-rules['no-case-label-in-switch'] = noCaseLabelInSwitch;
-rules['no-clear-text-protocols'] = noClearTextProtocols;
-rules['no-code-after-done'] = noCodeAfterDone;
-rules['no-commented-code'] = noCommentedCode;
-rules['no-dead-store'] = noDeadStore;
-rules['no-delete-var'] = noDeleteVar;
-rules['no-duplicate-in-composite'] = noDuplicateInComposite;
-rules['no-empty-after-reluctant'] = noEmptyAfterReluctant;
-rules['no-empty-alternatives'] = noEmptyAlternatives;
-rules['no-empty-group'] = noEmptyGroup;
-rules['no-equals-in-for-termination'] = noEqualsInForTermination;
-rules['no-exclusive-tests'] = noExclusiveTests;
-rules['no-for-in-iterable'] = noForInIterable;
-rules['no-function-declaration-in-block'] = noFunctionDeclarationInBlock;
-rules['no-global-this'] = noGlobalThis;
-rules['no-globals-shadowing'] = noGlobalsShadowing;
-rules['no-hardcoded-credentials'] = noHardcodedCredentials;
-rules['no-hardcoded-ip'] = noHardcodedIp;
-rules['no-hook-setter-in-body'] = noHookSetterInBody;
-rules['no-implicit-dependencies'] = noImplicitDependencies;
-rules['no-implicit-global'] = noImplicitGlobal;
-rules['no-in-misuse'] = noInMisuse;
-rules['no-incomplete-assertions'] = noIncompleteAssertions;
-rules['no-inconsistent-returns'] = noInconsistentReturns;
-rules['no-incorrect-string-concat'] = noIncorrectStringConcat;
-rules['no-infinite-loop'] = noInfiniteLoop;
-rules['no-intrusive-permissions'] = noIntrusivePermissions;
-rules['no-invalid-await'] = noInvalidAwait;
-rules['no-invariant-returns'] = noInvariantReturns;
-rules['no-ip-forward'] = noIpForward;
-rules['no-labels'] = noLabels;
-rules['no-mime-sniff'] = noMimeSniff;
-rules['no-misleading-array-reverse'] = noMisleadingArrayReverse;
-rules['no-mixed-content'] = noMixedContent;
-rules['no-nested-assignment'] = noNestedAssignment;
-rules['no-nested-conditional'] = noNestedConditional;
-rules['no-nested-incdec'] = noNestedIncDec;
-rules['no-new-symbol'] = noNewSymbol;
-rules['no-os-command-from-path'] = noOsCommandFromPath;
-rules['no-parameter-reassignment'] = noParameterReassignment;
-rules['no-primitive-wrappers'] = noPrimitiveWrappers;
-rules['no-redundant-assignments'] = noRedundantAssignments;
-rules['no-redundant-optional'] = noRedundantOptional;
-rules['no-redundant-parentheses'] = noRedundantParentheses;
-rules['no-reference-error'] = noReferenceError;
-rules['no-referrer-policy'] = noReferrerPolicy;
-rules['no-require-or-define'] = noRequireOrDefine;
-rules['no-return-type-any'] = noReturnTypeAny;
-rules['no-same-argument-assert'] = noSameArgumentAssert;
-rules['no-tab'] = noTab;
-rules['no-try-promise'] = noTryPromise;
-rules['no-undefined-argument'] = noUndefinedArgument;
-rules['no-undefined-assignment'] = noUndefinedAssignment;
-rules['no-unenclosed-multiline-block'] = noUnenclosedMultilineBlock;
-rules['no-uniq-key'] = noUniqKey;
-rules['no-unsafe-unzip'] = noUnsafeUnzip;
-rules['no-unthrown-error'] = noUnthrownError;
-rules['no-unused-function-argument'] = noUnusedFunctionArgument;
-rules['no-useless-increment'] = noUselessIncrement;
-rules['no-useless-intersection'] = noUselessIntersection;
-rules['no-useless-react-setstate'] = noUselessReactSetstate;
-rules['no-variable-usage-before-declaration'] = noVariableUsageBeforeDeclaration;
-rules['no-vue-bypass-sanitization'] = noVueBypassSanitization;
-rules['no-weak-cipher'] = noWeakCipher;
-rules['no-weak-keys'] = noWeakKeys;
-rules['no-wildcard-import'] = noWildcardImport;
-rules['non-number-in-arithmetic-expression'] = nonNumberInArithmeticExpression;
-rules['null-dereference'] = nullDereference;
-rules['operation-returning-nan'] = operationReturningNan;
-rules['os-command'] = osCommand;
-rules['post-message'] = postMessage;
-rules['prefer-default-last'] = preferDefaultLast;
-rules['prefer-promise-shorthand'] = preferPromiseShorthand;
-rules['prefer-type-guard'] = preferTypeGuard;
-rules['process-argv'] = processArgv;
-rules['production-debug'] = productionDebug;
-rules['pseudo-random'] = pseudoRandom;
-rules['publicly-writable-directories'] = publiclyWrittableDirectories;
-rules['regex-complexity'] = regexComplexity;
-rules['regular-expr'] = regularExpr;
-rules['rules-of-hooks'] = rulesOfHooks;
-rules['session-regeneration'] = sessionRegeneration;
-rules['shorthand-property-grouping'] = shorthandPropertyGrouping;
-rules['single-char-in-character-classes'] = singleCharInCharacterClasses;
-rules['single-character-alternation'] = singleCharacterAlternative;
-rules['slow-regex'] = slowRegex;
-rules['sockets'] = sockets;
-rules['sonar-block-scoped-var'] = sonarBlockScopedVar;
-rules['sonar-jsx-no-leaked-render'] = sonarJsxNoLeakedRender;
-rules['sonar-max-lines'] = sonarMaxLines;
-rules['sonar-max-lines-per-function'] = sonarMaxLinesPerFunction;
-rules['sonar-max-params'] = sonarMaxParams;
-rules['sonar-no-control-regex'] = sonarNoControlRegex;
-rules['sonar-no-dupe-keys'] = sonarNoDupeKeys;
-rules['sonar-no-fallthrough'] = sonarNoFallthrough;
-rules['sonar-no-invalid-regexp'] = sonarNoInvalidRegexp;
-rules['sonar-no-misleading-character-class'] = sonarNoMisleadingCharacterClass;
-rules['sonar-no-regex-spaces'] = sonarNoRegexSpaces;
-rules['sonar-no-unused-class-component-methods'] = sonarNoUnusedClassComponentMethods;
-rules['sonar-no-unused-vars'] = sonarNoUnusedVars;
-rules['sql-queries'] = sqlQueries;
-rules['standard-input'] = standardInput;
-rules['stateful-regex'] = statefulRegex;
-rules['strict-transport-security'] = strictTransportSecurity;
-rules['strings-comparison'] = stringsComparison;
-rules['super-invocation'] = superInvocation;
-rules['switch-without-default'] = switchWithoutDefault;
-rules['test-check-exception'] = testCheckException;
-rules['todo-tag'] = todoTag;
-rules['too-many-break-or-continue-in-loop'] = tooManyBreakOrContinueInLoop;
-rules['unicode-aware-regex'] = unicodeAwareRegex;
-rules['unused-import'] = unusedImport;
-rules['unused-named-groups'] = unusedNamedGroups;
-rules['unverified-certificate'] = unverifiedCertificate;
-rules['unverified-hostname'] = unverifiedHostname;
-rules['updated-const-var'] = updatedConstVar;
-rules['updated-loop-counter'] = updatedLoopCounter;
-rules['use-type-alias'] = useTypeAlias;
-rules['useless-string-operation'] = uselessStringOperation;
-rules['values-not-convertible-to-numbers'] = valuesNotConvertibleToNumbers;
-rules['variable-name'] = variableName;
-rules['void-use'] = voidUse;
-rules['weak-ssl'] = weakSsl;
-rules['web-sql-database'] = webSqlDatabase;
-rules['x-powered-by'] = xPoweredBy;
-rules['xml-parser-xxe'] = xmlParserXXE;
-rules['xpath'] = xpath;
-
-export { rules };
diff --git a/eslint-bridge/src/linting/eslint/rules/insecure-cookie.ts b/eslint-bridge/src/linting/eslint/rules/insecure-cookie.ts
deleted file mode 100644
index e34e26201b2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/insecure-cookie.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2092/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { CookieFlagCheck } from './cookie-flag-check';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) =>
- new CookieFlagCheck(context, 'secure').checkCookiesFromCallExpression(node),
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/insecure-jwt-token.ts b/eslint-bridge/src/linting/eslint/rules/insecure-jwt-token.ts
deleted file mode 100644
index afaf5b80d96..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/insecure-jwt-token.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5659/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getPropertyWithValue,
- getValueOfExpression,
- getObjectExpressionProperty,
- toEncodedMessage,
- isNullLiteral,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const SIGN_MESSAGE = 'Use only strong cipher algorithms when signing this JWT.';
- const VERIFY_MESSAGE =
- 'Use only strong cipher algorithms when verifying the signature of this JWT.';
- const SECONDARY_MESSAGE = `The "algorithms" option should be defined and should not contain 'none'.`;
-
- function checkCallToSign(
- callExpression: estree.CallExpression,
- thirdArgumentValue: estree.ObjectExpression,
- secondaryLocations: estree.Node[],
- ) {
- const unsafeAlgorithmProperty = getPropertyWithValue(
- context,
- thirdArgumentValue,
- 'algorithm',
- 'none',
- );
- if (unsafeAlgorithmProperty) {
- const unsafeAlgorithmValue = getValueOfExpression(
- context,
- unsafeAlgorithmProperty.value,
- 'Literal',
- );
- if (unsafeAlgorithmValue && unsafeAlgorithmValue !== unsafeAlgorithmProperty.value) {
- secondaryLocations.push(unsafeAlgorithmValue);
- }
- raiseIssueOn(callExpression.callee, SIGN_MESSAGE, secondaryLocations);
- }
- }
-
- function checkCallToVerify(
- callExpression: estree.CallExpression,
- publicKey: estree.Node,
- thirdArgumentValue: estree.ObjectExpression,
- secondaryLocations: estree.Node[],
- ) {
- const algorithmsProperty = getObjectExpressionProperty(thirdArgumentValue, 'algorithms');
- if (!algorithmsProperty) {
- if (isNullLiteral(publicKey)) {
- raiseIssueOn(callExpression.callee, VERIFY_MESSAGE, secondaryLocations);
- }
- return;
- }
- const algorithmsValue = getValueOfExpression(
- context,
- algorithmsProperty.value,
- 'ArrayExpression',
- );
- if (!algorithmsValue) {
- return;
- }
- const algorithmsContainNone = algorithmsValue.elements.some(e => {
- const value = getValueOfExpression(context, e, 'Literal');
- return value?.value === 'none';
- });
- if (algorithmsContainNone) {
- if (algorithmsProperty.value !== algorithmsValue) {
- secondaryLocations.push(algorithmsValue);
- }
- raiseIssueOn(callExpression.callee, VERIFY_MESSAGE, secondaryLocations);
- }
- }
-
- function raiseIssueOn(node: estree.Node, message: string, secondaryLocations: estree.Node[]) {
- context.report({
- node,
- message: toEncodedMessage(
- message,
- secondaryLocations,
- Array(secondaryLocations.length).fill(SECONDARY_MESSAGE),
- ),
- });
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression: estree.CallExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- const isCallToSign = fqn === 'jsonwebtoken.sign';
- const isCallToVerify = fqn === 'jsonwebtoken.verify';
- if (!isCallToSign && !isCallToVerify) {
- return;
- }
- if (callExpression.arguments.length < 3) {
- // algorithm(s) property is contained in third argument of "sign" and "verify" calls
- return;
- }
- const thirdArgument = callExpression.arguments[2];
- const thirdArgumentValue = getValueOfExpression(context, thirdArgument, 'ObjectExpression');
- if (!thirdArgumentValue) {
- return;
- }
- const secondaryLocations: estree.Node[] = [thirdArgumentValue];
- if (thirdArgumentValue !== thirdArgument) {
- secondaryLocations.push(thirdArgument);
- }
- if (isCallToSign) {
- checkCallToSign(callExpression, thirdArgumentValue, secondaryLocations);
- }
- const secondArgument = callExpression.arguments[1];
- if (isCallToVerify) {
- checkCallToVerify(callExpression, secondArgument, thirdArgumentValue, secondaryLocations);
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/inverted-assertion-arguments.ts b/eslint-bridge/src/linting/eslint/rules/inverted-assertion-arguments.ts
deleted file mode 100644
index c8a393b5adc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/inverted-assertion-arguments.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3415/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isLiteral, isMethodCall, Mocha, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const ASSERT_FUNCTIONS = [
- 'equal',
- 'notEqual',
- 'strictEqual',
- 'notStrictEqual',
- 'deepEqual',
- 'notDeepEqual',
- 'closeTo',
- 'approximately',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const testCases: estree.Node[] = [];
- return {
- CallExpression(node: estree.Node) {
- if (Mocha.isTestCase(node)) {
- testCases.push(node);
- return;
- }
- if (testCases.length > 0) {
- checkInvertedArguments(node as estree.CallExpression, context);
- }
- },
- 'CallExpression:exit': (node: estree.Node) => {
- if (Mocha.isTestCase(node)) {
- testCases.pop();
- }
- },
- };
- },
-};
-
-function checkInvertedArguments(node: estree.CallExpression, context: Rule.RuleContext) {
- const args = extractAssertionsArguments(node);
- if (args) {
- const [actual, expected, format] = args;
- if (isLiteral(actual) && !isLiteral(expected)) {
- const message = toEncodedMessage(
- `Swap these 2 arguments so they are in the correct order: ${format}.`,
- [actual],
- ['Other argument to swap.'],
- );
- context.report({
- node: expected,
- message,
- suggest: [
- {
- desc: 'Swap arguments',
- fix: fixer => [
- fixer.replaceText(actual, context.getSourceCode().getText(expected)),
- fixer.replaceText(expected, context.getSourceCode().getText(actual)),
- ],
- },
- ],
- });
- }
- }
-}
-
-function extractAssertionsArguments(
- node: estree.CallExpression,
-): [estree.Node, estree.Node, string] | null {
- return extractAssertArguments(node) ?? extractExpectArguments(node) ?? extractFailArguments(node);
-}
-
-function extractAssertArguments(
- node: estree.CallExpression,
-): [estree.Node, estree.Node, string] | null {
- if (isMethodCall(node) && node.arguments.length > 1) {
- const {
- callee: { object, property },
- arguments: [actual, expected],
- } = node;
- if (isIdentifier(object, 'assert') && isIdentifier(property, ...ASSERT_FUNCTIONS)) {
- return [actual, expected, `${object.name}.${property.name}(actual, expected)`];
- }
- }
- return null;
-}
-
-function extractExpectArguments(
- node: estree.CallExpression,
-): [estree.Node, estree.Node, string] | null {
- if (node.callee.type !== 'MemberExpression') {
- return null;
- }
- let { object, property } = node.callee;
- if (!isIdentifier(property, 'equal', 'eql', 'closeTo')) {
- return null;
- }
- while (object.type === 'MemberExpression') {
- object = object.object;
- }
- if (object.type === 'CallExpression' && isIdentifier(object.callee, 'expect')) {
- return [
- object.arguments[0],
- node.arguments[0],
- `${object.callee.name}(actual).to.${property.name}(expected)`,
- ];
- }
- return null;
-}
-
-function extractFailArguments(
- node: estree.CallExpression,
-): [estree.Node, estree.Node, string] | null {
- if (isMethodCall(node) && node.arguments.length > 1) {
- const {
- callee: { object, property },
- arguments: [actual, expected],
- } = node;
- if (isIdentifier(object, 'assert', 'expect', 'should') && isIdentifier(property, 'fail')) {
- return [actual, expected, `${object.name}.${property.name}(actual, expected)`];
- }
- }
- return null;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/label-position.ts b/eslint-bridge/src/linting/eslint/rules/label-position.ts
deleted file mode 100644
index 8ba564a5da5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/label-position.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1439/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeLabel: 'Remove this "{{label}}" label.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- LabeledStatement: (node: estree.Node) =>
- checkLabeledStatement(node as estree.LabeledStatement, context),
- };
- },
-};
-
-function checkLabeledStatement(node: estree.LabeledStatement, context: Rule.RuleContext) {
- if (!isLoopStatement(node.body) && !isSwitchStatement(node.body)) {
- context.report({
- messageId: 'removeLabel',
- data: {
- label: node.label.name,
- },
- node: node.label,
- });
- }
-}
-
-function isLoopStatement(node: estree.Node) {
- return (
- node.type === 'WhileStatement' ||
- node.type === 'DoWhileStatement' ||
- node.type === 'ForStatement' ||
- node.type === 'ForOfStatement' ||
- node.type === 'ForInStatement'
- );
-}
-
-function isSwitchStatement(node: estree.Node) {
- return node.type === 'SwitchStatement';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/link-with-target-blank.ts b/eslint-bridge/src/linting/eslint/rules/link-with-target-blank.ts
deleted file mode 100644
index 85b2f51719a..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/link-with-target-blank.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5148/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getValueOfExpression, isIdentifier, isMethodCall, isStringLiteral } from './helpers';
-
-const REQUIRED_OPTION = 'noopener';
-const REQUIRED_OPTION_INDEX = 2;
-const URL_INDEX = 0;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- missingNoopener: 'Make sure not using "noopener" is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.CallExpression) => {
- if (!isMethodCall(node)) {
- return;
- }
- const { object, property } = node.callee;
-
- const isWindowOpen =
- isIdentifier(property, 'open') &&
- (isIdentifier(object, 'window') || isThisWindow(object));
-
- if (!isWindowOpen) {
- return;
- }
-
- const args = node.arguments;
- const hasHttpUrl = URL_INDEX < args.length && isHttpUrl(context, args[URL_INDEX]);
- if (!hasHttpUrl) {
- return;
- }
-
- if (
- args.length <= REQUIRED_OPTION_INDEX ||
- !hasRequiredOption(context, args[REQUIRED_OPTION_INDEX])
- ) {
- context.report({
- messageId: 'missingNoopener',
- node: property,
- });
- }
- },
- };
- },
-};
-
-function isThisWindow(node: estree.Node) {
- return (
- node.type === 'MemberExpression' &&
- node.object.type === 'ThisExpression' &&
- isIdentifier(node.property, 'window')
- );
-}
-
-function hasRequiredOption(context: Rule.RuleContext, argument: estree.Node) {
- const stringOrNothing = extractString(context, argument);
- return stringOrNothing !== undefined && stringOrNothing.includes(REQUIRED_OPTION);
-}
-
-function isHttpUrl(context: Rule.RuleContext, argument: estree.Node): boolean {
- const stringOrNothing = extractString(context, argument);
- return (
- stringOrNothing !== undefined &&
- (stringOrNothing.startsWith('http://') || stringOrNothing.startsWith('https://'))
- );
-}
-
-function extractString(context: Rule.RuleContext, node: estree.Node): string | undefined {
- const literalNodeOrNothing = getValueOfExpression(context, node, 'Literal');
- if (literalNodeOrNothing === undefined || !isStringLiteral(literalNodeOrNothing)) {
- return undefined;
- } else {
- return literalNodeOrNothing.value;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/max-union-size.ts b/eslint-bridge/src/linting/eslint/rules/max-union-size.ts
deleted file mode 100644
index 7cd296e22c6..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/max-union-size.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4622/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- refactorUnion: 'Refactor this union type to have less than {{threshold}} elements.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- TSUnionType: (node: estree.Node) => {
- const union = node as unknown as TSESTree.TSUnionType;
- const [threshold] = context.options;
- if (union.types.length > threshold && !isFromTypeStatement(union)) {
- context.report({
- messageId: 'refactorUnion',
- data: {
- threshold,
- },
- node,
- });
- }
- },
- };
- },
-};
-
-function isFromTypeStatement(node: TSESTree.TSUnionType): boolean {
- return node.parent !== undefined && node.parent.type === 'TSTypeAliasDeclaration';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/misplaced-loop-counter.ts b/eslint-bridge/src/linting/eslint/rules/misplaced-loop-counter.ts
deleted file mode 100644
index 3f1b8b7af3e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/misplaced-loop-counter.ts
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1994/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { areEquivalent } from 'eslint-plugin-sonarjs/lib/utils/equivalence';
-import { getParent, RuleContext } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-class ForInfo {
- updatedExpressions: estree.Node[] = [];
- testedExpressions: estree.Node[] = [];
-
- constructor(readonly forLoop: estree.ForStatement) {}
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- misplacedCounter: `This loop's stop condition tests "{{test}}" but the incrementer updates "{{update}}".`,
- },
- },
- create(context: Rule.RuleContext) {
- const forLoopStack: ForInfo[] = [];
-
- function join(expressions: estree.Node[]) {
- return expressions.map(expr => context.getSourceCode().getText(expr)).join(', ');
- }
-
- function isInsideUpdate(node: estree.Node) {
- return isInside(node, f => f.update);
- }
-
- function isInsideTest(node: estree.Node) {
- return isInside(node, f => f.test);
- }
-
- function isInside(
- node: estree.Node,
- getChild: (loop: estree.ForStatement) => estree.Expression | null | undefined,
- ) {
- if (forLoopStack.length > 0) {
- const currentLoop = peekFor();
- const parentChain = context.getAncestors();
- parentChain.push(node);
- const forLoopChild = getChild(currentLoop.forLoop);
- if (forLoopChild) {
- return parentChain.some(parentChainNode => forLoopChild === parentChainNode);
- }
- }
- return false;
- }
-
- function peekFor() {
- return forLoopStack[forLoopStack.length - 1];
- }
-
- return {
- ForStatement: (node: estree.Node) => {
- forLoopStack.push(new ForInfo(node as estree.ForStatement));
- },
- 'ForStatement:exit': () => {
- const forInfo = forLoopStack.pop()!;
- if (forInfo.updatedExpressions.length === 0 || !forInfo.forLoop.test) {
- return;
- }
- const hasIntersection = forInfo.testedExpressions.some(testedExpr =>
- forInfo.updatedExpressions.some(updatedExpr =>
- areEquivalent(
- updatedExpr as TSESTree.Node,
- testedExpr as TSESTree.Node,
- (context as unknown as RuleContext).getSourceCode(),
- ),
- ),
- );
-
- if (!hasIntersection) {
- context.report({
- loc: context.getSourceCode().getFirstToken(forInfo.forLoop)!.loc,
- messageId: 'misplacedCounter',
- data: {
- test: join(forInfo.testedExpressions),
- update: join(forInfo.updatedExpressions),
- },
- });
- }
- },
-
- 'ForStatement AssignmentExpression': (node: estree.Node) => {
- if (isInsideUpdate(node)) {
- const left = (node as estree.AssignmentExpression).left;
- const assignedExpressions: estree.Node[] = [];
- computeAssignedExpressions(left, assignedExpressions);
- const { updatedExpressions } = peekFor();
- assignedExpressions.forEach(ass => updatedExpressions.push(ass));
- }
- },
-
- 'ForStatement UpdateExpression': (node: estree.Node) => {
- if (isInsideUpdate(node)) {
- peekFor().updatedExpressions.push((node as estree.UpdateExpression).argument);
- }
- },
-
- 'ForStatement CallExpression': (node: estree.Node) => {
- if (!isInsideUpdate(node)) {
- return;
- }
- const callee = getCalleeObject(node as estree.CallExpression);
- if (callee) {
- peekFor().updatedExpressions.push(callee);
- }
- },
-
- 'ForStatement Identifier': (node: estree.Node) => {
- if (isInsideTest(node)) {
- const parent = getParent(context)!;
- if (parent.type !== 'MemberExpression' || parent.computed || parent.object === node) {
- peekFor().testedExpressions.push(node);
- }
- }
- },
-
- 'ForStatement MemberExpression': (node: estree.Node) => {
- if (
- isInsideTest(node) &&
- getParent(context)!.type !== 'MemberExpression' &&
- getParent(context)!.type !== 'CallExpression'
- ) {
- peekFor().testedExpressions.push(node);
- }
- },
- };
- },
-};
-
-function getCalleeObject(node: estree.CallExpression) {
- let callee = node.callee;
- while (callee.type === 'MemberExpression') {
- callee = callee.object;
- }
- if (callee.type === 'Identifier' && callee !== node.callee) {
- return callee;
- }
- return null;
-}
-
-function computeAssignedExpressions(node: estree.Node | null, assigned: Array) {
- switch (node?.type) {
- case 'ArrayPattern':
- node.elements.forEach(element => computeAssignedExpressions(element, assigned));
- break;
- case 'ObjectPattern':
- node.properties.forEach(property => computeAssignedExpressions(property, assigned));
- break;
- case 'Property':
- computeAssignedExpressions(node.value, assigned);
- break;
- case 'AssignmentPattern':
- computeAssignedExpressions(node.left, assigned);
- break;
- default:
- assigned.push(node);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/nested-control-flow.ts b/eslint-bridge/src/linting/eslint/rules/nested-control-flow.ts
deleted file mode 100644
index f88211b2dfe..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/nested-control-flow.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S134/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- { type: 'integer' },
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- const [threshold] = context.options;
- const nodeStack: AST.Token[] = [];
- function push(n: AST.Token) {
- nodeStack.push(n);
- }
- function pop() {
- return nodeStack.pop();
- }
- function check(node: estree.Node) {
- if (nodeStack.length === threshold) {
- context.report({
- message: toEncodedMessage(
- `Refactor this code to not nest more than ${threshold} if/for/while/switch/try statements.`,
- nodeStack,
- nodeStack.map(_n => '+1'),
- ),
- loc: sourceCode.getFirstToken(node)!.loc,
- });
- }
- }
- function isElseIf(node: estree.Node) {
- const parent = last(context.getAncestors());
- return (
- node.type === 'IfStatement' && parent.type === 'IfStatement' && node === parent.alternate
- );
- }
- const controlFlowNodes = [
- 'ForStatement',
- 'ForInStatement',
- 'ForOfStatement',
- 'WhileStatement',
- 'DoWhileStatement',
- 'IfStatement',
- 'TryStatement',
- 'SwitchStatement',
- ].join(',');
- return {
- [controlFlowNodes]: (node: estree.Node) => {
- if (isElseIf(node)) {
- pop();
- push(sourceCode.getFirstToken(node)!);
- } else {
- check(node);
- push(sourceCode.getFirstToken(node)!);
- }
- },
- [`${controlFlowNodes}:exit`]: (node: estree.Node) => {
- if (!isElseIf(node)) {
- pop();
- }
- },
- };
- },
-};
-
-function last(arr: Array) {
- return arr[arr.length - 1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/new-operator-misuse.ts b/eslint-bridge/src/linting/eslint/rules/new-operator-misuse.ts
deleted file mode 100644
index 8a59b68ca6f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/new-operator-misuse.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2999/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import {
- isRequiredParserServices,
- getTypeFromTreeNode,
- getSignatureFromCallee,
- toEncodedMessage,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- { type: 'object' },
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const { considerJSDoc } = context.options[0];
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- 'NewExpression[callee.type!="ThisExpression"]': (node: estree.Node) => {
- const { callee } = node as estree.NewExpression;
- const type = getTypeFromTreeNode(callee, services);
- const signature = getSignatureFromCallee(node, services);
- if (!isInstantiable(type, signature, considerJSDoc) && !isAny(type)) {
- const functionToken = context
- .getSourceCode()
- .getFirstToken(node, token => token.type === 'Keyword' && token.value === 'function');
- const newToken = context
- .getSourceCode()
- .getFirstToken(node, token => token.type === 'Keyword' && token.value === 'new')!;
- const text = isFunction(type) ? 'this function' : context.getSourceCode().getText(callee);
- const loc = callee.type === 'FunctionExpression' ? functionToken!.loc : callee.loc!;
- context.report({
- message: toEncodedMessage(`Replace ${text} with a constructor function.`, [newToken]),
- loc,
- });
- }
- },
- };
- },
-};
-
-function isInstantiable(
- type: ts.Type,
- signature: ts.Signature | undefined,
- considerJSDoc: boolean,
-): boolean {
- return (
- isClass(type) ||
- isModule(type) ||
- isConstructor(type, signature, considerJSDoc) ||
- (type.isUnionOrIntersection() &&
- type.types.some(tp => isInstantiable(tp, signature, considerJSDoc)))
- );
-}
-
-function isClass(type: ts.Type) {
- return (
- type.symbol &&
- ((type.symbol.flags & ts.SymbolFlags.Class) !== 0 ||
- (type.symbol.flags & ts.SymbolFlags.Type) !== 0)
- );
-}
-
-function isModule(type: ts.Type) {
- return type.symbol && (type.symbol.flags & ts.SymbolFlags.Module) !== 0;
-}
-
-function isFunction(type: ts.Type) {
- return type.symbol && (type.symbol.flags & ts.SymbolFlags.Function) !== 0;
-}
-
-function isConstructor(type: ts.Type, signature: ts.Signature | undefined, considerJSDoc: boolean) {
- return isFunction(type) && (!considerJSDoc || hasJSDocAnnotation(signature));
-}
-
-function hasJSDocAnnotation(signature: ts.Signature | undefined) {
- return (
- signature !== undefined &&
- signature.getJsDocTags().some(tag => ['constructor', 'class'].includes(tag.name))
- );
-}
-
-function isAny(type: ts.Type) {
- return type.flags === ts.TypeFlags.Any;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-accessor-field-mismatch.ts b/eslint-bridge/src/linting/eslint/rules/no-accessor-field-mismatch.ts
deleted file mode 100644
index 9643e470700..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-accessor-field-mismatch.ts
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4275/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-interface AccessorInfo {
- type: 'getter' | 'setter';
- name: string;
-}
-
-interface Field {
- name: string;
- node: TSESTree.Node;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const currentFieldsStack = [new Map()];
-
- function checkAccessor(accessor: TSESTree.Property | TSESTree.MethodDefinition) {
- const accessorIsPublic =
- accessor.type !== 'MethodDefinition' || accessor.accessibility === 'public';
- const accessorInfo = getAccessorInfo(accessor);
- const statements = getFunctionBody(accessor.value);
- if (!accessorInfo || !accessorIsPublic || !statements || statements.length > 1) {
- return;
- }
-
- const matchingFields = findMatchingFields(
- currentFieldsStack[currentFieldsStack.length - 1],
- accessorInfo.name,
- );
- if (
- matchingFields.length > 0 &&
- (statements.length === 0 ||
- !isUsingAccessorFieldInBody(statements[0], accessorInfo, matchingFields))
- ) {
- const fieldToRefer = matchingFields[0];
- const primaryMessage =
- `Refactor this ${accessorInfo.type} ` +
- `so that it actually refers to the property '${fieldToRefer.name}'.`;
- const secondaryLocations = [fieldToRefer.node];
- const secondaryMessages = ['Property which should be referred.'];
-
- context.report({
- message: toEncodedMessage(primaryMessage, secondaryLocations, secondaryMessages),
- loc: accessor.key.loc,
- });
- }
- }
-
- return {
- Property: (node: estree.Node) => checkAccessor(node as TSESTree.Property),
- MethodDefinition: (node: estree.Node) => checkAccessor(node as TSESTree.MethodDefinition),
-
- ClassBody: (node: estree.Node) => {
- const classBody = node as TSESTree.ClassBody;
- const fields = getFieldMap(classBody.body, classElement =>
- (classElement.type === 'PropertyDefinition' ||
- classElement.type === 'TSAbstractPropertyDefinition') &&
- !classElement.static
- ? classElement.key
- : null,
- );
- const fieldsFromConstructor = fieldsDeclaredInConstructorParameters(classBody);
- const allFields = new Map([...fields, ...fieldsFromConstructor]);
- currentFieldsStack.push(allFields);
- },
- ObjectExpression: (node: estree.Node) => {
- const currentFields = getFieldMap((node as TSESTree.ObjectExpression).properties, prop =>
- isValidObjectField(prop) ? prop.key : null,
- );
- currentFieldsStack.push(currentFields);
- },
- ':matches(ClassBody, ObjectExpression):exit': () => {
- currentFieldsStack.pop();
- },
- };
- },
-};
-
-function getAccessorInfo(
- accessor: TSESTree.Property | TSESTree.MethodDefinition,
-): AccessorInfo | null {
- let name = getName(accessor.key);
- if (!name) {
- return null;
- }
-
- name = name.toLowerCase();
- if (accessor.kind === 'get') {
- return { type: 'getter', name };
- } else if (accessor.kind === 'set') {
- return { type: 'setter', name };
- } else {
- return setterOrGetter(name, accessor.value);
- }
-}
-
-function getName(key: TSESTree.Node) {
- if (key.type === 'Literal') {
- return String(key.value);
- } else if (key.type === 'Identifier') {
- return key.name;
- }
- return null;
-}
-
-function setterOrGetter(name: string, functionExpression: TSESTree.Node): AccessorInfo | null {
- if (functionExpression.type !== 'FunctionExpression') {
- return null;
- }
-
- if (name.startsWith('set') && functionExpression.params.length === 1) {
- return { type: 'setter', name: name.substring(3) };
- }
- if (name.startsWith('get') && functionExpression.params.length === 0) {
- return { type: 'getter', name: name.substring(3) };
- }
-
- return null;
-}
-
-function getFieldMap(
- elements: T[],
- getPropertyName: (arg: T) => TSESTree.PropertyName | null,
-) {
- const fields: Map = new Map();
- for (const element of elements) {
- const propertyNameNode = getPropertyName(element);
- if (propertyNameNode) {
- const name = getName(propertyNameNode);
- if (name) {
- fields.set(name.toLowerCase(), {
- name,
- node: element,
- });
- }
- }
- }
- return fields;
-}
-
-function isValidObjectField(prop: TSESTree.Node): prop is TSESTree.Property {
- return prop.type === 'Property' && !prop.method && prop.kind === 'init';
-}
-
-function fieldsDeclaredInConstructorParameters(containingClass: TSESTree.ClassBody) {
- const constr = getConstructorOf(containingClass);
- if (constr) {
- const fieldsFromConstructor = new Map();
- for (const parameter of constr.params) {
- if (
- parameter.type === 'TSParameterProperty' &&
- (parameter.accessibility || parameter.readonly)
- ) {
- const parameterName = getName(parameter.parameter);
- if (parameterName) {
- fieldsFromConstructor.set(parameterName, {
- name: parameterName,
- node: parameter,
- });
- }
- }
- }
- return fieldsFromConstructor;
- } else {
- return new Map();
- }
-}
-
-function getConstructorOf(
- containingClass: TSESTree.ClassBody,
-): TSESTree.FunctionExpression | TSESTree.TSEmptyBodyFunctionExpression | undefined {
- for (const classElement of containingClass.body) {
- if (classElement.type === 'MethodDefinition' && getName(classElement.key) === 'constructor') {
- return classElement.value;
- }
- }
-}
-
-function findMatchingFields(currentFields: Map, name: string) {
- const underscoredTargetName1 = `_${name}`;
- const underscoredTargetName2 = `${name}_`;
- const exactFieldName = currentFields.get(name);
- const underscoreFieldName1 = currentFields.get(underscoredTargetName1);
- const underscoreFieldName2 = currentFields.get(underscoredTargetName2);
- return [exactFieldName, underscoreFieldName1, underscoreFieldName2].filter(
- field => field,
- ) as Field[];
-}
-
-function getFunctionBody(node: TSESTree.Node) {
- if (node.type !== 'FunctionExpression' || !node.body) {
- return null;
- }
- return node.body.body;
-}
-
-function getPropertyName(expression: TSESTree.Expression | null) {
- if (
- expression &&
- expression.type === 'MemberExpression' &&
- expression.object.type === 'ThisExpression'
- ) {
- return getName(expression.property);
- }
- return null;
-}
-
-function getFieldUsedInsideSimpleBody(statement: TSESTree.Statement, accessorInfo: AccessorInfo) {
- if (accessorInfo.type === 'setter') {
- if (
- statement.type === 'ExpressionStatement' &&
- statement.expression.type === 'AssignmentExpression'
- ) {
- return getPropertyName(statement.expression.left);
- }
- } else if (statement.type === 'ReturnStatement') {
- return getPropertyName(statement.argument);
- }
- return null;
-}
-
-function isUsingAccessorFieldInBody(
- statement: TSESTree.Statement,
- accessorInfo: AccessorInfo,
- matchingFields: Field[],
-) {
- const usedField = getFieldUsedInsideSimpleBody(statement, accessorInfo);
- return !usedField || matchingFields.some(matchingField => usedField === matchingField.name);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-alphabetical-sort.ts b/eslint-bridge/src/linting/eslint/rules/no-alphabetical-sort.ts
deleted file mode 100644
index f9c0230e531..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-alphabetical-sort.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2871/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as ts from 'typescript';
-import { isRequiredParserServices, sortLike, RequiredParserServices } from './helpers';
-
-const compareFunctionPlaceholder = '(a, b) => (a - b)';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- provideCompareFunction:
- 'Provide a compare function to avoid sorting elements alphabetically.',
- suggestCompareFunction: 'Add a comparator function to sort in ascending order',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- CallExpression: (node: estree.Node) => {
- const call = node as TSESTree.CallExpression;
- const callee = call.callee;
- if (call.arguments.length === 0 && callee.type === 'MemberExpression') {
- const { object, property } = callee;
- const text = context.getSourceCode().getText(property as estree.Node);
- if (sortLike.includes(text)) {
- const arrayElementType = arrayElementTypeOf(object, services);
- if (arrayElementType && arrayElementType.kind === ts.SyntaxKind.NumberKeyword) {
- const closingParenthesis = context
- .getSourceCode()
- .getLastToken(node, token => token.value === ')')!;
- context.report({
- messageId: 'provideCompareFunction',
- node: property as estree.Node,
- suggest: [
- {
- messageId: 'suggestCompareFunction',
- fix: fixer =>
- fixer.insertTextBefore(closingParenthesis, compareFunctionPlaceholder),
- },
- ],
- });
- }
- }
- }
- },
- };
- },
-};
-
-function arrayElementTypeOf(node: TSESTree.Node, services: RequiredParserServices) {
- const { typeToTypeNode, getTypeAtLocation } = services.program.getTypeChecker();
- const typeNode = typeToTypeNode(
- getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node)),
- undefined,
- undefined,
- );
- if (typeNode && ts.isArrayTypeNode(typeNode)) {
- return typeNode.elementType;
- }
- return undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-angular-bypass-sanitization.ts b/eslint-bridge/src/linting/eslint/rules/no-angular-bypass-sanitization.ts
deleted file mode 100644
index ca26c2d461d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-angular-bypass-sanitization.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6268/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isMemberWithProperty, isLiteral } from './helpers';
-
-const bypassMethods = [
- 'bypassSecurityTrustHtml',
- 'bypassSecurityTrustStyle',
- 'bypassSecurityTrustScript',
- 'bypassSecurityTrustUrl',
- 'bypassSecurityTrustResourceUrl',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- checkAngularBypass: 'Make sure disabling Angular built-in sanitization is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) => {
- const { callee, arguments: args } = node as estree.CallExpression;
-
- if (
- isMemberWithProperty(callee, ...bypassMethods) &&
- args.length === 1 &&
- !isHardcodedLiteral(args[0])
- ) {
- context.report({
- messageId: 'checkAngularBypass',
- node: (callee as estree.MemberExpression).property,
- });
- }
- },
- };
- },
-};
-
-function isHardcodedLiteral(node: estree.Node) {
- if (node.type === 'TemplateLiteral') {
- return node.expressions.length === 0;
- } else {
- return isLiteral(node);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-array-delete.ts b/eslint-bridge/src/linting/eslint/rules/no-array-delete.ts
deleted file mode 100644
index 25c7dcfb388..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-array-delete.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2870/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getParent, isArray, isRequiredParserServices } from './helpers';
-
-const ArrayDeleteExpression =
- "UnaryExpression[operator='delete'] > MemberExpression[computed=true]";
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeDelete: 'Remove this use of "delete".',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (isRequiredParserServices(services)) {
- return {
- [ArrayDeleteExpression]: (node: estree.Node) => {
- const member = node as estree.MemberExpression;
- const object = member.object;
- if (isArray(object, services)) {
- raiseIssue(context);
- }
- },
- };
- }
- return {};
- },
-};
-
-function raiseIssue(context: Rule.RuleContext): void {
- const deleteKeyword = context.getSourceCode().getFirstToken(getParent(context)!);
- context.report({
- messageId: 'removeDelete',
- loc: deleteKeyword!.loc,
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-associative-arrays.ts b/eslint-bridge/src/linting/eslint/rules/no-associative-arrays.ts
deleted file mode 100644
index d468df19f5f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-associative-arrays.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3579/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isArray, isString, isRequiredParserServices } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- noAssociativeArray:
- 'Make it an object if it must have named properties; otherwise, use a numeric index here.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- return {
- 'AssignmentExpression[left.type="MemberExpression"]'(node: estree.Node) {
- const { property, object } = (node as estree.AssignmentExpression)
- .left as estree.MemberExpression;
- if (isString(property, services) && isArray(object, services)) {
- context.report({
- messageId: 'noAssociativeArray',
- node,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-built-in-override.ts b/eslint-bridge/src/linting/eslint/rules/no-built-in-override.ts
deleted file mode 100644
index 0d61396c177..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-built-in-override.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2424/javascript
-
-import { globalsByLibraries } from './helpers';
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeOverride: 'Remove this override of "{{overridden}}".',
- },
- },
- create(context: Rule.RuleContext) {
- const overriden: Set = new Set();
-
- function isBuiltIn(variable: Scope.Variable) {
- return globalsByLibraries.builtin.includes(variable.name);
- }
-
- function checkVariable(variable: Scope.Variable) {
- if (isBuiltIn(variable)) {
- variable.defs.forEach(def => overriden.add(def.name));
- variable.references
- .filter(ref => ref.isWrite())
- .forEach(ref => overriden.add(ref.identifier));
- }
- }
-
- function checkScope(scope: Scope.Scope) {
- scope.variables.forEach(checkVariable);
- scope.childScopes.forEach(checkScope);
- }
-
- function isTSEnumMemberId(node: estree.Identifier) {
- const id = node as TSESTree.Identifier;
- return id.parent?.type === 'TSEnumMember';
- }
-
- return {
- Program: () => {
- checkScope(context.getScope());
- },
- 'Program:exit': () => {
- overriden.forEach(node => {
- if (!isTSEnumMemberId(node)) {
- context.report({
- messageId: 'removeOverride',
- data: {
- overridden: node.name,
- },
- node,
- });
- }
- });
- overriden.clear();
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-case-label-in-switch.ts b/eslint-bridge/src/linting/eslint/rules/no-case-label-in-switch.ts
deleted file mode 100644
index a8ab9d00a02..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-case-label-in-switch.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1219/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeLabel: 'Remove this misleading "{{label}}" label.',
- },
- },
- create(context: Rule.RuleContext) {
- const stack: number[] = [0];
- function enterCase() {
- stack.push(stack.pop()! + 1);
- }
- function leaveCase() {
- stack.push(stack.pop()! - 1);
- }
- function inCase() {
- return stack[stack.length - 1] > 0;
- }
- return {
- SwitchCase: () => {
- enterCase();
- },
- LabeledStatement: (node: estree.Node) => {
- if (inCase()) {
- const label = (node as estree.LabeledStatement).label;
- context.report({
- messageId: 'removeLabel',
- data: {
- label: label.name,
- },
- node: label,
- });
- }
- },
- 'FunctionExpression, FunctionDeclaration': () => {
- stack.push(0);
- },
- 'SwitchCase:exit': () => {
- leaveCase();
- },
- 'FunctionExpression, FunctionDeclaration :exit': () => {
- stack.pop();
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.aws.ts b/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.aws.ts
deleted file mode 100644
index 2efebe4299b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.aws.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5332/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-import * as estree from 'estree';
-
-const sensitivePorts = [80, 8080, 8000, 8008];
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws-cdk-lib.aws_elasticache.CfnReplicationGroup': AwsCdkCheckArguments(
- 'replicationGroup',
- true,
- 'transitEncryptionEnabled',
- { primitives: { invalid: [false] } },
- ),
- 'aws-cdk-lib.aws_kinesis.Stream': AwsCdkCheckArguments(
- 'streamEncryptionDisabled',
- false,
- 'encryption',
- { fqns: { invalid: ['aws_cdk_lib.aws_kinesis.StreamEncryption.UNENCRYPTED'] } },
- ),
- 'aws-cdk-lib.aws_kinesis.CfnStream': AwsCdkCheckArguments(
- 'streamEncryptionDisabled',
- true,
- 'streamEncryption',
- ),
- 'aws-cdk-lib.aws_elasticloadbalancing.LoadBalancer': {
- callExpression: AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'externalProtocol',
- {
- fqns: {
- invalid: [
- 'aws-cdk-lib.aws_elasticloadbalancing.LoadBalancingProtocol.TCP',
- 'aws-cdk-lib.aws_elasticloadbalancing.LoadBalancingProtocol.HTTP',
- ],
- },
- },
- false,
- 0,
- ),
- functionName: 'addListener',
- newExpression: AwsCdkCheckArguments('noSSLTLS', false, ['listeners', 'externalProtocol'], {
- fqns: {
- invalid: [
- 'aws-cdk-lib.aws_elasticloadbalancing.LoadBalancingProtocol.TCP',
- 'aws-cdk-lib.aws_elasticloadbalancing.LoadBalancingProtocol.HTTP',
- ],
- },
- }),
- },
- 'aws-cdk-lib.aws_elasticloadbalancing.CfnLoadBalancer': AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- ['listeners', 'protocol'],
- { primitives: { invalid: ['tcp', 'http'], case_insensitive: true } },
- ),
- 'aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer': {
- callExpression: httpOrSensitivePort(1),
- functionName: 'addListener',
- },
- 'aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListener': httpOrSensitivePort(2),
- 'aws-cdk-lib.aws_elasticloadbalancingv2.NetworkLoadBalancer': {
- callExpression: (expr: estree.NewExpression, ctx: Rule.RuleContext) => {
- const httpProtocol = AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'protocol',
- {
- fqns: {
- invalid: [
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.HTTP',
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.TCP',
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.UDP',
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.TCP_UDP',
- ],
- },
- },
- true,
- 1,
- );
- const node = httpProtocol(expr, ctx);
- if (node) {
- ctx.report({ messageId: 'noSSLTLS', node });
- } else {
- const missingProtocol = AwsCdkCheckArguments(
- 'noSSLTLS',
- true,
- 'protocol',
- undefined,
- true,
- 1,
- );
- if (missingProtocol(expr, ctx)) {
- const certificatesChecker = AwsCdkCheckArguments(
- 'noSSLTLS',
- true,
- 'certificates',
- undefined,
- true,
- 1,
- );
- const portNode = certificatesChecker(expr, ctx);
- if (portNode) {
- ctx.report({ messageId: 'noSSLTLS', node: portNode });
- }
- }
- }
- },
- functionName: 'addListener',
- },
- 'aws-cdk-lib.aws_elasticloadbalancingv2.NetworkListener': (
- expr: estree.NewExpression,
- ctx: Rule.RuleContext,
- ) => {
- const httpProtocol = AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'protocol',
- {
- fqns: {
- invalid: [
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.TCP',
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.UDP',
- 'aws-cdk-lib.aws_elasticloadbalancingv2.Protocol.TCP_UDP',
- ],
- },
- },
- true,
- );
- const node = httpProtocol(expr, ctx);
- if (node) {
- ctx.report({ messageId: 'noSSLTLS', node });
- } else {
- const missingProtocol = AwsCdkCheckArguments('noSSLTLS', true, 'protocol', undefined, true);
- if (missingProtocol(expr, ctx)) {
- const certificatesChecker = AwsCdkCheckArguments(
- 'noSSLTLS',
- true,
- 'certificates',
- undefined,
- true,
- );
- const portNode = certificatesChecker(expr, ctx);
- if (portNode) {
- ctx.report({ messageId: 'noSSLTLS', node: portNode });
- }
- }
- }
- },
- 'aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener': AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'protocol',
- { primitives: { invalid: ['HTTP', 'TCP', 'UDP', 'TCP_UDP'], case_insensitive: true } },
- ),
- },
- {
- meta: {
- messages: {
- replicationGroup: 'Make sure that disabling transit encryption is safe here.',
- noSSLTLS:
- 'Make sure that using network protocols without an SSL/TLS underlay is safe here.',
- streamEncryptionDisabled: 'Make sure that disabling stream encryption is safe here.',
- },
- },
- },
-);
-
-function httpOrSensitivePort(position: number) {
- return function (expr: estree.NewExpression, ctx: Rule.RuleContext) {
- const httpProtocol = AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'protocol',
- { fqns: { invalid: ['aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationProtocol.HTTP'] } },
- true,
- position,
- );
- const node = httpProtocol(expr, ctx);
- if (node) {
- ctx.report({ messageId: 'noSSLTLS', node });
- } else {
- const missingProtocol = AwsCdkCheckArguments(
- 'noSSLTLS',
- true,
- 'protocol',
- undefined,
- true,
- position,
- );
- if (missingProtocol(expr, ctx)) {
- const portChecker = AwsCdkCheckArguments(
- 'noSSLTLS',
- false,
- 'port',
- { primitives: { invalid: sensitivePorts } },
- true,
- position,
- );
- const portNode = portChecker(expr, ctx);
- if (portNode) {
- ctx.report({ messageId: 'noSSLTLS', node: portNode });
- }
- }
- }
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.lib.ts b/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.lib.ts
deleted file mode 100644
index d9fb3759a24..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.lib.ts
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5332/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { URL } from 'url';
-import {
- getValueOfExpression,
- getObjectExpressionProperty,
- getParent,
- getFullyQualifiedName,
-} from './helpers';
-import { normalizeFQN } from './helpers/aws/cdk';
-
-const INSECURE_PROTOCOLS = ['http://', 'ftp://', 'telnet://'];
-const LOOPBACK_PATTERN = /localhost|127(?:\.[0-9]+){0,2}\.[0-9]+$|\/\/(?:0*\:)*?:?0*1$/;
-const EXCEPTION_FULL_HOSTS = [
- 'www.w3.org',
- 'xml.apache.org',
- 'schemas.xmlsoap.org',
- 'schemas.openxmlformats.org',
- 'rdfs.org',
- 'purl.org',
- 'xmlns.com',
- 'schemas.google.com',
- 'a9.com',
- 'ns.adobe.com',
- 'ltsc.ieee.org',
- 'docbook.org',
- 'graphml.graphdrawing.org',
- 'json-schema.org',
-];
-const EXCEPTION_TOP_HOSTS = [/(.*\.)?example\.com$/, /(.*\.)?example\.org$/, /(.*\.)?test\.com$/];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- insecureProtocol: 'Using {{protocol}} protocol is insecure. Use {{alternative}} instead.',
- },
- },
- create(context: Rule.RuleContext) {
- function checkNodemailer(callExpression: estree.CallExpression) {
- const firstArg = callExpression.arguments.length > 0 ? callExpression.arguments[0] : null;
- if (!firstArg) {
- return;
- }
-
- const firstArgValue = getValueOfExpression(context, firstArg, 'ObjectExpression');
-
- const ses = getObjectExpressionProperty(firstArgValue, 'SES');
- if (ses && usesSesCommunication(ses)) {
- return;
- }
-
- const secure = getObjectExpressionProperty(firstArgValue, 'secure');
- if (secure && (secure.value.type !== 'Literal' || secure.value.raw !== 'false')) {
- return;
- }
-
- const requireTls = getObjectExpressionProperty(firstArgValue, 'requireTLS');
- if (requireTls && (requireTls.value.type !== 'Literal' || requireTls.value.raw !== 'false')) {
- return;
- }
-
- const port = getObjectExpressionProperty(firstArgValue, 'port');
- if (port && (port.value.type !== 'Literal' || port.value.raw === '465')) {
- return;
- }
-
- context.report({ node: callExpression.callee, ...getMessageAndData('http') });
- }
-
- function usesSesCommunication(sesProperty: estree.Property) {
- const configuration = getValueOfExpression(context, sesProperty.value, 'ObjectExpression');
- if (!configuration) {
- return false;
- }
-
- const ses = getValueOfExpression(
- context,
- getObjectExpressionProperty(configuration, 'ses')?.value,
- 'NewExpression',
- );
- if (!ses || normalizeFQN(getFullyQualifiedName(context, ses)) !== '@aws_sdk.client_ses.SES') {
- return false;
- }
-
- const aws = getObjectExpressionProperty(configuration, 'aws');
- if (
- !aws ||
- normalizeFQN(getFullyQualifiedName(context, aws.value)) !== '@aws_sdk.client_ses'
- ) {
- return false;
- }
-
- return true;
- }
-
- function checkCallToFtp(callExpression: estree.CallExpression) {
- if (
- callExpression.callee.type === 'MemberExpression' &&
- callExpression.callee.property.type === 'Identifier' &&
- callExpression.callee.property.name === 'connect'
- ) {
- const newExpression = getValueOfExpression(
- context,
- callExpression.callee.object,
- 'NewExpression',
- );
- if (!!newExpression && getFullyQualifiedName(context, newExpression.callee) === 'ftp') {
- const firstArg = callExpression.arguments.length > 0 ? callExpression.arguments[0] : null;
- if (!firstArg) {
- return;
- }
- const firstArgValue = getValueOfExpression(context, firstArg, 'ObjectExpression');
- const secure = getObjectExpressionProperty(firstArgValue, 'secure');
- if (secure && secure.value.type === 'Literal' && secure.value.raw === 'false') {
- context.report({
- node: callExpression.callee,
- ...getMessageAndData('ftp'),
- });
- }
- }
- }
- }
-
- function checkCallToRequire(callExpression: estree.CallExpression) {
- if (callExpression.callee.type === 'Identifier' && callExpression.callee.name === 'require') {
- const firstArg = callExpression.arguments.length > 0 ? callExpression.arguments[0] : null;
- if (
- firstArg &&
- firstArg.type === 'Literal' &&
- typeof firstArg.value === 'string' &&
- firstArg.value === 'telnet-client'
- ) {
- context.report({
- node: firstArg,
- ...getMessageAndData('telnet'),
- });
- }
- }
- }
-
- function isExceptionUrl(value: string) {
- if (INSECURE_PROTOCOLS.includes(value)) {
- const parent = getParent(context);
- return !(parent?.type === 'BinaryExpression' && parent.operator === '+');
- }
- return hasExceptionHost(value);
- }
-
- function hasExceptionHost(value: string) {
- let url;
-
- try {
- url = new URL(value);
- } catch (err) {
- return false;
- }
-
- const host = url.hostname;
- return (
- host.length === 0 ||
- LOOPBACK_PATTERN.test(host) ||
- EXCEPTION_FULL_HOSTS.some(exception => exception === host) ||
- EXCEPTION_TOP_HOSTS.some(exception => exception.test(host))
- );
- }
-
- return {
- Literal: (node: estree.Node) => {
- const literal = node as estree.Literal;
- if (typeof literal.value === 'string') {
- const value = literal.value.trim().toLocaleLowerCase();
- const insecure = INSECURE_PROTOCOLS.find(protocol => value.startsWith(protocol));
- if (insecure && !isExceptionUrl(value)) {
- const protocol = insecure.substring(0, insecure.indexOf(':'));
- context.report({
- ...getMessageAndData(protocol),
- node,
- });
- }
- }
- },
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- if (getFullyQualifiedName(context, callExpression) === 'nodemailer.createTransport') {
- checkNodemailer(callExpression);
- }
- checkCallToFtp(callExpression);
- checkCallToRequire(callExpression);
- },
- ImportDeclaration: (node: estree.Node) => {
- const importDeclaration = node as estree.ImportDeclaration;
- if (
- typeof importDeclaration.source.value === 'string' &&
- importDeclaration.source.value === 'telnet-client'
- ) {
- context.report({
- node: importDeclaration.source,
- ...getMessageAndData('telnet'),
- });
- }
- },
- };
- },
-};
-
-function getMessageAndData(protocol: string) {
- let alternative;
- switch (protocol) {
- case 'http':
- alternative = 'https';
- break;
- case 'ftp':
- alternative = 'sftp, scp or ftps';
- break;
- default:
- alternative = 'ssh';
- }
- return { messageId: 'insecureProtocol', data: { protocol, alternative } };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.ts b/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.ts
deleted file mode 100644
index 108549d8ea5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-clear-text-protocols.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5332/javascript
-
-import { Rule } from 'eslint';
-import { mergeRules } from './decorators/helpers';
-import { rule as networkProtocolsRule } from './no-clear-text-protocols.lib';
-import { rule as awsRule } from './no-clear-text-protocols.aws';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: { ...networkProtocolsRule.meta!.messages, ...awsRule.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- return mergeRules(networkProtocolsRule.create(context), awsRule.create(context));
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-code-after-done.ts b/eslint-bridge/src/linting/eslint/rules/no-code-after-done.ts
deleted file mode 100644
index 05653e68183..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-code-after-done.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6079/javascript
-
-import { Rule, Scope } from 'eslint';
-import { getVariableFromIdentifier, Mocha, toEncodedMessage } from './helpers';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let currentDoneVariable: Scope.Variable | undefined;
- let doneCall: estree.Node | undefined;
- let doneSegment: Rule.CodePathSegment | undefined;
-
- let currentSegment: Rule.CodePathSegment | undefined;
- let currentCase: Mocha.TestCase;
- const segmentFirstStatement: Map = new Map();
-
- function checkForTestCase(node: estree.Node) {
- const testCase = Mocha.extractTestCase(node);
- if (!testCase) {
- return;
- }
-
- currentCase = testCase;
- currentDoneVariable = undefined;
- if (testCase.callback.params.length === 0) {
- return;
- }
- const [done] = testCase.callback.params;
- if (done.type !== 'Identifier') {
- return;
- }
- const callbackScope = context
- .getScope()
- .childScopes.find(scope => scope.block === testCase.callback);
- if (!callbackScope) {
- return;
- }
- currentDoneVariable = getVariableFromIdentifier(done, callbackScope);
- }
-
- function checkForDoneCall(node: estree.CallExpression) {
- const { callee } = node;
- if (
- currentDoneVariable &&
- currentDoneVariable.references.some(ref => ref.identifier === callee)
- ) {
- doneCall = node;
- doneSegment = currentSegment;
- }
- }
-
- function report(statementAfterDone: estree.Node) {
- context.report({
- node: statementAfterDone,
- message: toEncodedMessage(`Move this code before the call to "done".`, [
- doneCall as TSESTree.Node,
- ]),
- });
-
- doneSegment = undefined;
- doneCall = undefined;
- currentDoneVariable = undefined;
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- checkForTestCase(node);
- checkForDoneCall(node as estree.CallExpression);
- },
-
- ExpressionStatement: (node: estree.Node) => {
- if (currentSegment && currentSegment === doneSegment) {
- report(node);
- }
-
- if (currentSegment && !segmentFirstStatement.has(currentSegment)) {
- segmentFirstStatement.set(currentSegment, node);
- }
- },
-
- onCodePathSegmentStart(segment: Rule.CodePathSegment) {
- currentSegment = segment;
- },
-
- onCodePathEnd(_codePath: Rule.CodePath, node: estree.Node) {
- currentSegment = undefined;
- if (currentCase?.callback === node && doneSegment) {
- // we report an issue if one of 'doneSegment.nextSegments' is not empty
- const statementAfterDone = doneSegment.nextSegments
- .map(segment => segmentFirstStatement.get(segment))
- .find(stmt => !!stmt);
- if (statementAfterDone) {
- report(statementAfterDone);
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-commented-code.ts b/eslint-bridge/src/linting/eslint/rules/no-commented-code.ts
deleted file mode 100644
index 5989a7bafc0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-commented-code.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S125/javascript
-
-import { Rule, SourceCode } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as babel from '@babel/eslint-parser';
-import { buildParserOptions } from 'parsing/jsts';
-import { CodeRecognizer, JavaScriptFootPrint } from '../linter/recognizers';
-
-const EXCLUDED_STATEMENTS = ['BreakStatement', 'LabeledStatement', 'ContinueStatement'];
-
-const recognizer = new CodeRecognizer(0.9, new JavaScriptFootPrint());
-
-interface GroupComment {
- value: string;
- nodes: TSESTree.Comment[];
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- commentedCode: 'Remove this commented out code.',
- commentedCodeFix: 'Remove this commented out code',
- },
- hasSuggestions: true,
- },
- create(context: Rule.RuleContext) {
- function getGroupedComments(comments: TSESTree.Comment[]): GroupComment[] {
- const groupedComments: GroupComment[] = [];
- let currentGroup: TSESTree.Comment[] = [];
- for (const comment of comments) {
- if (comment.type === 'Block') {
- groupedComments.push({ value: comment.value, nodes: [comment] });
- } else if (
- currentGroup.length === 0 ||
- areAdjacentLineComments(currentGroup[currentGroup.length - 1], comment)
- ) {
- currentGroup.push(comment);
- } else {
- groupedComments.push({
- value: currentGroup.map(lineComment => lineComment.value).join('\n'),
- nodes: currentGroup,
- });
- currentGroup = [comment];
- }
- }
-
- if (currentGroup.length > 0) {
- groupedComments.push({
- value: currentGroup.map(lineComment => lineComment.value).join('\n'),
- nodes: currentGroup,
- });
- }
-
- return groupedComments;
- }
-
- function areAdjacentLineComments(previous: TSESTree.Comment, next: TSESTree.Comment) {
- const nextCommentLine = next.loc.start.line;
- if (previous.loc.start.line + 1 === nextCommentLine) {
- const nextCodeToken = context.getSourceCode().getTokenAfter(previous);
- return !nextCodeToken || nextCodeToken.loc.start.line > nextCommentLine;
- }
- return false;
- }
-
- return {
- 'Program:exit': () => {
- const groupedComments = getGroupedComments(
- context.getSourceCode().getAllComments() as TSESTree.Comment[],
- );
- groupedComments.forEach(groupComment => {
- const rawTextTrimmed = groupComment.value.trim();
- if (rawTextTrimmed !== '}' && containsCode(injectMissingBraces(rawTextTrimmed))) {
- context.report({
- messageId: 'commentedCode',
- loc: getCommentLocation(groupComment.nodes),
- suggest: [
- {
- messageId: 'commentedCodeFix',
- fix(fixer) {
- const start = groupComment.nodes[0].range[0];
- const end = groupComment.nodes[groupComment.nodes.length - 1].range[1];
- return fixer.removeRange([start, end]);
- },
- },
- ],
- });
- }
- });
- },
- };
- },
-};
-
-function isExpressionExclusion(statement: estree.Node, code: SourceCode) {
- if (statement.type === 'ExpressionStatement') {
- const expression = statement.expression;
- if (
- expression.type === 'Identifier' ||
- expression.type === 'SequenceExpression' ||
- isUnaryPlusOrMinus(expression) ||
- isExcludedLiteral(expression) ||
- !code.getLastToken(statement, token => token.value === ';')
- ) {
- return true;
- }
- }
- return false;
-}
-
-function isExclusion(parsedBody: Array, code: SourceCode) {
- if (parsedBody.length === 1) {
- const singleStatement = parsedBody[0];
- return (
- EXCLUDED_STATEMENTS.includes(singleStatement.type) ||
- isReturnThrowExclusion(singleStatement) ||
- isExpressionExclusion(singleStatement, code)
- );
- }
- return false;
-}
-
-function containsCode(value: string) {
- if (!couldBeJsCode(value)) {
- return false;
- }
-
- try {
- const options = buildParserOptions(
- { filePath: 'some/filePath', tsConfigs: [], fileContent: '', fileType: 'MAIN' },
- true,
- );
- const result = babel.parse(value, options);
- const parseResult = new SourceCode(value, result);
- return parseResult.ast.body.length > 0 && !isExclusion(parseResult.ast.body, parseResult);
- } catch (exception) {
- return false;
- }
-
- function couldBeJsCode(input: string): boolean {
- return recognizer.extractCodeLines(input.split('\n')).length > 0;
- }
-}
-
-function injectMissingBraces(value: string) {
- const openCurlyBraceNum = (value.match(/{/g) || []).length;
- const closeCurlyBraceNum = (value.match(/}/g) || []).length;
- const missingBraces = openCurlyBraceNum - closeCurlyBraceNum;
- if (missingBraces > 0) {
- return value + Array(missingBraces).fill('}').join('');
- } else if (missingBraces < 0) {
- return Array(-missingBraces).fill('{').join('') + value;
- } else {
- return value;
- }
-}
-
-function getCommentLocation(nodes: TSESTree.Comment[]) {
- return {
- start: nodes[0].loc.start,
- end: nodes[nodes.length - 1].loc.end,
- };
-}
-
-function isReturnThrowExclusion(statement: estree.Node) {
- if (statement.type === 'ReturnStatement' || statement.type === 'ThrowStatement') {
- return statement.argument == null || statement.argument.type === 'Identifier';
- }
- return false;
-}
-
-function isUnaryPlusOrMinus(expression: estree.Expression) {
- return (
- expression.type === 'UnaryExpression' &&
- (expression.operator === '+' || expression.operator === '-')
- );
-}
-
-function isExcludedLiteral(expression: estree.Expression) {
- if (expression.type === 'Literal') {
- return typeof expression.value === 'string' || typeof expression.value === 'number';
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-dead-store.ts b/eslint-bridge/src/linting/eslint/rules/no-dead-store.ts
deleted file mode 100644
index 6186e2cf6ce..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-dead-store.ts
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1854/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import {
- isLiteral,
- isObjectExpression,
- isIdentifier,
- isAssignmentExpression,
-} from 'eslint-plugin-sonarjs/lib/utils/nodes';
-import CodePath = Rule.CodePath;
-import Variable = Scope.Variable;
-import CodePathSegment = Rule.CodePathSegment;
-import {
- isUnaryExpression,
- isArrayExpression,
- LiveVariables,
- lva,
- ReferenceLike,
- isNullLiteral,
-} from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeAssignment: 'Remove this useless assignment to variable "{{variable}}".',
- },
- },
- create(context: Rule.RuleContext) {
- const codePathStack: CodePathContext[] = [];
- const liveVariablesMap = new Map();
- const readVariables = new Set();
- // map from Variable to CodePath ids where variable is used
- const variableUsages = new Map>();
- const referencesUsedInDestructuring = new Set();
- const destructuringStack: DestructuringContext[] = [];
-
- return {
- ':matches(AssignmentExpression, VariableDeclarator[init])': (node: estree.Node) => {
- pushAssignmentContext(node as AssignmentLike);
- },
- ':matches(AssignmentExpression, VariableDeclarator[init]):exit': () => {
- popAssignmentContext();
- },
- Identifier: (node: estree.Node) => {
- if (isEnumConstant()) {
- return;
- }
- checkIdentifierUsage(node as estree.Identifier);
- },
- JSXIdentifier: (node: unknown) => {
- checkIdentifierUsage(node as TSESTree.JSXIdentifier);
- },
- ObjectPattern: () => {
- destructuringStack.push(new DestructuringContext());
- },
- 'ObjectPattern > Property > Identifier': (node: estree.Node) => {
- const destructuring = peek(destructuringStack)!;
- const { ref } = resolveReference(node as estree.Identifier);
- if (ref) {
- destructuring.references.push(ref);
- }
- },
- 'ObjectPattern > :matches(RestElement, ExperimentalRestProperty)': () => {
- peek(destructuringStack).hasRest = true;
- },
- 'ObjectPattern:exit': () => {
- const destructuring = destructuringStack.pop();
- if (destructuring && destructuring.hasRest) {
- destructuring.references.forEach(ref => referencesUsedInDestructuring.add(ref));
- }
- },
-
- 'Program:exit': () => {
- lva(liveVariablesMap);
- liveVariablesMap.forEach(lva => {
- checkSegment(lva);
- reportNeverReadVariables(lva);
- });
- },
-
- // CodePath events
- onCodePathSegmentStart: (segment: CodePathSegment) => {
- liveVariablesMap.set(segment.id, new LiveVariables(segment));
- },
- onCodePathStart: codePath => {
- pushContext(new CodePathContext(codePath));
- },
- onCodePathEnd: () => {
- popContext();
- },
- };
-
- function pushAssignmentContext(node: AssignmentLike) {
- peek(codePathStack).assignmentStack.push(new AssignmentContext(node));
- }
-
- function popAssignmentContext() {
- const assignment = peek(codePathStack).assignmentStack.pop()!;
- assignment.rhs.forEach(r => processReference(r));
- assignment.lhs.forEach(r => processReference(r));
- }
-
- function checkSegment(liveVariables: LiveVariables) {
- const willBeRead = new Set(liveVariables.out);
- const references = [...liveVariables.references].reverse();
- references.forEach(ref => {
- const variable = ref.resolved;
- if (!variable) {
- return;
- }
- if (ref.isWrite()) {
- if (!willBeRead.has(variable) && shouldReport(ref)) {
- report(ref);
- }
- willBeRead.delete(variable);
- }
- if (ref.isRead()) {
- willBeRead.add(variable);
- }
- });
- }
-
- function reportNeverReadVariables(lva: LiveVariables) {
- lva.references.forEach(ref => {
- if (shouldReportReference(ref) && !readVariables.has(ref.resolved!)) {
- report(ref);
- }
- });
- }
-
- function shouldReport(ref: ReferenceLike) {
- const variable = ref.resolved;
- return (
- variable &&
- shouldReportReference(ref) &&
- !variableUsedOutsideOfCodePath(variable) &&
- readVariables.has(variable)
- );
- }
-
- function shouldReportReference(ref: ReferenceLike) {
- const variable = ref.resolved;
- return (
- variable &&
- isLocalVar(variable) &&
- !isReferenceWithBasicValue(ref) &&
- !isDefaultParameter(ref) &&
- !referencesUsedInDestructuring.has(ref) &&
- !variable.name.startsWith('_') &&
- !isIncrementOrDecrement(ref) &&
- !isNullAssignment(ref)
- );
- }
-
- function isIncrementOrDecrement(ref: ReferenceLike) {
- const parent = (ref.identifier as TSESTree.Identifier).parent;
- return parent && parent.type === 'UpdateExpression';
- }
-
- function isNullAssignment(ref: ReferenceLike) {
- const parent = (ref.identifier as TSESTree.Identifier).parent;
- return (
- parent &&
- parent.type === 'AssignmentExpression' &&
- isNullLiteral(parent.right as estree.Node)
- );
- }
-
- function isEnumConstant() {
- return (context.getAncestors() as TSESTree.Node[]).some(n => n.type === 'TSEnumDeclaration');
- }
-
- function isDefaultParameter(ref: ReferenceLike) {
- if (ref.identifier.type !== 'Identifier') {
- return false;
- }
- const parent = (ref.identifier as TSESTree.Identifier).parent;
- return parent && parent.type === 'AssignmentPattern';
- }
-
- function isLocalVar(variable: Variable) {
- // @ts-ignore
- const scope = variable.scope;
- const node = scope.block as TSESTree.Node;
- return node.type !== 'Program' && node.type !== 'TSModuleDeclaration';
- }
-
- function variableUsedOutsideOfCodePath(variable: Scope.Variable) {
- return variableUsages.get(variable)!.size > 1;
- }
-
- function isReferenceWithBasicValue(ref: ReferenceLike) {
- return ref.init && ref.writeExpr && isBasicValue(ref.writeExpr);
- }
-
- function isBasicValue(node: estree.Node): boolean {
- const node1 = node as TSESTree.Node;
- if (isLiteral(node1)) {
- return node1.value === '' || [0, 1, null, true, false].includes(node1.value as any);
- }
- if (isIdentifier(node1)) {
- return node1.name === 'undefined';
- }
- if (isUnaryExpression(node)) {
- return isBasicValue(node.argument);
- }
- if (isObjectExpression(node1)) {
- return node1.properties.length === 0;
- }
- if (isArrayExpression(node)) {
- return node.elements.length === 0;
- }
- return false;
- }
-
- function report(ref: ReferenceLike) {
- context.report({
- messageId: 'removeAssignment',
- data: {
- variable: ref.identifier.name,
- },
- loc: ref.identifier.loc!,
- });
- }
-
- function checkIdentifierUsage(node: estree.Identifier | TSESTree.JSXIdentifier) {
- const { ref, variable } =
- node.type === 'Identifier' ? resolveReference(node) : resolveJSXReference(node);
- if (ref) {
- processReference(ref);
- if (variable) {
- updateReadVariables(ref);
- }
- }
- if (variable) {
- updateVariableUsages(variable);
- }
- }
-
- function resolveJSXReference(node: TSESTree.JSXIdentifier) {
- if (isJSXAttributeName(node)) {
- return {};
- }
- const jsxReference = new JSXReference(node, context.getScope());
- return { ref: jsxReference, variable: jsxReference.resolved };
- }
-
- function isJSXAttributeName(node: TSESTree.JSXIdentifier) {
- const parent = node.parent;
- return parent && parent.type === 'JSXAttribute' && parent.name === node;
- }
-
- function processReference(ref: ReferenceLike) {
- const assignmentStack = peek(codePathStack).assignmentStack;
- if (assignmentStack.length > 0) {
- const assignment = peek(assignmentStack);
- assignment.add(ref);
- } else {
- peek(codePathStack).codePath.currentSegments.forEach(segment => {
- lvaForSegment(segment).add(ref);
- });
- }
- }
-
- function lvaForSegment(segment: CodePathSegment) {
- let lva;
- if (liveVariablesMap.has(segment.id)) {
- lva = liveVariablesMap.get(segment.id)!;
- } else {
- lva = new LiveVariables(segment);
- liveVariablesMap.set(segment.id, lva);
- }
- return lva;
- }
-
- function updateReadVariables(reference: ReferenceLike) {
- const variable = reference.resolved!;
- if (reference.isRead()) {
- readVariables.add(variable);
- }
- }
-
- function updateVariableUsages(variable: Scope.Variable) {
- const codePathId = peek(codePathStack).codePath.id;
- if (variableUsages.has(variable)) {
- variableUsages.get(variable)!.add(codePathId);
- } else {
- variableUsages.set(variable, new Set([codePathId]));
- }
- }
-
- function popContext() {
- codePathStack.pop();
- }
-
- function pushContext(codePathContext: CodePathContext) {
- codePathStack.push(codePathContext);
- }
-
- function resolveReference(node: estree.Identifier) {
- return resolveReferenceRecursively(node, context.getScope());
- }
-
- function resolveReferenceRecursively(
- node: estree.Identifier,
- scope: Scope.Scope | null,
- depth = 0,
- ): { ref: ReferenceLike | null; variable: Scope.Variable | null } {
- if (scope === null || depth > 2) {
- return { ref: null, variable: null };
- }
- const ref = scope.references.find(r => r.identifier === node);
- if (ref) {
- return { ref, variable: ref.resolved };
- } else {
- // if it's not a reference, it can be just declaration without initializer
- const variable = scope.variables.find(v => v.defs.find(def => def.name === node));
- if (variable) {
- return { ref: null, variable };
- }
- // we only need 1-level recursion, only for switch expression, which is likely a bug in eslint
- return resolveReferenceRecursively(node, scope.upper, depth + 1);
- }
- }
- },
-};
-
-class CodePathContext {
- codePath: CodePath;
- segments = new Map();
- assignmentStack: AssignmentContext[] = [];
-
- constructor(codePath: CodePath) {
- this.codePath = codePath;
- }
-}
-
-class DestructuringContext {
- hasRest = false;
- references: ReferenceLike[] = [];
-}
-
-type AssignmentLike = TSESTree.AssignmentExpression | TSESTree.VariableDeclarator;
-
-class AssignmentContext {
- node: AssignmentLike;
-
- constructor(node: AssignmentLike) {
- this.node = node;
- }
-
- lhs = new Set();
- rhs = new Set();
-
- isRhs(node: TSESTree.Node) {
- return isAssignmentExpression(this.node) ? this.node.right === node : this.node.init === node;
- }
-
- isLhs(node: TSESTree.Node) {
- return isAssignmentExpression(this.node) ? this.node.left === node : this.node.id === node;
- }
-
- add(ref: ReferenceLike) {
- let parent = ref.identifier as TSESTree.Node | undefined;
- while (parent) {
- if (this.isLhs(parent)) {
- this.lhs.add(ref);
- break;
- }
- if (this.isRhs(parent)) {
- this.rhs.add(ref);
- break;
- }
- parent = parent.parent;
- }
- if (parent === null) {
- throw new Error('failed to find assignment lhs/rhs');
- }
- }
-}
-
-class JSXReference implements ReferenceLike {
- from: Scope.Scope;
- identifier: TSESTree.JSXIdentifier;
- init = false;
- resolved: Scope.Variable | null;
- writeExpr: estree.Node | null = null;
-
- constructor(node: TSESTree.JSXIdentifier, scope: Scope.Scope) {
- this.from = scope;
- this.identifier = node;
- this.resolved = findJSXVariableInScope(node, scope);
- }
-
- isRead(): boolean {
- return true;
- }
-
- isReadOnly(): boolean {
- return true;
- }
-
- isReadWrite(): boolean {
- return false;
- }
-
- isWrite(): boolean {
- return false;
- }
-
- isWriteOnly(): boolean {
- return false;
- }
-}
-
-function findJSXVariableInScope(
- node: TSESTree.JSXIdentifier,
- scope: Scope.Scope | null,
-): Scope.Variable | null {
- return (
- scope &&
- (scope.variables.find(v => v.name === node.name) || findJSXVariableInScope(node, scope.upper))
- );
-}
-
-function peek(arr: Array) {
- return arr[arr.length - 1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-delete-var.ts b/eslint-bridge/src/linting/eslint/rules/no-delete-var.ts
deleted file mode 100644
index afbd41d27ca..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-delete-var.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3001/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeDelete: 'Remove this "delete" operator or pass an object property to it.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- "UnaryExpression[operator='delete'][argument.type!='MemberExpression'][argument.type!='ChainExpression']":
- (node: estree.Node) => {
- const { argument } = node as estree.UnaryExpression;
- if (!isGlobalProperty(argument, context.getScope().references)) {
- context.report({
- messageId: 'removeDelete',
- node,
- });
- }
- },
- };
- },
-};
-
-function isGlobalProperty(expr: estree.Expression, references: Scope.Reference[]) {
- return (
- expr.type === 'Identifier' &&
- references.filter(ref => ref.identifier.name === expr.name && ref.resolved).length === 0
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-duplicate-in-composite.ts b/eslint-bridge/src/linting/eslint/rules/no-duplicate-in-composite.ts
deleted file mode 100644
index 51a45979407..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-duplicate-in-composite.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4621/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- return {
- 'TSUnionType, TSIntersectionType'(node: estree.Node) {
- const sourceCode = context.getSourceCode();
- const compositeType = node as unknown as TSESTree.TSUnionType | TSESTree.TSIntersectionType;
- const groupedTypes: Map> = new Map();
-
- compositeType.types.forEach(typescriptType => {
- const nodeValue = sourceCode.getText(typescriptType as unknown as estree.Node);
- const nodesWithGivenType = groupedTypes.get(nodeValue);
- const nodeType = typescriptType as TSESTree.Node;
- if (!nodesWithGivenType) {
- groupedTypes.set(nodeValue, [nodeType]);
- } else {
- nodesWithGivenType.push(nodeType);
- }
- });
-
- groupedTypes.forEach(duplicates => {
- if (duplicates.length > 1) {
- const suggest = getSuggestions(compositeType, duplicates, context);
- const primaryNode = duplicates.splice(1, 1)[0];
- const secondaryMessages = Array(duplicates.length);
- secondaryMessages[0] = `Original`;
- secondaryMessages.fill(`Another duplicate`, 1, duplicates.length);
-
- context.report({
- message: toEncodedMessage(
- `Remove this duplicated type or replace with another one.`,
- duplicates,
- secondaryMessages,
- ),
- loc: primaryNode.loc,
- suggest,
- });
- }
- });
- },
- };
- },
-};
-
-function getSuggestions(
- composite: TSESTree.TSUnionType | TSESTree.TSIntersectionType,
- duplicates: TSESTree.Node[],
- context: Rule.RuleContext,
-): Rule.SuggestionReportDescriptor[] {
- const ranges: [number, number][] = duplicates.slice(1).map(duplicate => {
- const idx = composite.types.indexOf(duplicate as TSESTree.TypeNode);
- return [
- getEnd(context, composite.types[idx - 1], composite),
- getEnd(context, duplicate, composite),
- ];
- });
- return [
- {
- desc: 'Remove duplicate types',
- fix: fixer => ranges.map(r => fixer.removeRange(r)),
- },
- ];
-}
-
-function getEnd(context: Rule.RuleContext, node: TSESTree.Node, composite: TSESTree.Node) {
- let end: estree.Node | AST.Token = node as unknown as estree.Node;
- while (true) {
- const nextToken: AST.Token | null = context.getSourceCode().getTokenAfter(end);
- if (nextToken && nextToken.value === ')' && nextToken.range![1] <= composite.range![1]) {
- end = nextToken;
- } else {
- break;
- }
- }
- return end.range![1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-empty-after-reluctant.ts b/eslint-bridge/src/linting/eslint/rules/no-empty-after-reluctant.ts
deleted file mode 100644
index 012eefb522d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-empty-after-reluctant.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6019/javascript
-
-import { Rule } from 'eslint';
-import * as regexpp from 'regexpp';
-import { createRegExpRule, RegexRuleContext } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- return {
- onRegExpLiteralEnter: (node: regexpp.AST.RegExpLiteral) => {
- node.pattern.alternatives.forEach(({ elements }) => checkElements(elements, context));
- },
- };
-});
-
-function report(quantifier: regexpp.AST.Quantifier, context: RegexRuleContext) {
- const ending = quantifier.min === 1 ? '' : 's';
- const message = `Fix this reluctant quantifier that will only ever match ${quantifier.min} repetition${ending}.`;
- context.reportRegExpNode({
- message,
- regexpNode: quantifier,
- node: context.node,
- });
-}
-
-function checkElements(elements: regexpp.AST.Element[], context: RegexRuleContext) {
- if (elements.length === 0) {
- return;
- }
-
- const lastElement = elements[elements.length - 1];
- if (lastElement.type === 'Quantifier' && !lastElement.greedy) {
- report(lastElement, context);
- return;
- }
-
- if (elements.length === 1) {
- return;
- }
-
- const lastButOneElement = elements[elements.length - 2];
- if (lastButOneElement.type === 'Quantifier' && !lastButOneElement.greedy) {
- if (lastElement.type === 'Assertion' && lastElement.kind === 'end') {
- context.reportRegExpNode({
- message: `Remove the '?' from this unnecessarily reluctant quantifier.`,
- regexpNode: lastButOneElement,
- node: context.node,
- });
- } else if (lastElement.type === 'Quantifier' && lastElement.min === 0) {
- report(lastButOneElement, context);
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-empty-alternatives.ts b/eslint-bridge/src/linting/eslint/rules/no-empty-alternatives.ts
deleted file mode 100644
index 0d92fc43dfa..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-empty-alternatives.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6323/javascript
-
-import { Rule } from 'eslint';
-import { last } from './helpers';
-import { Alternation } from './helpers/regex';
-import * as regexpp from 'regexpp';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- function checkAlternation(alternation: Alternation) {
- const { alternatives: alts } = alternation;
- if (alts.length <= 1) {
- return;
- }
- for (let i = 0; i < alts.length; i++) {
- let alt = alts[i];
- if (alt.elements.length === 0 && !isLastEmptyInGroup(alt)) {
- context.reportRegExpNode({
- message: 'Remove this empty alternative.',
- regexpNode: alt,
- offset: i === alts.length - 1 ? [-1, 0] : [0, 1], // we want to raise the issue on the |
- node: context.node,
- });
- }
- }
- }
-
- return {
- onPatternEnter: checkAlternation,
- onGroupEnter: checkAlternation,
- onCapturingGroupEnter: checkAlternation,
- };
-});
-
-function isLastEmptyInGroup(alt: regexpp.AST.Alternative) {
- const group = alt.parent;
- return (
- (group.type === 'Group' || group.type === 'CapturingGroup') &&
- last(group.alternatives) === alt &&
- group.parent.type !== 'Quantifier'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-empty-group.ts b/eslint-bridge/src/linting/eslint/rules/no-empty-group.ts
deleted file mode 100644
index 656c099adea..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-empty-group.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6331/javascript
-
-import { Rule } from 'eslint';
-import { AST } from 'regexpp';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- function checkEmptyGroup(group: AST.Group | AST.CapturingGroup) {
- const { alternatives } = group;
- if (alternatives.every(alt => alt.elements.length === 0)) {
- context.reportRegExpNode({
- message: 'Remove this empty group.',
- node: context.node,
- regexpNode: group,
- });
- }
- }
- return {
- onGroupEnter: checkEmptyGroup,
- onCapturingGroupEnter: checkEmptyGroup,
- };
-});
diff --git a/eslint-bridge/src/linting/eslint/rules/no-equals-in-for-termination.ts b/eslint-bridge/src/linting/eslint/rules/no-equals-in-for-termination.ts
deleted file mode 100644
index 0b762cec4ae..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-equals-in-for-termination.ts
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S888/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getVariableFromName } from './helpers';
-
-const allEqualityOperators = ['!=', '==', '!==', '==='];
-const notEqualOperators = ['!==', '!='];
-const plusMinusOperators = ['+=', '-='];
-
-interface CompleteForStatement extends estree.BaseStatement {
- type: 'ForStatement';
- init?: estree.VariableDeclaration | estree.Expression | null;
- test: estree.Expression;
- update: estree.Expression;
- body: estree.Statement;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- replaceOperator:
- "Replace '{{operator}}' operator with one of '<=', '>=', '<', or '>' comparison operators.",
- },
- },
- create(context: Rule.RuleContext) {
- return {
- ForStatement: (node: estree.Node) => {
- const forStatement = node as estree.ForStatement;
- if (!forStatement.test || !forStatement.update) {
- return;
- }
- const completeForStatement = node as CompleteForStatement;
- const condition = completeForStatement.test;
- if (
- isEquality(condition) &&
- isUpdateIncDec(completeForStatement.update) &&
- !isException(completeForStatement, context)
- ) {
- context.report({
- messageId: 'replaceOperator',
- data: {
- operator: condition.operator,
- },
- node: condition,
- });
- }
- },
- };
- },
-};
-
-function isEquality(expression: estree.Expression): expression is estree.BinaryExpression {
- return (
- expression.type === 'BinaryExpression' && allEqualityOperators.includes(expression.operator)
- );
-}
-
-function isUpdateIncDec(expression: estree.Expression): boolean {
- if (isIncDec(expression) || expression.type === 'UpdateExpression') {
- return true;
- } else if (expression.type === 'SequenceExpression') {
- return expression.expressions.every(isUpdateIncDec);
- }
- return false;
-}
-
-function isIncDec(expression: estree.Expression): expression is estree.AssignmentExpression {
- return (
- expression.type === 'AssignmentExpression' && plusMinusOperators.includes(expression.operator)
- );
-}
-
-function isException(forStatement: CompleteForStatement, context: Rule.RuleContext) {
- return (
- isNontrivialConditionException(forStatement) ||
- isTrivialIteratorException(forStatement, context)
- );
-}
-
-function isNontrivialConditionException(forStatement: CompleteForStatement) {
- //If we reach this point, we know that test is an equality kind
- const condition = forStatement.test as estree.BinaryExpression;
- const counters: Array = [];
- collectCounters(forStatement.update, counters);
- return condition.left.type !== 'Identifier' || !counters.includes(condition.left.name);
-}
-
-function collectCounters(expression: estree.Expression, counters: Array) {
- let counter: estree.Node | null | undefined = undefined;
-
- if (isIncDec(expression)) {
- counter = expression.left;
- } else if (expression.type === 'UpdateExpression') {
- counter = expression.argument;
- } else if (expression.type === 'SequenceExpression') {
- expression.expressions.forEach(e => collectCounters(e, counters));
- }
-
- if (counter && counter.type === 'Identifier') {
- counters.push(counter.name);
- }
-}
-
-function isTrivialIteratorException(forStatement: CompleteForStatement, context: Rule.RuleContext) {
- const init = forStatement.init;
- const condition = forStatement.test;
-
- if (init && isNotEqual(condition)) {
- const updatedByOne = checkForUpdateByOne(forStatement.update, forStatement.body, context);
- if (updatedByOne !== 0) {
- const beginValue = getValue(init);
- const endValue = getValue(condition);
- return (
- beginValue !== undefined &&
- endValue !== undefined &&
- updatedByOne === Math.sign(endValue - beginValue)
- );
- }
- }
-
- return false;
-}
-
-function isNotEqual(node: estree.Node): node is estree.BinaryExpression {
- return node.type === 'BinaryExpression' && notEqualOperators.includes(node.operator);
-}
-
-function checkForUpdateByOne(
- update: estree.Expression,
- loopBody: estree.Node,
- context: Rule.RuleContext,
-) {
- if (isUpdateByOne(update, loopBody, context)) {
- if (update.operator === '++' || update.operator === '+=') {
- return +1;
- }
- if (update.operator === '--' || update.operator === '-=') {
- return -1;
- }
- }
- return 0;
-}
-
-function isUpdateByOne(
- update: estree.Expression,
- loopBody: estree.Node,
- context: Rule.RuleContext,
-): update is estree.UpdateExpression | estree.AssignmentExpression {
- return (
- (update.type === 'UpdateExpression' && !isUsedInsideBody(update.argument, loopBody, context)) ||
- (isUpdateOnOneWithAssign(update) && !isUsedInsideBody(update.left, loopBody, context))
- );
-}
-
-function isUsedInsideBody(id: estree.Node, loopBody: estree.Node, context: Rule.RuleContext) {
- if (id.type === 'Identifier') {
- const variable = getVariableFromName(context, id.name);
- const bodyRange = loopBody.range;
- if (variable && bodyRange) {
- return variable.references.some(ref => isInBody(ref.identifier, bodyRange));
- }
- }
- return false;
-}
-
-function isInBody(id: estree.Identifier, bodyRange: [number, number]) {
- return id && id.range && id.range[0] > bodyRange[0] && id.range[1] < bodyRange[1];
-}
-
-function getValue(node: estree.Node) {
- if (isNotEqual(node)) {
- return getInteger(node.right);
- } else if (isOneVarDeclaration(node)) {
- const variable = node.declarations[0];
- return getInteger(variable.init);
- } else if (node.type === 'AssignmentExpression') {
- return getInteger(node.right);
- }
- return undefined;
-}
-
-function getInteger(node: estree.Node | undefined | null) {
- if (node && node.type === 'Literal' && typeof node.value === 'number') {
- return node.value;
- }
- return undefined;
-}
-
-function isOneVarDeclaration(node: estree.Node): node is estree.VariableDeclaration {
- return node.type === 'VariableDeclaration' && node.declarations.length === 1;
-}
-
-function isUpdateOnOneWithAssign(
- expression: estree.Expression,
-): expression is estree.AssignmentExpression {
- if (isIncDec(expression)) {
- const right = expression.right;
- return right.type === 'Literal' && right.value === 1;
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-exclusive-tests.ts b/eslint-bridge/src/linting/eslint/rules/no-exclusive-tests.ts
deleted file mode 100644
index eb326b1773e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-exclusive-tests.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6426/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isMethodCall, isIdentifier } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- issue: 'Remove ".only()" from your test case.',
- quickfix: 'Remove ."only()".',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.CallExpression) => {
- if (isMethodCall(node)) {
- const { property, object } = node.callee;
- if (isIdentifier(property, 'only') && isIdentifier(object, 'describe', 'it', 'test')) {
- context.report({
- messageId: 'issue',
- node: property,
- suggest: [
- {
- fix: (fixer: Rule.RuleFixer) => {
- const fixes = [fixer.remove(property)];
- const dotBeforeOnly = context.getSourceCode().getTokenBefore(property);
- if (dotBeforeOnly != null) {
- fixes.push(fixer.remove(dotBeforeOnly));
- }
- return fixes;
- },
- messageId: 'quickfix',
- },
- ],
- });
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-for-in-iterable.ts b/eslint-bridge/src/linting/eslint/rules/no-for-in-iterable.ts
deleted file mode 100644
index feb66d65d58..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-for-in-iterable.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4139/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import ts from 'typescript';
-import { getTypeFromTreeNode, isRequiredParserServices } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- useForOf: 'Use "for...of" to iterate over this "{{iterable}}".',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- ForInStatement: (node: estree.Node) => {
- const type = getTypeFromTreeNode((node as estree.ForInStatement).right, services);
- if (isIterable(type)) {
- const iterable = type.symbol ? type.symbol.name : 'String';
- context.report({
- messageId: 'useForOf',
- data: { iterable },
- loc: context.getSourceCode().getFirstToken(node)!.loc,
- });
- }
- },
- };
- },
-};
-
-function isIterable(type: ts.Type) {
- return isCollection(type) || isString(type);
-}
-
-function isCollection(type: ts.Type) {
- return (
- type.symbol !== undefined &&
- [
- 'Array',
- 'Int8Array',
- 'Uint8Array',
- 'Uint8ClampedArray',
- 'Int16Array',
- 'Uint16Array',
- 'Int32Array',
- 'Uint32Array',
- 'Float32Array',
- 'Float64Array',
- 'BigInt64Array',
- 'BigUint64Array',
- 'Set',
- 'Map',
- ].includes(type.symbol.name)
- );
-}
-
-function isString(type: ts.Type) {
- return (
- (type.symbol !== undefined && type.symbol.name === 'String') ||
- (type.flags & ts.TypeFlags.StringLike) !== 0
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-function-declaration-in-block.ts b/eslint-bridge/src/linting/eslint/rules/no-function-declaration-in-block.ts
deleted file mode 100644
index d808b071bb9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-function-declaration-in-block.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1530/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getParent, RuleContext } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- blockedFunction: 'Do not use function declarations within blocks.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- ':not(FunctionDeclaration, FunctionExpression, ArrowFunctionExpression) > BlockStatement > FunctionDeclaration':
- (node: estree.Node) => {
- context.report({
- messageId: 'blockedFunction',
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionDeclaration,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-global-this.ts b/eslint-bridge/src/linting/eslint/rules/no-global-this.ts
deleted file mode 100644
index 2a377c883fe..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-global-this.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2990/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- removeThis: `Remove the use of "this".`,
- suggestRemoveThis: 'Remove "this"',
- suggestUseWindow: 'Replace "this" with "window" object',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'MemberExpression[object.type="ThisExpression"]'(node: estree.Node) {
- const memberExpression = node as estree.MemberExpression;
- const scopeType = context.getScope().variableScope.type;
- const isInsideClass = context
- .getAncestors()
- .some(
- ancestor => ancestor.type === 'ClassDeclaration' || ancestor.type === 'ClassExpression',
- );
- if ((scopeType === 'global' || scopeType === 'module') && !isInsideClass) {
- const suggest: Rule.SuggestionReportDescriptor[] = [];
- if (!memberExpression.computed) {
- const propertyText = context.getSourceCode().getText(memberExpression.property);
- suggest.push(
- {
- messageId: 'suggestRemoveThis',
- fix: fixer => fixer.replaceText(node, propertyText),
- },
- {
- messageId: 'suggestUseWindow',
- fix: fixer => fixer.replaceText(memberExpression.object, 'window'),
- },
- );
- }
- context.report({
- messageId: 'removeThis',
- node: memberExpression.object,
- suggest,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-globals-shadowing.ts b/eslint-bridge/src/linting/eslint/rules/no-globals-shadowing.ts
deleted file mode 100644
index 7b8f2d15de8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-globals-shadowing.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2137/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-const illegalNames = ['eval', 'arguments', 'undefined', 'NaN', 'Infinity'];
-
-const getDeclarationIssue = (redeclareType: string) => (name: string) => ({
- messageId: 'forbidDeclaration',
- data: { symbol: name, type: redeclareType },
-});
-
-const getModificationIssue = (functionName: string) => ({
- messageId: 'removeModification',
- data: { symbol: functionName },
-});
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeModification: 'Remove the modification of "{{symbol}}".',
- forbidDeclaration: 'Do not use "{{symbol}}" to declare a {{type}} - use another name.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'FunctionDeclaration, FunctionExpression': function (node: estree.Node) {
- const func = node as estree.FunctionDeclaration | estree.FunctionExpression;
- reportBadUsageOnFunction(func, func.id, context);
- },
- ArrowFunctionExpression: function (node: estree.Node) {
- reportBadUsageOnFunction(node as estree.ArrowFunctionExpression, undefined, context);
- },
- VariableDeclaration(node: estree.Node) {
- (node as estree.VariableDeclaration).declarations.forEach(decl => {
- reportBadUsage(decl.id, getDeclarationIssue('variable'), context);
- });
- },
- UpdateExpression(node: estree.Node) {
- reportBadUsage((node as estree.UpdateExpression).argument, getModificationIssue, context);
- },
- AssignmentExpression(node: estree.Node) {
- reportBadUsage((node as estree.AssignmentExpression).left, getModificationIssue, context);
- },
- CatchClause(node: estree.Node) {
- reportBadUsage(
- (node as estree.CatchClause).param,
- getDeclarationIssue('variable'),
- context,
- );
- },
- };
- },
-};
-
-function reportBadUsageOnFunction(
- func: estree.Function,
- id: estree.Node | null | undefined,
- context: Rule.RuleContext,
-) {
- reportBadUsage(id, getDeclarationIssue('function'), context);
- func.params.forEach(p => {
- reportBadUsage(p, getDeclarationIssue('parameter'), context);
- });
-}
-
-function reportBadUsage(
- node: estree.Node | null | undefined,
- buildMessageAndData: (name: string) => { messageId: string; data: any },
- context: Rule.RuleContext,
-) {
- if (node) {
- switch (node.type) {
- case 'Identifier': {
- if (illegalNames.includes(node.name)) {
- context.report({
- node: node,
- ...buildMessageAndData(node.name),
- });
- }
- break;
- }
- case 'RestElement':
- reportBadUsage(node.argument, buildMessageAndData, context);
- break;
- case 'ObjectPattern':
- node.properties.forEach(prop => {
- if (prop.type === 'Property') {
- reportBadUsage(prop.value, buildMessageAndData, context);
- } else {
- reportBadUsage(prop.argument, buildMessageAndData, context);
- }
- });
- break;
- case 'ArrayPattern':
- node.elements.forEach(elem => {
- reportBadUsage(elem, buildMessageAndData, context);
- });
- break;
- case 'AssignmentPattern':
- reportBadUsage(node.left, buildMessageAndData, context);
- break;
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-hardcoded-credentials.ts b/eslint-bridge/src/linting/eslint/rules/no-hardcoded-credentials.ts
deleted file mode 100644
index 35cde9816a7..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-hardcoded-credentials.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2068/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isStringLiteral } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- reviewCredential: 'Review this potentially hardcoded credential.',
- },
- },
- create(context: Rule.RuleContext) {
- const variableNames = context.options;
- const literalRegExp = variableNames.map(name => new RegExp(`${name}=.+`));
- return {
- VariableDeclarator: (node: estree.Node) => {
- const declaration = node as estree.VariableDeclarator;
- checkAssignment(context, variableNames, declaration.id, declaration.init);
- },
- AssignmentExpression: (node: estree.Node) => {
- const assignment = node as estree.AssignmentExpression;
- checkAssignment(context, variableNames, assignment.left, assignment.right);
- },
- Property: (node: estree.Node) => {
- const property = node as estree.Property;
- checkAssignment(context, variableNames, property.key, property.value);
- },
- Literal: (node: estree.Node) => {
- const literal = node as estree.Literal;
- checkLiteral(context, literalRegExp, literal);
- },
- };
- },
-};
-
-function checkAssignment(
- context: Rule.RuleContext,
- patterns: string[],
- variable: estree.Node,
- initializer?: estree.Node | null,
-) {
- if (
- initializer &&
- isStringLiteral(initializer) &&
- (initializer.value as string).length > 0 &&
- patterns.some(pattern => context.getSourceCode().getText(variable).includes(pattern))
- ) {
- context.report({
- messageId: 'reviewCredential',
- node: initializer,
- });
- }
-}
-
-function checkLiteral(context: Rule.RuleContext, patterns: RegExp[], literal: estree.Literal) {
- if (isStringLiteral(literal) && patterns.some(pattern => pattern.test(literal.value as string))) {
- context.report({
- messageId: 'reviewCredential',
- node: literal,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-hardcoded-ip.ts b/eslint-bridge/src/linting/eslint/rules/no-hardcoded-ip.ts
deleted file mode 100644
index 6e2e4742fb9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-hardcoded-ip.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1313/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIP } from 'net';
-
-const netMaskRegex = /(^[^\/]+)\/\d{1,3}$/;
-const acceptedIpAddresses = ['255.255.255.255', '::1', '::', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:0'];
-const ipV4Octets = 4;
-const ipV4MappedToV6Prefix = '::ffff:0:';
-const acceptedIpV6Starts = [
- // https://datatracker.ietf.org/doc/html/rfc3849
- '2001:db8:',
-];
-const acceptedIpV4Starts = [
- '127.',
- '0.',
- // avoid FP for OID http://www.oid-info.com/introduction.htm
- '2.5',
- // https://datatracker.ietf.org/doc/html/rfc5737
- '192.0.2.',
- '198.51.100.',
- '203.0.113.',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- checkIP: 'Make sure using a hardcoded IP address {{ip}} is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- function isException(ip: string) {
- return (
- acceptedIpV6Starts.some(prefix => ip.startsWith(prefix)) ||
- acceptedIpV4Starts.some(
- prefix => ip.startsWith(ipV4MappedToV6Prefix + prefix) || ip.startsWith(prefix),
- ) ||
- acceptedIpAddresses.includes(ip)
- );
- }
- function isIPV4OctalOrHex(ip: string) {
- const digits = ip.split('.');
- if (digits.length !== ipV4Octets) {
- return false;
- }
- const decimalDigits = [];
- for (const digit of digits) {
- if (digit.match(/^0[0-7]*$/)) {
- decimalDigits.push(parseInt(digit, 8));
- } else if (digit.match(/^0[xX][0-9a-fA-F]+$/)) {
- decimalDigits.push(parseInt(digit, 16));
- } else {
- return false;
- }
- }
- const convertedIp = `${decimalDigits[0]}.${decimalDigits[1]}.${decimalDigits[2]}.${decimalDigits[3]}`;
- return !isException(convertedIp) && isIP(convertedIp) !== 0;
- }
- return {
- Literal(node: estree.Node) {
- const { value } = node as estree.Literal;
- if (typeof value !== 'string') {
- return;
- }
- let ip = value;
- const result = value.match(netMaskRegex);
- if (result) {
- ip = result[1];
- }
- if ((!isException(ip) && isIP(ip) !== 0) || isIPV4OctalOrHex(ip)) {
- context.report({
- node,
- messageId: 'checkIP',
- data: {
- ip: value,
- },
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-hook-setter-in-body.ts b/eslint-bridge/src/linting/eslint/rules/no-hook-setter-in-body.ts
deleted file mode 100644
index 7e8848b21a0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-hook-setter-in-body.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6442/javascript
-
-import { Rule, Scope as ESLintScope } from 'eslint';
-import Variable = ESLintScope.Variable;
-import Scope = ESLintScope.Scope;
-import * as estree from 'estree';
-import {
- findFirstMatchingLocalAncestor,
- getFullyQualifiedName,
- getVariableFromName,
- isFunctionNode,
- isIdentifier,
-} from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-type HookDeclarator = estree.VariableDeclarator & {
- id: {
- elements: estree.Identifier[];
- };
- init: estree.CallExpression;
-};
-
-type SetterCall = estree.CallExpression & {
- callee: estree.Identifier;
-};
-
-const REACT_MODULE = 'react';
-const REACT_PATTERN = /^[^a-z]/;
-const HOOK_FUNCTION = 'useState';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- noHookSetterInBody:
- 'Remove this state setter call, perhaps move it to an event handler or JSX attribute',
- },
- },
- create(context: Rule.RuleContext) {
- function isHookCall(node: estree.CallExpression): boolean {
- return (
- getFullyQualifiedName(context, node) === `${REACT_MODULE}.${HOOK_FUNCTION}` &&
- node.arguments.length === 1
- );
- }
-
- function getReactComponentScope(): Scope | null {
- const scope = context.getScope();
- const isReact = isFunctionNode(scope.block) && matchesReactComponentName(scope.block, 1);
- return isReact ? scope : null;
- }
-
- function isInsideFunctionScope(scope: Scope | null): boolean {
- function searchUpperFunctionScope(current: Scope | null): Scope | null {
- if (current === null) {
- return null;
- } else if (current.type === 'function') {
- return current;
- } else {
- return searchUpperFunctionScope(current.upper);
- }
- }
-
- return scope !== null && searchUpperFunctionScope(context.getScope()) === scope;
- }
-
- function isInsideConditional(node: estree.Node): boolean {
- return (
- findFirstMatchingLocalAncestor(node as TSESTree.Node, n => n.type === 'IfStatement') !==
- undefined
- );
- }
-
- let reactComponentScope: Scope | null; // Scope of the React component render function.
- const setters: Variable[] = []; // Setter variables returned by the React useState() function.
-
- return {
- ':function'() {
- reactComponentScope ??= getReactComponentScope(); // Store the top-most React component scope.
- },
-
- ':function:exit'() {
- if (context.getScope() === reactComponentScope) {
- // Clean variables when leaving the React component scope.
- reactComponentScope = null;
- setters.length = 0;
- }
- },
-
- // Selector matching declarations like: const [count, setCount] = useState(0);
- ['VariableDeclarator[init.type="CallExpression"]' +
- ':has(ArrayPattern[elements.length=2][elements.0.type="Identifier"][elements.1.type="Identifier"])'](
- node: estree.VariableDeclarator,
- ) {
- if (!isInsideFunctionScope(reactComponentScope)) {
- return;
- }
-
- const hookDeclarator = node as HookDeclarator;
-
- if (isHookCall(hookDeclarator.init)) {
- const variable = getVariableFromName(context, hookDeclarator.id.elements[1].name);
- if (variable != null) {
- setters.push(variable);
- }
- }
- },
-
- // Selector matching function calls like: setCount(1)
- 'CallExpression[callee.type="Identifier"][arguments.length=1]'(node: estree.CallExpression) {
- if (
- !isInsideFunctionScope(reactComponentScope) ||
- setters.length === 0 ||
- isInsideConditional(node)
- ) {
- return;
- }
-
- const maybeSetterCall = node as SetterCall;
-
- const calleeVariable = getVariableFromName(context, maybeSetterCall.callee.name);
- if (setters.some(variable => variable === calleeVariable)) {
- context.report({
- messageId: 'noHookSetterInBody',
- node: node.callee,
- });
- }
- },
- };
- },
-};
-
-function hasParent(node: estree.Node): node is Rule.Node {
- return (node as Rule.Node).parent != null;
-}
-
-function matchesReactComponentName(node: estree.Node | null, max = 0): boolean {
- if (node == null) {
- return false;
- } else if (isIdentifier(node)) {
- return REACT_PATTERN.test(node.name);
- } else if (node.type === 'FunctionDeclaration') {
- return matchesReactComponentName(node.id);
- } else if (node.type === 'VariableDeclarator') {
- return matchesReactComponentName(node.id);
- } else if (node.type === 'AssignmentExpression') {
- return matchesReactComponentName(node.left);
- } else if (node.type === 'MemberExpression') {
- return matchesReactComponentName(node.property);
- } else if (hasParent(node) && max > 0) {
- return matchesReactComponentName(node.parent, max - 1);
- } else {
- return false;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-implicit-dependencies.ts b/eslint-bridge/src/linting/eslint/rules/no-implicit-dependencies.ts
deleted file mode 100644
index 5f6af30d87b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-implicit-dependencies.ts
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4328/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import builtins from 'builtin-modules';
-import * as path from 'path';
-import * as fs from 'fs';
-import * as ts from 'typescript';
-import { RequiredParserServices } from './helpers';
-import { stripBOM } from 'helpers';
-
-const DefinitelyTyped = '@types/';
-
-/**
- * Cache for each dirname the dependencies of the package.json in this directory, empty set when no package.json.
- */
-const dirCache: Map> = new Map();
-
-/**
- * Cache for the available dependencies by dirname.
- */
-const cache: Map> = new Map();
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeOrAddDependency: 'Either remove this import or add it as a dependency.',
- },
- },
- create(context: Rule.RuleContext) {
- const whitelist = context.options;
- const dependencies = getDependencies(context.getFilename());
- const aliasedPathsMappingPatterns = extractPathMappingPatterns(context.parserServices);
- const baseUrl = getBaseUrl(context.parserServices);
- if (aliasedPathsMappingPatterns === 'matchAll') {
- // deactivates this rule altogether.
- return {};
- }
- return {
- CallExpression: (node: estree.Node) => {
- const call = node as estree.CallExpression;
- if (
- call.callee.type === 'Identifier' &&
- call.callee.name === 'require' &&
- call.arguments.length === 1
- ) {
- const [argument] = call.arguments;
- if (argument.type === 'Literal') {
- const requireToken = call.callee;
- raiseOnImplicitImport(
- argument,
- requireToken.loc!,
- dependencies,
- whitelist,
- aliasedPathsMappingPatterns,
- baseUrl,
- context,
- );
- }
- }
- },
- ImportDeclaration: (node: estree.Node) => {
- const module = (node as estree.ImportDeclaration).source;
- const importToken = context.getSourceCode().getFirstToken(node);
- raiseOnImplicitImport(
- module,
- importToken!.loc,
- dependencies,
- whitelist,
- aliasedPathsMappingPatterns,
- baseUrl,
- context,
- );
- },
- };
- },
-};
-
-function raiseOnImplicitImport(
- module: estree.Literal,
- loc: estree.SourceLocation,
- dependencies: Set,
- whitelist: string[],
- aliasedPathsMappingPatterns: PathMappingPattern[],
- baseUrl: string | undefined,
- context: Rule.RuleContext,
-) {
- const moduleName = module.value;
- if (typeof moduleName !== 'string') {
- return;
- }
-
- if (ts.isExternalModuleNameRelative(moduleName)) {
- return;
- }
-
- if (aliasedPathsMappingPatterns.some(pattern => pattern.isApplicableTo(moduleName))) {
- return;
- }
-
- if (['node:', 'data:', 'file:'].some(prefix => moduleName.startsWith(prefix))) {
- return;
- }
-
- if (baseUrl) {
- const underBaseUrlPath = path.join(baseUrl, moduleName);
- const extensions = ['', '.ts', '.d.ts', '.tsx', '.js', '.jsx', '.vue', '.mjs'];
- if (extensions.some(extension => fs.existsSync(underBaseUrlPath + extension))) {
- return;
- }
- }
-
- const packageName = getPackageName(moduleName);
- if (
- !whitelist.includes(packageName) &&
- !builtins.includes(packageName) &&
- !dependencies.has(packageName)
- ) {
- context.report({
- messageId: 'removeOrAddDependency',
- loc,
- });
- }
-}
-
-function getPackageName(name: string) {
- /*
- - scoped `@namespace/foo/bar` -> package `@namespace/foo`
- - scope `foo/bar` -> package `foo`
- */
- const parts = name.split('/');
- if (!name.startsWith('@')) {
- return parts[0];
- } else {
- return `${parts[0]}/${parts[1]}`;
- }
-}
-
-function getDependencies(fileName: string) {
- let dirname = path.dirname(fileName);
- const cached = cache.get(dirname);
- if (cached) {
- return cached;
- }
-
- const result = new Set();
- cache.set(dirname, result);
-
- while (true) {
- const dirCached = dirCache.get(dirname);
- if (dirCached) {
- dirCached.forEach(d => result.add(d));
- } else {
- const packageJsonPath = path.join(path.resolve(dirname), 'package.json');
- const dep = fs.existsSync(packageJsonPath)
- ? getDependenciesFromPackageJson(packageJsonPath)
- : new Set();
- dep.forEach(d => result.add(d));
- dirCache.set(dirname, dep);
- }
-
- const upperDir = path.dirname(dirname);
- if (upperDir === dirname) {
- break;
- } else {
- dirname = upperDir;
- }
- }
-
- return result;
-}
-
-function getDependenciesFromPackageJson(packageJsonPath: string) {
- const result = new Set();
- try {
- const content = JSON.parse(readFile(packageJsonPath));
- if (content.dependencies !== undefined) {
- addDependencies(result, content.dependencies);
- }
- if (content.devDependencies !== undefined) {
- addDependencies(result, content.devDependencies);
- }
- if (content.peerDependencies !== undefined) {
- addDependencies(result, content.peerDependencies);
- }
- } catch {}
- return result;
-}
-
-function addDependencies(result: Set, dependencies: any) {
- Object.keys(dependencies).forEach(name =>
- result.add(name.startsWith(DefinitelyTyped) ? name.substring(DefinitelyTyped.length) : name),
- );
-}
-
-/**
- * The matching pattern part of a path mapping specified
- * in `paths` in `tsconfig.json`.
- */
-interface PathMappingPattern {
- isApplicableTo(name: string): boolean;
-}
-
-class PathMappingNoAsteriskPattern implements PathMappingPattern {
- constructor(private readonly value: string) {}
- isApplicableTo(name: string): boolean {
- return name === this.value;
- }
-}
-
-class PathMappingSingleAsteriskPattern implements PathMappingPattern {
- constructor(private readonly prefix: string, private readonly suffix: string) {}
- isApplicableTo(name: string): boolean {
- return name.startsWith(this.prefix) && name.endsWith(this.suffix);
- }
-}
-
-const PATH_MAPPING_ASTERISK_PATTERN = /^([^*]*)\*([^*]*)$/; // matches any string with single asterisk '*'
-const PATH_MAPPING_ASTERISK_PATTERN_PREFIX_IDX = 1;
-const PATH_MAPPING_ASTERISK_PATTERN_SUFFIX_IDX = 2;
-function extractPathMappingPatterns(
- parserServices: RequiredParserServices,
-): PathMappingPattern[] | 'matchAll' {
- const compilerOptions = parserServices.program && parserServices.program.getCompilerOptions();
- const paths = (compilerOptions && compilerOptions.paths) || [];
- const pathMappingPatterns: PathMappingPattern[] = [];
- for (const p in paths) {
- if (p === '*') {
- return 'matchAll';
- } else {
- const m = p.match(PATH_MAPPING_ASTERISK_PATTERN);
- if (m) {
- pathMappingPatterns.push(
- new PathMappingSingleAsteriskPattern(
- m[PATH_MAPPING_ASTERISK_PATTERN_PREFIX_IDX],
- m[PATH_MAPPING_ASTERISK_PATTERN_SUFFIX_IDX],
- ),
- );
- } else if (!p.includes('*')) {
- pathMappingPatterns.push(new PathMappingNoAsteriskPattern(p));
- } else {
- // This case should not occur: `tsc` emits error if there is more than one asterisk
- }
- }
- }
- return pathMappingPatterns;
-}
-
-function getBaseUrl(parserServices: RequiredParserServices): string | undefined {
- if (parserServices.program && parserServices.program.getCompilerOptions()) {
- return parserServices.program.getCompilerOptions().baseUrl;
- }
-
- return undefined;
-}
-
-function readFile(filePath: string) {
- const fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
- return stripBOM(fileContent);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-implicit-global.ts b/eslint-bridge/src/linting/eslint/rules/no-implicit-global.ts
deleted file mode 100644
index ba64230dfb5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-implicit-global.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2703/javascript
-
-import { Rule } from 'eslint';
-import { flatMap, globalsByLibraries } from './helpers';
-
-const excludedNames = new Set(flatMap(Object.values(globalsByLibraries), globals => globals));
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- explicitModifier:
- 'Add the "let", "const" or "var" keyword to this declaration of "{{variable}}" to make it explicit.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'Program:exit'() {
- const globalScope = context.getScope();
- const alreadyReported: Set = new Set();
- globalScope.through
- .filter(ref => ref.isWrite())
- .forEach(ref => {
- const name = ref.identifier.name;
- if (!alreadyReported.has(name) && !excludedNames.has(name)) {
- alreadyReported.add(name);
- context.report({
- messageId: 'explicitModifier',
- data: {
- variable: name,
- },
- node: ref.identifier,
- });
- }
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-in-misuse.ts b/eslint-bridge/src/linting/eslint/rules/no-in-misuse.ts
deleted file mode 100644
index af32d50fc68..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-in-misuse.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4619/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isArray, isNumber, isRequiredParserServices } from './helpers';
-import { isLiteral } from 'eslint-plugin-sonarjs/lib/utils/nodes';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- inMisuse: 'Use "indexOf" or "includes" (available from ES2016) instead.',
- suggestIndexOf: 'Replace with "indexOf" method',
- suggestIncludes: 'Replace with "includes" method',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- function prototypeProperty(node: estree.Expression) {
- const expr = node as TSESTree.Expression;
- if (!isLiteral(expr) || typeof expr.value !== 'string') {
- return false;
- }
-
- return ['indexOf', 'lastIndexOf', 'forEach', 'map', 'filter', 'every', 'some'].includes(
- expr.value,
- );
- }
-
- if (isRequiredParserServices(services)) {
- return {
- "BinaryExpression[operator='in']": (node: estree.Node) => {
- const { left, right } = node as estree.BinaryExpression;
- if (isArray(right, services) && !prototypeProperty(left) && !isNumber(left, services)) {
- const leftText = context.getSourceCode().getText(left);
- const rightText = context.getSourceCode().getText(right);
- context.report({
- messageId: 'inMisuse',
- node,
- suggest: [
- {
- messageId: 'suggestIndexOf',
- fix: fixer => fixer.replaceText(node, `${rightText}.indexOf(${leftText}) > -1`),
- },
- {
- messageId: 'suggestIncludes',
- fix: fixer => fixer.replaceText(node, `${rightText}.includes(${leftText})`),
- },
- ],
- });
- }
- },
- };
- }
- return {};
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-incomplete-assertions.ts b/eslint-bridge/src/linting/eslint/rules/no-incomplete-assertions.ts
deleted file mode 100644
index b195b0e9c1a..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-incomplete-assertions.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2970/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isNumberLiteral } from './helpers';
-
-const assertionFunctions = [
- 'a',
- 'an',
- 'include',
- 'includes',
- 'contain',
- 'contains',
- 'equal',
- 'equals',
- 'eq',
- 'eql',
- 'eqls',
- 'above',
- 'gt',
- 'greaterThan',
- 'least',
- 'gte',
- 'below',
- 'lt',
- 'lessThan',
- 'most',
- 'lte',
- 'within',
- 'instanceof',
- 'instanceOf',
- 'property',
- 'ownPropertyDescriptor',
- 'haveOwnPropertyDescriptor',
- 'lengthOf',
- 'length',
- 'match',
- 'matches',
- 'string',
- 'key',
- 'keys',
- 'throw',
- 'throws',
- 'Throw',
- 'respondTo',
- 'respondsTo',
- 'satisfy',
- 'satisfies',
- 'closeTo',
- 'approximately',
- 'members',
- 'oneOf',
- 'change',
- 'changes',
- 'increase',
- 'increases',
- 'decrease',
- 'decreases',
- 'by',
- 'fail',
-];
-
-const gettersOrModifiers = [
- 'to',
- 'be',
- 'been',
- 'is',
- 'that',
- 'which',
- 'and',
- 'has',
- 'have',
- 'with',
- 'at',
- 'of',
- 'same',
- 'but',
- 'does',
- 'still',
-
- // Modifier functions
- 'not',
- 'deep',
- 'nested',
- 'own',
- 'ordered',
- 'any',
- 'all',
- 'itself',
-
- 'should',
-];
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- ExpressionStatement(node: estree.Node) {
- const exprStatement = node as estree.ExpressionStatement;
- if (exprStatement.expression.type === 'MemberExpression') {
- const { property } = exprStatement.expression;
- if (isTestAssertion(exprStatement.expression)) {
- if (isIdentifier(property, ...assertionFunctions)) {
- context.report({
- node: property,
- message: `Call this '${property.name}' assertion.`,
- });
- }
- if (isIdentifier(property, ...gettersOrModifiers)) {
- context.report({
- node: property,
- message: `Complete this assertion; '${property.name}' doesn't assert anything by itself.`,
- });
- }
- }
- }
- if (isExpectCall(exprStatement.expression)) {
- const { callee } = exprStatement.expression;
- context.report({
- node: callee,
- message: `Complete this assertion; '${callee.name}' doesn't assert anything by itself.`,
- });
- }
- },
- };
- },
-};
-
-function isTestAssertion(node: estree.MemberExpression): boolean {
- const { object, property } = node;
- // Chai's BDD style where 'should' extends Object.prototype https://www.chaijs.com/guide/styles/
- if (isIdentifier(object) && isIdentifier(property, 'should')) {
- return true;
- }
- if (isExpectCall(object) || isIdentifier(object, 'assert', 'expect', 'should')) {
- return true;
- } else if (object.type === 'MemberExpression') {
- return isTestAssertion(object);
- } else if (object.type === 'CallExpression' && object.callee.type === 'MemberExpression') {
- return isTestAssertion(object.callee);
- }
- return false;
-}
-
-function isExpectCall(
- node: estree.Node,
-): node is estree.CallExpression & { callee: estree.Identifier } {
- return (
- node.type === 'CallExpression' &&
- isIdentifier(node.callee, 'expect') &&
- !isNumberLiteral(node.arguments[0])
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-inconsistent-returns.ts b/eslint-bridge/src/linting/eslint/rules/no-inconsistent-returns.ts
deleted file mode 100644
index 4e5670b2067..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-inconsistent-returns.ts
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3801/javascript
-
-import { AST, Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { getParent, RuleContext, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-interface FunctionContext {
- codePath: Rule.CodePath;
- containsReturnWithValue: boolean;
- containsReturnWithoutValue: boolean;
- containsImplicitReturn: boolean;
- returnStatements: estree.ReturnStatement[];
-}
-
-interface FunctionLikeDeclaration {
- type: string;
- id?: estree.Node | null;
- returnType?: TSESTree.TSTypeAnnotation;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- const functionContextStack: FunctionContext[] = [];
- const checkOnFunctionExit = (node: estree.Node) =>
- checkFunctionLikeDeclaration(
- node as FunctionLikeDeclaration,
- functionContextStack[functionContextStack.length - 1],
- );
-
- function checkFunctionLikeDeclaration(
- node: FunctionLikeDeclaration,
- functionContext?: FunctionContext,
- ) {
- if (
- !functionContext ||
- (!!node.returnType &&
- declaredReturnTypeContainsVoidOrNeverTypes(node.returnType.typeAnnotation))
- ) {
- return;
- }
-
- checkFunctionForImplicitReturn(functionContext);
-
- if (hasInconsistentReturns(functionContext)) {
- const [secondaryLocationsHolder, secondaryLocationMessages] = getSecondaryLocations(
- functionContext,
- node as estree.Node,
- );
- const message = toEncodedMessage(
- `Refactor this function to use "return" consistently.`,
- secondaryLocationsHolder,
- secondaryLocationMessages,
- );
-
- context.report({
- message,
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
- }
-
- function checkFunctionForImplicitReturn(functionContext: FunctionContext) {
- // As this method is called at the exit point of a function definition, the current
- // segments are the ones leading to the exit point at the end of the function. If they
- // are reachable, it means there is an implicit return.
- functionContext.containsImplicitReturn = functionContext.codePath.currentSegments.some(
- segment => segment.reachable,
- );
- }
-
- function getSecondaryLocations(
- functionContext: FunctionContext,
- node: estree.Node,
- ): [Array, Array] {
- const secondaryLocationsHolder = functionContext.returnStatements.slice() as TSESTree.Node[];
- const secondaryLocationMessages: string[] = functionContext.returnStatements.map(
- returnStatement =>
- returnStatement.argument ? 'Return with value' : 'Return without value',
- );
-
- if (functionContext.containsImplicitReturn) {
- const closeCurlyBraceToken = sourceCode.getLastToken(node, token => token.value === '}');
- if (!!closeCurlyBraceToken) {
- secondaryLocationsHolder.push(closeCurlyBraceToken as TSESTree.Node);
- secondaryLocationMessages.push('Implicit return without value');
- }
- }
-
- return [secondaryLocationsHolder, secondaryLocationMessages];
- }
-
- return {
- onCodePathStart(codePath: Rule.CodePath) {
- functionContextStack.push({
- codePath,
- containsReturnWithValue: false,
- containsReturnWithoutValue: false,
- containsImplicitReturn: false,
- returnStatements: [],
- });
- },
- onCodePathEnd() {
- functionContextStack.pop();
- },
-
- ReturnStatement(node: estree.Node) {
- const currentContext = functionContextStack[functionContextStack.length - 1];
- if (!!currentContext) {
- const returnStatement = node as estree.ReturnStatement;
- currentContext.containsReturnWithValue =
- currentContext.containsReturnWithValue || !!returnStatement.argument;
- currentContext.containsReturnWithoutValue =
- currentContext.containsReturnWithoutValue || !returnStatement.argument;
- currentContext.returnStatements.push(returnStatement);
- }
- },
- 'FunctionDeclaration:exit': checkOnFunctionExit,
- 'FunctionExpression:exit': checkOnFunctionExit,
- 'ArrowFunctionExpression:exit': checkOnFunctionExit,
- };
- },
-};
-
-function hasInconsistentReturns(functionContext: FunctionContext) {
- return (
- functionContext.containsReturnWithValue &&
- (functionContext.containsReturnWithoutValue || functionContext.containsImplicitReturn)
- );
-}
-
-function declaredReturnTypeContainsVoidOrNeverTypes(returnTypeNode: TSESTree.TypeNode): boolean {
- return (
- isVoidType(returnTypeNode) ||
- (returnTypeNode.type === 'TSUnionType' &&
- returnTypeNode.types.some(declaredReturnTypeContainsVoidOrNeverTypes))
- );
-}
-
-function isVoidType(typeNode: TSESTree.TypeNode) {
- return (
- typeNode.type === 'TSUndefinedKeyword' ||
- typeNode.type === 'TSVoidKeyword' ||
- typeNode.type === 'TSNeverKeyword'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-incorrect-string-concat.ts b/eslint-bridge/src/linting/eslint/rules/no-incorrect-string-concat.ts
deleted file mode 100644
index 5b42b36a611..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-incorrect-string-concat.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3402/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as tsTypes from 'typescript';
-import {
- RequiredParserServices,
- isRequiredParserServices,
- getTypeFromTreeNode,
- toEncodedMessage,
- isStringLiteral,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const message = `Review this expression to be sure that the concatenation was intended.`;
-const objectLikeTypes = new Set(['object', 'Object']);
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services: RequiredParserServices = context.parserServices;
-
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- const checker = services.program.getTypeChecker();
-
- function isStringPlusNonString(type1: tsTypes.Type, type2: tsTypes.Type) {
- if (isLiteralType(type1) || isLiteralType(type2)) {
- return false;
- }
- const isObjectLike = objectLikeTypes.has(checker.typeToString(type2));
- // @ts-ignore private API, see https://github.com/microsoft/TypeScript/issues/9879
- return isStringType(type1) && !isObjectLike && !checker.isTypeAssignableTo(type1, type2);
- }
-
- function getOperatorLocation(left: estree.Node, right: estree.Node) {
- return context
- .getSourceCode()
- .getTokensBetween(left, right)
- .find(token => token.value === '+')!.loc;
- }
-
- return {
- 'BinaryExpression[operator="+"]'(node: estree.Node) {
- const { left, right } = node as estree.BinaryExpression;
- if (
- isStringLiteral(left) ||
- isStringLiteral(right) ||
- isConcatenation(left) ||
- isConcatenation(right)
- ) {
- return;
- }
-
- const leftType = getTypeFromTreeNode(left, services);
- const rightType = getTypeFromTreeNode(right, services);
- if (
- isStringPlusNonString(leftType, rightType) ||
- isStringPlusNonString(rightType, leftType)
- ) {
- context.report({
- message: toEncodedMessage(
- message,
- [left, right],
- [
- `left operand has type ${checker.typeToString(leftType)}.`,
- `right operand has type ${checker.typeToString(rightType)}.`,
- ],
- ),
- loc: getOperatorLocation(left, right),
- });
- }
- },
- };
- },
-};
-
-function isStringType(typ: tsTypes.Type) {
- return (typ.getFlags() & tsTypes.TypeFlags.StringLike) !== 0;
-}
-
-function isLiteralType(type: tsTypes.Type): boolean {
- if (type.isUnion()) {
- return type.types.some(t => isLiteralType(t));
- }
- return type.isStringLiteral();
-}
-
-function isConcatenation(node: estree.Node) {
- return node.type === 'BinaryExpression' && node.operator === '+';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-infinite-loop.ts b/eslint-bridge/src/linting/eslint/rules/no-infinite-loop.ts
deleted file mode 100644
index e6f7bc3bed0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-infinite-loop.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2189/javascript
-
-import { Rule, Scope } from 'eslint';
-import { eslintRules } from 'linting/eslint/rules/core';
-import * as estree from 'estree';
-import { childrenOf } from 'linting/eslint';
-import { interceptReport, mergeRules } from './decorators/helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isUndefined } from './helpers';
-
-const noUnmodifiedLoopEslint = eslintRules['no-unmodified-loop-condition'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: { ...noUnmodifiedLoopEslint.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- /**
- * Decorates ESLint `no-unmodified-loop-condition` to raise one issue per symbol.
- */
- const alreadyRaisedSymbols: Set = new Set();
- const ruleDecoration: Rule.RuleModule = interceptReport(
- noUnmodifiedLoopEslint,
- function (context: Rule.RuleContext, descriptor: Rule.ReportDescriptor) {
- const node = (descriptor as any).node as estree.Node;
-
- const symbol = context.getScope().references.find(v => v.identifier === node)?.resolved;
- /** Ignoring symbols that have already been reported */
- if (isUndefined(node) || (symbol && alreadyRaisedSymbols.has(symbol))) {
- return;
- }
-
- /** Ignoring symbols called on or passed as arguments */
- for (const reference of symbol?.references || []) {
- const id = reference.identifier as TSESTree.Node;
-
- if (
- id.parent?.type === 'CallExpression' &&
- id.parent.arguments.includes(id as TSESTree.CallExpressionArgument)
- ) {
- return;
- }
-
- if (
- id.parent?.type === 'MemberExpression' &&
- id.parent.parent?.type === 'CallExpression' &&
- id.parent.object === id
- ) {
- return;
- }
- }
-
- if (symbol) {
- alreadyRaisedSymbols.add(symbol);
- }
-
- context.report(descriptor);
- },
- );
-
- /**
- * Extends ESLint `no-unmodified-loop-condition` to consider more corner cases.
- */
- const MESSAGE = "Correct this loop's end condition to not be invariant.";
- const ruleExtension: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- WhileStatement: checkWhileStatement,
- DoWhileStatement: checkWhileStatement,
- ForStatement: (node: estree.Node) => {
- const { test, body } = node as estree.ForStatement;
- if (!test || (test.type === 'Literal' && test.value === true)) {
- const hasEndCondition = LoopVisitor.hasEndCondition(body, context);
- if (!hasEndCondition) {
- const firstToken = context.getSourceCode().getFirstToken(node);
- context.report({
- loc: firstToken!.loc,
- message: MESSAGE,
- });
- }
- }
- },
- };
-
- function checkWhileStatement(node: estree.Node) {
- const whileStatement = node as estree.WhileStatement | estree.DoWhileStatement;
- if (whileStatement.test.type === 'Literal' && whileStatement.test.value === true) {
- const hasEndCondition = LoopVisitor.hasEndCondition(whileStatement.body, context);
- if (!hasEndCondition) {
- const firstToken = context.getSourceCode().getFirstToken(node);
- context.report({ loc: firstToken!.loc, message: MESSAGE });
- }
- }
- }
- },
- };
-
- const decorationListeners: Rule.RuleListener = ruleDecoration.create(context);
- const extensionListeners: Rule.RuleListener = ruleExtension.create(context);
-
- return mergeRules(decorationListeners, extensionListeners);
- },
-};
-
-class LoopVisitor {
- hasEndCondition = false;
-
- static hasEndCondition(node: estree.Node, context: Rule.RuleContext) {
- const visitor = new LoopVisitor();
- visitor.visit(node, context);
- return visitor.hasEndCondition;
- }
-
- private visit(root: estree.Node, context: Rule.RuleContext) {
- const visitNode = (node: estree.Node, isNestedLoop = false) => {
- switch (node.type) {
- case 'WhileStatement':
- case 'DoWhileStatement':
- case 'ForStatement':
- isNestedLoop = true;
- break;
- case 'FunctionExpression':
- case 'FunctionDeclaration':
- // Don't consider nested functions
- return;
- case 'BreakStatement':
- if (!isNestedLoop || !!node.label) {
- this.hasEndCondition = true;
- }
- break;
- case 'YieldExpression':
- case 'ReturnStatement':
- case 'ThrowStatement':
- this.hasEndCondition = true;
- return;
- }
- childrenOf(node, context.getSourceCode().visitorKeys).forEach(child =>
- visitNode(child, isNestedLoop),
- );
- };
- visitNode(root);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-intrusive-permissions.ts b/eslint-bridge/src/linting/eslint/rules/no-intrusive-permissions.ts
deleted file mode 100644
index 7fc9170297e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-intrusive-permissions.ts
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5604/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isMemberExpression, getValueOfExpression } from './helpers';
-
-const permissions = ['geolocation', 'camera', 'microphone', 'notifications', 'persistent-storage'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- checkPermission: 'Make sure the use of the {{feature}} is necessary.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'CallExpression[callee.type="MemberExpression"]'(node: estree.Node) {
- const call = node as estree.CallExpression;
- const callee = call.callee as estree.MemberExpression;
- if (
- isNavigatorMemberExpression(callee, 'permissions', 'query') &&
- call.arguments.length > 0
- ) {
- checkPermissions(context, call);
- return;
- }
- if (
- context.options.includes('geolocation') &&
- isNavigatorMemberExpression(callee, 'geolocation', 'watchPosition', 'getCurrentPosition')
- ) {
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: 'geolocation',
- },
- node: callee,
- });
- return;
- }
- if (
- isNavigatorMemberExpression(callee, 'mediaDevices', 'getUserMedia') &&
- call.arguments.length > 0
- ) {
- const firstArg = getValueOfExpression(context, call.arguments[0], 'ObjectExpression');
- checkForCameraAndMicrophonePermissions(context, callee, firstArg);
- return;
- }
- if (
- context.options.includes('notifications') &&
- isMemberExpression(callee, 'Notification', 'requestPermission')
- ) {
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: 'notifications',
- },
- node: callee,
- });
- return;
- }
- if (
- context.options.includes('persistent-storage') &&
- isMemberExpression(callee.object, 'navigator', 'storage')
- ) {
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: 'persistent-storage',
- },
- node: callee,
- });
- }
- },
- NewExpression(node: estree.Node) {
- const { callee } = node as estree.NewExpression;
- if (context.options.includes('notifications') && isIdentifier(callee, 'Notification')) {
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: 'notifications',
- },
- node: callee,
- });
- }
- },
- };
- },
-};
-
-function checkForCameraAndMicrophonePermissions(
- context: Rule.RuleContext,
- callee: estree.MemberExpression,
- firstArg: estree.ObjectExpression | undefined,
-) {
- if (!firstArg) {
- return;
- }
- const shouldCheckAudio = context.options.includes('microphone');
- const shouldCheckVideo = context.options.includes('camera');
- if (!shouldCheckAudio && !shouldCheckVideo) {
- return;
- }
- const perms = [];
- for (const prop of firstArg.properties) {
- if (prop.type === 'Property') {
- const { value, key } = prop;
- if (isIdentifier(key, 'audio') && shouldCheckAudio && isOtherThanFalse(context, value)) {
- perms.push('microphone');
- } else if (
- isIdentifier(key, 'video') &&
- shouldCheckVideo &&
- isOtherThanFalse(context, value)
- ) {
- perms.push('camera');
- }
- }
- }
- if (perms.length > 0) {
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: perms.join(' and '),
- },
- node: callee,
- });
- }
-}
-
-function isOtherThanFalse(context: Rule.RuleContext, value: estree.Node) {
- const exprValue = getValueOfExpression(context, value, 'Literal');
- if (exprValue && exprValue.value === false) {
- return false;
- }
- return true;
-}
-
-function checkPermissions(context: Rule.RuleContext, call: estree.CallExpression) {
- const firstArg = getValueOfExpression(context, call.arguments[0], 'ObjectExpression');
- if (firstArg?.type === 'ObjectExpression') {
- const nameProp = firstArg.properties.find(prop => hasNamePropertyWithPermission(prop, context));
- if (nameProp) {
- const { value } = (nameProp as estree.Property).value as estree.Literal;
- context.report({
- messageId: 'checkPermission',
- data: {
- feature: String(value),
- },
- node: nameProp,
- });
- }
- }
-}
-
-function isNavigatorMemberExpression(
- { object, property }: estree.MemberExpression,
- firstProperty: string,
- ...secondProperty: string[]
-) {
- return (
- isMemberExpression(object, 'navigator', firstProperty) &&
- isIdentifier(property, ...secondProperty)
- );
-}
-
-function hasNamePropertyWithPermission(
- prop: estree.Property | estree.SpreadElement,
- context: Rule.RuleContext,
-) {
- if (prop.type === 'Property' && isIdentifier(prop.key, 'name')) {
- const value = getValueOfExpression(context, prop.value, 'Literal');
- return (
- value &&
- typeof value.value === 'string' &&
- permissions.includes(value.value) &&
- context.options.includes(value.value)
- );
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-invalid-await.ts b/eslint-bridge/src/linting/eslint/rules/no-invalid-await.ts
deleted file mode 100644
index 5700c323e0e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-invalid-await.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4123/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { isRequiredParserServices, getTypeFromTreeNode } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- refactorAwait: "Refactor this redundant 'await' on a non-promise.",
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (isRequiredParserServices(services)) {
- return {
- AwaitExpression: (node: estree.Node) => {
- const awaitedType = getTypeFromTreeNode(
- (node as estree.AwaitExpression).argument,
- services,
- );
- if (!hasThenMethod(awaitedType) && !isAny(awaitedType) && !isUnion(awaitedType)) {
- context.report({
- messageId: 'refactorAwait',
- node,
- });
- }
- },
- };
- }
- return {};
- },
-};
-
-function hasThenMethod(type: ts.Type) {
- const thenProperty = type.getProperty('then');
- return thenProperty?.declarations?.some(
- d => d.kind === ts.SyntaxKind.MethodSignature || d.kind === ts.SyntaxKind.MethodDeclaration,
- );
-}
-
-function isAny(type: ts.Type) {
- return Boolean(type.flags & ts.TypeFlags.Any);
-}
-
-function isUnion(type: ts.Type) {
- return Boolean(type.flags & ts.TypeFlags.Union);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-invariant-returns.ts b/eslint-bridge/src/linting/eslint/rules/no-invariant-returns.ts
deleted file mode 100644
index d3cd13ae4b6..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-invariant-returns.ts
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3516/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import {
- findFirstMatchingAncestor,
- FUNCTION_NODES,
- getParent,
- isElementWrite,
- RuleContext,
- toEncodedMessage,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-interface FunctionContext {
- codePath: Rule.CodePath;
- containsReturnWithoutValue: boolean;
- returnStatements: estree.ReturnStatement[];
-}
-
-interface SingleWriteVariable {
- variable: Scope.Variable;
- initExpression?: estree.Expression | null;
-}
-
-type LiteralValue = number | RegExp | string | null | boolean | bigint;
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- const functionContextStack: FunctionContext[] = [];
-
- const checkOnFunctionExit = (node: estree.Node) =>
- checkInvariantReturnStatements(node, functionContextStack[functionContextStack.length - 1]);
-
- function checkInvariantReturnStatements(node: estree.Node, functionContext?: FunctionContext) {
- if (!functionContext || hasDifferentReturnTypes(functionContext)) {
- return;
- }
-
- const returnedValues = functionContext.returnStatements.map(
- returnStatement => returnStatement.argument as estree.Node,
- );
- if (areAllSameValue(returnedValues, context.getScope())) {
- const message = toEncodedMessage(
- `Refactor this function to not always return the same value.`,
- returnedValues as TSESTree.Node[],
- returnedValues.map(_ => 'Returned value.'),
- returnedValues.length,
- );
-
- context.report({
- message,
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- });
- }
- }
-
- return {
- onCodePathStart(codePath: Rule.CodePath) {
- functionContextStack.push({
- codePath,
- containsReturnWithoutValue: false,
- returnStatements: [],
- });
- },
- onCodePathEnd() {
- functionContextStack.pop();
- },
- ReturnStatement(node: estree.Node) {
- const currentContext = functionContextStack[functionContextStack.length - 1];
- if (currentContext) {
- const returnStatement = node as estree.ReturnStatement;
- currentContext.containsReturnWithoutValue =
- currentContext.containsReturnWithoutValue || !returnStatement.argument;
- currentContext.returnStatements.push(returnStatement);
- }
- },
- 'FunctionDeclaration:exit': checkOnFunctionExit,
- 'FunctionExpression:exit': checkOnFunctionExit,
- 'ArrowFunctionExpression:exit': checkOnFunctionExit,
- };
- },
-};
-
-function hasDifferentReturnTypes(functionContext: FunctionContext) {
- // As this method is called at the exit point of a function definition, the current
- // segments are the ones leading to the exit point at the end of the function. If they
- // are reachable, it means there is an implicit return.
- const hasImplicitReturn = functionContext.codePath.currentSegments.some(
- segment => segment.reachable,
- );
-
- return (
- hasImplicitReturn ||
- functionContext.containsReturnWithoutValue ||
- functionContext.returnStatements.length <= 1 ||
- functionContext.codePath.thrownSegments.length > 0
- );
-}
-
-function areAllSameValue(returnedValues: estree.Node[], scope: Scope.Scope) {
- const firstReturnedValue = returnedValues[0];
- const firstValue = getLiteralValue(firstReturnedValue, scope);
- if (firstValue !== undefined) {
- return returnedValues
- .slice(1)
- .every(returnedValue => getLiteralValue(returnedValue, scope) === firstValue);
- } else if (firstReturnedValue.type === 'Identifier') {
- const singleWriteVariable = getSingleWriteDefinition(firstReturnedValue.name, scope);
- if (singleWriteVariable) {
- const readReferenceIdentifiers = singleWriteVariable.variable.references
- .slice(1)
- .map(ref => ref.identifier);
- return returnedValues.every(returnedValue =>
- readReferenceIdentifiers.includes(returnedValue as estree.Identifier),
- );
- }
- }
- return false;
-}
-
-function getSingleWriteDefinition(
- variableName: string,
- scope: Scope.Scope,
-): SingleWriteVariable | null {
- const variable = scope.set.get(variableName);
- if (variable) {
- const references = variable.references.slice(1);
- if (!references.some(ref => ref.isWrite() || isPossibleObjectUpdate(ref))) {
- let initExpression = null;
- if (variable.defs.length === 1 && variable.defs[0].type === 'Variable') {
- initExpression = variable.defs[0].node.init;
- }
- return { variable, initExpression };
- }
- }
- return null;
-}
-
-function isPossibleObjectUpdate(ref: Scope.Reference) {
- const expressionStatement = findFirstMatchingAncestor(
- ref.identifier as TSESTree.Node,
- n => n.type === 'ExpressionStatement' || FUNCTION_NODES.includes(n.type),
- ) as estree.Node | undefined;
-
- // To avoid FP, we consider method calls as write operations, since we do not know whether they will
- // update the object state or not.
- return (
- expressionStatement &&
- expressionStatement.type === 'ExpressionStatement' &&
- (isElementWrite(expressionStatement, ref) ||
- expressionStatement.expression.type === 'CallExpression')
- );
-}
-
-function getLiteralValue(returnedValue: estree.Node, scope: Scope.Scope): LiteralValue | undefined {
- if (returnedValue.type === 'Literal') {
- return returnedValue.value;
- } else if (returnedValue.type === 'UnaryExpression') {
- const innerReturnedValue = getLiteralValue(returnedValue.argument, scope);
- return innerReturnedValue !== undefined
- ? evaluateUnaryLiteralExpression(returnedValue.operator, innerReturnedValue)
- : undefined;
- } else if (returnedValue.type === 'Identifier') {
- const singleWriteVariable = getSingleWriteDefinition(returnedValue.name, scope);
- if (singleWriteVariable && singleWriteVariable.initExpression) {
- return getLiteralValue(singleWriteVariable.initExpression, scope);
- }
- }
- return undefined;
-}
-
-function evaluateUnaryLiteralExpression(operator: string, innerReturnedValue: LiteralValue) {
- switch (operator) {
- case '-':
- return -Number(innerReturnedValue);
- case '+':
- return Number(innerReturnedValue);
- case '~':
- return ~Number(innerReturnedValue);
- case '!':
- return !Boolean(innerReturnedValue);
- case 'typeof':
- return typeof innerReturnedValue;
- default:
- return undefined;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-ip-forward.ts b/eslint-bridge/src/linting/eslint/rules/no-ip-forward.ts
deleted file mode 100644
index 7942d6aa069..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-ip-forward.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5759/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getObjectExpressionProperty,
- getValueOfExpression,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression(node: estree.Node) {
- const call = node as estree.CallExpression;
- const { callee, arguments: args } = call;
- if (isSensitiveFQN(context, call) && args.length > 0) {
- const xfwdProp = getObjectExpressionProperty(args[0], 'xfwd');
- if (!xfwdProp) {
- return;
- }
- const xfwdValue = getValueOfExpression(context, xfwdProp.value, 'Literal');
- if (xfwdValue?.value === true) {
- context.report({
- node: callee,
- message: toEncodedMessage('Make sure forwarding client IP address is safe here.', [
- xfwdProp,
- ]),
- });
- }
- }
- },
- };
- },
-};
-
-function isSensitiveFQN(context: Rule.RuleContext, call: estree.CallExpression) {
- const fqn = getFullyQualifiedName(context, call);
- return (
- fqn &&
- ['http-proxy.createProxyServer', 'http-proxy-middleware.createProxyMiddleware'].includes(fqn)
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-labels.ts b/eslint-bridge/src/linting/eslint/rules/no-labels.ts
deleted file mode 100644
index b573da938ae..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-labels.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1119/javascript
-
-import { Rule } from 'eslint';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeLabel: 'Refactor the code to remove this label and the need for it.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- LabeledStatement(node) {
- const sourceCode = context.getSourceCode();
- context.report({
- messageId: 'removeLabel',
- loc: sourceCode.getFirstToken(node)!.loc,
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-mime-sniff.ts b/eslint-bridge/src/linting/eslint/rules/no-mime-sniff.ts
deleted file mode 100644
index e2ba5ce254a..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-mime-sniff.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5734/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, getFullyQualifiedName, getPropertyWithValue } from './helpers';
-
-const HELMET = 'helmet';
-const NO_SNIFF = 'noSniff';
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findFalseNoSniffPropertyFromHelmet,
- `Make sure allowing browsers to sniff MIME types is safe here.`,
-);
-
-/**
- * Looks for property `noSniff: false` in node looking
- * somewhat similar to `helmet(?)`, and returns it.
- */
-function findFalseNoSniffPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- let sensitive: estree.Property | undefined;
- const { callee, arguments: args } = node;
- if (
- getFullyQualifiedName(context, callee) === HELMET &&
- args.length === 1 &&
- args[0].type === 'ObjectExpression'
- ) {
- sensitive = getPropertyWithValue(context, args[0], NO_SNIFF, false);
- }
- return sensitive ? [sensitive] : [];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-misleading-array-reverse.ts b/eslint-bridge/src/linting/eslint/rules/no-misleading-array-reverse.ts
deleted file mode 100644
index e52e95c209f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-misleading-array-reverse.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4043/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as ts from 'typescript';
-import {
- isArray,
- sortLike,
- isRequiredParserServices,
- RequiredParserServices,
- getSymbolAtLocation,
- localAncestorsChain,
-} from './helpers';
-
-const arrayMutatingMethods = ['reverse', "'reverse'", '"reverse"', ...sortLike];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- moveMethod: 'Move this array "{{method}}" operation to a separate statement.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- CallExpression(node: estree.Node) {
- const callee = (node as estree.CallExpression).callee;
- if (callee.type === 'MemberExpression') {
- const propertyText = context.getSourceCode().getText(callee.property);
- if (isArrayMutatingCall(callee, services, propertyText)) {
- const mutatedArray = callee.object;
-
- if (
- isIdentifierOrPropertyAccessExpression(mutatedArray, services) &&
- !isInSelfAssignment(mutatedArray, node) &&
- isForbiddenOperation(node)
- ) {
- context.report({
- messageId: 'moveMethod',
- data: {
- method: formatMethod(propertyText),
- },
- node,
- });
- }
- }
- }
- },
- };
- },
-};
-
-function formatMethod(mutatingMethod: string) {
- if (mutatingMethod.startsWith('"') || mutatingMethod.startsWith("'")) {
- return mutatingMethod.substr(1, mutatingMethod.length - 2);
- } else {
- return mutatingMethod;
- }
-}
-
-function isArrayMutatingCall(
- memberExpression: estree.MemberExpression,
- services: RequiredParserServices,
- propertyText: string,
-) {
- return arrayMutatingMethods.includes(propertyText) && isArray(memberExpression.object, services);
-}
-
-function isIdentifierOrPropertyAccessExpression(
- node: estree.Node,
- services: RequiredParserServices,
-): boolean {
- return (
- node.type === 'Identifier' ||
- (node.type === 'MemberExpression' && !isGetAccessor(node.property, services))
- );
-}
-
-function isGetAccessor(node: estree.Node, services: RequiredParserServices): boolean {
- const symbol = getSymbolAtLocation(node, services);
- const declarations = symbol && symbol.declarations;
- return (
- declarations !== undefined &&
- declarations.length === 1 &&
- declarations[0].kind === ts.SyntaxKind.GetAccessor
- );
-}
-
-function isInSelfAssignment(mutatedArray: estree.Node, node?: estree.Node): boolean {
- const parent = (node as TSESTree.Node).parent;
- return (
- // check assignment
- parent !== undefined &&
- parent.type === 'AssignmentExpression' &&
- parent.operator === '=' &&
- parent.left.type === 'Identifier' &&
- mutatedArray.type === 'Identifier' &&
- parent.left.name === mutatedArray.name
- );
-}
-
-function isForbiddenOperation(node: estree.Node) {
- return !isStandaloneExpression(node) && !isReturnedExpression(node);
-}
-
-function isStandaloneExpression(node: estree.Node) {
- const ancestors = localAncestorsChain(node as TSESTree.Node);
- const returnIdx = ancestors.findIndex(ancestor => ancestor.type === 'ExpressionStatement');
- return (
- returnIdx > -1 &&
- ancestors
- .slice(0, returnIdx)
- .every(ancestor => ['ChainExpression', 'LogicalExpression'].includes(ancestor.type))
- );
-}
-
-function isReturnedExpression(node: estree.Node) {
- const ancestors = localAncestorsChain(node as TSESTree.Node);
- const returnIdx = ancestors.findIndex(ancestor => ancestor.type === 'ReturnStatement');
- return (
- returnIdx > -1 &&
- ancestors
- .slice(0, returnIdx)
- .every(ancestor =>
- ['ArrayExpression', 'ObjectExpression', 'ConditionalExpression', 'SpreadElement'].includes(
- ancestor.type,
- ),
- )
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-mixed-content.ts b/eslint-bridge/src/linting/eslint/rules/no-mixed-content.ts
deleted file mode 100644
index 3ac8e1455fc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-mixed-content.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5730/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, getObjectExpressionProperty, getFullyQualifiedName } from './helpers';
-
-const HELMET = 'helmet';
-const HELMET_CSP = 'helmet-csp';
-const DIRECTIVES = 'directives';
-const CONTENT_SECURITY_POLICY = 'contentSecurityPolicy';
-const BLOCK_ALL_MIXED_CONTENT_CAMEL = 'blockAllMixedContent';
-const BLOCK_ALL_MIXED_CONTENT_HYPHEN = 'block-all-mixed-content';
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findDirectivesWithMissingMixedContentPropertyFromHelmet,
- `Make sure allowing mixed-content is safe here.`,
-);
-
-function findDirectivesWithMissingMixedContentPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- let sensitive: estree.Property | undefined;
- const { arguments: args } = node;
- if (args.length === 1) {
- const [options] = args;
- const maybeDirectives = getObjectExpressionProperty(options, DIRECTIVES);
- if (
- maybeDirectives &&
- isMissingMixedContentProperty(maybeDirectives) &&
- isValidHelmetModuleCall(context, node)
- ) {
- sensitive = maybeDirectives;
- }
- }
- return sensitive ? [sensitive] : [];
-}
-
-function isValidHelmetModuleCall(context: Rule.RuleContext, callExpr: estree.CallExpression) {
- const fqn = getFullyQualifiedName(context, callExpr);
- return fqn === `${HELMET}.${CONTENT_SECURITY_POLICY}` || fqn === HELMET_CSP;
-}
-
-function isMissingMixedContentProperty(directives: estree.Property): boolean {
- return !(
- Boolean(getObjectExpressionProperty(directives.value, BLOCK_ALL_MIXED_CONTENT_CAMEL)) ||
- Boolean(getObjectExpressionProperty(directives.value, BLOCK_ALL_MIXED_CONTENT_HYPHEN))
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-nested-assignment.ts b/eslint-bridge/src/linting/eslint/rules/no-nested-assignment.ts
deleted file mode 100644
index 5a0af695d0b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-nested-assignment.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1121/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getParent } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- extractAssignment: 'Extract the assignment of "{{symbol}}" from this expression.',
- },
- },
- create(context: Rule.RuleContext) {
- function isAssignmentStatement(parent: estree.Node) {
- return parent.type === 'ExpressionStatement';
- }
-
- function isEnclosingChain(parent: estree.Node) {
- return parent.type === 'AssignmentExpression';
- }
-
- function isEnclosingRelation(parent: estree.Node) {
- return (
- parent.type === 'BinaryExpression' &&
- ['==', '!=', '===', '!==', '<', '<=', '>', '>='].includes(parent.operator)
- );
- }
-
- function isEnclosingSequence(parent: estree.Node) {
- return parent.type === 'SequenceExpression';
- }
-
- function isEnclosingDeclarator(parent: estree.Node) {
- return parent.type === 'VariableDeclarator';
- }
-
- function isLambdaBody(parent: estree.Node, expr: estree.AssignmentExpression) {
- return parent.type === 'ArrowFunctionExpression' && parent.body === expr;
- }
-
- function isConditionalAssignment(parent: estree.Node, expr: estree.AssignmentExpression) {
- return parent.type === 'LogicalExpression' && parent.right === expr;
- }
-
- function isWhileCondition(parent: estree.Node, expr: estree.AssignmentExpression) {
- return (
- (parent.type === 'DoWhileStatement' || parent.type === 'WhileStatement') &&
- parent.test === expr
- );
- }
-
- function isForInitOrUpdate(parent: estree.Node, expr: estree.AssignmentExpression) {
- return parent.type === 'ForStatement' && (parent.init === expr || parent.update === expr);
- }
-
- return {
- AssignmentExpression: (node: estree.Node) => {
- const assignment = node as estree.AssignmentExpression;
- const parent = getParent(context);
- if (
- parent &&
- !isAssignmentStatement(parent) &&
- !isEnclosingChain(parent) &&
- !isEnclosingRelation(parent) &&
- !isEnclosingSequence(parent) &&
- !isEnclosingDeclarator(parent) &&
- !isLambdaBody(parent, assignment) &&
- !isConditionalAssignment(parent, assignment) &&
- !isWhileCondition(parent, assignment) &&
- !isForInitOrUpdate(parent, assignment)
- ) {
- raiseIssue(assignment, context);
- }
- },
- };
- },
-};
-
-function raiseIssue(node: estree.AssignmentExpression, context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- const operator = sourceCode.getFirstTokenBetween(
- node.left,
- node.right,
- token => token.value === node.operator,
- );
- const text = sourceCode.getText(node.left);
- context.report({
- messageId: 'extractAssignment',
- data: {
- symbol: text,
- },
- loc: operator!.loc,
- });
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-nested-conditional.ts b/eslint-bridge/src/linting/eslint/rules/no-nested-conditional.ts
deleted file mode 100644
index 2ca93df650b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-nested-conditional.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3358/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- extractTernary: 'Extract this nested ternary operation into an independent statement.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'ConditionalExpression ConditionalExpression': (node: estree.Node) => {
- if (!isNestingBroken(context.getAncestors())) {
- context.report({
- messageId: 'extractTernary',
- node,
- });
- }
- },
- };
- },
-};
-
-function isNestingBroken(ancestors: estree.Node[]) {
- let parent = ancestors.pop()!;
- while (parent.type !== 'ConditionalExpression') {
- if (breaksNesting(parent)) {
- return true;
- }
- parent = ancestors.pop()!;
- }
- return false;
-}
-
-function breaksNesting(node: estree.Node) {
- return [
- 'ArrayExpression',
- 'ObjectExpression',
- 'FunctionExpression',
- 'ArrowFunctionExpression',
- 'JSXExpressionContainer',
- ].includes(node.type);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-nested-incdec.ts b/eslint-bridge/src/linting/eslint/rules/no-nested-incdec.ts
deleted file mode 100644
index 0de9da06f50..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-nested-incdec.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S881/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- extractOperation: 'Extract this {{incrementType}} operation into a dedicated statement.',
- },
- },
- create(context: Rule.RuleContext) {
- function reportUpdateExpression(node: estree.UpdateExpression) {
- context.report({
- messageId: 'extractOperation',
- data: {
- incrementType: node.operator === '++' ? 'increment' : 'decrement',
- },
- node,
- });
- }
-
- return {
- UpdateExpression(node: estree.Node) {
- if (!isIgnored(node, context.getAncestors())) {
- reportUpdateExpression(node as estree.UpdateExpression);
- }
- },
- };
- },
-};
-
-function isIgnored(node: estree.Node, ancestors: estree.Node[]): boolean {
- const firstAncestor = ancestors.pop();
-
- if (firstAncestor) {
- switch (firstAncestor.type) {
- case 'ExpressionStatement':
- return true;
- case 'ForStatement':
- return firstAncestor.update === node;
- case 'SequenceExpression': {
- const secondAncestor = ancestors.pop();
- return (
- secondAncestor !== undefined &&
- secondAncestor.type === 'ForStatement' &&
- secondAncestor.update === firstAncestor
- );
- }
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-nested-template-literals.ts b/eslint-bridge/src/linting/eslint/rules/no-nested-template-literals.ts
deleted file mode 100644
index c4c7a5aac77..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-nested-template-literals.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4624/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-const message = 'Refactor this code to not use nested template literals.';
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- 'TemplateLiteral TemplateLiteral': function (node: estree.Node) {
- context.report({
- message,
- node,
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-new-symbol.ts b/eslint-bridge/src/linting/eslint/rules/no-new-symbol.ts
deleted file mode 100644
index e80ace42d8f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-new-symbol.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3834/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getVariableFromName, toEncodedMessage } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const SYMBOL = 'Symbol';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- function isSymbol(node: estree.Node) {
- return node.type === 'Identifier' && node.name === SYMBOL;
- }
- function isShadowed(_node: estree.Node) {
- const variable = getVariableFromName(context, SYMBOL);
- return variable && variable.defs.length > 0;
- }
- return {
- NewExpression: (node: estree.Node) => {
- const { callee } = node as estree.NewExpression;
- if (isSymbol(callee) && !isShadowed(callee)) {
- const newToken = context
- .getSourceCode()
- .getFirstToken(node, token => token.value === 'new')!;
- context.report({
- message: toEncodedMessage(`Remove this "new" operator.`, [callee as TSESTree.Node]),
- loc: newToken.loc,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-os-command-from-path.ts b/eslint-bridge/src/linting/eslint/rules/no-os-command-from-path.ts
deleted file mode 100644
index ced71235426..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-os-command-from-path.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4036/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isStringLiteral, getValueOfExpression, getFullyQualifiedName } from './helpers';
-
-const SENSITIVE_METHODS = ['exec', 'execSync', 'spawn', 'spawnSync', 'execFile', 'execFileSync'];
-const REQUIRED_PATH_PREFIXES = ['./', '.\\', '../', '..\\', '/', '\\', 'C:\\'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- issue: 'Make sure the "PATH" used to find this command includes only what you intend.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.CallExpression) => {
- const fqn = getFullyQualifiedName(context, node);
- if (SENSITIVE_METHODS.some(method => fqn === `child_process.${method}`)) {
- const sensitiveArg = findSensitiveArgument(
- context,
- node.arguments as estree.Expression[],
- );
- if (sensitiveArg !== null) {
- context.report({
- messageId: 'issue',
- node: sensitiveArg,
- });
- }
- }
- },
- };
- },
-};
-
-function findSensitiveArgument(context: Rule.RuleContext, functionArgs: estree.Expression[]) {
- if (functionArgs.length === 0) {
- return null;
- }
- const pathArg = functionArgs[0]; // we know this for the SENSITIVE_METHODS
- const literalInExpression: estree.Literal | undefined = getValueOfExpression(
- context,
- pathArg,
- 'Literal',
- );
- let stringLiteral: estree.Literal & { value: string };
- if (literalInExpression !== undefined && isStringLiteral(literalInExpression)) {
- stringLiteral = literalInExpression;
- } else {
- return null;
- }
- const startsWithRequiredPrefix = REQUIRED_PATH_PREFIXES.some(prefix =>
- stringLiteral.value.startsWith(prefix),
- );
- return startsWithRequiredPrefix ? null : pathArg;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-parameter-reassignment.ts b/eslint-bridge/src/linting/eslint/rules/no-parameter-reassignment.ts
deleted file mode 100644
index 10c5609898f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-parameter-reassignment.ts
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1226/javascript
-
-import { AST, Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getParent, resolveIdentifiers } from './helpers';
-
-type ContextType = 'catch' | 'function' | 'foreach' | 'global';
-
-interface ReassignmentContext {
- type: ContextType;
- variablesToCheckInCurrentScope: Set;
- variablesToCheck: Set;
- variablesRead: Set;
- referencesByIdentifier: Map;
- parentContext?: ReassignmentContext;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- noReassignment:
- 'Introduce a new variable or use its initial value before reassigning "{{reference}}".',
- },
- },
- create(context: Rule.RuleContext) {
- let variableUsageContext: ReassignmentContext = {
- type: 'global',
- variablesToCheckInCurrentScope: new Set(),
- variablesToCheck: new Set(),
- variablesRead: new Set(),
- referencesByIdentifier: new Map(),
- };
-
- function checkIdentifierUsage(
- identifier: estree.Identifier,
- identifierContextType: ContextType,
- ) {
- if (variableUsageContext.type !== identifierContextType) {
- return;
- }
-
- const variableName = identifier.name;
- const currentReference = getReference(variableUsageContext, identifier);
- if (
- currentReference &&
- !currentReference.init &&
- !variableUsageContext.variablesRead.has(variableName)
- ) {
- if (
- variableUsageContext.variablesToCheck.has(variableName) &&
- currentReference.isWriteOnly() &&
- !isUsedInWriteExpression(variableName, currentReference.writeExpr)
- ) {
- // we do not raise issue when value is reassigned inside a top-level IfStatement, as it might be a shift or
- // default value reassignment
- if (
- isInsideIfStatement(context) ||
- context.getAncestors().some(node => node.type === 'SwitchCase') // issue-2398
- ) {
- return;
- }
- raiseIssue(currentReference);
- }
- markAsRead(variableUsageContext, variableName);
- } else if (variableName === 'arguments') {
- markAllFunctionArgumentsAsRead(variableUsageContext);
- }
- }
-
- function isUsedInWriteExpression(variableName: string, writeExpr: estree.Node | null) {
- return (
- writeExpr &&
- context
- .getSourceCode()
- .getFirstToken(
- writeExpr,
- token => token.value === variableName || token.value === 'arguments',
- )
- );
- }
-
- function raiseIssue(reference: Scope.Reference) {
- const locationHolder = getPreciseLocationHolder(reference);
- context.report({
- messageId: 'noReassignment',
- data: {
- reference: reference.identifier.name,
- },
- ...locationHolder,
- });
- }
-
- function popContext() {
- variableUsageContext = variableUsageContext.parentContext
- ? variableUsageContext.parentContext
- : variableUsageContext;
- }
-
- return {
- onCodePathStart(_codePath: Rule.CodePath, node: estree.Node) {
- const currentScope = context.getScope();
- if (currentScope && currentScope.type === 'function') {
- const { referencesByIdentifier, variablesToCheck, variablesToCheckInCurrentScope } =
- computeNewContextInfo(variableUsageContext, context, node);
-
- const functionName = getFunctionName(node as estree.FunctionExpression);
- if (functionName) {
- variablesToCheck.delete(functionName);
- }
-
- variableUsageContext = {
- type: 'function',
- parentContext: variableUsageContext,
- variablesToCheck,
- referencesByIdentifier,
- variablesToCheckInCurrentScope,
- variablesRead: computeSetDifference(
- variableUsageContext.variablesRead,
- variablesToCheckInCurrentScope,
- ),
- };
- } else {
- variableUsageContext = {
- type: 'global',
- parentContext: variableUsageContext,
- variablesToCheckInCurrentScope: new Set(),
- variablesToCheck: new Set(),
- variablesRead: new Set(),
- referencesByIdentifier: new Map(),
- };
- }
- },
-
- onCodePathSegmentLoop(
- _fromSegment: Rule.CodePathSegment,
- _toSegment: Rule.CodePathSegment,
- node: estree.Node,
- ) {
- const parent = getParent(context);
- if (!isForEachLoopStart(node, parent)) {
- return;
- }
- const currentScope = context.getSourceCode().scopeManager.acquire(parent.body);
- const { referencesByIdentifier, variablesToCheck, variablesToCheckInCurrentScope } =
- computeNewContextInfo(variableUsageContext, context, parent.left);
-
- if (currentScope) {
- for (const ref of currentScope.references) {
- referencesByIdentifier.set(ref.identifier, ref);
- }
- }
-
- // In case of array or object pattern expression, the left hand side are not declared variables but simply identifiers
- resolveIdentifiers(parent.left as TSESTree.Node, true)
- .map(identifier => identifier.name)
- .forEach(name => {
- variablesToCheck.add(name);
- variablesToCheckInCurrentScope.add(name);
- });
-
- variableUsageContext = {
- type: 'foreach',
- parentContext: variableUsageContext,
- variablesToCheckInCurrentScope,
- variablesToCheck,
- variablesRead: computeSetDifference(
- variableUsageContext.variablesRead,
- variablesToCheckInCurrentScope,
- ),
- referencesByIdentifier,
- };
- },
-
- onCodePathSegmentStart(_segment: Rule.CodePathSegment, node: estree.Node) {
- if (node.type !== 'CatchClause') {
- return;
- }
-
- const { referencesByIdentifier, variablesToCheck, variablesToCheckInCurrentScope } =
- computeNewContextInfo(variableUsageContext, context, node);
-
- variableUsageContext = {
- type: 'catch',
- parentContext: variableUsageContext,
- variablesToCheckInCurrentScope,
- variablesToCheck,
- variablesRead: computeSetDifference(
- variableUsageContext.variablesRead,
- variablesToCheckInCurrentScope,
- ),
- referencesByIdentifier,
- };
- },
-
- onCodePathEnd: popContext,
- 'ForInStatement:exit': popContext,
- 'ForOfStatement:exit': popContext,
- 'CatchClause:exit': popContext,
- '*:function > BlockStatement Identifier': (node: estree.Node) =>
- checkIdentifierUsage(node as estree.Identifier, 'function'),
- 'ForInStatement > *:statement Identifier': (node: estree.Node) =>
- checkIdentifierUsage(node as estree.Identifier, 'foreach'),
- 'ForOfStatement > *:statement Identifier': (node: estree.Node) =>
- checkIdentifierUsage(node as estree.Identifier, 'foreach'),
- 'CatchClause > BlockStatement Identifier': (node: estree.Node) =>
- checkIdentifierUsage(node as estree.Identifier, 'catch'),
- };
- },
-};
-
-function isInsideIfStatement(context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- for (let i = ancestors.length - 1; i >= 0; i--) {
- if (
- ancestors[i].type === 'IfStatement' &&
- // We check if the consequent or the alternate are also ancestors
- // Nodes in the test attribute should be raised
- i < ancestors.length - 1 &&
- (ancestors[i + 1] === (ancestors[i] as estree.IfStatement).consequent ||
- ancestors[i + 1] === (ancestors[i] as estree.IfStatement).alternate)
- ) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * Computes the set difference (a \ b)
- */
-function computeSetDifference(a: Set, b: Set) {
- return new Set([...a].filter(str => !b.has(str)));
-}
-
-function getFunctionName(node: estree.FunctionExpression) {
- return !node.id ? null : node.id.name;
-}
-
-function isForEachLoopStart(
- node: estree.Node,
- parent?: estree.Node,
-): parent is estree.ForInStatement | estree.ForOfStatement {
- return (
- node.type === 'BlockStatement' &&
- !!parent &&
- (parent.type === 'ForInStatement' || parent.type === 'ForOfStatement')
- );
-}
-
-function computeNewContextInfo(
- variableUsageContext: ReassignmentContext,
- context: Rule.RuleContext,
- node: estree.Node,
-) {
- const referencesByIdentifier = new Map();
- const variablesToCheck = new Set(variableUsageContext.variablesToCheck);
- const variablesToCheckInCurrentScope = new Set();
- context.getDeclaredVariables(node).forEach(variable => {
- variablesToCheck.add(variable.name);
- variablesToCheckInCurrentScope.add(variable.name);
- for (const currentRef of variable.references) {
- referencesByIdentifier.set(currentRef.identifier, currentRef);
- }
- });
- return { referencesByIdentifier, variablesToCheck, variablesToCheckInCurrentScope };
-}
-
-function markAsRead(context: ReassignmentContext, variableName: string) {
- context.variablesRead.add(variableName);
- if (!context.variablesToCheckInCurrentScope.has(variableName) && context.parentContext) {
- markAsRead(context.parentContext, variableName);
- }
-}
-
-function markAllFunctionArgumentsAsRead(variableUsageContext: ReassignmentContext) {
- let functionContext: ReassignmentContext | undefined = variableUsageContext;
- while (functionContext && functionContext.type !== 'function') {
- functionContext = functionContext.parentContext;
- }
-
- if (functionContext) {
- for (const variableName of functionContext.variablesToCheckInCurrentScope) {
- functionContext.variablesRead.add(variableName);
- }
- }
-}
-
-function getPreciseLocationHolder(
- reference: Scope.Reference,
-): { node: estree.Node } | { loc: AST.SourceLocation } {
- const identifierLoc = reference.identifier.loc;
- if (identifierLoc && reference.writeExpr && reference.writeExpr.loc) {
- return { loc: { start: identifierLoc.start, end: reference.writeExpr.loc.end } };
- }
- return { node: reference.identifier };
-}
-
-function getReference(
- variableUsageContext: ReassignmentContext,
- identifier: estree.Identifier,
-): Scope.Reference | undefined {
- const identifierReference = variableUsageContext.referencesByIdentifier.get(identifier);
- if (!identifierReference && variableUsageContext.parentContext) {
- return getReference(variableUsageContext.parentContext, identifier);
- }
- return identifierReference;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-primitive-wrappers.ts b/eslint-bridge/src/linting/eslint/rules/no-primitive-wrappers.ts
deleted file mode 100644
index 9300b3841f1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-primitive-wrappers.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1533/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-const WRAPPER_TYPES = ['Boolean', 'Number', 'String'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- removeConstructor: 'Remove this use of "{{constructor}}" constructor.',
- replaceWrapper:
- 'Replace this "{{wrapper}}" wrapper object with primitive type "{{primitive}}".',
- suggestRemoveNew: 'Remove "new" operator',
- suggestReplaceWrapper: 'Replace "{{wrapper}}" with "{{primitive}}"',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression(node: estree.Node) {
- const constructor = (node as estree.NewExpression).callee;
- if (constructor.type === 'Identifier' && WRAPPER_TYPES.includes(constructor.name)) {
- const newToken = context
- .getSourceCode()
- .getFirstToken(node, token => token.value === 'new')!;
- const [begin, end] = newToken.range;
- context.report({
- messageId: 'removeConstructor',
- data: {
- constructor: constructor.name,
- },
- node,
- suggest: [
- {
- messageId: 'suggestRemoveNew',
- fix: fixer => fixer.removeRange([begin, end + 1]),
- },
- ],
- });
- }
- },
- TSTypeReference(node: estree.Node) {
- const typeString = context.getSourceCode().getText(node);
- if (WRAPPER_TYPES.includes(typeString)) {
- const primitiveType = typeString.toLowerCase();
- context.report({
- messageId: 'replaceWrapper',
- data: {
- wrapper: typeString,
- primitive: primitiveType,
- },
- node,
- suggest: [
- {
- messageId: 'suggestReplaceWrapper',
- data: {
- wrapper: typeString,
- primitive: primitiveType,
- },
- fix: fixer => fixer.replaceText(node, primitiveType),
- },
- ],
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-redundant-assignments.ts b/eslint-bridge/src/linting/eslint/rules/no-redundant-assignments.ts
deleted file mode 100644
index 6c80af7b3f7..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-redundant-assignments.ts
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4165/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isAssignmentExpression } from 'eslint-plugin-sonarjs/lib/utils/nodes';
-import CodePath = Rule.CodePath;
-import Variable = Scope.Variable;
-import Reference = Scope.Reference;
-import CodePathSegment = Rule.CodePathSegment;
-import {
- getVariableFromIdentifier,
- reachingDefinitions,
- ReachingDefinitions,
- resolveAssignedValues,
- Values,
-} from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- reviewAssignment:
- 'Review this redundant assignment: "{{symbol}}" already holds the assigned value along all execution paths.',
- },
- },
- create(context: Rule.RuleContext) {
- const codePathStack: CodePathContext[] = [];
- const reachingDefsMap = new Map();
- // map from Variable to CodePath ids where variable is used
- const variableUsages = new Map>();
-
- return {
- ':matches(AssignmentExpression, VariableDeclarator[init])': (node: estree.Node) => {
- pushAssignmentContext(node as AssignmentLike);
- },
- ':matches(AssignmentExpression, VariableDeclarator[init]):exit': () => {
- popAssignmentContext();
- },
- Identifier: (node: estree.Node) => {
- if (isEnumConstant()) {
- return;
- }
- checkIdentifierUsage(node as estree.Identifier);
- },
- 'Program:exit': () => {
- reachingDefinitions(reachingDefsMap);
- reachingDefsMap.forEach(defs => {
- checkSegment(defs);
- });
- reachingDefsMap.clear();
- variableUsages.clear();
- while (codePathStack.length > 0) {
- codePathStack.pop();
- }
- },
-
- // CodePath events
- onCodePathSegmentStart: (segment: CodePathSegment) => {
- reachingDefsMap.set(segment.id, new ReachingDefinitions(segment));
- },
- onCodePathStart: codePath => {
- pushContext(new CodePathContext(codePath));
- },
- onCodePathEnd: () => {
- popContext();
- },
- };
-
- function popAssignmentContext() {
- const assignment = peek(codePathStack).assignmentStack.pop()!;
- assignment.rhs.forEach(r => processReference(r));
- assignment.lhs.forEach(r => processReference(r));
- }
-
- function pushAssignmentContext(node: AssignmentLike) {
- peek(codePathStack).assignmentStack.push(new AssignmentContext(node));
- }
-
- function checkSegment(reachingDefs: ReachingDefinitions) {
- const assignedValuesMap = new Map(reachingDefs.in);
- reachingDefs.references.forEach(ref => {
- const variable = ref.resolved;
- if (!variable || !ref.isWrite() || !shouldReport(ref)) {
- return;
- }
- const lhsValues = assignedValuesMap.get(variable);
- const rhsValues = resolveAssignedValues(
- variable,
- ref.writeExpr,
- assignedValuesMap,
- ref.from,
- );
- if (lhsValues?.type === 'AssignedValues' && lhsValues?.size === 1) {
- const [lhsVal] = [...lhsValues];
- checkRedundantAssignement(ref, ref.writeExpr, lhsVal, rhsValues, variable.name);
- }
- assignedValuesMap.set(variable, rhsValues);
- });
- }
-
- function checkRedundantAssignement(
- { resolved: variable }: Scope.Reference,
- node: estree.Node | null,
- lhsVal: string | Variable,
- rhsValues: Values,
- name: string,
- ) {
- if (rhsValues.type === 'UnknownValue' || rhsValues.size !== 1) {
- return;
- }
- const [rhsVal] = [...rhsValues];
- if (!isWrittenOnlyOnce(variable!) && lhsVal === rhsVal) {
- context.report({
- node: node!,
- messageId: 'reviewAssignment',
- data: {
- symbol: name,
- },
- });
- }
- }
-
- // to avoid raising on code like:
- // while (cond) { let x = 42; }
- function isWrittenOnlyOnce(variable: Scope.Variable) {
- return variable.references.filter(ref => ref.isWrite()).length === 1;
- }
-
- function shouldReport(ref: Reference) {
- const variable = ref.resolved;
- return variable && shouldReportReference(ref) && !variableUsedOutsideOfCodePath(variable);
- }
-
- function shouldReportReference(ref: Reference) {
- const variable = ref.resolved;
-
- return (
- variable &&
- !isDefaultParameter(ref) &&
- !variable.name.startsWith('_') &&
- !isCompoundAssignment(ref.writeExpr) &&
- !isSelfAssignement(ref) &&
- !variable.defs.some(
- def => def.type === 'Parameter' || (def.type === 'Variable' && !def.node.init),
- )
- );
- }
-
- function isEnumConstant() {
- return (context.getAncestors() as TSESTree.Node[]).some(n => n.type === 'TSEnumDeclaration');
- }
-
- function variableUsedOutsideOfCodePath(variable: Scope.Variable) {
- return variableUsages.get(variable)!.size > 1;
- }
-
- function checkIdentifierUsage(node: estree.Identifier) {
- const { ref, variable } = resolveReference(node);
- if (ref) {
- processReference(ref);
- }
- if (variable) {
- updateVariableUsages(variable);
- }
- }
-
- function processReference(ref: Reference) {
- const assignmentStack = peek(codePathStack).assignmentStack;
- if (assignmentStack.length > 0) {
- const assignment = peek(assignmentStack);
- assignment.add(ref);
- } else {
- peek(codePathStack).codePath.currentSegments.forEach(segment => {
- const reachingDefs = reachingDefsForSegment(segment);
- reachingDefs.add(ref);
- });
- }
- }
-
- function reachingDefsForSegment(segment: CodePathSegment) {
- let defs;
- if (reachingDefsMap.has(segment.id)) {
- defs = reachingDefsMap.get(segment.id)!;
- } else {
- defs = new ReachingDefinitions(segment);
- reachingDefsMap.set(segment.id, defs);
- }
- return defs;
- }
-
- function updateVariableUsages(variable: Scope.Variable) {
- const codePathId = peek(codePathStack).codePath.id;
- if (variableUsages.has(variable)) {
- variableUsages.get(variable)!.add(codePathId);
- } else {
- variableUsages.set(variable, new Set([codePathId]));
- }
- }
-
- function pushContext(codePathContext: CodePathContext) {
- codePathStack.push(codePathContext);
- }
-
- function popContext() {
- codePathStack.pop();
- }
-
- function resolveReferenceRecursively(
- node: estree.Identifier,
- scope: Scope.Scope | null,
- ): { ref: Reference | null; variable: Scope.Variable | null } {
- if (scope === null) {
- return { ref: null, variable: null };
- }
- const ref = scope.references.find(r => r.identifier === node);
- if (ref) {
- return { ref, variable: ref.resolved };
- } else {
- // if it's not a reference, it can be just declaration without initializer
- const variable = scope.variables.find(v => v.defs.find(def => def.name === node));
- if (variable) {
- return { ref: null, variable };
- }
- // in theory we only need 1-level recursion, only for switch expression, which is likely a bug in eslint
- // generic recursion is used for safety & readability
- return resolveReferenceRecursively(node, scope.upper);
- }
- }
-
- function resolveReference(node: estree.Identifier) {
- return resolveReferenceRecursively(node, context.getScope());
- }
- },
-};
-
-class CodePathContext {
- reachingDefinitionsMap = new Map();
- reachingDefinitionsStack: ReachingDefinitions[] = [];
- codePath: CodePath;
- segments = new Map();
- assignmentStack: AssignmentContext[] = [];
-
- constructor(codePath: CodePath) {
- this.codePath = codePath;
- }
-}
-
-type AssignmentLike = TSESTree.AssignmentExpression | TSESTree.VariableDeclarator;
-
-class AssignmentContext {
- node: AssignmentLike;
-
- constructor(node: AssignmentLike) {
- this.node = node;
- }
-
- lhs = new Set();
- rhs = new Set();
-
- isRhs(node: TSESTree.Node) {
- return isAssignmentExpression(this.node) ? this.node.right === node : this.node.init === node;
- }
-
- isLhs(node: TSESTree.Node) {
- return isAssignmentExpression(this.node) ? this.node.left === node : this.node.id === node;
- }
-
- add(ref: Reference) {
- let parent = ref.identifier as TSESTree.Node | undefined;
- while (parent) {
- if (this.isLhs(parent)) {
- this.lhs.add(ref);
- break;
- }
- if (this.isRhs(parent)) {
- this.rhs.add(ref);
- break;
- }
- parent = parent.parent;
- }
- if (parent === null) {
- throw new Error('failed to find assignment lhs/rhs');
- }
- }
-}
-
-function peek(arr: Array) {
- return arr[arr.length - 1];
-}
-
-function isSelfAssignement(ref: Reference) {
- const lhs = ref.resolved;
- if (ref.writeExpr?.type === 'Identifier') {
- const rhs = getVariableFromIdentifier(ref.writeExpr, ref.from);
- return lhs === rhs;
- }
- return false;
-}
-
-function isCompoundAssignment(writeExpr: estree.Node | null) {
- if (writeExpr && writeExpr.hasOwnProperty('parent')) {
- const node = (writeExpr as TSESTree.Node).parent;
- return node && node.type === 'AssignmentExpression' && node.operator !== '=';
- }
- return false;
-}
-
-function isDefaultParameter(ref: Reference) {
- if (ref.identifier.type !== 'Identifier') {
- return false;
- }
- const parent = (ref.identifier as TSESTree.Identifier).parent;
- return parent && parent.type === 'AssignmentPattern';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-redundant-optional.ts b/eslint-bridge/src/linting/eslint/rules/no-redundant-optional.ts
deleted file mode 100644
index 79fbc62e0a2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-redundant-optional.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4782/javascript
-
-import { Rule, AST } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- if (!isRequiredParserServices(context.parserServices)) {
- return {};
- }
-
- function checkProperty(node: estree.Node) {
- const tsNode = node as TSESTree.Node as
- | TSESTree.PropertyDefinition
- | TSESTree.TSPropertySignature;
- const optionalToken = context
- .getSourceCode()
- .getFirstToken(node, token => token.value === '?');
- if (!tsNode.optional || !optionalToken) {
- return;
- }
-
- const typeNode = getUndefinedTypeAnnotation(tsNode.typeAnnotation);
- if (typeNode) {
- const suggest = getQuickFixSuggestions(context, optionalToken, typeNode);
- const secondaryLocations = [typeNode];
- const message = toEncodedMessage(
- "Consider removing 'undefined' type or '?' specifier, one of them is redundant.",
- secondaryLocations,
- );
- context.report({
- message,
- loc: optionalToken.loc,
- suggest,
- });
- }
- }
-
- return {
- 'PropertyDefinition, TSPropertySignature': (node: estree.Node) => checkProperty(node),
- };
- },
-};
-
-function getUndefinedTypeAnnotation(tsTypeAnnotation?: TSESTree.TSTypeAnnotation) {
- if (tsTypeAnnotation) {
- return getUndefinedTypeNode(tsTypeAnnotation.typeAnnotation);
- }
- return undefined;
-}
-
-function getUndefinedTypeNode(typeNode: TSESTree.TypeNode): TSESTree.TypeNode | undefined {
- if (typeNode.type === 'TSUndefinedKeyword') {
- return typeNode;
- } else if (typeNode.type === 'TSUnionType') {
- return typeNode.types.map(getUndefinedTypeNode).find(tpe => tpe !== undefined);
- }
- return undefined;
-}
-
-function getQuickFixSuggestions(
- context: Rule.RuleContext,
- optionalToken: AST.Token,
- undefinedType: TSESTree.TypeNode,
-): Rule.SuggestionReportDescriptor[] {
- const suggestions: Rule.SuggestionReportDescriptor[] = [
- {
- desc: 'Remove "?" operator',
- fix: fixer => fixer.remove(optionalToken),
- },
- ];
- if (undefinedType.parent?.type === 'TSUnionType') {
- suggestions.push(getUndefinedRemovalSuggestion(context, undefinedType));
- }
- return suggestions;
-}
-
-function getUndefinedRemovalSuggestion(
- context: Rule.RuleContext,
- undefinedType: TSESTree.TypeNode,
-): Rule.SuggestionReportDescriptor {
- return {
- desc: 'Remove "undefined" type annotation',
- fix: fixer => {
- const fixes: Rule.Fix[] = [];
- const unionType = undefinedType.parent as TSESTree.TSUnionType;
- if (unionType.types.length === 2) {
- const unionTypeNode = unionType as any as estree.Node;
- const otherType =
- unionType.types[0] === undefinedType ? unionType.types[1] : unionType.types[0];
- const otherTypeText = context.getSourceCode().getText(otherType as any as estree.Node);
- fixes.push(fixer.replaceText(unionTypeNode, otherTypeText));
-
- const tokenBefore = context.getSourceCode().getTokenBefore(unionTypeNode);
- const tokenAfter = context.getSourceCode().getTokenAfter(unionTypeNode);
- if (tokenBefore?.value === '(' && tokenAfter?.value === ')') {
- fixes.push(fixer.remove(tokenBefore));
- fixes.push(fixer.remove(tokenAfter));
- }
- } else {
- const index = unionType.types.indexOf(undefinedType);
- if (index === 0) {
- fixes.push(fixer.removeRange([undefinedType.range[0], unionType.types[1].range[0]]));
- } else {
- fixes.push(
- fixer.removeRange([unionType.types[index - 1].range[1], undefinedType.range[1]]),
- );
- }
- }
- return fixes;
- },
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-redundant-parentheses.ts b/eslint-bridge/src/linting/eslint/rules/no-redundant-parentheses.ts
deleted file mode 100644
index d762866c0ab..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-redundant-parentheses.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1110/javascript
-
-import { AST, Rule, SourceCode } from 'eslint';
-import * as estree from 'estree';
-import { getParent, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-interface ParenthesesPair {
- openingParenthesis: AST.Token;
- closingParenthesis: AST.Token;
-}
-
-/**
- * Parts of the grammar that are required to have parentheses.
- */
-const parenthesized: { [key: string]: string } = {
- DoWhileStatement: 'test',
- IfStatement: 'test',
- SwitchStatement: 'discriminant',
- WhileStatement: 'test',
- WithStatement: 'object',
- ArrowFunctionExpression: 'body',
- ImportExpression: 'source',
-};
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- hasSuggestions: true,
- },
- create(context: Rule.RuleContext) {
- return {
- '*': function (node: estree.Node) {
- checkRedundantParentheses(context.getSourceCode(), node, context);
- },
- };
- },
-};
-
-function checkRedundantParentheses(
- sourceCode: SourceCode,
- node: estree.Node,
- context: Rule.RuleContext,
-) {
- const parenthesesPairsAroundNode = getParenthesesPairsAround(sourceCode, node, node);
- const parent = getParent(context);
-
- // Ignore parentheses pair from the parent node
- if (!!parent && isInParentNodeParentheses(node, parent)) {
- parenthesesPairsAroundNode.pop();
- }
- // One pair of parentheses is allowed for readability purposes
- parenthesesPairsAroundNode.shift();
-
- parenthesesPairsAroundNode.forEach(parentheses => {
- context.report({
- message: toEncodedMessage(`Remove these redundant parentheses.`, [
- parentheses.closingParenthesis,
- ]),
- loc: parentheses.openingParenthesis.loc,
- suggest: [
- {
- desc: 'Remove these redundant parentheses',
- fix(fixer) {
- return [
- fixer.remove(parentheses.openingParenthesis),
- fixer.remove(parentheses.closingParenthesis),
- ];
- },
- },
- ],
- });
- });
-}
-
-function getParenthesesPairsAround(
- sourceCode: SourceCode,
- start: estree.Node | AST.Token,
- end: estree.Node | AST.Token,
-): ParenthesesPair[] {
- const tokenBefore = sourceCode.getTokenBefore(start);
- const tokenAfter = sourceCode.getTokenAfter(end);
-
- if (!!tokenBefore && !!tokenAfter && tokenBefore.value === '(' && tokenAfter.value === ')') {
- return [
- { openingParenthesis: tokenBefore, closingParenthesis: tokenAfter },
- ...getParenthesesPairsAround(sourceCode, tokenBefore, tokenAfter),
- ];
- }
-
- return [];
-}
-
-function isInParentNodeParentheses(node: estree.Node, parent: estree.Node): boolean {
- // Applying same logic as https://github.com/eslint/eslint/blob/main/lib/rules/no-sequences.js#L81
- // both rules (S1110 and S878) can contradict each other, so better use the same logic
- const parentAttribute = parenthesized[parent.type as keyof typeof parenthesized];
- const nodeIsInConditionOfParent =
- parentAttribute &&
- node === (parent[parentAttribute as keyof estree.Node] as unknown as estree.Node);
-
- const nodeIsArgumentOfCallExpression =
- (parent.type === 'CallExpression' || parent.type === 'NewExpression') &&
- parent.arguments.includes(node as estree.Expression);
-
- return nodeIsInConditionOfParent || nodeIsArgumentOfCallExpression;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-reference-error.ts b/eslint-bridge/src/linting/eslint/rules/no-reference-error.ts
deleted file mode 100644
index 52e65285c04..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-reference-error.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3827/javascript
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { findFirstMatchingAncestor, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const excludedNames = new Set();
- const undeclaredIdentifiersByName: Map = new Map();
- return {
- 'Program:exit'() {
- excludedNames.clear();
- undeclaredIdentifiersByName.clear();
- const globalScope = context.getScope();
- globalScope.through.forEach(ref => {
- const identifier = ref.identifier;
- if (excludedNames.has(identifier.name)) {
- return;
- }
- if (
- ref.writeExpr ||
- hasTypeOfOperator(identifier as TSESTree.Node) ||
- isWithinWithStatement(identifier as TSESTree.Node)
- ) {
- excludedNames.add(identifier.name);
- return;
- }
- const undeclaredIndentifiers = undeclaredIdentifiersByName.get(identifier.name);
- if (!!undeclaredIndentifiers) {
- undeclaredIndentifiers.push(identifier);
- } else {
- undeclaredIdentifiersByName.set(identifier.name, [identifier]);
- }
- });
- undeclaredIdentifiersByName.forEach((identifiers, name) => {
- context.report({
- node: identifiers[0],
- message: toEncodedMessage(
- `\"${name}\" does not exist. Change its name or declare it so that its usage doesn't result in a \"ReferenceError\".`,
- identifiers.slice(1),
- ),
- });
- });
- },
- };
- },
-};
-
-function isWithinWithStatement(node: TSESTree.Node) {
- return !!findFirstMatchingAncestor(node, ancestor => ancestor.type === 'WithStatement');
-}
-
-function hasTypeOfOperator(node: TSESTree.Node) {
- const parent = node.parent;
- return parent?.type === 'UnaryExpression' && parent.operator === 'typeof';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-referrer-policy.ts b/eslint-bridge/src/linting/eslint/rules/no-referrer-policy.ts
deleted file mode 100644
index 6845d589870..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-referrer-policy.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5736/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- Express,
- getPropertyWithValue,
- getObjectExpressionProperty,
- getFullyQualifiedName,
-} from './helpers';
-
-const HELMET = 'helmet';
-const POLICY = 'policy';
-const REFERRER_POLICY = 'referrerPolicy';
-const UNSAFE_REFERRER_POLICY_VALUES = ['', 'unsafe-url', 'no-referrer-when-downgrade'];
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findNoReferrerPolicyPropertyFromHelmet,
- `Make sure disabling strict HTTP no-referrer policy is safe here.`,
-);
-
-function findNoReferrerPolicyPropertyFromHelmet(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- let sensitive: estree.Property | undefined;
-
- const { callee, arguments: args } = node;
- if (args.length === 1) {
- const [options] = args;
-
- /* helmet({ referrerPolicy: false }) or helmet.referrerPolicy({ policy: }) */
- const fqn = getFullyQualifiedName(context, callee);
- if (fqn === HELMET && options.type === 'ObjectExpression') {
- sensitive = getPropertyWithValue(context, options, REFERRER_POLICY, false);
- } else if (fqn === `${HELMET}.${REFERRER_POLICY}`) {
- const maybePolicy = getObjectExpressionProperty(options, POLICY);
- if (maybePolicy && !isSafePolicy(maybePolicy)) {
- sensitive = maybePolicy;
- }
- }
- }
-
- return sensitive ? [sensitive] : [];
-}
-
-function isSafePolicy(policy: estree.Property): boolean {
- const { value } = policy;
- const values: Array =
- value.type === 'ArrayExpression' ? value.elements : [value];
- const sensitiveValue = values.find(
- v =>
- v?.type === 'Literal' &&
- typeof v.value === 'string' &&
- UNSAFE_REFERRER_POLICY_VALUES.includes(v.value),
- );
- return !Boolean(sensitiveValue);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-require-or-define.ts b/eslint-bridge/src/linting/eslint/rules/no-require-or-define.ts
deleted file mode 100644
index 2167327f4b0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-require-or-define.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3533/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isRequiredParserServices, RequiredParserServices, isFunction, isString } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- standardImport: 'Use a standard "import" statement instead of "{{adhocImport}}".',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- 'CallExpression[callee.type="Identifier"]': (node: estree.Node) => {
- if (context.getScope().type !== 'module' && context.getScope().type !== 'global') {
- return;
- }
- const callExpression = node as estree.CallExpression;
- const identifier = callExpression.callee as estree.Identifier;
- if (
- isAmdImport(callExpression, identifier, services) ||
- isCommonJsImport(callExpression, identifier, services)
- ) {
- context.report({
- node: identifier,
- messageId: 'standardImport',
- data: {
- adhocImport: identifier.name,
- },
- });
- }
- },
- };
- },
-};
-
-function isCommonJsImport(
- callExpression: estree.CallExpression,
- identifier: estree.Identifier,
- services: RequiredParserServices,
-): boolean {
- return (
- callExpression.arguments.length === 1 &&
- isString(callExpression.arguments[0], services) &&
- identifier.name === 'require'
- );
-}
-
-function isAmdImport(
- callExpression: estree.CallExpression,
- identifier: estree.Identifier,
- services: RequiredParserServices,
-): boolean {
- if (identifier.name !== 'require' && identifier.name !== 'define') {
- return false;
- }
- if (callExpression.arguments.length !== 2 && callExpression.arguments.length !== 3) {
- return false;
- }
- return isFunction(callExpression.arguments[callExpression.arguments.length - 1], services);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-return-type-any.ts b/eslint-bridge/src/linting/eslint/rules/no-return-type-any.ts
deleted file mode 100644
index 62ab817eb6b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-return-type-any.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4324/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices, RequiredParserServices } from './helpers';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-
-type ReturnedExpression = estree.Expression | undefined | null;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeOrChangeType: 'Remove this return type or change it to a more specific.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- if (isRequiredParserServices(services)) {
- const returnedExpressions: ReturnedExpression[][] = [];
- return {
- ReturnStatement(node: estree.Node) {
- if (returnedExpressions.length > 0) {
- returnedExpressions[returnedExpressions.length - 1].push(
- (node as estree.ReturnStatement).argument,
- );
- }
- },
- FunctionDeclaration: function () {
- returnedExpressions.push([]);
- },
- 'FunctionDeclaration:exit': function (node: estree.Node) {
- const returnType = (node as TSESTree.FunctionDeclaration).returnType;
- if (
- returnType &&
- returnType.typeAnnotation.type === 'TSAnyKeyword' &&
- returnedExpressions.length > 0 &&
- allReturnTypesEqual(returnedExpressions[returnedExpressions.length - 1], services)
- ) {
- context.report({
- messageId: 'removeOrChangeType',
- loc: returnType.loc,
- });
- }
- returnedExpressions.pop();
- },
- };
- }
- return {};
- },
-};
-
-function allReturnTypesEqual(
- returns: ReturnedExpression[],
- services: RequiredParserServices,
-): boolean {
- const firstReturnType = getTypeFromTreeNode(returns.pop(), services);
- if (!!firstReturnType && !!isPrimitiveType(firstReturnType)) {
- return returns.every(nextReturn => {
- const nextReturnType = getTypeFromTreeNode(nextReturn, services);
- return !!nextReturnType && nextReturnType.flags === firstReturnType.flags;
- });
- }
- return false;
-}
-
-function getTypeFromTreeNode(node: ReturnedExpression, services: RequiredParserServices) {
- const checker = services.program.getTypeChecker();
- return checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node));
-}
-
-function isPrimitiveType({ flags }: ts.Type) {
- return (
- flags & ts.TypeFlags.BooleanLike ||
- flags & ts.TypeFlags.NumberLike ||
- flags & ts.TypeFlags.StringLike ||
- flags & ts.TypeFlags.EnumLike
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-same-argument-assert.ts b/eslint-bridge/src/linting/eslint/rules/no-same-argument-assert.ts
deleted file mode 100644
index 5cc0655bef9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-same-argument-assert.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5863/javascript
-
-import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import { areEquivalent } from 'eslint-plugin-sonarjs/lib/utils/equivalence';
-import * as estree from 'estree';
-import { Chai, isIdentifier, isLiteral, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- if (!Chai.isImported(context)) {
- return {};
- }
- return {
- ExpressionStatement(node: estree.Node) {
- const { expression } = node as estree.ExpressionStatement;
- checkExpect(context, expression);
- checkShould(context, expression);
- checkAssert(context, expression);
- },
- };
- },
-};
-
-function checkAssert(context: Rule.RuleContext, expression: estree.Expression) {
- if (expression.type === 'CallExpression') {
- const { callee, arguments: args } = expression;
- if (callee.type === 'MemberExpression' && isIdentifier(callee.object, 'assert')) {
- findDuplicates(context, args);
- }
- }
-}
-
-function checkExpect(context: Rule.RuleContext, expression: estree.Expression) {
- let currentExpression: estree.Node = expression;
- let args: estree.Node[] = [];
-
- while (true) {
- if (currentExpression.type === 'CallExpression') {
- args = [...currentExpression.arguments, ...args];
- currentExpression = currentExpression.callee;
- } else if (currentExpression.type === 'MemberExpression') {
- currentExpression = currentExpression.object;
- } else if (isIdentifier(currentExpression, 'expect')) {
- break;
- } else {
- return;
- }
- }
-
- findDuplicates(context, args);
-}
-
-function checkShould(context: Rule.RuleContext, expression: estree.Expression) {
- let currentExpression: estree.Node = expression;
- let args: estree.Node[] = [];
- let hasShould = false;
-
- while (true) {
- if (currentExpression.type === 'CallExpression') {
- args = [...currentExpression.arguments, ...args];
- currentExpression = currentExpression.callee;
- } else if (currentExpression.type === 'MemberExpression') {
- if (isIdentifier(currentExpression.property, 'should')) {
- hasShould = true;
- }
- currentExpression = currentExpression.object;
- } else if (isIdentifier(currentExpression, 'should')) {
- break;
- } else if (hasShould) {
- args = [currentExpression, ...args];
- break;
- } else {
- return;
- }
- }
-
- findDuplicates(context, args);
-}
-
-function findDuplicates(context: Rule.RuleContext, args: estree.Node[]) {
- const castedContext = context.getSourceCode() as unknown as TSESLint.SourceCode;
- for (let i = 0; i < args.length; i++) {
- for (let j = i + 1; j < args.length; j++) {
- const duplicates = areEquivalent(
- args[i] as TSESTree.Node,
- args[j] as TSESTree.Node,
- castedContext,
- );
- if (duplicates && !isLiteral(args[i])) {
- const message = toEncodedMessage(`Replace this argument or its duplicate.`, [args[j]]);
- context.report({ message, node: args[i] });
- }
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-tab.ts b/eslint-bridge/src/linting/eslint/rules/no-tab.ts
deleted file mode 100644
index ef6486d26be..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-tab.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S105/javascript
-
-import { Rule } from 'eslint';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- replaceTab: 'Replace all tab characters in this file by sequences of white-spaces.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'Program:exit': function () {
- const firstTab = context
- .getSourceCode()
- .lines.map((content, line) => ({ content, line }))
- .find(t => t.content.includes('\t'));
-
- if (firstTab !== undefined) {
- context.report({
- messageId: 'replaceTab',
- loc: { line: firstTab.line + 1, column: 0 },
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-try-promise.ts b/eslint-bridge/src/linting/eslint/rules/no-try-promise.ts
deleted file mode 100644
index fd5dcc3353b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-try-promise.ts
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4822/javascript
-
-import { Rule, SourceCode } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices, isThenable, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-type CallLikeExpression =
- | TSESTree.CallExpression
- | TSESTree.NewExpression
- | TSESTree.AwaitExpression;
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (isRequiredParserServices(services)) {
- return {
- TryStatement: (node: estree.Node) =>
- visitTryStatement(node as TSESTree.TryStatement, context, services),
- };
- }
- return {};
- },
-};
-
-function visitTryStatement(
- tryStmt: TSESTree.TryStatement,
- context: Rule.RuleContext,
- services: any,
-) {
- if (tryStmt.handler) {
- // without '.catch()'
- const openPromises: TSESTree.Node[] = [];
- // with '.catch()'
- const capturedPromises: TSESTree.Node[] = [];
-
- let hasPotentiallyThrowingCalls = false;
- CallLikeExpressionVisitor.getCallExpressions(tryStmt.block, context).forEach(callLikeExpr => {
- if (
- callLikeExpr.type === 'AwaitExpression' ||
- !isThenable(callLikeExpr as estree.Node, services)
- ) {
- hasPotentiallyThrowingCalls = true;
- return;
- }
-
- if (isAwaitLike(callLikeExpr) || isThened(callLikeExpr) || isCatch(callLikeExpr)) {
- return;
- }
-
- (isCaught(callLikeExpr) ? capturedPromises : openPromises).push(callLikeExpr);
- });
-
- if (!hasPotentiallyThrowingCalls) {
- checkForWrongCatch(tryStmt, openPromises, context);
- checkForUselessCatch(tryStmt, openPromises, capturedPromises, context);
- }
- }
-}
-
-class CallLikeExpressionVisitor {
- private readonly callLikeExpressions: CallLikeExpression[] = [];
-
- static getCallExpressions(node: TSESTree.Node, context: Rule.RuleContext) {
- const visitor = new CallLikeExpressionVisitor();
- visitor.visit(node, context);
- return visitor.callLikeExpressions;
- }
-
- private visit(root: TSESTree.Node, context: Rule.RuleContext) {
- const visitNode = (node: TSESTree.Node) => {
- switch (node.type) {
- case 'AwaitExpression':
- case 'CallExpression':
- case 'NewExpression':
- this.callLikeExpressions.push(node);
- break;
- case 'FunctionDeclaration':
- case 'FunctionExpression':
- case 'ArrowFunctionExpression':
- return;
- }
- childrenOf(node, context.getSourceCode().visitorKeys).forEach(visitNode);
- };
- visitNode(root);
- }
-}
-
-function checkForWrongCatch(
- tryStmt: TSESTree.TryStatement,
- openPromises: TSESTree.Node[],
- context: Rule.RuleContext,
-) {
- if (openPromises.length > 0) {
- const ending = openPromises.length > 1 ? 's' : '';
- const message = `Consider using 'await' for the promise${ending} inside this 'try' or replace it with 'Promise.prototype.catch(...)' usage${ending}.`;
- const token = context.getSourceCode().getFirstToken(tryStmt as estree.Node);
- context.report({
- message: toEncodedMessage(message, openPromises, Array(openPromises.length).fill('Promise')),
- loc: token!.loc,
- });
- }
-}
-
-function checkForUselessCatch(
- tryStmt: TSESTree.TryStatement,
- openPromises: TSESTree.Node[],
- capturedPromises: TSESTree.Node[],
- context: Rule.RuleContext,
-) {
- if (openPromises.length === 0 && capturedPromises.length > 0) {
- const ending = capturedPromises.length > 1 ? 's' : '';
- const message = `Consider removing this 'try' statement as promise${ending} rejection is already captured by '.catch()' method.`;
- const token = context.getSourceCode().getFirstToken(tryStmt as estree.Node);
- context.report({
- message: toEncodedMessage(
- message,
- capturedPromises,
- Array(capturedPromises.length).fill('Caught promise'),
- ),
- loc: token!.loc,
- });
- }
-}
-
-function isAwaitLike(callExpr: CallLikeExpression) {
- return (
- callExpr.parent &&
- (callExpr.parent.type === 'AwaitExpression' || callExpr.parent.type === 'YieldExpression')
- );
-}
-
-function isThened(callExpr: CallLikeExpression) {
- return (
- callExpr.parent &&
- callExpr.parent.type === 'MemberExpression' &&
- callExpr.parent.property.type === 'Identifier' &&
- callExpr.parent.property.name === 'then'
- );
-}
-
-function isCaught(callExpr: CallLikeExpression) {
- return (
- callExpr.parent &&
- callExpr.parent.type === 'MemberExpression' &&
- callExpr.parent.property.type === 'Identifier' &&
- callExpr.parent.property.name === 'catch'
- );
-}
-
-function isCatch(callExpr: CallLikeExpression) {
- return (
- callExpr.type === 'CallExpression' &&
- callExpr.callee.type === 'MemberExpression' &&
- callExpr.callee.property.type === 'Identifier' &&
- callExpr.callee.property.name === 'catch'
- );
-}
-
-function childrenOf(node: TSESTree.Node, visitorKeys: SourceCode.VisitorKeys) {
- const keys = visitorKeys[node.type];
- const children = [];
- if (keys) {
- for (const key of keys) {
- const child = (node as any)[key];
- if (Array.isArray(child)) {
- children.push(...child);
- } else {
- children.push(child);
- }
- }
- }
- return children.filter(Boolean);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-undefined-argument.ts b/eslint-bridge/src/linting/eslint/rules/no-undefined-argument.ts
deleted file mode 100644
index 9c69c3aa312..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-undefined-argument.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4623/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices, isUndefined, RequiredParserServices } from './helpers';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- removeUndefined: 'Remove this redundant "undefined".',
- suggestRemoveUndefined: 'Remove this redundant argument',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (isRequiredParserServices(services)) {
- return {
- CallExpression: (node: estree.Node) => {
- const call = node as estree.CallExpression;
- const { arguments: args } = call;
- if (args.length === 0) {
- return;
- }
-
- const lastArgument = args[args.length - 1];
- if (isUndefined(lastArgument) && isOptionalParameter(args.length - 1, call, services)) {
- context.report({
- messageId: 'removeUndefined',
- node: lastArgument,
- suggest: [
- {
- messageId: 'suggestRemoveUndefined',
- fix: fixer => {
- if (call.arguments.length === 1) {
- const openingParen = context.getSourceCode().getTokenAfter(call.callee)!;
- const closingParen = context.getSourceCode().getLastToken(node)!;
- const [, begin] = openingParen.range;
- const [end] = closingParen.range;
- return fixer.removeRange([begin, end]);
- } else {
- const [, begin] = args[args.length - 2].range!;
- const [, end] = lastArgument.range!;
- return fixer.removeRange([begin, end]);
- }
- },
- },
- ],
- });
- }
- },
- };
- }
- return {};
- },
-};
-
-function isOptionalParameter(
- paramIndex: number,
- node: estree.CallExpression,
- services: RequiredParserServices,
-) {
- const signature = services.program
- .getTypeChecker()
- .getResolvedSignature(
- services.esTreeNodeToTSNodeMap.get(node as TSESTree.Node) as ts.CallLikeExpression,
- );
- if (signature) {
- const declaration = signature.declaration;
- if (declaration && isFunctionLikeDeclaration(declaration)) {
- const { parameters } = declaration;
- const parameter = parameters[paramIndex];
- return parameter && (parameter.initializer || parameter.questionToken);
- }
- }
- return false;
-}
-
-function isFunctionLikeDeclaration(
- declaration: ts.Declaration,
-): declaration is ts.FunctionLikeDeclarationBase {
- return [
- ts.SyntaxKind.FunctionDeclaration,
- ts.SyntaxKind.FunctionExpression,
- ts.SyntaxKind.ArrowFunction,
- ts.SyntaxKind.MethodDeclaration,
- ts.SyntaxKind.Constructor,
- ts.SyntaxKind.GetAccessor,
- ts.SyntaxKind.SetAccessor,
- ].includes(declaration.kind);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-undefined-assignment.ts b/eslint-bridge/src/linting/eslint/rules/no-undefined-assignment.ts
deleted file mode 100644
index e83f1b069d9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-undefined-assignment.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2138/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isUndefined } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- useNull: 'Use null instead.',
- },
- },
- create(context: Rule.RuleContext) {
- function raiseOnUndefined(node: estree.Node) {
- if (isUndefined(node)) {
- context.report({
- messageId: 'useNull',
- node,
- });
- }
- }
- return {
- VariableDeclarator: (node: estree.Node) => {
- const { init } = node as estree.VariableDeclarator;
- if (init) {
- raiseOnUndefined(init);
- }
- },
- AssignmentExpression: (node: estree.Node) => {
- const { right } = node as estree.AssignmentExpression;
- raiseOnUndefined(right);
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-unenclosed-multiline-block.ts b/eslint-bridge/src/linting/eslint/rules/no-unenclosed-multiline-block.ts
deleted file mode 100644
index 51862696b0d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-unenclosed-multiline-block.ts
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2681/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-const NestingStatementLike = [
- 'IfStatement',
- 'ForStatement',
- 'ForInStatement',
- 'ForOfStatement',
- 'WhileStatement',
-];
-
-type Statement = estree.Statement | estree.ModuleDeclaration;
-
-type NestingStatement =
- | estree.IfStatement
- | estree.ForStatement
- | estree.ForInStatement
- | estree.ForOfStatement
- | estree.WhileStatement;
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- return {
- Program: (node: estree.Node) => checkStatements((node as estree.Program).body, context),
- BlockStatement: (node: estree.Node) =>
- checkStatements((node as estree.BlockStatement).body, context),
- TSModuleBlock: (node: estree.Node) =>
- checkStatements((node as unknown as TSESTree.TSModuleBlock).body as Statement[], context),
- };
- },
-};
-
-function checkStatements(statements: Statement[], context: Rule.RuleContext) {
- chain(statements)
- .filter(chainedStatements => chainedStatements.areUnenclosed())
- .forEach(unenclosedConsecutives => {
- if (unenclosedConsecutives.areAdjacent()) {
- raiseAdjacenceIssue(unenclosedConsecutives, context);
- } else if (unenclosedConsecutives.areBothIndented()) {
- raiseBlockIssue(
- unenclosedConsecutives,
- countStatementsInTheSamePile(unenclosedConsecutives.prev, statements),
- context,
- );
- } else if (unenclosedConsecutives.areInlinedAndIndented()) {
- raiseInlineAndIndentedIssue(unenclosedConsecutives, context);
- }
- });
-}
-
-function chain(statements: Statement[]): ChainedStatements[] {
- return statements
- .reduce((result, statement, i, array) => {
- if (i < array.length - 1 && isNestingStatement(statement)) {
- result.push({ prev: statement, next: array[i + 1] });
- }
- return result;
- }, new Array<{ prev: NestingStatement; next: Statement }>())
- .map(pair => {
- return new ChainedStatements(pair.prev, extractLastBody(pair.prev), pair.next);
- });
-}
-
-function extractLastBody(statement: NestingStatement) {
- if (statement.type === 'IfStatement') {
- if (statement.alternate) {
- return statement.alternate;
- } else {
- return statement.consequent;
- }
- } else {
- return statement.body;
- }
-}
-
-function countStatementsInTheSamePile(reference: Statement, statements: Statement[]) {
- const startOfPile = position(reference).start;
- let lastLineOfPile = startOfPile.line;
- for (const statement of statements) {
- const currentPosition = position(statement);
- const currentLine = currentPosition.end.line;
- const currentIndentation = currentPosition.start.column;
- if (currentLine > startOfPile.line) {
- if (currentIndentation === startOfPile.column) {
- lastLineOfPile = currentPosition.end.line;
- } else {
- break;
- }
- }
- }
- return lastLineOfPile - startOfPile.line + 1;
-}
-
-function raiseAdjacenceIssue(adjacentStatements: ChainedStatements, context: Rule.RuleContext) {
- context.report({
- message:
- `This statement will not be executed ${adjacentStatements.includedStatementQualifier()}; only the first statement will be. ` +
- `The rest will execute ${adjacentStatements.excludedStatementsQualifier()}.`,
- node: adjacentStatements.next,
- });
-}
-
-function raiseBlockIssue(
- piledStatements: ChainedStatements,
- sizeOfPile: number,
- context: Rule.RuleContext,
-) {
- context.report({
- message:
- `This line will not be executed ${piledStatements.includedStatementQualifier()}; only the first line of this ${sizeOfPile}-line block will be. ` +
- `The rest will execute ${piledStatements.excludedStatementsQualifier()}.`,
- node: piledStatements.next,
- });
-}
-
-function raiseInlineAndIndentedIssue(
- chainedStatements: ChainedStatements,
- context: Rule.RuleContext,
-) {
- context.report({
- message:
- `This line will not be executed ${chainedStatements.includedStatementQualifier()}; only the first statement will be. ` +
- `The rest will execute ${chainedStatements.excludedStatementsQualifier()}.`,
- node: chainedStatements.next,
- });
-}
-
-function isNestingStatement(node: estree.Node): node is NestingStatement {
- return NestingStatementLike.includes(node.type);
-}
-
-class ChainedStatements {
- private readonly positions: Positions;
-
- constructor(
- readonly topStatement: NestingStatement,
- readonly prev: Statement,
- readonly next: Statement,
- ) {
- const topPosition = position(topStatement);
- const prevPosition = position(prev);
- const nextPosition = position(next);
- this.positions = {
- prevTopStart: topPosition.start,
- prevTopEnd: topPosition.end,
- prevStart: prevPosition.start,
- prevEnd: prevPosition.end,
- nextStart: nextPosition.start,
- nextEnd: nextPosition.end,
- };
- }
-
- public areUnenclosed(): boolean {
- return this.prev.type !== 'BlockStatement';
- }
-
- public areAdjacent(): boolean {
- return this.positions.prevEnd.line === this.positions.nextStart.line;
- }
-
- public areBothIndented(): boolean {
- return (
- this.positions.prevStart.column === this.positions.nextStart.column && this.prevIsIndented()
- );
- }
-
- public areInlinedAndIndented(): boolean {
- return (
- this.positions.prevStart.line === this.positions.prevTopEnd.line &&
- this.positions.nextStart.column > this.positions.prevTopStart.column
- );
- }
-
- public includedStatementQualifier(): string {
- return this.topStatement.type === 'IfStatement' ? 'conditionally' : 'in a loop';
- }
-
- public excludedStatementsQualifier(): string {
- return this.topStatement.type === 'IfStatement' ? 'unconditionally' : 'only once';
- }
-
- private prevIsIndented(): boolean {
- return this.positions.prevStart.column > this.positions.prevTopStart.column;
- }
-}
-
-type Positions = {
- prevTopStart: estree.Position;
- prevTopEnd: estree.Position;
- prevStart: estree.Position;
- prevEnd: estree.Position;
- nextStart: estree.Position;
- nextEnd: estree.Position;
-};
-
-function position(node: estree.Node) {
- return (node as TSESTree.Node).loc;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-uniq-key.ts b/eslint-bridge/src/linting/eslint/rules/no-uniq-key.ts
deleted file mode 100644
index c988de196e6..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-uniq-key.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6486/javascript
-
-// inspired from `no-array-index` from `eslint-plugin-react`:
-// https://github.com/jsx-eslint/eslint-plugin-react/blob/0a2f6b7e9df32215fcd4e3061ec69ea3f2eef793/lib/rules/no-array-index-key.js#L16
-
-import { Rule } from 'eslint';
-import { isMemberExpression } from './helpers';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- noGeneratedKeys: 'Do not use generated values for keys of React list components.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- "JSXAttribute[name.name='key']": (pNode: estree.Node) => {
- // hack: it's not possible to type the argument node from TSESTree
- const node = pNode as unknown as TSESTree.JSXAttribute;
-
- const value = node.value;
- if (!value || value.type !== 'JSXExpressionContainer') {
- // key='foo' or just simply 'key'
- return;
- }
-
- checkPropValue(context, value.expression);
- },
- };
- },
-};
-
-function checkPropValue(context: Rule.RuleContext, node: TSESTree.Node) {
- if (isGeneratedExpression(node)) {
- // key={bar}
- context.report({
- messageId: 'noGeneratedKeys',
- node: node as estree.Node,
- });
- return;
- }
-
- if (node.type === 'TemplateLiteral') {
- // key={`foo-${bar}`}
- node.expressions.filter(isGeneratedExpression).forEach(() => {
- context.report({
- messageId: 'noGeneratedKeys',
- node: node as estree.Node,
- });
- });
-
- return;
- }
-
- if (node.type === 'BinaryExpression') {
- // key={'foo' + bar}
- const callExpressions = getCallExpressionsFromBinaryExpression(
- node,
- ) as TSESTree.CallExpression[];
-
- callExpressions.filter(isGeneratedExpression).forEach(() => {
- context.report({
- messageId: 'noGeneratedKeys',
- node: node as estree.Node,
- });
- });
-
- return;
- }
-
- if (
- node.type === 'CallExpression' &&
- node.callee &&
- node.callee.type === 'MemberExpression' &&
- node.callee.object &&
- isGeneratedExpression(node.callee.object) &&
- node.callee.property &&
- node.callee.property.type === 'Identifier' &&
- node.callee.property.name === 'toString'
- ) {
- // key={bar.toString()}
- context.report({
- messageId: 'noGeneratedKeys',
- node: node as estree.Node,
- });
- return;
- }
-
- if (
- node.type === 'CallExpression' &&
- node.callee &&
- node.callee.type === 'Identifier' &&
- node.callee.name === 'String' &&
- Array.isArray(node.arguments) &&
- node.arguments.length > 0 &&
- isGeneratedExpression(node.arguments[0])
- ) {
- // key={String(bar)}
- context.report({
- messageId: 'noGeneratedKeys',
- node: node.arguments[0] as estree.Node,
- });
- }
-}
-
-function isGeneratedExpression(node: TSESTree.Node) {
- return isMathRandom(node) || isDateNow(node);
-
- function isMathRandom(node: TSESTree.Node) {
- return (
- node.type === 'CallExpression' &&
- isMemberExpression(node.callee as estree.Node, 'Math', 'random')
- );
- }
-
- function isDateNow(node: TSESTree.Node) {
- return (
- node.type === 'CallExpression' &&
- isMemberExpression(node.callee as estree.Node, 'Date', 'now')
- );
- }
-}
-
-function getCallExpressionsFromBinaryExpression(side: TSESTree.Node) {
- if (side.type === 'CallExpression') {
- return side;
- }
-
- if (side.type === 'BinaryExpression') {
- // recurse
- const left: any = getCallExpressionsFromBinaryExpression(side.left);
- const right: any = getCallExpressionsFromBinaryExpression(side.right);
- return [].concat(left, right).filter(Boolean);
- }
-
- return null;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-unsafe-unzip.ts b/eslint-bridge/src/linting/eslint/rules/no-unsafe-unzip.ts
deleted file mode 100644
index 2cdaa66b997..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-unsafe-unzip.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5042/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isLiteral, getValueOfExpression, getFullyQualifiedName } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeExpanding: 'Make sure that expanding this archive file is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- function canBeProperty(prop: estree.Property | estree.SpreadElement, name: string) {
- return (
- prop.type === 'SpreadElement' ||
- isIdentifier(prop.key, name) ||
- (isLiteral(prop.key) && prop.key.value === name)
- );
- }
-
- function isSensiteTarCall(call: estree.CallExpression, fqn: string | null) {
- if (fqn === 'tar.x') {
- const firstArg = call.arguments.length > 0 ? call.arguments[0] : null;
- if (!firstArg) {
- return false;
- }
- const firstArgValue = getValueOfExpression(context, firstArg, 'ObjectExpression');
- return (
- !!firstArgValue && !firstArgValue.properties.some(prop => canBeProperty(prop, 'filter'))
- );
- }
- return false;
- }
-
- function isSensiteExtractZipCall(call: estree.CallExpression, fqn: string | null) {
- if (fqn === 'extract-zip') {
- const secondArg = call.arguments.length > 1 ? call.arguments[1] : null;
- if (!secondArg) {
- return false;
- }
- const secondArgValue = getValueOfExpression(context, secondArg, 'ObjectExpression');
- return (
- !!secondArgValue &&
- !secondArgValue.properties.some(prop => canBeProperty(prop, 'onEntry'))
- );
- }
- return false;
- }
-
- return {
- CallExpression(node: estree.Node) {
- const call = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, call);
- if (
- isSensiteTarCall(call, fqn) ||
- isSensiteExtractZipCall(call, fqn) ||
- fqn === 'jszip.loadAsync' ||
- fqn === 'yauzl.open' ||
- fqn === 'adm-zip.extractAllTo'
- ) {
- context.report({
- messageId: 'safeExpanding',
- node: call.callee,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-unthrown-error.ts b/eslint-bridge/src/linting/eslint/rules/no-unthrown-error.ts
deleted file mode 100644
index a58ffff7bd2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-unthrown-error.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3984/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getParent } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- throwOrRemoveError: 'Throw this error or remove this useless statement.',
- suggestThrowError: 'Throw this error',
- },
- },
- create(context: Rule.RuleContext) {
- function looksLikeAnError(expression: estree.Expression | estree.Super): boolean {
- const text = context.getSourceCode().getText(expression);
- return text.endsWith('Error') || text.endsWith('Exception');
- }
-
- return {
- 'ExpressionStatement > NewExpression': function (node: estree.Node) {
- const expression = (node as estree.NewExpression).callee;
- if (looksLikeAnError(expression)) {
- context.report({
- messageId: 'throwOrRemoveError',
- node,
- suggest: [
- {
- messageId: 'suggestThrowError',
- fix: fixer => fixer.insertTextBefore(getParent(context)!, 'throw '),
- },
- ],
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-unused-function-argument.ts b/eslint-bridge/src/linting/eslint/rules/no-unused-function-argument.ts
deleted file mode 100644
index de07af8df88..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-unused-function-argument.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1172/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-type FunctionLike =
- | TSESTree.ArrowFunctionExpression
- | TSESTree.FunctionDeclaration
- | TSESTree.FunctionExpression;
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- removeOrRenameParameter:
- 'Remove the unused function parameter "{{param}}" or rename it to "_{{param}}" to make intention explicit.',
- suggestRemoveParameter: 'Remove "{{param}}" (beware of call sites)',
- suggestRenameParameter: 'Rename "{{param}}" to "_{{param}}"',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'FunctionDeclaration, FunctionExpression': function (node: estree.Node) {
- reportUnusedArgument(
- node,
- (node as estree.FunctionDeclaration | estree.FunctionExpression).id,
- context,
- );
- },
- ArrowFunctionExpression: (node: estree.Node) => {
- reportUnusedArgument(node, undefined, context);
- },
- };
- },
-};
-
-function reportUnusedArgument(
- node: estree.Node,
- functionId: estree.Identifier | undefined | null,
- context: Rule.RuleContext,
-) {
- const parent = (node as TSESTree.Node).parent;
- if (parent && parent.type === 'Property' && parent.kind === 'set') {
- return;
- }
-
- if (
- context
- .getScope()
- .variables.some(
- v => v.name === 'arguments' && v.identifiers.length === 0 && v.references.length > 0,
- )
- ) {
- return;
- }
-
- let parametersVariable = context.getDeclaredVariables(node);
-
- if (functionId) {
- parametersVariable = parametersVariable.filter(v => v.name !== functionId.name);
- }
-
- for (const param of parametersVariable) {
- if (
- isUnusedVariable(param) &&
- !isIgnoredParameter(param) &&
- !isParameterProperty(param) &&
- !isThisParameter(param)
- ) {
- context.report({
- messageId: 'removeOrRenameParameter',
- node: param.identifiers[0],
- data: {
- param: param.name,
- },
- suggest: getSuggestions(param, context),
- });
- }
- }
-}
-
-function getSuggestions(paramVariable: Scope.Variable, context: Rule.RuleContext) {
- const paramIdentifier = paramVariable.identifiers[0];
- const suggestions: Rule.SuggestionReportDescriptor[] = [
- {
- messageId: 'suggestRenameParameter',
- data: {
- param: paramVariable.name,
- },
- fix: fixer => fixer.insertTextBefore(paramIdentifier, '_'),
- },
- ];
- const func = paramVariable.defs[0].node as FunctionLike;
- if ((paramIdentifier as TSESTree.Node).parent === func) {
- suggestions.push(getParameterRemovalSuggestion(func, paramVariable, paramIdentifier, context));
- }
- return suggestions;
-}
-
-function getParameterRemovalSuggestion(
- func: FunctionLike,
- paramVariable: Scope.Variable,
- paramIdentifier: estree.Identifier,
- context: Rule.RuleContext,
-): Rule.SuggestionReportDescriptor {
- return {
- messageId: 'suggestRemoveParameter',
- data: {
- param: paramVariable.name,
- },
- fix: fixer => {
- const paramIndex = func.params.indexOf(paramIdentifier as TSESTree.Parameter);
- const param = func.params[paramIndex] as estree.Node;
- if (func.params.length === 1) {
- const openingParenthesis = context.getSourceCode().getTokenBefore(param);
- const closingParenthesis = context
- .getSourceCode()
- .getTokenAfter(param, token => token.value === ')');
- let [start, end] = param.range!;
- if (openingParenthesis && openingParenthesis.value === '(') {
- start = openingParenthesis.range[0];
- end = closingParenthesis!.range[1];
- }
- return fixer.replaceTextRange([start, end], '()');
- } else if (func.params.length - 1 === paramIndex) {
- const commaAfter = context
- .getSourceCode()
- .getTokenAfter(param, token => token.value === ',');
- const commaBefore = context
- .getSourceCode()
- .getTokenBefore(param, token => token.value === ',')!;
- let start = commaBefore.range[1];
- let end = param.range![1];
- if (commaAfter) {
- end = commaAfter.range[1];
- } else {
- start = commaBefore.range[0];
- }
- return fixer.removeRange([start, end]);
- } else {
- const [start] = func.params[paramIndex].range;
- const [end] = func.params[paramIndex + 1].range;
- return fixer.removeRange([start, end]);
- }
- },
- };
-}
-
-function isUnusedVariable(variable: Scope.Variable) {
- const refs = variable.references;
- //Parameter with default value has one reference, but should still be considered as unused.
- return refs.length === 0 || (refs.length === 1 && refs[0].init);
-}
-
-function isIgnoredParameter(variable: Scope.Variable) {
- return variable.name.startsWith('_');
-}
-
-export function isParameterProperty(variable: Scope.Variable) {
- return variable.defs.some(def => {
- const parent = (def.name as TSESTree.Node).parent;
-
- return (
- parent?.type === 'TSParameterProperty' ||
- (parent?.type === 'AssignmentPattern' && parent.parent?.type === 'TSParameterProperty')
- );
- });
-}
-
-function isThisParameter(variable: Scope.Variable) {
- return variable.name === 'this';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-useless-increment.ts b/eslint-bridge/src/linting/eslint/rules/no-useless-increment.ts
deleted file mode 100644
index d5675584002..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-useless-increment.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2123/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeIncrement: 'Remove this {{updateOperator}}rement or correct the code not to waste it.',
- },
- },
- create(context: Rule.RuleContext) {
- function reportUpdateExpression(updateExpression: estree.UpdateExpression) {
- const updateOperator = updateExpression.operator === '++' ? 'inc' : 'dec';
- context.report({
- messageId: 'removeIncrement',
- data: {
- updateOperator,
- },
- node: updateExpression,
- });
- }
-
- return {
- 'ReturnStatement > UpdateExpression': function (node: estree.Node) {
- const updateExpression = node as estree.UpdateExpression;
- const argument = updateExpression.argument;
- if (
- !updateExpression.prefix &&
- argument.type === 'Identifier' &&
- isLocalIdentifier(argument, context.getScope())
- ) {
- reportUpdateExpression(updateExpression);
- }
- },
- AssignmentExpression(node: estree.Node) {
- const assignment = node as estree.AssignmentExpression;
- const rhs = assignment.right;
- if (rhs.type === 'UpdateExpression' && !rhs.prefix) {
- const lhs = assignment.left;
- if (
- lhs.type === 'Identifier' &&
- rhs.argument.type === 'Identifier' &&
- rhs.argument.name === lhs.name
- ) {
- reportUpdateExpression(rhs);
- }
- }
- },
- };
- },
-};
-
-function isLocalIdentifier(id: estree.Identifier, scope: Scope.Scope) {
- return scope.variables.some(v => v.identifiers.some(i => i.name === id.name));
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-useless-intersection.ts b/eslint-bridge/src/linting/eslint/rules/no-useless-intersection.ts
deleted file mode 100644
index 23530f79b2b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-useless-intersection.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4335/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeIntersection: 'Remove this type without members or change this type intersection.',
- simplifyIntersection: 'Simplify this intersection as it always has type "{{type}}".',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (isRequiredParserServices(services)) {
- return {
- TSIntersectionType: (node: estree.Node) => {
- const intersection = node as unknown as TSESTree.TSIntersectionType;
- const anyOrNever = intersection.types.find(typeNode =>
- ['TSAnyKeyword', 'TSNeverKeyword'].includes(typeNode.type),
- );
- if (anyOrNever) {
- context.report({
- messageId: 'simplifyIntersection',
- data: {
- type: anyOrNever.type === 'TSAnyKeyword' ? 'any' : 'never',
- },
- node,
- });
- } else {
- intersection.types.forEach(typeNode => {
- const tp: ts.Type = services.program
- .getTypeChecker()
- .getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(typeNode));
- if (isTypeWithoutMembers(tp)) {
- context.report({
- messageId: 'removeIntersection',
- node: typeNode as unknown as estree.Node,
- });
- }
- });
- }
- },
- };
- }
- return {};
- },
-};
-
-function isTypeWithoutMembers(tp: ts.Type): boolean {
- return isNullLike(tp) || (isEmptyInterface(tp) && isStandaloneInterface(tp.symbol));
-}
-
-function isNullLike(tp: ts.Type): boolean {
- return (
- Boolean(tp.flags & ts.TypeFlags.Null) ||
- Boolean(tp.flags & ts.TypeFlags.Undefined) ||
- Boolean(tp.flags & ts.TypeFlags.Void)
- );
-}
-
-function isEmptyInterface(tp: ts.Type): boolean {
- return (
- tp.getProperties().length === 0 &&
- (!(tp as ts.InterfaceTypeWithDeclaredMembers).declaredIndexInfos ||
- (tp as ts.InterfaceTypeWithDeclaredMembers).declaredIndexInfos.length === 0)
- );
-}
-
-function isStandaloneInterface(typeSymbol: ts.Symbol) {
- // there is no declarations for `{}`
- // otherwise check that none of declarations has a heritage clause (`extends X` or `implements X`)
- if (!typeSymbol) {
- return false;
- }
- const { declarations } = typeSymbol;
- return (
- !declarations ||
- declarations.every(declaration => {
- return (
- isInterfaceDeclaration(declaration) && (declaration.heritageClauses || []).length === 0
- );
- })
- );
-}
-
-function isInterfaceDeclaration(
- declaration: ts.Declaration,
-): declaration is ts.InterfaceDeclaration {
- return declaration.kind === ts.SyntaxKind.InterfaceDeclaration;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-useless-react-setstate.ts b/eslint-bridge/src/linting/eslint/rules/no-useless-react-setstate.ts
deleted file mode 100644
index 243c88c3629..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-useless-react-setstate.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6443/javascript
-
-import { Rule, Scope } from 'eslint';
-import { getFullyQualifiedName, getVariableFromName } from './helpers';
-import * as estree from 'estree';
-
-type Reference = {
- setter: Scope.Variable | undefined;
- value: Scope.Variable | undefined;
-};
-
-const declarationSelector = [
- ':matches(',
- [
- 'VariableDeclarator[init.callee.name="useState"]',
- 'VariableDeclarator[init.callee.object.type="Identifier"][init.callee.property.name="useState"]',
- ].join(','),
- ')',
- '[id.type="ArrayPattern"]',
- '[id.elements.length=2]',
- '[id.elements.0.type="Identifier"]',
- '[id.elements.1.type="Identifier"]',
-].join('');
-
-const callSelector = [
- 'CallExpression[callee.type="Identifier"]',
- '[arguments.length=1]',
- '[arguments.0.type="Identifier"]',
-].join('');
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- uselessSetState: 'Change the argument of this setter to not use its matching state variable',
- },
- },
- create(context: Rule.RuleContext) {
- const referencesBySetterName: { [key: string]: Reference } = {};
-
- return {
- [declarationSelector](node: estree.VariableDeclarator) {
- if (isReactCall(context, node.init as estree.CallExpression)) {
- const { elements } = node.id as estree.ArrayPattern;
- const setter = (elements[1] as estree.Identifier).name;
- referencesBySetterName[setter] = {
- setter: getVariableFromName(context, setter),
- value: getVariableFromName(context, (elements[0] as estree.Identifier).name),
- };
- }
- },
- [callSelector](node: estree.CallExpression) {
- const setter = getVariableFromName(context, (node.callee as estree.Identifier).name);
- const value = getVariableFromName(context, (node.arguments[0] as estree.Identifier).name);
- const key = setter?.name as string;
- if (
- setter &&
- value &&
- referencesBySetterName.hasOwnProperty(key) &&
- referencesBySetterName[key].setter === setter &&
- referencesBySetterName[key].value === value
- ) {
- context.report({
- messageId: 'uselessSetState',
- node,
- });
- }
- },
- };
- },
-};
-
-function isReactCall(context: Rule.RuleContext, callExpr: estree.CallExpression): boolean {
- const fqn = getFullyQualifiedName(context, callExpr);
- if (fqn) {
- const [module] = fqn.split('.');
- return module === 'react';
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-variable-usage-before-declaration.ts b/eslint-bridge/src/linting/eslint/rules/no-variable-usage-before-declaration.ts
deleted file mode 100644
index 9c9ab8bc1f7..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-variable-usage-before-declaration.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1526/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- return {
- "VariableDeclaration[kind='var']": (node: estree.Node) => {
- const variables = context.getDeclaredVariables(node);
- for (const variable of variables) {
- const declaration = variable.identifiers[0];
- const misused = variable.references
- .filter(reference => !reference.init && comesBefore(reference.identifier, declaration))
- .map(reference => reference.identifier);
- if (misused.length > 0) {
- context.report({
- message: toEncodedMessage(
- `Move the declaration of \"${declaration.name}\" before this usage.`,
- [declaration as TSESTree.Node],
- ['Declaration'],
- ),
- node: misused[0],
- });
- }
- }
- },
- };
- },
-};
-
-function comesBefore(node: estree.Node, other: estree.Node) {
- const nodeLine = line(node),
- otherLine = line(other);
- return nodeLine < otherLine || (nodeLine === otherLine && column(node) < column(other));
-}
-
-function line(node: estree.Node) {
- return node.loc!.start.line;
-}
-
-function column(node: estree.Node) {
- return node.loc!.start.column;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/no-vue-bypass-sanitization.ts b/eslint-bridge/src/linting/eslint/rules/no-vue-bypass-sanitization.ts
deleted file mode 100644
index 27dbfe12dcc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-vue-bypass-sanitization.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6299/javascript
-
-import * as estree from 'estree';
-import { Rule } from 'eslint';
-import { AST } from 'vue-eslint-parser';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeVueBypassing: 'Make sure bypassing Vue built-in sanitization is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
-
- function attrsHref(calleeName: string) {
- // select call expression with given name where second argument is object expression like { attrs: { href: 'bla' } }
- return `CallExpression[callee.name='${calleeName}'] ObjectExpression.arguments:nth-child(2) > Property[key.name='attrs'] > ObjectExpression.value > Property[key.name='href']`;
- }
-
- const ruleListener: Rule.RuleListener = {
- ["JSXAttribute[name.name='domPropsInnerHTML']," +
- "Property[key.name='domProps'] > ObjectExpression.value > Property[key.name='innerHTML']"](
- node: estree.Node,
- ) {
- context.report({ node, messageId: 'safeVueBypassing' });
- },
- [`${attrsHref('createElement')},${attrsHref('h')}`](node: estree.Node) {
- context.report({ node, messageId: 'safeVueBypassing' });
- },
- };
-
- // @ts-ignore
- if (services.defineTemplateBodyVisitor) {
- // analyze in .vue file
- const templateBodyVisitor = context.parserServices.defineTemplateBodyVisitor({
- ["VAttribute[directive=true][key.name.name='html']," +
- "VAttribute[directive=true][key.argument.name='href']"](node: AST.VAttribute) {
- context.report({
- loc: node.loc,
- messageId: 'safeVueBypassing',
- });
- },
- });
- Object.assign(ruleListener, templateBodyVisitor);
- }
-
- return ruleListener;
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-weak-cipher.ts b/eslint-bridge/src/linting/eslint/rules/no-weak-cipher.ts
deleted file mode 100644
index 0931f33f5c9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-weak-cipher.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5547/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getValueOfExpression, getFullyQualifiedName } from './helpers';
-
-const WEAK_CIPHERS = ['bf', 'blowfish', 'des', 'rc2', 'rc4'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- strongerCipher: 'Use a strong cipher algorithm.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression(node: estree.Node) {
- const callExpression = node as estree.CallExpression;
- if (getFullyQualifiedName(context, callExpression) === 'crypto.createCipheriv') {
- const algorithm = getValueOfExpression(context, callExpression.arguments[0], 'Literal');
- const algorithmValue = algorithm?.value?.toString().toLowerCase();
- if (
- algorithm &&
- algorithmValue &&
- WEAK_CIPHERS.findIndex(cipher => algorithmValue.startsWith(cipher)) >= 0
- ) {
- context.report({
- messageId: 'strongerCipher',
- node: algorithm,
- });
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-weak-keys.ts b/eslint-bridge/src/linting/eslint/rules/no-weak-keys.ts
deleted file mode 100644
index 7370106acc8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-weak-keys.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4426/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, getValueOfExpression, getObjectExpressionProperty } from './helpers';
-
-const MINIMAL_MODULUS_LENGTH = 2048;
-const MINIMAL_DIVISOR_LENGTH = 224;
-const WEAK_CURVES = [
- 'secp112r1',
- 'secp112r2',
- 'secp128r1',
- 'secp128r2',
- 'secp160k1',
- 'secp160r1',
- 'secp160r2',
- 'secp160r2',
- 'secp192k1',
- 'secp192r1',
- 'prime192v2',
- 'prime192v3',
- 'sect113r1',
- 'sect113r2',
- 'sect131r1',
- 'sect131r2',
- 'sect163k1',
- 'sect163r1',
- 'sect163r2',
- 'sect193r1',
- 'sect193r2',
- 'c2tnb191v1',
- 'c2tnb191v2',
- 'c2tnb191v3',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- modulusLength:
- 'Use a modulus length of at least {{minimalLength}} bits for {{algorithm}} cipher algorithm.',
- divisorLength:
- 'Use a divisor length of at least {{minimalLength}} bits for {{algorithm}} cipher algorithm.',
- strongerCurve: `{{curve}} doesn't provide enough security. Use a stronger curve.`,
- },
- },
- create(context: Rule.RuleContext) {
- function getNumericValue(node: estree.Node | undefined) {
- const literal = getValueOfExpression(context, node, 'Literal');
- if (literal && typeof literal.value === 'number') {
- return literal.value;
- }
- return undefined;
- }
-
- function checkRsaAndDsaOptions(algorithm: string, options: estree.Node) {
- const modulusProperty = getObjectExpressionProperty(options, 'modulusLength');
- const modulusLength = getNumericValue(modulusProperty?.value);
- if (modulusProperty && modulusLength && modulusLength < MINIMAL_MODULUS_LENGTH) {
- context.report({
- node: modulusProperty,
- messageId: 'modulusLength',
- data: {
- minimalLength: MINIMAL_MODULUS_LENGTH.toString(),
- algorithm,
- },
- });
- }
- const divisorProperty = getObjectExpressionProperty(options, 'divisorLength');
- const divisorLength = getNumericValue(divisorProperty?.value);
- if (divisorProperty && divisorLength && divisorLength < MINIMAL_DIVISOR_LENGTH) {
- context.report({
- node: divisorProperty,
- messageId: 'divisorLength',
- data: {
- minimalLength: MINIMAL_DIVISOR_LENGTH.toString(),
- algorithm,
- },
- });
- }
- }
-
- function checkEcCurve(options: estree.Node) {
- const namedCurveProperty = getObjectExpressionProperty(options, 'namedCurve');
- const namedCurve = getValueOfExpression(
- context,
- namedCurveProperty?.value,
- 'Literal',
- )?.value?.toString();
- if (namedCurveProperty && namedCurve && WEAK_CURVES.includes(namedCurve)) {
- context.report({
- node: namedCurveProperty,
- messageId: 'strongerCurve',
- data: {
- curve: namedCurve,
- },
- });
- }
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const { callee } = callExpression;
- if (
- callee.type === 'MemberExpression' &&
- isIdentifier(callee.property, 'generateKeyPair', 'generateKeyPairSync')
- ) {
- if (callExpression.arguments.length < 2) {
- return;
- }
- const [algorithmArg, options] = callExpression.arguments;
- const optionsArg = getValueOfExpression(context, options, 'ObjectExpression');
- if (!optionsArg) {
- return;
- }
- const algorithm = getValueOfExpression(context, algorithmArg, 'Literal')?.value;
- if (algorithm === 'rsa' || algorithm === 'dsa') {
- checkRsaAndDsaOptions(algorithm, optionsArg);
- } else if (algorithm === 'ec') {
- checkEcCurve(optionsArg);
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/no-wildcard-import.ts b/eslint-bridge/src/linting/eslint/rules/no-wildcard-import.ts
deleted file mode 100644
index e85813edfd0..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/no-wildcard-import.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2208/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- wildcardImport: 'Explicitly {{xPort}} the specific member needed.',
- },
- },
- create(context: Rule.RuleContext) {
- function report(node: estree.Node, xPort: string) {
- context.report({
- messageId: 'wildcardImport',
- data: { xPort },
- node,
- });
- }
-
- return {
- ImportNamespaceSpecifier: (node: estree.Node) => report(node, 'import'),
- ExportAllDeclaration: (node: estree.Node) => report(node, 'export'),
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/non-number-in-arithmetic-expression.ts b/eslint-bridge/src/linting/eslint/rules/non-number-in-arithmetic-expression.ts
deleted file mode 100644
index 50a318513c9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/non-number-in-arithmetic-expression.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3760/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import ts from 'typescript';
-import {
- isRequiredParserServices,
- getTypeFromTreeNode,
- isStringType,
- toEncodedMessage,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const MESSAGE = 'Convert this operand into a number.';
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- return {
- BinaryExpression: (node: estree.Node) => {
- const binaryExpression = node as estree.BinaryExpression;
- const operator = binaryExpression.operator;
- const leftType = getTypeFromTreeNode(binaryExpression.left, services);
- const rightType = getTypeFromTreeNode(binaryExpression.right, services);
- if (operator === '+') {
- checkPlus(leftType, rightType, binaryExpression, context);
- }
- if (operator === '<' || operator === '>' || operator === '<=' || operator === '>=') {
- checkComparison(leftType, rightType, binaryExpression, context);
- }
- if (operator === '-' || operator === '*' || operator === '/' || operator === '%') {
- checkArithmetic(leftType, rightType, binaryExpression, context);
- }
- },
- AssignmentExpression: (node: estree.Node) => {
- const assignmentExpression = node as estree.AssignmentExpression;
- const operator = assignmentExpression.operator;
- const leftType = getTypeFromTreeNode(assignmentExpression.left, services);
- const rightType = getTypeFromTreeNode(assignmentExpression.right, services);
- if (operator === '+=') {
- checkPlus(leftType, rightType, assignmentExpression, context);
- }
- if (operator === '-=' || operator === '*=' || operator === '/=' || operator === '%=') {
- checkArithmetic(leftType, rightType, assignmentExpression, context);
- }
- },
- 'UnaryExpression[operator="-"]': (node: estree.Node) => {
- const unaryExpression = node as estree.UnaryExpression;
- const type = getTypeFromTreeNode(unaryExpression.argument, services);
- if (isBooleanStringOrDate(type)) {
- context.report({
- node: unaryExpression.argument,
- message: toEncodedMessage(MESSAGE, []),
- });
- }
- },
- UpdateExpression: (node: estree.Node) => {
- const updateExpression = node as estree.UpdateExpression;
- const type = getTypeFromTreeNode(updateExpression.argument, services);
- if (isBooleanStringOrDate(type)) {
- context.report({
- node: updateExpression.argument,
- message: toEncodedMessage(MESSAGE, []),
- });
- }
- },
- };
- },
-};
-
-function isDateMinusDateException(
- leftType: ts.Type,
- rightType: ts.Type,
- operator: estree.BinaryOperator | estree.AssignmentOperator,
-) {
- if (operator !== '-' && operator !== '-=') {
- return false;
- }
- if (
- leftType.symbol?.name === 'Date' &&
- (rightType.symbol?.name === 'Date' || (rightType.flags & ts.TypeFlags.Any) > 0)
- ) {
- return true;
- }
- if (rightType.symbol?.name === 'Date' && (leftType.flags & ts.TypeFlags.Any) > 0) {
- return true;
- }
- return false;
-}
-
-function checkPlus(
- leftType: ts.Type,
- rightType: ts.Type,
- expression: estree.BinaryExpression | estree.AssignmentExpression,
- context: Rule.RuleContext,
-) {
- if (isNumber(leftType) && isBooleanOrDate(rightType)) {
- context.report({
- node: expression.right,
- message: toEncodedMessage(MESSAGE, [expression.left]),
- });
- }
- if (isNumber(rightType) && isBooleanOrDate(leftType)) {
- context.report({
- node: expression.left,
- message: toEncodedMessage(MESSAGE, [expression.right]),
- });
- }
-}
-
-function checkComparison(
- leftType: ts.Type,
- rightType: ts.Type,
- expression: estree.BinaryExpression | estree.AssignmentExpression,
- context: Rule.RuleContext,
-) {
- if (isBooleanOrNumber(leftType) && isBooleanStringOrDate(rightType)) {
- context.report({
- node: expression.right,
- message: toEncodedMessage(MESSAGE, []),
- });
- } else if (isBooleanOrNumber(rightType) && isBooleanStringOrDate(leftType)) {
- context.report({
- node: expression.left,
- message: toEncodedMessage(MESSAGE, []),
- });
- }
-}
-
-function checkArithmetic(
- leftType: ts.Type,
- rightType: ts.Type,
- expression: estree.BinaryExpression | estree.AssignmentExpression,
- context: Rule.RuleContext,
-) {
- if (isDateMinusDateException(leftType, rightType, expression.operator)) {
- return;
- }
- const secondaryLocations = [];
- if (isBooleanStringOrDate(leftType)) {
- secondaryLocations.push(expression.left);
- }
- if (isBooleanStringOrDate(rightType)) {
- secondaryLocations.push(expression.right);
- }
- if (secondaryLocations.length !== 0) {
- context.report({
- node: expression,
- message: toEncodedMessage(
- 'Convert the operands of this operation into numbers.',
- secondaryLocations,
- ),
- });
- }
-}
-
-function isBooleanOrDate(type: ts.Type) {
- if (isBoolean(type)) {
- return true;
- }
- return type.symbol?.name === 'Date';
-}
-
-function isBooleanOrNumber(type: ts.Type) {
- return isBoolean(type) || isNumber(type);
-}
-
-function isBoolean(type: ts.Type) {
- return (type.flags & ts.TypeFlags.BooleanLike) > 0 || type.symbol?.name === 'Boolean';
-}
-
-function isNumber(type: ts.Type) {
- return (type.flags & ts.TypeFlags.NumberLike) > 0 || type.symbol?.name === 'Number';
-}
-
-function isBooleanStringOrDate(type: ts.Type) {
- return isBoolean(type) || isStringType(type) || type.symbol?.name === 'Date';
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/null-dereference.ts b/eslint-bridge/src/linting/eslint/rules/null-dereference.ts
deleted file mode 100644
index 0cf935ddf4c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/null-dereference.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S22259/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import {
- isRequiredParserServices,
- functionLike,
- isUndefinedOrNull,
- findFirstMatchingAncestor,
- RuleContext,
- isNullLiteral,
- isUndefined,
-} from './helpers';
-import { areEquivalent } from 'eslint-plugin-sonarjs/lib/utils/equivalence';
-
-enum Null {
- confirmed,
- discarded,
- unknown,
-}
-
-function isNull(n: estree.Node): boolean {
- return isNullLiteral(n) || isUndefined(n);
-}
-
-const equalOperators = ['==', '==='];
-const notEqualOperators = ['!=', '!=='];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- nullDereference: 'TypeError can be thrown as "{{symbol}}" might be null or undefined here.',
- shortCircuitError: 'TypeError can be thrown as expression might be null or undefined here.',
- },
- },
- create(context: Rule.RuleContext) {
- if (!isRequiredParserServices(context.parserServices)) {
- return {};
- }
- const alreadyRaisedSymbols: Set = new Set();
-
- return {
- MemberExpression(node: estree.Node) {
- const { object, optional } = node as estree.MemberExpression;
- if (!optional) {
- checkNullDereference(object, context, alreadyRaisedSymbols);
- }
- },
- 'LogicalExpression MemberExpression'(node: estree.Node) {
- const { object, optional } = node as estree.MemberExpression;
- if (!optional) {
- const ancestors = context.getAncestors();
- const enclosingLogicalExpression = ancestors.find(
- n => n.type === 'LogicalExpression',
- ) as estree.LogicalExpression;
- checkLogicalNullDereference(enclosingLogicalExpression, object, context);
- }
- },
- ForOfStatement(node: estree.Node) {
- const { right } = node as estree.ForOfStatement;
- checkNullDereference(right, context, alreadyRaisedSymbols);
- },
- 'Program:exit'() {
- alreadyRaisedSymbols.clear();
- },
- };
- },
-};
-
-function getNullState(
- expr: estree.BinaryExpression,
- node: estree.Node,
- context: RuleContext,
-): Null {
- const { left, right } = expr;
- if (
- (isNull(right) &&
- areEquivalent(left as TSESTree.Node, node as TSESTree.Node, context.getSourceCode())) ||
- (isNull(left) &&
- areEquivalent(right as TSESTree.Node, node as TSESTree.Node, context.getSourceCode()))
- ) {
- if (notEqualOperators.includes(expr.operator)) return Null.discarded;
- if (equalOperators.includes(expr.operator)) return Null.confirmed;
- }
- return Null.unknown;
-}
-
-function checkLogicalNullDereference(
- expr: estree.LogicalExpression,
- node: estree.Node,
- context: Rule.RuleContext,
-) {
- if (expr.left.type === 'BinaryExpression') {
- const nullState = getNullState(expr.left, node, context as unknown as RuleContext);
- if (
- (nullState === Null.confirmed && expr.operator === '&&') ||
- (nullState === Null.discarded && expr.operator === '||')
- ) {
- context.report({
- messageId: 'shortCircuitError',
- node: node,
- });
- }
- }
-}
-
-function isWrittenInInnerFunction(symbol: Scope.Variable, fn: estree.Node | undefined) {
- return symbol.references.some(ref => {
- if (ref.isWrite() && ref.identifier.hasOwnProperty('parent')) {
- const enclosingFn = findFirstMatchingAncestor(ref.identifier as TSESTree.Node, node =>
- functionLike.has(node.type),
- );
- return enclosingFn && enclosingFn !== fn;
- }
- return false;
- });
-}
-
-function checkNullDereference(
- node: estree.Node,
- context: Rule.RuleContext,
- alreadyRaisedSymbols: Set,
-) {
- if (node.type !== 'Identifier') {
- return;
- }
- const scope = context.getScope();
- const symbol = scope.references.find(v => v.identifier === node)?.resolved;
- if (!symbol) {
- return;
- }
-
- const enclosingFunction = context.getAncestors().find(n => functionLike.has(n.type));
-
- if (
- !alreadyRaisedSymbols.has(symbol) &&
- !isWrittenInInnerFunction(symbol, enclosingFunction) &&
- isUndefinedOrNull(node, context.parserServices)
- ) {
- alreadyRaisedSymbols.add(symbol);
- context.report({
- messageId: 'nullDereference',
- data: {
- symbol: node.name,
- },
- node,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/operation-returning-nan.ts b/eslint-bridge/src/linting/eslint/rules/operation-returning-nan.ts
deleted file mode 100644
index 41ed7f04f57..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/operation-returning-nan.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3757/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import ts, { TypeFlags } from 'typescript';
-import { isRequiredParserServices, getTypeFromTreeNode } from './helpers';
-
-const BINARY_OPERATORS = ['/', '*', '%', '-', '-=', '*=', '/=', '%='];
-const UNARY_OPERATORS = ['++', '--', '+', '-'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- noEvaluatedNaN:
- 'Change the expression which uses this operand so that it can\'t evaluate to "NaN" (Not a Number).',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- function isObjectType(...types: ts.Type[]): boolean {
- return types.some(
- t => !!(t.getFlags() & TypeFlags.Object) && !isDate(t) && t.symbol?.name !== 'Number',
- );
- }
-
- function isDate(type: ts.Type) {
- const { typeToString } = services.program.getTypeChecker();
- return typeToString(type) === 'Date';
- }
-
- return {
- 'BinaryExpression, AssignmentExpression': (node: estree.Node) => {
- const expression = node as estree.BinaryExpression | estree.AssignmentExpression;
- if (!BINARY_OPERATORS.includes(expression.operator)) {
- return;
- }
- const leftType = getTypeFromTreeNode(expression.left, services);
- const rightType = getTypeFromTreeNode(expression.right, services);
- if (isObjectType(leftType)) {
- context.report({ node: expression.left, messageId: 'noEvaluatedNaN' });
- }
- if (isObjectType(rightType)) {
- context.report({ node: expression.right, messageId: 'noEvaluatedNaN' });
- }
- },
- 'UnaryExpression, UpdateExpression': (node: estree.Node) => {
- const expr = node as estree.UpdateExpression | estree.UnaryExpression;
- if (!UNARY_OPERATORS.includes(expr.operator)) {
- return;
- }
- const argType = getTypeFromTreeNode(expr.argument, services);
- if (isObjectType(argType)) {
- context.report({ node, messageId: 'noEvaluatedNaN' });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/os-command.ts b/eslint-bridge/src/linting/eslint/rules/os-command.ts
deleted file mode 100644
index 3f2b138f3bb..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/os-command.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4721/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, getFullyQualifiedName } from './helpers';
-
-const EXEC_FUNCTIONS = ['exec', 'execSync'];
-
-const SPAWN_EXEC_FILE_FUNCTIONS = ['spawn', 'spawnSync', 'execFile', 'execFileSync'];
-
-const CHILD_PROCESS_MODULE = 'child_process';
-
-type Argument = estree.Expression | estree.SpreadElement;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeOSCommand: 'Make sure that executing this OS command is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression: (node: estree.Node) => checkOSCommand(context, node as estree.CallExpression),
- };
- },
-};
-
-function checkOSCommand(context: Rule.RuleContext, call: estree.CallExpression) {
- const { callee, arguments: args } = call;
- const fqn = getFullyQualifiedName(context, call);
- if (!fqn) {
- return;
- }
- const [module, method] = fqn.split('.');
- if (module === CHILD_PROCESS_MODULE && isQuestionable(method, args)) {
- context.report({
- node: callee,
- messageId: 'safeOSCommand',
- });
- }
-}
-
-function isQuestionable(method: string, [command, ...otherArguments]: Argument[]) {
- // if command is hardcoded => no issue
- if (!command || command.type === 'Literal') {
- return false;
- }
- // for `spawn` and `execFile`, `shell` option must be set to `true`
- if (SPAWN_EXEC_FILE_FUNCTIONS.includes(method)) {
- return containsShellOption(otherArguments);
- }
- return EXEC_FUNCTIONS.includes(method);
-}
-
-function containsShellOption(otherArguments: Argument[]) {
- return otherArguments.some(
- arg =>
- arg.type === 'ObjectExpression' &&
- (arg.properties.filter(v => v.type === 'Property') as estree.Property[]).some(
- ({ key, value }) =>
- isIdentifier(key, 'shell') && value.type === 'Literal' && value.value === true,
- ),
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/post-message.ts b/eslint-bridge/src/linting/eslint/rules/post-message.ts
deleted file mode 100644
index 84fcdf36db3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/post-message.ts
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2819/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import {
- isRequiredParserServices,
- getValueOfExpression,
- getTypeAsString,
- resolveFunction,
- isIdentifier,
- findFirstMatchingLocalAncestor,
-} from './helpers';
-import { childrenOf } from 'linting/eslint';
-import { isIfStatement } from 'eslint-plugin-sonarjs/lib/utils/nodes';
-
-const POST_MESSAGE = 'postMessage';
-const ADD_EVENT_LISTENER = 'addEventListener';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- specifyTarget: `Specify a target origin for this message.`,
- verifyOrigin: `Verify the origin of the received message.`,
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- [`CallExpression:matches([callee.name="${POST_MESSAGE}"], [callee.property.name="${POST_MESSAGE}"])`]:
- (node: estree.Node) => {
- checkPostMessageCall(node as estree.CallExpression, context);
- },
- [`CallExpression[callee.property.name="${ADD_EVENT_LISTENER}"]`]: (node: estree.Node) => {
- checkAddEventListenerCall(node as estree.CallExpression, context);
- },
- };
- },
-};
-
-function isWindowObject(node: estree.Node, context: Rule.RuleContext) {
- const type = getTypeAsString(node, context.parserServices);
- const hasWindowName = WindowNameVisitor.containsWindowName(node, context);
- return type.match(/window/i) || type.match(/globalThis/i) || hasWindowName;
-}
-
-function checkPostMessageCall(callExpr: estree.CallExpression, context: Rule.RuleContext) {
- const { callee } = callExpr;
- // Window.postMessage() can take 2 or 3 arguments
- if (
- ![2, 3].includes(callExpr.arguments.length) ||
- getValueOfExpression(context, callExpr.arguments[1], 'Literal')?.value !== '*'
- ) {
- return;
- }
- if (callee.type === 'Identifier') {
- context.report({
- node: callee,
- messageId: 'specifyTarget',
- });
- }
- if (callee.type !== 'MemberExpression') {
- return;
- }
- if (isWindowObject(callee.object, context)) {
- context.report({
- node: callee,
- messageId: 'specifyTarget',
- });
- }
-}
-
-function checkAddEventListenerCall(callExpr: estree.CallExpression, context: Rule.RuleContext) {
- const { callee, arguments: args } = callExpr;
- if (
- !isWindowObject(callee, context) ||
- args.length < 2 ||
- !isMessageTypeEvent(args[0], context)
- ) {
- return;
- }
-
- let listener = resolveFunction(context, args[1]);
- if (listener?.body.type === 'CallExpression') {
- listener = resolveFunction(context, listener.body);
- }
- if (!listener || listener.params.length === 0) {
- return;
- }
-
- const event = listener.params[0];
- if (event.type !== 'Identifier') {
- return;
- }
-
- if (!hasVerifiedOrigin(context, listener, event)) {
- context.report({
- node: callee,
- messageId: 'verifyOrigin',
- });
- }
-}
-
-/**
- * Checks if event.origin or event.originalEvent.origin is verified
- */
-function hasVerifiedOrigin(
- context: Rule.RuleContext,
- listener: estree.Function,
- event: estree.Identifier,
-) {
- const scope = context.getSourceCode().scopeManager.acquire(listener);
- const eventVariable = scope?.variables.find(v => v.name === event.name);
- if (eventVariable) {
- const eventIdentifiers = eventVariable.references.map(e => e.identifier);
- for (const reference of eventVariable.references) {
- const eventRef = reference.identifier as TSESTree.Identifier;
-
- if (isEventOriginCompared(eventRef) || isEventOriginalEventCompared(eventRef)) {
- return true;
- }
- // event OR-ed with event.originalEvent
- const unionEvent = findUnionEvent(eventRef, eventIdentifiers as TSESTree.Identifier[]);
- if (unionEvent !== null && isReferenceCompared(scope, unionEvent as TSESTree.Identifier)) {
- return true;
- }
- // event.origin OR-ed with event.originalEvent.origin
- const unionOrigin = findUnionOrigin(eventRef, eventIdentifiers as TSESTree.Identifier[]);
- if (
- unionOrigin !== null &&
- isEventOriginReferenceCompared(scope, unionOrigin as TSESTree.Identifier)
- ) {
- return true;
- }
- }
- }
- return false;
-
- /**
- * Looks for unionEvent = event | event.originalEvent
- */
- function findUnionEvent(event: TSESTree.Node, eventIdentifiers: TSESTree.Identifier[]) {
- const logicalExpr = event.parent;
- if (logicalExpr?.type !== 'LogicalExpression') {
- return null;
- }
- if (
- (logicalExpr.left === event &&
- isEventOriginalEvent(logicalExpr.right as estree.MemberExpression, eventIdentifiers)) ||
- (logicalExpr.right === event &&
- isEventOriginalEvent(logicalExpr.left as estree.MemberExpression, eventIdentifiers))
- ) {
- return extractVariableDeclaratorIfExists(logicalExpr);
- }
- return null;
- }
-
- /**
- * looks for unionOrigin = event.origin | event.originalEvent.origin
- */
- function findUnionOrigin(eventRef: TSESTree.Node, eventIdentifiers: TSESTree.Identifier[]) {
- const memberExpr = eventRef.parent;
- // looks for event.origin in a LogicalExpr
- if (
- !(memberExpr?.type === 'MemberExpression' && memberExpr.parent?.type === 'LogicalExpression')
- ) {
- return null;
- }
- const logicalExpr = memberExpr.parent;
- if (
- !(
- logicalExpr.left === memberExpr &&
- isEventOriginalEventOrigin(logicalExpr.right as estree.MemberExpression, eventIdentifiers)
- ) &&
- !(
- logicalExpr.right === memberExpr &&
- isEventOriginalEventOrigin(logicalExpr.left as estree.MemberExpression, eventIdentifiers)
- )
- ) {
- return null;
- }
- return extractVariableDeclaratorIfExists(logicalExpr);
-
- /**
- * checks if memberExpr is event.originalEvent.origin
- */
- function isEventOriginalEventOrigin(
- memberExpr: estree.MemberExpression,
- eventIdentifiers: TSESTree.Identifier[],
- ) {
- const subMemberExpr = memberExpr.object;
- if (subMemberExpr?.type !== 'MemberExpression') {
- return false;
- }
- const isOrigin =
- memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'origin';
- return isEventOriginalEvent(subMemberExpr, eventIdentifiers) && isOrigin;
- }
- }
-}
-
-/**
- * Looks for an occurence of the provided node in an IfStatement
- */
-function isReferenceCompared(scope: Scope.Scope | null, identifier: TSESTree.Identifier) {
- function getGrandParent(node: TSESTree.Node) {
- return node?.parent?.parent as TSESTree.Identifier;
- }
- return checkReference(scope, identifier, getGrandParent);
-}
-
-/**
- * checks if a reference of identifier is
- * node.identifier
- */
-function isEventOriginReferenceCompared(
- scope: Scope.Scope | null,
- identifier: TSESTree.Identifier,
-) {
- function getParent(node: TSESTree.Node) {
- return node?.parent as TSESTree.Identifier;
- }
- return checkReference(scope, identifier, getParent);
-}
-
-/**
- *
- */
-function checkReference(
- scope: Scope.Scope | null,
- identifier: TSESTree.Identifier,
- callback: Function,
-) {
- const identifierVariable = scope?.variables.find(v => v.name === identifier.name);
- if (!identifierVariable) {
- return false;
- }
- for (const reference of identifierVariable.references) {
- const binaryExpressionCandidate = callback(reference.identifier);
- if (isInIfStatement(binaryExpressionCandidate)) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * checks if memberExpr is event.originalEvent
- */
-function isEventOriginalEvent(
- memberExpr: estree.MemberExpression,
- eventIdentifiers: TSESTree.Identifier[],
-) {
- const isEvent =
- memberExpr.object.type === 'Identifier' &&
- eventIdentifiers.includes(memberExpr.object as TSESTree.Identifier);
- const isOriginalEvent =
- memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'originalEvent';
- return isEvent && isOriginalEvent;
-}
-
-/**
- * Extracts the identifier to which the 'node' expression is assigned to
- */
-function extractVariableDeclaratorIfExists(node: TSESTree.Node) {
- if (node.parent?.type !== 'VariableDeclarator') {
- return null;
- }
- return node.parent.id;
-}
-
-/**
- * Looks for an IfStatement with event.origin
- */
-function isEventOriginCompared(event: TSESTree.Identifier) {
- const memberExpr = findEventOrigin(event);
- return isInIfStatement(memberExpr);
-}
-
-/**
- * Looks for an IfStatement with event.originalEvent.origin
- */
-function isEventOriginalEventCompared(event: TSESTree.Identifier) {
- const eventOriginalEvent = findEventOriginalEvent(event);
- if (!eventOriginalEvent || !eventOriginalEvent.parent) {
- return false;
- }
-
- if (!isPropertyOrigin(eventOriginalEvent.parent as TSESTree.MemberExpression)) {
- return false;
- }
- return isInIfStatement(eventOriginalEvent);
-}
-
-/**
- * Returns event.origin MemberExpression, if exists
- */
-function findEventOrigin(event: TSESTree.Identifier) {
- const parent = event.parent;
- if (parent?.type !== 'MemberExpression') {
- return null;
- }
- if (isPropertyOrigin(parent)) {
- return parent;
- } else {
- return null;
- }
-}
-
-/**
- * Checks if node has a property 'origin'
- */
-function isPropertyOrigin(node: TSESTree.MemberExpression) {
- return isIdentifier(node.property as estree.Node, 'origin');
-}
-
-/**
- * Returns event.originalEvent MemberExpression, if exists
- */
-function findEventOriginalEvent(event: TSESTree.Identifier) {
- const memberExpr = event.parent;
- if (memberExpr?.type !== 'MemberExpression') {
- return null;
- }
- const { object: eventCandidate, property: originalEventIdentifierCandidate } = memberExpr;
- if (
- eventCandidate === event &&
- isIdentifier(originalEventIdentifierCandidate as estree.Node, 'originalEvent')
- ) {
- return memberExpr;
- }
- return null;
-}
-
-/**
- * Checks if the current node is nested in an IfStatement
- */
-function isInIfStatement(node: TSESTree.Node | undefined | null) {
- // this checks for 'undefined' and 'null', because node.parent can be 'null'
- if (node == null) {
- return false;
- }
- return findFirstMatchingLocalAncestor(node, isIfStatement) != null;
-}
-
-function isMessageTypeEvent(eventNode: estree.Node, context: Rule.RuleContext) {
- const eventValue = getValueOfExpression(context, eventNode, 'Literal');
- return typeof eventValue?.value === 'string' && eventValue.value.toLowerCase() === 'message';
-}
-
-class WindowNameVisitor {
- private hasWindowName = false;
-
- static containsWindowName(node: estree.Node, context: Rule.RuleContext) {
- const visitor = new WindowNameVisitor();
- visitor.visit(node, context);
- return visitor.hasWindowName;
- }
-
- private visit(root: estree.Node, context: Rule.RuleContext) {
- const visitNode = (node: estree.Node) => {
- if (node.type === 'Identifier' && node.name.match(/window/i)) {
- this.hasWindowName = true;
- }
- childrenOf(node, context.getSourceCode().visitorKeys).forEach(visitNode);
- };
- visitNode(root);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/prefer-default-last.ts b/eslint-bridge/src/linting/eslint/rules/prefer-default-last.ts
deleted file mode 100644
index ed3fcd4482b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/prefer-default-last.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4524/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- defaultLast: 'Move this "default" clause to the end of this "switch" statement.',
- },
- },
- create(context: Rule.RuleContext) {
- const sourceCode = context.getSourceCode();
- return {
- SwitchStatement(node: estree.Node) {
- const cases = (node as estree.SwitchStatement).cases;
- const defaultPosition = cases.findIndex(c => c.test === null);
-
- if (defaultPosition >= 0 && defaultPosition !== cases.length - 1) {
- context.report({
- messageId: 'defaultLast',
- loc: sourceCode.getFirstToken(cases[defaultPosition])!.loc,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/prefer-promise-shorthand.ts b/eslint-bridge/src/linting/eslint/rules/prefer-promise-shorthand.ts
deleted file mode 100644
index 38925000f4e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/prefer-promise-shorthand.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4634/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isFunctionNode } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- promiseAction: 'Replace this trivial promise with "Promise.{{action}}".',
- suggestPromiseAction: 'Replace with "Promise.{{action}}"',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression: (node: estree.Node) => {
- const newExpr = node as estree.NewExpression;
- const executor = getPromiseExecutor(newExpr, context);
- if (executor) {
- checkExecutor(newExpr, executor, context);
- }
- },
- };
- },
-};
-
-function getPromiseExecutor(node: estree.NewExpression, context: Rule.RuleContext) {
- if (
- node.callee.type === 'Identifier' &&
- context.getSourceCode().getText(node.callee) === 'Promise' &&
- node.arguments.length === 1
- ) {
- return node.arguments[0];
- }
- return undefined;
-}
-
-function checkExecutor(
- newExpr: estree.NewExpression,
- executor: estree.Node,
- context: Rule.RuleContext,
-) {
- if (!isFunctionNode(executor)) {
- return;
- }
- const { params, body } = executor;
- const [resolveParameterDeclaration, rejectParameterDeclaration] = params;
-
- const resolveParameterName = getParameterName(resolveParameterDeclaration);
- const rejectParameterName = getParameterName(rejectParameterDeclaration);
-
- const bodyExpression = getOnlyBodyExpression(body);
- if (bodyExpression && bodyExpression.type === 'CallExpression') {
- const { callee, arguments: args } = bodyExpression;
- if (callee.type === 'Identifier') {
- const action = getPromiseAction(callee.name, resolveParameterName, rejectParameterName);
- if (action && args.length === 1) {
- context.report({
- messageId: 'promiseAction',
- data: {
- action,
- },
- node: newExpr.callee,
- suggest: [
- {
- messageId: 'suggestPromiseAction',
- data: {
- action,
- },
- fix: fixer => {
- const argText = context.getSourceCode().getText(args[0]);
- return fixer.replaceText(newExpr, `Promise.${action}(${argText})`);
- },
- },
- ],
- });
- }
- }
- }
-}
-
-function getOnlyBodyExpression(node: estree.Node) {
- let bodyExpression: estree.Node | undefined;
- if (node.type === 'BlockStatement') {
- if (node.body.length === 1) {
- const statement = node.body[0];
- if (statement.type === 'ExpressionStatement') {
- bodyExpression = statement.expression;
- }
- }
- } else {
- bodyExpression = node;
- }
- return bodyExpression;
-}
-
-function getPromiseAction(
- callee: string,
- resolveParameterName: string | undefined,
- rejectParameterName: string | undefined,
-) {
- switch (callee) {
- case resolveParameterName:
- return 'resolve';
- case rejectParameterName:
- return 'reject';
- default:
- return undefined;
- }
-}
-
-function getParameterName(node: estree.Node | undefined) {
- return node && node.type === 'Identifier' ? node.name : undefined;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/prefer-type-guard.ts b/eslint-bridge/src/linting/eslint/rules/prefer-type-guard.ts
deleted file mode 100644
index 09e96efe8c2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/prefer-type-guard.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4322/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { getParent, RuleContext, isUndefined } from './helpers';
-
-type FunctionLikeDeclaration = TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- useTypePredicate:
- 'Declare this function return type using type predicate "{{castedExpressionText}} is {{castedTypeText}}".',
- suggestTypePredicate: 'Use type predicate',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- "MethodDefinition[kind='method'] FunctionExpression": function (node: estree.Node) {
- checkFunctionLikeDeclaration(node as FunctionLikeDeclaration, context);
- },
- FunctionDeclaration(node: estree.Node) {
- checkFunctionLikeDeclaration(node as FunctionLikeDeclaration, context);
- },
- };
- },
-};
-
-function checkFunctionLikeDeclaration(
- functionDeclaration: FunctionLikeDeclaration,
- context: Rule.RuleContext,
-) {
- if (
- functionDeclaration.returnType &&
- functionDeclaration.returnType.typeAnnotation.type === 'TSTypePredicate'
- ) {
- return;
- }
-
- const body = functionDeclaration.body;
- const returnedExpression = getReturnedExpression(body);
- if (!returnedExpression) {
- return;
- }
-
- if (isInequalityBinaryExpression(returnedExpression)) {
- const { left, right } = returnedExpression;
- if (isUndefined(right)) {
- checkCastedType(functionDeclaration, left, context);
- } else if (isUndefined(left)) {
- checkCastedType(functionDeclaration, right, context);
- }
- } else if (isBooleanCall(returnedExpression)) {
- checkCastedType(functionDeclaration, returnedExpression.arguments[0], context);
- } else if (isNegation(returnedExpression) && isNegation(returnedExpression.argument)) {
- checkCastedType(functionDeclaration, returnedExpression.argument.argument, context);
- }
-}
-
-function getReturnedExpression(
- block?: TSESTree.BlockStatement | null,
-): TSESTree.Expression | undefined | null {
- if (block && block.body.length === 1) {
- const statement = block.body[0];
- if (statement.type === 'ReturnStatement') {
- return statement.argument;
- }
- }
- return undefined;
-}
-
-function isInequalityBinaryExpression(
- returnExpression: TSESTree.Expression,
-): returnExpression is TSESTree.BinaryExpression {
- return (
- returnExpression.type === 'BinaryExpression' &&
- (returnExpression.operator === '!==' || returnExpression.operator === '!=')
- );
-}
-
-function checkCastedType(
- node: FunctionLikeDeclaration,
- expression: TSESTree.Node,
- context: Rule.RuleContext,
-) {
- const sourceCode = context.getSourceCode();
- const castedType = getCastTupleFromMemberExpression(expression);
- if (castedType && (castedType[1] as TSESTree.Node).type !== 'TSAnyKeyword') {
- const nOfParam = node.params.length;
- if (nOfParam === 1 || (nOfParam === 0 && castedType[0].type === 'ThisExpression')) {
- const castedExpressionText = sourceCode.getText(castedType[0]);
- const castedTypeText = sourceCode.getText(castedType[1]);
- const predicate = `: ${castedExpressionText} is ${castedTypeText}`;
- const suggest = getTypePredicateSuggestion(node, context, predicate);
- context.report({
- messageId: 'useTypePredicate',
- data: {
- castedExpressionText,
- castedTypeText,
- },
- loc: getMainFunctionTokenLocation(
- node as TSESTree.FunctionLike,
- getParent(context) as TSESTree.Node,
- context as unknown as RuleContext,
- ),
- suggest,
- });
- }
- }
-}
-
-function getTypePredicateSuggestion(
- node: FunctionLikeDeclaration,
- context: Rule.RuleContext,
- predicate: string,
-) {
- const suggestions: Rule.SuggestionReportDescriptor[] = [];
- let fix: (fixer: Rule.RuleFixer) => Rule.Fix;
- if (node.returnType) {
- fix = fixer => fixer.replaceText(node.returnType as unknown as estree.Node, predicate);
- } else {
- const closingParenthesis = context
- .getSourceCode()
- .getTokenBefore(node.body as estree.Node, token => token.value === ')')!;
- fix = fixer => fixer.insertTextAfter(closingParenthesis, predicate);
- }
- suggestions.push({ messageId: 'suggestTypePredicate', fix });
- return suggestions;
-}
-
-function getCastTupleFromMemberExpression(
- node: TSESTree.Node,
-): [estree.Node, estree.Node] | undefined {
- if (node.type === 'MemberExpression') {
- const object = node.object as TSESTree.Node;
- if (object.type === 'TSAsExpression' || object.type === 'TSTypeAssertion') {
- return [object.expression as estree.Node, object.typeAnnotation as unknown as estree.Node];
- }
- }
- return undefined;
-}
-
-function isNegation(node: TSESTree.Expression): node is TSESTree.UnaryExpression {
- return node.type === 'UnaryExpression' && node.prefix && node.operator === '!';
-}
-
-function isBooleanCall(node: TSESTree.Expression): node is TSESTree.CallExpression {
- if (node.type === 'CallExpression') {
- const callee = node.callee;
- return node.arguments.length === 1 && callee.type === 'Identifier' && callee.name === 'Boolean';
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/process-argv.ts b/eslint-bridge/src/linting/eslint/rules/process-argv.ts
deleted file mode 100644
index 33e37193d92..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/process-argv.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4823/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isMemberExpression } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeArg: `Make sure that command line arguments are used safely here.`,
- },
- },
- create(context: Rule.RuleContext) {
- return {
- MemberExpression(node: estree.Node) {
- if (isMemberExpression(node, 'process', 'argv')) {
- context.report({
- messageId: 'safeArg',
- node,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/production-debug.ts b/eslint-bridge/src/linting/eslint/rules/production-debug.ts
deleted file mode 100644
index 47cfeda521b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/production-debug.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4507/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- flattenArgs,
- getUniqueWriteUsageOrNode,
- getFullyQualifiedName,
- isMemberWithProperty,
-} from './helpers';
-
-const ERRORHANDLER_MODULE = 'errorhandler';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- deactivateDebug:
- 'Make sure this debug feature is deactivated before delivering the code in production.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression(node: estree.Node) {
- const callExpression = node as estree.CallExpression;
- // app.use(...)
- checkErrorHandlerMiddleware(context, callExpression);
- },
- };
- },
-};
-
-function checkErrorHandlerMiddleware(
- context: Rule.RuleContext,
- callExpression: estree.CallExpression,
-) {
- const { callee, arguments: args } = callExpression;
- if (isMemberWithProperty(callee, 'use') && args.length > 0 && !isInsideConditional(context)) {
- for (const m of flattenArgs(context, args)) {
- const middleware = getUniqueWriteUsageOrNode(context, m);
- if (
- middleware.type === 'CallExpression' &&
- getFullyQualifiedName(context, middleware) === ERRORHANDLER_MODULE
- ) {
- context.report({
- node: middleware,
- messageId: 'deactivateDebug',
- });
- }
- }
- }
-}
-
-function isInsideConditional(context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- return ancestors.some(ancestor => ancestor.type === 'IfStatement');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/pseudo-random.ts b/eslint-bridge/src/linting/eslint/rules/pseudo-random.ts
deleted file mode 100644
index e1163cf6f9e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/pseudo-random.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2245/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeGenerator: 'Make sure that using this pseudorandom number generator is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- CallExpression(node: estree.CallExpression) {
- const fqn = getFullyQualifiedName(context, node);
- if (fqn === 'Math.random') {
- context.report({
- messageId: 'safeGenerator',
- node,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/publicly-writable-directories.ts b/eslint-bridge/src/linting/eslint/rules/publicly-writable-directories.ts
deleted file mode 100644
index 3fe45a5978c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/publicly-writable-directories.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5443/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-const UNIX_DIRECTORIES = [
- '/tmp/',
- '/var/tmp/',
- '/usr/tmp/',
- '/dev/shm/',
- '/dev/mqueue/',
- '/run/lock/',
- '/var/run/lock/',
- '/library/caches/',
- '/users/shared/',
- '/private/tmp/',
- '/private/var/tmp/',
-].map(v => new RegExp(`^${v}`, 'i'));
-
-const WINDOWS_DIRECTORIES_PATTERN = new RegExp(
- '^[^\\\\]*(\\\\){1,2}(Windows(\\\\){1,2}Temp|Temp|TMP)(\\\\.*|$)',
- 'i',
-);
-const SENSITIVE_ENV_VARIABLES = ['TMPDIR', 'TMP', 'TEMPDIR', 'TEMP'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeDirectory: 'Make sure publicly writable directories are used safely here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- Literal: (node: estree.Node) => {
- const literal = node as estree.Literal;
- // Using literal.raw instead of literal.value as the latter escapes backslashes
- const value = literal.raw?.slice(1, literal.raw.length - 1);
- if (
- value &&
- (UNIX_DIRECTORIES.find(i => value.match(i)) || value.match(WINDOWS_DIRECTORIES_PATTERN))
- ) {
- context.report({
- node: literal,
- messageId: 'safeDirectory',
- });
- }
- },
- MemberExpression: (node: estree.Node) => {
- const memberExpression = node as estree.MemberExpression;
- const { object, property } = memberExpression;
- if (
- property.type !== 'Identifier' ||
- !SENSITIVE_ENV_VARIABLES.includes(property.name) ||
- object.type !== 'MemberExpression'
- ) {
- return;
- }
- if (
- object.property.type === 'Identifier' &&
- object.property.name === 'env' &&
- object.object.type === 'Identifier' &&
- object.object.name === 'process'
- ) {
- context.report({ node: memberExpression, messageId: 'safeDirectory' });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/regex-complexity.ts b/eslint-bridge/src/linting/eslint/rules/regex-complexity.ts
deleted file mode 100644
index cbdb1b54a62..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/regex-complexity.ts
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5843/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import {
- Assertion,
- Backreference,
- CapturingGroup,
- CharacterClass,
- Group,
- LookaroundAssertion,
- Pattern,
- Quantifier,
-} from 'regexpp/ast';
-import {
- getUniqueWriteUsage,
- isBinaryPlus,
- isIdentifier,
- isRegexLiteral,
- isRequiredParserServices,
- isStaticTemplateLiteral,
- isStringLiteral,
- LocationHolder,
- toEncodedMessage,
-} from './helpers';
-import {
- getParsedRegex,
- getRegexpLocation,
- getRegexpRange,
- isRegExpConstructor,
- isStringRegexMethodCall,
-} from './helpers/regex';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const DEFAULT_THESHOLD = 20;
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- { type: 'integer' },
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const threshold = context.options.length > 0 ? context.options[0] : DEFAULT_THESHOLD;
- const services = context.parserServices;
- const regexNodes: estree.Node[] = [];
- return {
- 'Literal[regex]:exit': (node: estree.Node) => {
- regexNodes.push(node);
- },
- 'NewExpression:exit': (node: estree.Node) => {
- if (isRegExpConstructor(node)) {
- regexNodes.push(node);
- }
- },
- 'CallExpression:exit': (node: estree.Node) => {
- const callExpr = node as estree.CallExpression;
- if (isRequiredParserServices(services) && isStringRegexMethodCall(callExpr, services)) {
- regexNodes.push(callExpr.arguments[0]);
- } else if (isRegExpConstructor(callExpr)) {
- regexNodes.push(callExpr);
- }
- },
- 'Program:exit': () => {
- regexNodes.forEach(regexNode => checkRegexComplexity(regexNode, threshold, context));
- },
- };
- },
-};
-
-function checkRegexComplexity(
- regexNode: estree.Node,
- threshold: number,
- context: Rule.RuleContext,
-) {
- for (const regexParts of findRegexParts(regexNode, context)) {
- let complexity = 0;
- const secondaryLocations: LocationHolder[] = [];
- const secondaryMessages: string[] = [];
- for (const regexPart of regexParts) {
- const calculator = new ComplexityCalculator(regexPart, context);
- calculator.visit();
- calculator.components.forEach(component => {
- secondaryLocations.push(component.location);
- secondaryMessages.push(component.message);
- });
- complexity += calculator.complexity;
- }
- if (complexity > threshold) {
- context.report({
- message: toEncodedMessage(
- `Simplify this regular expression to reduce its complexity from ${complexity} to the ${threshold} allowed.`,
- secondaryLocations,
- secondaryMessages,
- complexity - threshold,
- ),
- node: regexParts[0],
- });
- }
- }
-}
-
-type RegexPart = estree.Literal | estree.TemplateLiteral;
-
-function findRegexParts(node: estree.Node, context: Rule.RuleContext): RegexPart[][] {
- const finder = new RegexPartFinder(context);
- finder.find(node);
- return finder.parts;
-}
-
-class RegexPartFinder {
- readonly parts: RegexPart[][] = [];
- constructor(private readonly context: Rule.RuleContext) {}
-
- find(node: estree.Node) {
- if (isRegExpConstructor(node)) {
- this.find(node.arguments[0]);
- } else if (isRegexLiteral(node)) {
- this.parts.push([node]);
- } else if (isStringLiteral(node)) {
- this.parts.push([node]);
- } else if (isStaticTemplateLiteral(node)) {
- this.parts.push([node]);
- } else if (isIdentifier(node)) {
- const initializer = getUniqueWriteUsage(this.context, node.name);
- if (initializer) {
- this.find(initializer);
- }
- } else if (isBinaryPlus(node)) {
- const literals: estree.Literal[] = [];
- this.findInStringConcatenation(node.left, literals);
- this.findInStringConcatenation(node.right, literals);
- if (literals.length > 0) {
- this.parts.push(literals);
- }
- }
- }
-
- findInStringConcatenation(node: estree.Node, literals: estree.Literal[]) {
- if (isStringLiteral(node)) {
- literals.push(node);
- } else if (isBinaryPlus(node)) {
- this.findInStringConcatenation(node.left, literals);
- this.findInStringConcatenation(node.right, literals);
- } else {
- this.find(node);
- }
- }
-}
-
-type Disjunction = CapturingGroup | Group | LookaroundAssertion | Pattern;
-
-class ComplexityCalculator {
- nesting = 1;
- complexity = 0;
- components: { location: LocationHolder; message: string }[] = [];
- regexPartAST: regexpp.AST.Node | null;
-
- constructor(readonly regexPart: RegexPart, readonly context: Rule.RuleContext) {
- this.regexPartAST = getParsedRegex(regexPart, context);
- }
-
- visit() {
- if (!this.regexPartAST) {
- return;
- }
- regexpp.visitRegExpAST(this.regexPartAST, {
- onAssertionEnter: (node: Assertion) => {
- /* lookaround */
- if (node.kind === 'lookahead' || node.kind === 'lookbehind') {
- const [start, end] = getRegexpRange(this.regexPart, node);
- this.increaseComplexity(this.nesting, node, [
- 0,
- -(end - start - 1) + (node.kind === 'lookahead' ? '?='.length : '?<='.length),
- ]);
- this.nesting++;
- this.onDisjunctionEnter(node);
- }
- },
- onAssertionLeave: (node: Assertion) => {
- /* lookaround */
- if (node.kind === 'lookahead' || node.kind === 'lookbehind') {
- this.onDisjunctionLeave(node);
- this.nesting--;
- }
- },
- onBackreferenceEnter: (node: Backreference) => {
- this.increaseComplexity(1, node);
- },
- onCapturingGroupEnter: (node: CapturingGroup) => {
- /* disjunction */
- this.onDisjunctionEnter(node);
- },
- onCapturingGroupLeave: (node: CapturingGroup) => {
- /* disjunction */
- this.onDisjunctionLeave(node);
- },
- onCharacterClassEnter: (node: CharacterClass) => {
- /* character class */
- const [start, end] = getRegexpRange(this.regexPart, node);
- this.increaseComplexity(1, node, [0, -(end - start - 1)]);
- this.nesting++;
- },
- onCharacterClassLeave: (_node: CharacterClass) => {
- /* character class */
- this.nesting--;
- },
- onGroupEnter: (node: Group) => {
- /* disjunction */
- this.onDisjunctionEnter(node);
- },
- onGroupLeave: (node: Group) => {
- /* disjunction */
- this.onDisjunctionLeave(node);
- },
- onPatternEnter: (node: Pattern) => {
- /* disjunction */
- this.onDisjunctionEnter(node);
- },
- onPatternLeave: (node: Pattern) => {
- /* disjunction */
- this.onDisjunctionLeave(node);
- },
- onQuantifierEnter: (node: Quantifier) => {
- /* repetition */
- const [start] = getRegexpRange(this.regexPart, node);
- const [, end] = getRegexpRange(this.regexPart, node.element);
- this.increaseComplexity(this.nesting, node, [end - start, 0]);
- this.nesting++;
- },
- onQuantifierLeave: (_node: Quantifier) => {
- /* repetition */
- this.nesting--;
- },
- });
- }
-
- private increaseComplexity(increment: number, node: regexpp.AST.Node, offset?: number[]) {
- this.complexity += increment;
- let message = '+' + increment;
- if (increment > 1) {
- message += ` (incl ${increment - 1} for nesting)`;
- }
- const loc = getRegexpLocation(this.regexPart, node, this.context, offset);
- this.components.push({
- location: {
- loc,
- },
- message,
- });
- }
-
- private onDisjunctionEnter(node: Disjunction) {
- if (node.alternatives.length > 1) {
- let { alternatives } = node;
- let increment = this.nesting;
- while (alternatives.length > 1) {
- const [start, end] = getRegexpRange(this.regexPart, alternatives[1]);
- this.increaseComplexity(increment, alternatives[1], [-1, -(end - start)]);
- increment = 1;
- alternatives = alternatives.slice(1);
- }
- this.nesting++;
- }
- }
-
- private onDisjunctionLeave(node: Disjunction) {
- if (node.alternatives.length > 1) {
- this.nesting--;
- }
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/regular-expr.ts b/eslint-bridge/src/linting/eslint/rules/regular-expr.ts
deleted file mode 100644
index bbbf53cc405..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/regular-expr.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4784/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isIdentifier, isMemberWithProperty } from './helpers';
-
-const stringMethods = ['match', 'search', 'split'];
-const minPatternLength = 3;
-const specialChars = ['+', '*', '{'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeRegex: 'Make sure that using a regular expression is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- Literal(node: estree.Node) {
- const { regex } = node as estree.RegExpLiteral;
- if (regex) {
- const { pattern } = regex;
- if (isUnsafeRegexLiteral(pattern)) {
- context.report({
- messageId: 'safeRegex',
- node,
- });
- }
- }
- },
-
- CallExpression(node: estree.Node) {
- const { callee, arguments: args } = node as estree.CallExpression;
- if (isMemberWithProperty(callee, ...stringMethods)) {
- checkFirstArgument(args, context);
- }
- },
-
- NewExpression(node: estree.Node) {
- const { callee, arguments: args } = node as estree.NewExpression;
- if (isIdentifier(callee, 'RegExp')) {
- checkFirstArgument(args, context);
- }
- },
- };
- },
-};
-
-function checkFirstArgument(args: estree.Node[], context: Rule.RuleContext) {
- const firstArg = args[0];
- if (
- firstArg &&
- firstArg.type === 'Literal' &&
- typeof firstArg.value === 'string' &&
- isUnsafeRegexLiteral(firstArg.value)
- ) {
- context.report({
- messageId: 'safeRegex',
- node: firstArg,
- });
- }
-}
-
-function isUnsafeRegexLiteral(value: string) {
- return value.length >= minPatternLength && hasEnoughNumberOfSpecialChars(value);
-}
-
-function hasEnoughNumberOfSpecialChars(value: string) {
- let numberOfSpecialChars = 0;
- for (const c of value) {
- if (specialChars.includes(c)) {
- numberOfSpecialChars++;
- }
- if (numberOfSpecialChars === 2) {
- return true;
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/rules-of-hooks.ts b/eslint-bridge/src/linting/eslint/rules/rules-of-hooks.ts
deleted file mode 100644
index 43454c1ee5c..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/rules-of-hooks.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6441/javascript
-
-import { Rule } from 'eslint';
-import { rules as reactHooksRules } from 'eslint-plugin-react-hooks';
-import { rule as detectReact } from './helpers';
-import { mergeRules } from './decorators/helpers';
-
-const rulesOfHooks = reactHooksRules['rules-of-hooks'];
-
-export const rule: Rule.RuleModule = {
- meta: rulesOfHooks.meta,
- create(context: Rule.RuleContext) {
- function overrideContext(overrides: any) {
- Object.setPrototypeOf(overrides, context);
- return overrides;
- }
-
- let isReact = false;
-
- const detectReactListener = detectReact.create(
- overrideContext({
- report(_descriptor: Rule.ReportDescriptor): void {
- isReact = true;
- },
- }),
- );
- const rulesOfHooksListener = rulesOfHooks.create(
- overrideContext({
- report(descriptor: Rule.ReportDescriptor): void {
- if (isReact) {
- context.report(descriptor);
- }
- },
- }),
- );
-
- return mergeRules(detectReactListener, rulesOfHooksListener);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/session-regeneration.ts b/eslint-bridge/src/linting/eslint/rules/session-regeneration.ts
deleted file mode 100644
index bce782b0bc5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/session-regeneration.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5876/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { childrenOf } from 'linting/eslint';
-import {
- isIdentifier,
- getPropertyWithValue,
- last,
- getValueOfExpression,
- getFullyQualifiedName,
-} from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- createSession:
- 'Create a new session during user authentication to prevent session fixation attacks.',
- },
- },
- create(context: Rule.RuleContext) {
- let sessionRegenerate = false;
-
- function isSessionRegenerate(node: estree.Node) {
- return (
- node.type === 'CallExpression' &&
- node.callee.type === 'MemberExpression' &&
- isIdentifier(node.callee.property, 'regenerate')
- );
- }
-
- function visitCallback(node: estree.Node) {
- if (sessionRegenerate) {
- // terminate recursion once call is detected
- return;
- }
- if (isSessionRegenerate(node)) {
- sessionRegenerate = true;
- return;
- }
- childrenOf(node, context.getSourceCode().visitorKeys).forEach(visitCallback);
- }
-
- function hasSessionFalseOption(callExpression: estree.CallExpression) {
- const opt = callExpression.arguments[1];
- if (opt?.type === 'ObjectExpression') {
- const sessionProp = getPropertyWithValue(context, opt, 'session', false);
- return !!sessionProp;
- }
- return false;
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- if (getFullyQualifiedName(context, callExpression) === 'passport.authenticate') {
- if (hasSessionFalseOption(callExpression)) {
- return;
- }
- const parent = last(context.getAncestors());
- if (parent.type === 'CallExpression') {
- const callback = getValueOfExpression(
- context,
- (parent as estree.CallExpression).arguments[2],
- 'FunctionExpression',
- );
- if (callback && callback.type === 'FunctionExpression') {
- sessionRegenerate = false;
- visitCallback(callback);
- if (!sessionRegenerate) {
- context.report({ node: callback, messageId: 'createSession' });
- }
- }
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/shorthand-property-grouping.ts b/eslint-bridge/src/linting/eslint/rules/shorthand-property-grouping.ts
deleted file mode 100644
index 930580d61f8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/shorthand-property-grouping.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3499/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- function raiseIssue(
- node: estree.ObjectExpression,
- begin: number,
- end: number,
- positionMessage: string,
- ) {
- const properties = node.properties;
- const secondaryNodes = [];
- const secondaryMessages = [];
-
- for (let i = begin; i < end; i++) {
- const prop = properties[i] as estree.Property;
- if (prop.shorthand) {
- secondaryNodes.push(prop);
- secondaryMessages.push(`Move to ${positionMessage}`);
- }
- }
-
- const message = toEncodedMessage(
- `Group all shorthand properties at ${positionMessage} of this object declaration.`,
- secondaryNodes as TSESTree.Node[],
- secondaryMessages,
- );
-
- context.report({
- message,
- loc: context.getSourceCode().getFirstToken(node)!.loc,
- });
- }
- return {
- ObjectExpression(node: estree.Node) {
- const objectExpression = node as estree.ObjectExpression;
- const objectExpressionProperties = objectExpression.properties;
- if (objectExpressionProperties.some(p => p.type !== 'Property')) {
- return;
- }
- const isShorthandPropertyList = objectExpressionProperties.map(
- p => (p as estree.Property).shorthand,
- );
- const shorthandPropertiesNumber = isShorthandPropertyList.filter(b => b).length;
-
- const numberOfShorthandAtBeginning = getNumberOfTrueAtBeginning(isShorthandPropertyList);
- const numberOfShorthandAtEnd = getNumberOfTrueAtBeginning(
- [...isShorthandPropertyList].reverse(),
- );
-
- const allAtBeginning = numberOfShorthandAtBeginning === shorthandPropertiesNumber;
- const allAtEnd = numberOfShorthandAtEnd === shorthandPropertiesNumber;
-
- const propertiesNumber = isShorthandPropertyList.length;
-
- if (!allAtBeginning && numberOfShorthandAtBeginning > numberOfShorthandAtEnd) {
- raiseIssue(
- objectExpression,
- numberOfShorthandAtBeginning,
- propertiesNumber,
- 'the beginning',
- );
- } else if (!allAtEnd && numberOfShorthandAtEnd > numberOfShorthandAtBeginning) {
- raiseIssue(objectExpression, 0, propertiesNumber - numberOfShorthandAtEnd, 'the end');
- } else if (!allAtBeginning && !allAtEnd) {
- raiseIssue(objectExpression, 0, propertiesNumber, 'either the beginning or end');
- }
- },
- };
- },
-};
-
-function getNumberOfTrueAtBeginning(list: Array) {
- let numberOfTrueAtBeginning = 0;
- for (const b of list) {
- if (b) {
- numberOfTrueAtBeginning++;
- } else {
- break;
- }
- }
- return numberOfTrueAtBeginning;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/single-char-in-character-classes.ts b/eslint-bridge/src/linting/eslint/rules/single-char-in-character-classes.ts
deleted file mode 100644
index dd0e84b2eb7..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/single-char-in-character-classes.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6397/javascript
-
-import { Rule } from 'eslint';
-import { CharacterClass, CharacterClassElement } from 'regexpp/ast';
-import { createRegExpRule } from './helpers/regex';
-
-const FORBIDDEN_TYPES = [
- 'EscapeCharacterSet',
- 'UnicodePropertyCharacterSet',
- 'Character',
- 'CharacterSet',
-];
-const EXCEPTION_META_CHARACTERS = '[{(.?+*$^\\\\';
-
-export const rule: Rule.RuleModule = createRegExpRule(
- context => {
- return {
- onCharacterClassEnter: (node: CharacterClass) => {
- if (hasSingleForbiddenCharacter(node.elements) && !node.negate) {
- context.reportRegExpNode({
- messageId: 'issue',
- node: context.node,
- regexpNode: node,
- });
- }
- },
- };
- },
- {
- meta: {
- messages: {
- issue: 'Replace this character class by the character itself.',
- },
- },
- },
-);
-
-function hasSingleForbiddenCharacter(elems: CharacterClassElement[]) {
- return (
- elems.length === 1 &&
- FORBIDDEN_TYPES.includes(elems[0].type) &&
- !EXCEPTION_META_CHARACTERS.includes(elems[0].raw)
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/single-character-alternation.ts b/eslint-bridge/src/linting/eslint/rules/single-character-alternation.ts
deleted file mode 100644
index aead6ea0c22..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/single-character-alternation.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6035/javascript
-
-import { Rule } from 'eslint';
-import { AST } from 'regexpp';
-import { Alternation } from './helpers/regex';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- function checkAlternation(alternation: Alternation) {
- const { alternatives } = alternation;
- if (alternatives.length <= 1) {
- return;
- }
- if (
- alternatives.every(alt => alt.elements.length === 1 && alt.elements[0].type === 'Character')
- ) {
- context.reportRegExpNode({
- message: 'Replace this alternation with a character class.',
- node: context.node,
- regexpNode: alternation,
- });
- }
- }
- return {
- onPatternEnter: checkAlternation,
- onGroupEnter: checkAlternation,
- onCapturingGroupEnter: checkAlternation,
- onAssertionEnter(node: AST.Assertion) {
- if (node.kind === 'lookahead' || node.kind === 'lookbehind') {
- checkAlternation(node as Alternation);
- }
- },
- };
-});
diff --git a/eslint-bridge/src/linting/eslint/rules/slow-regex.ts b/eslint-bridge/src/linting/eslint/rules/slow-regex.ts
deleted file mode 100644
index 8297d4ce7e3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/slow-regex.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5852/javascript
-
-import { Rule } from 'eslint';
-import { RegExpLiteral } from 'regexpp/ast';
-import { analyse } from 'scslre';
-import { createRegExpRule } from './helpers/regex';
-
-const message = `Make sure the regex used here, which is vulnerable to super-linear runtime due to backtracking, cannot lead to denial of service.`;
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- return {
- onRegExpLiteralEnter: (node: RegExpLiteral) => {
- const { reports } = analyse(node);
- if (reports.length > 0) {
- context.report({
- message,
- node: context.node,
- });
- }
- },
- };
-});
diff --git a/eslint-bridge/src/linting/eslint/rules/sockets.ts b/eslint-bridge/src/linting/eslint/rules/sockets.ts
deleted file mode 100644
index 91345d81f9b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sockets.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4818/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getFullyQualifiedName } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeSocket: 'Make sure that sockets are used safely here.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- NewExpression: (node: estree.Node) =>
- checkCallExpression(node as estree.NewExpression, context, 'net.Socket'),
- CallExpression: (node: estree.Node) =>
- checkCallExpression(
- node as estree.CallExpression,
- context,
- 'net.createConnection',
- 'net.connect',
- ),
- };
- },
-};
-
-function checkCallExpression(
- callExpr: estree.CallExpression,
- context: Rule.RuleContext,
- ...sensitiveFqns: string[]
-) {
- const callFqn = getFullyQualifiedName(context, callExpr);
- if (sensitiveFqns.some(sensitiveFqn => sensitiveFqn === callFqn)) {
- context.report({ messageId: 'safeSocket', node: callExpr.callee });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-block-scoped-var.ts b/eslint-bridge/src/linting/eslint/rules/sonar-block-scoped-var.ts
deleted file mode 100644
index 23044b9b5a1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-block-scoped-var.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2392/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let scopeRanges: [number, number][] = [];
- let reported: estree.Identifier[] = [];
-
- function enterScope(node: estree.Node) {
- scopeRanges.push(node.range!);
- }
-
- function exitScope() {
- scopeRanges.pop();
- }
-
- return {
- Program(node) {
- scopeRanges = [node.range!];
- reported = [];
- },
-
- BlockStatement: enterScope,
- 'BlockStatement:exit': exitScope,
- ForStatement: enterScope,
- 'ForStatement:exit': exitScope,
- ForInStatement: enterScope,
- 'ForInStatement:exit': exitScope,
- ForOfStatement: enterScope,
- 'ForOfStatement:exit': exitScope,
- SwitchStatement: enterScope,
- 'SwitchStatement:exit': exitScope,
-
- VariableDeclaration: (node: estree.Node) => {
- const varDeclaration = node as estree.VariableDeclaration;
-
- if (varDeclaration.kind !== 'var') {
- return;
- }
-
- const scopeRange = scopeRanges[scopeRanges.length - 1];
-
- function isOutsideOfScope(reference: estree.Identifier) {
- const idRange = reference.range!;
- return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
- }
-
- context.getDeclaredVariables(node).forEach(variable => {
- const referencesOutside = variable.references
- .map(ref => ref.identifier)
- .filter(isOutsideOfScope);
- if (referencesOutside.length === 0) {
- return;
- }
- const definition = variable.defs.find(def =>
- varDeclaration.declarations.includes(def.node),
- );
- if (definition && !reported.includes(definition.name)) {
- context.report({
- node: definition.name,
- message: toEncodedMessage(
- `Consider moving declaration of '${variable.name}' ` +
- `as it is referenced outside current binding context.`,
- referencesOutside as TSESTree.Node[],
- Array(referencesOutside.length).fill('Outside reference.'),
- ),
- });
- variable.defs.map(def => def.name).forEach(defId => reported.push(defId));
- }
- });
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-jsx-no-leaked-render.ts b/eslint-bridge/src/linting/eslint/rules/sonar-jsx-no-leaked-render.ts
deleted file mode 100644
index 76b313613a8..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-jsx-no-leaked-render.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6439/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getTypeFromTreeNode,
- isBigIntType,
- isNumberType,
- isRequiredParserServices,
- isStringType,
-} from './helpers';
-
-const detectReactNativeSelector = [
- ':matches(',
- [
- 'CallExpression[callee.name="require"][arguments.0.value="react-native"]',
- 'ImportDeclaration[source.value="react-native"]',
- ].join(','),
- ')',
-].join('');
-
-export const rule: Rule.RuleModule = {
- meta: {
- hasSuggestions: true,
- messages: {
- nonBooleanMightRender: 'Convert the conditional to a boolean to avoid leaked value',
- suggestConversion: 'Convert the conditional to a boolean',
- },
- },
- create(context: Rule.RuleContext) {
- if (!isRequiredParserServices(context.parserServices)) {
- return {};
- }
- let usesReactNative = false;
-
- return {
- [detectReactNativeSelector]() {
- usesReactNative = true;
- },
- 'JSXExpressionContainer > LogicalExpression[operator="&&"]'(node: estree.LogicalExpression) {
- const leftSide = node.left;
- checkNonBoolean(context, usesReactNative ? isStringOrNumber : isNumber, leftSide);
- },
- };
- },
-};
-
-function report(node: estree.Node, context: Rule.RuleContext) {
- context.report({
- messageId: 'nonBooleanMightRender',
- node,
- suggest: [
- {
- messageId: 'suggestConversion',
- fix: fixer => {
- const sourceCode = context.getSourceCode();
- const previousToken = sourceCode.getTokenBefore(node);
- const nextToken = sourceCode.getTokenAfter(node);
-
- const fixes = [];
- if (
- !!previousToken &&
- !!nextToken &&
- node.range !== undefined &&
- previousToken.value === '(' &&
- previousToken.range[1] <= node.range[0] &&
- nextToken.value === ')' &&
- nextToken.range[0] >= node.range[1]
- ) {
- fixes.push(fixer.remove(previousToken));
- fixes.push(fixer.remove(nextToken));
- }
- fixes.push(fixer.replaceText(node, `!!(${sourceCode.getText(node)})`));
- return fixes;
- },
- },
- ],
- });
-}
-
-function isStringOrNumber(node: estree.Node, context: Rule.RuleContext) {
- const type = getTypeFromTreeNode(node, context.parserServices);
- return isStringType(type) || isBigIntType(type) || isNumberType(type);
-}
-
-function isNumber(node: estree.Node, context: Rule.RuleContext) {
- const type = getTypeFromTreeNode(node, context.parserServices);
- return isBigIntType(type) || isNumberType(type);
-}
-
-function checkNonBoolean(
- context: Rule.RuleContext,
- isLeakingType: (node: estree.Node, context: Rule.RuleContext) => boolean,
- node: estree.Node,
-): void {
- if (node.type === 'LogicalExpression') {
- checkNonBoolean(context, isLeakingType, node.left);
- checkNonBoolean(context, isLeakingType, node.right);
- } else if (isLeakingType(node, context)) {
- report(node, context);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-max-lines-per-function.ts b/eslint-bridge/src/linting/eslint/rules/sonar-max-lines-per-function.ts
deleted file mode 100644
index 8d0edf7ebb2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-max-lines-per-function.ts
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// Greatly inspired by https://github.com/eslint/eslint/blob/561b6d4726f3e77dd40ba0d340ca7f08429cd2eb/lib/rules/max-lines-per-function.js
-// We had to fork the implementation to control the reporting (issue location), in order to provide a better user experience.
-
-// https://sonarsource.github.io/rspec/#/rspec/S138/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { getMainFunctionTokenLocation } from 'eslint-plugin-sonarjs/lib/utils/locations';
-import { getParent, last, RuleContext } from './helpers';
-
-interface FunctionKnowledge {
- node: estree.Node;
- lineCount: number;
- startsWithCapital: boolean;
- returnsJSX: boolean;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- functionMaxLine:
- 'This function has {{lineCount}} lines, which is greater than the {{threshold}} lines authorized. Split it into smaller functions.',
- },
- schema: [{ type: 'integer' }],
- },
- create(context: Rule.RuleContext) {
- const [threshold] = context.options;
-
- const sourceCode = context.getSourceCode();
- const lines = sourceCode.lines;
-
- const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments());
-
- const functionStack: estree.Node[] = [];
- const functionKnowledge = new Map();
- return {
- 'FunctionDeclaration, FunctionExpression, ArrowFunctionExpression': (node: estree.Node) => {
- functionStack.push(node);
- const parent = getParent(context);
-
- if (!node.loc || isIIFE(node, parent as estree.Node)) {
- return;
- }
-
- const lineCount = getLocsNumber(node.loc, lines, commentLineNumbers);
- const startsWithCapital = nameStartsWithCapital(node);
- functionKnowledge.set(node, { node, lineCount, startsWithCapital, returnsJSX: false });
- },
- ReturnStatement: (node: estree.Node) => {
- const returnStatement = node as estree.ReturnStatement;
- const knowledge = functionKnowledge.get(last(functionStack));
- if (
- knowledge &&
- returnStatement.argument &&
- (returnStatement.argument as any).type.startsWith('JSX')
- ) {
- knowledge.returnsJSX = true;
- }
- },
- 'FunctionDeclaration:exit': () => {
- functionStack.pop();
- },
- 'FunctionExpression:exit': () => {
- functionStack.pop();
- },
- 'ArrowFunctionExpression:exit': () => {
- functionStack.pop();
- },
- 'Program:exit': () => {
- for (const knowledge of functionKnowledge.values()) {
- const { node, lineCount } = knowledge;
- if (lineCount > threshold && !isReactFunctionComponent(knowledge)) {
- const functionLike = node as TSESTree.FunctionLike;
- context.report({
- messageId: 'functionMaxLine',
- data: {
- lineCount: lineCount.toString(),
- threshold,
- },
- loc: getMainFunctionTokenLocation(
- functionLike,
- functionLike.parent,
- context as unknown as RuleContext,
- ),
- });
- }
- }
- },
- };
- },
-};
-
-export function getLocsNumber(
- loc: estree.SourceLocation,
- lines: string[],
- commentLineNumbers: Map,
-) {
- let lineCount = 0;
-
- for (let i = loc.start.line - 1; i < loc.end.line; ++i) {
- const line = lines[i];
- const comment = commentLineNumbers.get(i + 1);
- if (comment && isFullLineComment(line, i + 1, comment)) {
- continue;
- }
-
- if (line.match(/^\s*$/u)) {
- continue;
- }
-
- lineCount++;
- }
-
- return lineCount;
-}
-
-export function getCommentLineNumbers(comments: estree.Comment[]): Map {
- const map = new Map();
-
- comments.forEach(comment => {
- if (comment.loc) {
- for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) {
- map.set(i, comment);
- }
- }
- });
- return map;
-}
-
-function isFullLineComment(line: string, lineNumber: number, comment: estree.Comment) {
- if (!comment.loc) {
- return false;
- }
- const start = comment.loc.start,
- end = comment.loc.end,
- isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(),
- isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim();
-
- return (
- comment &&
- (start.line < lineNumber || isFirstTokenOnLine) &&
- (end.line > lineNumber || isLastTokenOnLine)
- );
-}
-
-function isIIFE(node: estree.Node, parent: estree.Node) {
- return (
- node.type === 'FunctionExpression' &&
- parent &&
- parent.type === 'CallExpression' &&
- parent.callee === node
- );
-}
-
-function isReactFunctionComponent(knowledge: FunctionKnowledge) {
- return knowledge.startsWithCapital && knowledge.returnsJSX;
-}
-
-function nameStartsWithCapital(node: estree.Node) {
- return !!(
- (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
- node.id &&
- node.id.name[0] === node.id.name[0].toUpperCase()
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-max-lines.ts b/eslint-bridge/src/linting/eslint/rules/sonar-max-lines.ts
deleted file mode 100644
index 99cd961b14e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-max-lines.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S104/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getLocsNumber, getCommentLineNumbers } from './sonar-max-lines-per-function';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- maxFileLine:
- 'This file has {{lineCount}} lines, which is greater than {{threshold}} authorized. Split it into smaller files.',
- },
- schema: [{ type: 'integer' }],
- },
- create(context: Rule.RuleContext) {
- const [threshold] = context.options;
-
- const sourceCode = context.getSourceCode();
- const lines = sourceCode.lines;
-
- const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments());
-
- return {
- 'Program:exit': (node: estree.Node) => {
- if (!node.loc) {
- return;
- }
-
- const lineCount = getLocsNumber(node.loc, lines, commentLineNumbers);
-
- if (lineCount > threshold) {
- context.report({
- messageId: 'maxFileLine',
- data: {
- lineCount: lineCount.toString(),
- threshold,
- },
- loc: { line: 0, column: 0 },
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-max-params.ts b/eslint-bridge/src/linting/eslint/rules/sonar-max-params.ts
deleted file mode 100644
index 4877ae8d773..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-max-params.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S107/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { interceptReport, mergeRules } from './decorators/helpers';
-import { eslintRules } from './core';
-import { getFullyQualifiedName, isFunctionCall, isIdentifier } from './helpers';
-
-const eslintMaxParams = eslintRules['max-params'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: { ...eslintMaxParams.meta?.messages },
- },
- create(context: Rule.RuleContext) {
- /**
- * Decorates ESLint `max-params` to ignore TypeScript constructor when its parameters
- * are all parameter properties, e.g., `constructor(private a: any, public b: any) {}`.
- */
- const ruleDecoration: Rule.RuleModule = interceptReport(
- eslintMaxParams,
- function (context: Rule.RuleContext, descriptor: Rule.ReportDescriptor) {
- if ('node' in descriptor) {
- const functionLike = descriptor.node as TSESTree.FunctionLike;
- if (!isException(functionLike)) {
- context.report(descriptor);
- }
- }
-
- function isException(functionLike: TSESTree.FunctionLike) {
- return hasOnlyParameterProperties(functionLike) || isAngularConstructor(functionLike);
- }
-
- function hasOnlyParameterProperties(functionLike: TSESTree.FunctionLike) {
- return functionLike.params.every(param => param.type === 'TSParameterProperty');
- }
-
- function isAngularConstructor(functionLike: TSESTree.FunctionLike) {
- /** A constructor is represented as MethodDefinition > FunctionExpression */
- const maybeConstructor = functionLike.parent;
- if (!isConstructor(maybeConstructor)) {
- return false;
- }
-
- /** A component is represented as ClassDeclaration > ClassBody */
- const maybeComponent = maybeConstructor.parent?.parent;
- if (!isAngularComponent(maybeComponent)) {
- return false;
- }
-
- return true;
-
- function isConstructor(
- node: TSESTree.Node | undefined,
- ): node is TSESTree.MethodDefinition {
- return (
- node?.type === 'MethodDefinition' &&
- isIdentifier(node.key as estree.Node, 'constructor')
- );
- }
-
- function isAngularComponent(node: TSESTree.Node | undefined) {
- return (
- node?.type === 'ClassDeclaration' &&
- node.decorators?.some(decorator => {
- const node = decorator.expression as estree.Node;
- return (
- isFunctionCall(node) &&
- getFullyQualifiedName(context, node.callee) === '@angular.core.Component'
- );
- })
- );
- }
- }
- },
- );
-
- /**
- * Extends ESLint `max-params` to detect TypeScript function
- * declarations, e.g., `function f(p: any): any;`.
- */
- const ruleExtension: Rule.RuleModule = {
- meta: {
- messages: { ...ruleDecoration.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- return {
- TSDeclareFunction: checkFunction,
- TSEmptyBodyFunctionExpression: checkFunction,
- };
-
- function checkFunction(node: estree.Node) {
- const functionLike = node as unknown as TSESTree.FunctionLike;
- const maxParams = context.options[0] as number;
- const numParams = functionLike.params.length;
- if (numParams > maxParams) {
- context.report({
- messageId: 'exceed',
- loc: getFunctionHeaderLocation(functionLike),
- data: {
- name: getFunctionNameWithKind(functionLike),
- count: numParams.toString(),
- max: maxParams.toString(),
- },
- });
- }
-
- function getFunctionHeaderLocation(functionLike: TSESTree.FunctionLike) {
- const sourceCode = context.getSourceCode();
- const functionNode = (
- functionLike.type === 'TSEmptyBodyFunctionExpression'
- ? functionLike.parent!
- : functionLike
- ) as estree.Node;
- const headerStart = sourceCode.getFirstToken(functionNode)!;
- const headerEnd = sourceCode.getFirstToken(functionNode, token => token.value === '(')!;
- return {
- start: headerStart.loc.start,
- end: headerEnd.loc.start,
- };
- }
-
- function getFunctionNameWithKind(functionLike: TSESTree.FunctionLike) {
- let name: string | undefined;
- let kind = 'function';
- switch (functionLike.type) {
- case 'TSDeclareFunction':
- kind = 'Function declaration';
- if (functionLike.id) {
- name = functionLike.id.name;
- }
- break;
- case 'TSEmptyBodyFunctionExpression':
- kind = 'Empty function';
- const parent = functionLike.parent;
- if (parent?.type === 'MethodDefinition' && parent.key.type === 'Identifier') {
- name = parent.key.name;
- }
- break;
- }
- if (name) {
- return `${kind} '${name}'`;
- } else {
- return kind;
- }
- }
- }
- },
- };
-
- const decorationListeners: Rule.RuleListener = ruleDecoration.create(context);
- const extensionListeners: Rule.RuleListener = ruleExtension.create(context);
-
- return mergeRules(decorationListeners, extensionListeners);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-control-regex.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-control-regex.ts
deleted file mode 100644
index 77406799037..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-control-regex.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6324/javascript
-
-import { Rule } from 'eslint';
-import { Character } from 'regexpp/ast';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- return {
- onCharacterEnter: (character: Character) => {
- const { value, raw } = character;
- if (value >= 0x00 && value <= 0x1f && (raw.startsWith('\\x') || raw.startsWith('\\u'))) {
- context.reportRegExpNode({
- message: `Remove this control character: ${character.raw}.`,
- node: context.node,
- regexpNode: character,
- });
- }
- },
- };
-});
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-dupe-keys.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-dupe-keys.ts
deleted file mode 100644
index 21523f89cab..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-dupe-keys.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1534/javascript
-
-import { Rule } from 'eslint';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { rules as reactRules } from 'eslint-plugin-react';
-import { mergeRules } from './decorators/helpers';
-
-const noDupeKeysRule = eslintRules['no-dupe-keys'];
-const jsxNoDuplicatePropsRule = reactRules['jsx-no-duplicate-props'];
-
-export const rule: Rule.RuleModule = {
- // meta of no-dupe-keys and jsx-no-duplicate-props is required for issue messages
- meta: {
- messages: { ...noDupeKeysRule.meta!.messages, ...jsxNoDuplicatePropsRule.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- const noDupeKeysListener: Rule.RuleListener = noDupeKeysRule.create(context);
- const jsxNoDuplicatePropsListener: Rule.RuleListener = jsxNoDuplicatePropsRule.create(context);
-
- return mergeRules(noDupeKeysListener, jsxNoDuplicatePropsListener);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-fallthrough.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-fallthrough.ts
deleted file mode 100644
index e42d153c3fd..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-fallthrough.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S128/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getParent } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- switchEnd:
- 'End this switch case with an unconditional break, continue, return or throw statement.',
- },
- },
- create(context: Rule.RuleContext) {
- let currentCodePath: Rule.CodePath | null = null;
- let currentCodeSegment: Rule.CodePathSegment | null = null;
- let enteringSwitchCase = false;
- const segmentsWithExit: Set = new Set();
- const initialSegmentBySwitchCase: Map = new Map();
- const switchCaseStack: estree.SwitchCase[] = [];
-
- function noComment(node: estree.Node) {
- return context.getSourceCode().getCommentsAfter(node).length === 0;
- }
-
- function isAfterProcessExitCall(
- segment: Rule.CodePathSegment,
- initialSegment: Rule.CodePathSegment,
- ) {
- const stack = [];
- const visitedSegments: Set = new Set();
- stack.push(segment);
- while (stack.length !== 0) {
- const current = stack.pop()!;
- visitedSegments.add(current.id);
- if (!segmentsWithExit.has(current.id)) {
- if (current === initialSegment) {
- return false;
- }
- current.prevSegments.filter(p => !visitedSegments.has(p.id)).forEach(p => stack.push(p));
- }
- }
- return true;
- }
-
- return {
- onCodePathStart(codePath: Rule.CodePath) {
- currentCodePath = codePath;
- },
- onCodePathEnd() {
- currentCodePath = currentCodePath!.upper;
- },
- onCodePathSegmentStart(segment: Rule.CodePathSegment) {
- currentCodeSegment = segment;
- if (enteringSwitchCase) {
- initialSegmentBySwitchCase.set(
- switchCaseStack.pop() as estree.SwitchCase,
- currentCodeSegment,
- );
- enteringSwitchCase = false;
- }
- },
- CallExpression(node: estree.Node) {
- const callExpr = node as estree.CallExpression;
- if (isProcessExitCall(callExpr)) {
- segmentsWithExit.add(currentCodeSegment!.id);
- }
- },
- SwitchCase(node: estree.Node) {
- enteringSwitchCase = true;
- switchCaseStack.push(node as estree.SwitchCase);
- },
- 'SwitchCase:exit'(node: estree.Node) {
- const switchCase = node as estree.SwitchCase;
- const initialSegment: Rule.CodePathSegment = initialSegmentBySwitchCase.get(switchCase)!;
- const isReachable = currentCodePath!.currentSegments.some(
- s => s.reachable && !isAfterProcessExitCall(s, initialSegment),
- );
- const { cases } = getParent(context) as estree.SwitchStatement;
- if (
- isReachable &&
- switchCase.consequent.length > 0 &&
- cases[cases.length - 1] !== node &&
- noComment(switchCase)
- ) {
- context.report({
- messageId: 'switchEnd',
- loc: context.getSourceCode().getFirstToken(node)!.loc,
- });
- }
- },
- };
- },
-};
-
-function isProcessExitCall(callExpr: estree.CallExpression) {
- return (
- callExpr.callee.type === 'MemberExpression' &&
- callExpr.callee.object.type === 'Identifier' &&
- callExpr.callee.object.name === 'process' &&
- callExpr.callee.property.type === 'Identifier' &&
- callExpr.callee.property.name === 'exit'
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-invalid-regexp.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-invalid-regexp.ts
deleted file mode 100644
index bb6eb6a40a4..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-invalid-regexp.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5856/javascript
-
-import { Rule } from 'eslint';
-import {
- getTypeFromTreeNode,
- isIdentifier,
- isRequiredParserServices,
- isStringLiteral,
- isStringType,
-} from './helpers';
-import * as estree from 'estree';
-import { RegExpValidator } from 'regexpp';
-
-const validator = new RegExpValidator();
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- function getFlags(node: estree.CallExpression): string | null {
- if (node.arguments.length < 2) {
- return '';
- }
-
- if (isStringLiteral(node.arguments[1])) {
- return node.arguments[1].value as string;
- }
-
- return null;
- }
-
- function validateRegExpPattern(pattern: string, uFlag: boolean): string | null {
- try {
- validator.validatePattern(pattern, undefined, undefined, uFlag);
- return null;
- } catch (err) {
- return err.message;
- }
- }
-
- function validateRegExpFlags(flags: string) {
- try {
- validator.validateFlags(flags);
- return null;
- } catch {
- return `Invalid flags supplied to RegExp constructor '${flags}'`;
- }
- }
-
- function isRegExpConstructor(call: estree.CallExpression) {
- const { callee } = call;
- return callee.type === 'Identifier' && callee.name === 'RegExp';
- }
-
- function isStringMatch(call: estree.CallExpression) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return false;
- }
- const { callee } = call;
- return (
- callee.type === 'MemberExpression' &&
- isStringType(getTypeFromTreeNode(callee.object, services)) &&
- isIdentifier(callee.property, 'match')
- );
- }
-
- function getPattern(call: estree.CallExpression): string | null {
- if (isStringLiteral(call.arguments[0])) {
- return call.arguments[0].value as string;
- }
- return null;
- }
-
- return {
- 'CallExpression, NewExpression'(node: estree.Node) {
- const call = node as estree.CallExpression;
- if (!isRegExpConstructor(call) && !isStringMatch(call)) {
- return;
- }
- const pattern = getPattern(call);
- if (!pattern) {
- return;
- }
- const flags = getFlags(call);
-
- const message =
- (flags && validateRegExpFlags(flags)) ||
- // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag
- (flags === null
- ? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
- : validateRegExpPattern(pattern, flags.includes('u')));
-
- if (message) {
- context.report({
- node,
- message,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-misleading-character-class.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-misleading-character-class.ts
deleted file mode 100644
index 323b1c95514..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-misleading-character-class.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5868/javascript
-
-import { Rule } from 'eslint';
-import { Character, CharacterClassElement } from 'regexpp/ast';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- function characters(nodes: CharacterClassElement[]): Character[][] {
- let current: Character[] = [];
- const sequences: Character[][] = [current];
- for (const node of nodes) {
- if (node.type === 'Character') {
- current.push(node);
- } else if (node.type === 'CharacterClassRange') {
- // for following regexp [xa-z] we produce [[xa],[z]]
- // we would report for example if instead of 'xa' there would be unicode combined class
- current.push(node.min);
- current = [node.max];
- sequences.push(current);
- } else if (node.type === 'CharacterSet' && current.length > 0) {
- // CharacterSet is for example [\d], ., or \p{ASCII}
- // see https://github.com/mysticatea/regexpp/blob/master/src/ast.ts#L222
- current = [];
- sequences.push(current);
- }
- }
- return sequences;
- }
-
- return {
- onCharacterClassEnter(ccNode) {
- for (const chars of characters(ccNode.elements)) {
- const idx = chars.findIndex(
- (c, i) =>
- i !== 0 && isCombiningCharacter(c.value) && !isCombiningCharacter(chars[i - 1].value),
- );
- if (idx >= 0) {
- const combinedChar = chars[idx - 1].raw + chars[idx].raw;
- const message = `Move this Unicode combined character '${combinedChar}' outside of [...]`;
- context.reportRegExpNode({ regexpNode: chars[idx], node: context.node, message });
- }
- }
- },
- };
-});
-
-function isCombiningCharacter(codePoint: number) {
- return /^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(codePoint));
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-regex-spaces.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-regex-spaces.ts
deleted file mode 100644
index 0692c15848a..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-regex-spaces.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6326/javascript
-
-import { Rule } from 'eslint';
-import * as regexpp from 'regexpp';
-import { createRegExpRule } from './helpers/regex';
-
-export const rule: Rule.RuleModule = createRegExpRule(context => {
- let rawPattern: string;
-
- return {
- onRegExpLiteralEnter: (node: regexpp.AST.RegExpLiteral) => {
- rawPattern = node.raw;
- },
- onCharacterEnter: (node: regexpp.AST.Character) => {
- if (node.raw !== ' ' || node.parent.type === 'CharacterClass') {
- return;
- }
-
- const nextChar = rawPattern[node.start + 1];
- if (nextChar !== ' ') {
- const spacesBefore = countSpacesBefore(rawPattern, node.start);
- if (spacesBefore > 0) {
- const spacesNumber = spacesBefore + 1;
- context.reportRegExpNode({
- message: `If multiple spaces are required here, use number quantifier ({${spacesNumber}}).`,
- regexpNode: node,
- offset: [-spacesNumber + 1, 0],
- node: context.node,
- });
- }
- }
- },
- };
-});
-
-function countSpacesBefore(pattern: string, index: number) {
- let counter = 0;
- for (let i = index - 1; i > 0; i--) {
- if (pattern[i] === ' ') {
- counter++;
- } else {
- break;
- }
- }
-
- return counter;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-class-component-methods.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-class-component-methods.ts
deleted file mode 100644
index 35d2b1353c1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-class-component-methods.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6441/javascript
-
-import { Rule } from 'eslint';
-import { rules as reactRules } from 'eslint-plugin-react';
-import { rule as detectReact } from './helpers';
-import { mergeRules } from './decorators/helpers';
-
-const noUnusedClassComponentMethod = reactRules['no-unused-class-component-methods'];
-
-function overrideContext(context: Rule.RuleContext, overrides: any): Rule.RuleContext {
- Object.setPrototypeOf(overrides, context);
- return overrides;
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- unused:
- 'Remove this property or method or refactor this component, as "{{name}}" is not used inside component body',
- unusedWithClass:
- 'Remove this property or method or refactor "{{className}}", as "{{name}}" is not used inside component body',
- },
- },
- create(context: Rule.RuleContext) {
- let isReact = false;
-
- const detectReactListener: Rule.RuleListener = detectReact.create(
- overrideContext(context, {
- report(_descriptor: Rule.ReportDescriptor): void {
- isReact = true;
- },
- }),
- );
-
- const noUnusedClassComponentMethodListener: Rule.RuleListener =
- noUnusedClassComponentMethod.create(
- overrideContext(context, {
- report(descriptor: Rule.ReportDescriptor): void {
- if (isReact) {
- context.report(descriptor);
- }
- },
- }),
- );
-
- return mergeRules(detectReactListener, noUnusedClassComponentMethodListener);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-vars.ts b/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-vars.ts
deleted file mode 100644
index 56997e1fd9d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sonar-no-unused-vars.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1481/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- unusedFunction: `Remove unused function '{{symbol}}'.`,
- unusedVariable: `Remove the declaration of the unused '{{symbol}}' variable.`,
- },
- },
- create(context: Rule.RuleContext) {
- let toIgnore: estree.Identifier[] = [];
- let jsxComponentsToIgnore: string[] = [];
-
- function checkVariable(v: Scope.Variable, toCheck: 'let-const-function' | 'all') {
- if (v.defs.length === 0) {
- return;
- }
- const type = v.defs[0].type;
- if (type !== 'Variable' && type !== 'FunctionName') {
- return;
- }
- if (toCheck === 'let-const-function') {
- const def = v.defs[0];
- if (def.parent && def.parent.type === 'VariableDeclaration' && def.parent.kind === 'var') {
- return;
- }
- }
-
- const defs = v.defs.map(def => def.name);
- const unused = v.references.every(ref => defs.includes(ref.identifier));
-
- if (unused && !toIgnore.includes(defs[0]) && !jsxComponentsToIgnore.includes(v.name)) {
- const messageAndData = getMessageAndData(v.name, type === 'FunctionName');
- defs.forEach(def =>
- context.report({
- node: def,
- ...messageAndData,
- }),
- );
- }
- }
-
- function isParentOfModuleScope(scope: Scope.Scope) {
- return scope.childScopes.some(s => s.type === 'module');
- }
-
- function checkScope(
- scope: Scope.Scope,
- checkedInParent: 'nothing' | 'let-const-function' | 'all',
- ) {
- let toCheck = checkedInParent;
- if (scope.type === 'function' && !isParentOfModuleScope(scope)) {
- toCheck = 'all';
- } else if (checkedInParent === 'nothing' && scope.type === 'block') {
- toCheck = 'let-const-function';
- }
-
- if (toCheck !== 'nothing' && scope.type !== 'function-expression-name') {
- scope.variables.forEach(v => checkVariable(v, toCheck as 'let-const-function' | 'all'));
- }
-
- scope.childScopes.forEach(childScope => checkScope(childScope, toCheck));
- }
-
- return {
- ObjectPattern: (node: estree.Node) => {
- const elements = (node as estree.ObjectPattern).properties;
- const hasRest = elements.some(element => (element as any).type === 'RestElement');
-
- if (!hasRest) {
- return;
- }
-
- elements.forEach(element => {
- if (
- element.type === 'Property' &&
- element.shorthand &&
- element.value.type === 'Identifier'
- ) {
- toIgnore.push(element.value);
- }
- });
- },
-
- JSXIdentifier: (node: estree.Node) => {
- // using 'any' as standard typings for AST don't provide types for JSX
- jsxComponentsToIgnore.push((node as any).name);
- },
-
- 'Program:exit': () => {
- checkScope(context.getScope(), 'nothing');
- toIgnore = [];
- jsxComponentsToIgnore = [];
- },
- };
- },
-};
-
-function getMessageAndData(name: string, isFunction: boolean) {
- if (isFunction) {
- return { messageId: 'unusedFunction', data: { symbol: name } };
- } else {
- return { messageId: 'unusedVariable', data: { symbol: name } };
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/sql-queries.ts b/eslint-bridge/src/linting/eslint/rules/sql-queries.ts
deleted file mode 100644
index 6bab6cc2c0e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/sql-queries.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2077/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isRequireModule, isMemberWithProperty } from './helpers';
-
-const dbModules = ['pg', 'mysql', 'mysql2', 'sequelize'];
-
-type Argument = estree.Expression | estree.SpreadElement;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeQuery: `Make sure that executing SQL queries is safe here.`,
- },
- },
- create(context: Rule.RuleContext) {
- let isDbModuleImported = false;
-
- return {
- Program() {
- // init flag for each file
- isDbModuleImported = false;
- },
-
- ImportDeclaration(node: estree.Node) {
- const { source } = node as estree.ImportDeclaration;
- if (dbModules.includes(String(source.value))) {
- isDbModuleImported = true;
- }
- },
-
- CallExpression(node: estree.Node) {
- const call = node as estree.CallExpression;
- const { callee, arguments: args } = call;
-
- if (isRequireModule(call, ...dbModules)) {
- isDbModuleImported = true;
- return;
- }
-
- if (
- isDbModuleImported &&
- isMemberWithProperty(callee, 'query') &&
- isQuestionable(args[0])
- ) {
- context.report({
- messageId: 'safeQuery',
- node: callee,
- });
- }
- },
- };
- },
-};
-
-function isQuestionable(sqlQuery: Argument | undefined) {
- if (!sqlQuery) {
- return false;
- }
- if (isTemplateWithVar(sqlQuery)) {
- return true;
- }
- if (isConcatenation(sqlQuery)) {
- return isVariableConcat(sqlQuery);
- }
- return (
- sqlQuery.type === 'CallExpression' && isMemberWithProperty(sqlQuery.callee, 'concat', 'replace')
- );
-}
-
-function isVariableConcat(node: estree.BinaryExpression): boolean {
- const { left, right } = node;
- if (!isHardcodedLiteral(right)) {
- return true;
- }
- if (isConcatenation(left)) {
- return isVariableConcat(left);
- }
- return !isHardcodedLiteral(left);
-}
-
-function isTemplateWithVar(node: estree.Node) {
- return node.type === 'TemplateLiteral' && node.expressions.length !== 0;
-}
-
-function isTemplateWithoutVar(node: estree.Node) {
- return node.type === 'TemplateLiteral' && node.expressions.length === 0;
-}
-
-function isConcatenation(node: estree.Node): node is estree.BinaryExpression {
- return node.type === 'BinaryExpression' && node.operator === '+';
-}
-
-function isHardcodedLiteral(node: estree.Node) {
- return node.type === 'Literal' || isTemplateWithoutVar(node);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/standard-input.ts b/eslint-bridge/src/linting/eslint/rules/standard-input.ts
deleted file mode 100644
index cd998f95985..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/standard-input.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4829/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isMemberExpression } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- safeStdin: `Make sure that reading the standard input is safe here.`,
- },
- },
- create(context: Rule.RuleContext) {
- return {
- MemberExpression(node: estree.Node) {
- if (isMemberExpression(node, 'process', 'stdin')) {
- context.report({
- messageId: 'safeStdin',
- node,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/stateful-regex.ts b/eslint-bridge/src/linting/eslint/rules/stateful-regex.ts
deleted file mode 100644
index 820f13e9bf3..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/stateful-regex.ts
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S6351/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import {
- functionLike,
- getParent,
- getUniqueWriteUsage,
- getVariableFromName,
- isCallingMethod,
- isDotNotation,
- isMethodCall,
- isRegexLiteral,
- toEncodedMessage,
-} from './helpers';
-import { getFlags, isRegExpConstructor } from './helpers/regex';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-type RegexInfo = { node: estree.Node; flags: string };
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const invocations = new Map();
- const regexes: RegexInfo[] = [];
- const resets = new Set();
- return {
- 'Literal:exit': (node: estree.Node) => {
- extractRegex(node, regexes);
- },
- 'CallExpression:exit': (node: estree.Node) => {
- const callExpr = node as estree.CallExpression;
- extractRegex(node, regexes);
- extractRegexInvocation(callExpr, regexes, invocations, context);
- checkWhileConditionRegex(callExpr, context);
- },
- 'MemberExpression:exit': (node: estree.Node) => {
- extractResetRegex(node, regexes, resets, context);
- },
- 'NewExpression:exit': (node: estree.Node) => {
- extractRegex(node, regexes);
- },
- 'Program:exit': () => {
- regexes.forEach(regex => checkGlobalStickyRegex(regex, context));
- invocations.forEach((usages, regex) =>
- checkMultipleInputsRegex(regex, usages, resets, context),
- );
- },
- };
- },
-};
-
-function extractRegex(node: estree.Node, acc: RegexInfo[]) {
- if (isRegexLiteral(node)) {
- const { flags } = node.regex;
- acc.push({ node, flags });
- } else if (isRegExpConstructor(node)) {
- const flags = getFlags(node) || '';
- acc.push({ node, flags });
- }
-}
-
-function extractRegexInvocation(
- callExpr: estree.CallExpression,
- regexes: RegexInfo[],
- invocations: Map,
- context: Rule.RuleContext,
-) {
- if (
- isCallingMethod(callExpr, 1, 'exec', 'test') &&
- callExpr.callee.object.type === 'Identifier'
- ) {
- const { object } = callExpr.callee;
- const variable = getVariableFromName(context, object.name);
- if (variable) {
- const value = getUniqueWriteUsage(context, variable.name);
- const regex = regexes.find(r => r.node === value);
- if (regex && regex.flags.includes('g')) {
- const usages = invocations.get(variable);
- if (usages) {
- usages.push(callExpr);
- } else {
- invocations.set(variable, [callExpr]);
- }
- }
- }
- }
-}
-
-function extractResetRegex(
- node: estree.Node,
- regexes: RegexInfo[],
- resets: Set,
- context: Rule.RuleContext,
-) {
- /* RegExp.prototype.lastIndex = ... */
- if (
- isDotNotation(node) &&
- node.object.type === 'Identifier' &&
- node.property.name === 'lastIndex'
- ) {
- const parent = getParent(context);
- if (parent?.type === 'AssignmentExpression' && parent.left === node) {
- const variable = getVariableFromName(context, node.object.name);
- if (variable) {
- const value = getUniqueWriteUsage(context, variable.name);
- const regex = regexes.find(r => r.node === value);
- if (regex) {
- resets.add(variable);
- }
- }
- }
- }
-}
-
-function checkWhileConditionRegex(callExpr: estree.CallExpression, context: Rule.RuleContext) {
- /* RegExp.prototype.exec() within while conditions */
- if (isMethodCall(callExpr)) {
- const { object, property } = callExpr.callee;
- if ((isRegexLiteral(object) || isRegExpConstructor(object)) && property.name === 'exec') {
- const flags = object.type === 'Literal' ? object.regex.flags : getFlags(object);
- if (flags && flags.includes('g') && isWithinWhileCondition(callExpr, context)) {
- context.report({
- message: toEncodedMessage('Extract this regular expression to avoid infinite loop.', []),
- node: object,
- });
- }
- }
- }
-}
-
-function checkGlobalStickyRegex(regex: RegexInfo, context: Rule.RuleContext) {
- /* RegExp with `g` and `y` flags */
- if (regex.flags.includes('g') && regex.flags.includes('y')) {
- context.report({
- message: toEncodedMessage(
- `Remove the 'g' flag from this regex as it is shadowed by the 'y' flag.`,
- [],
- ),
- node: regex.node,
- });
- }
-}
-
-function checkMultipleInputsRegex(
- regex: Scope.Variable,
- usages: estree.CallExpression[],
- resets: Set,
- context: Rule.RuleContext,
-) {
- /* RegExp.prototype.exec(input) / RegExp.prototype.test(input) */
- if (!resets.has(regex)) {
- const definition = regex.defs.find(def => def.type === 'Variable' && def.node.init);
- const uniqueInputs = new Set(
- usages.map(callExpr => context.getSourceCode().getText(callExpr.arguments[0])),
- );
- const regexReset = uniqueInputs.has(`''`) || uniqueInputs.has(`""`);
- if (definition && uniqueInputs.size > 1 && !regexReset) {
- const pattern = definition.node.init as estree.Expression;
- context.report({
- message: toEncodedMessage(
- `Remove the 'g' flag from this regex as it is used on different inputs.`,
- usages,
- usages.map((_, idx) => `Usage ${idx + 1}`),
- ),
- node: pattern,
- });
- }
- }
-}
-
-function isWithinWhileCondition(node: estree.Node, context: Rule.RuleContext) {
- const ancestors = context.getAncestors();
- let parent: estree.Node | undefined;
- let child: estree.Node = node;
- while ((parent = ancestors.pop()) !== undefined) {
- if (functionLike.has(parent.type)) {
- break;
- }
- if (parent.type === 'WhileStatement' || parent.type === 'DoWhileStatement') {
- return parent.test === child;
- }
- child = parent;
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/strict-transport-security.ts b/eslint-bridge/src/linting/eslint/rules/strict-transport-security.ts
deleted file mode 100644
index fd944ec0985..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/strict-transport-security.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5734/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- Express,
- getPropertyWithValue,
- getObjectExpressionProperty,
- getValueOfExpression,
- getFullyQualifiedName,
-} from './helpers';
-
-const HSTS = 'hsts';
-const HELMET = 'helmet';
-const MAX_AGE = 'maxAge';
-const INCLUDE_SUB_DOMAINS = 'includeSubDomains';
-const RECOMMENDED_MAX_AGE = 15552000;
-
-export const rule: Rule.RuleModule = Express.SensitiveMiddlewarePropertyRule(
- findSensitiveTransportSecurityPolicyProperty,
- `Disabling Strict-Transport-Security policy is security-sensitive.`,
-);
-
-function findSensitiveTransportSecurityPolicyProperty(
- context: Rule.RuleContext,
- node: estree.CallExpression,
-): estree.Property[] {
- const sensitiveFinders = [findSensitiveHsts, findSensitiveMaxAge, findSensitiveIncludeSubDomains];
- const sensitives: estree.Property[] = [];
- const { callee, arguments: args } = node;
- if (args.length === 1 && args[0].type === 'ObjectExpression') {
- const [options] = args;
- for (const finder of sensitiveFinders) {
- const maybeSensitive = finder(context, callee, options);
- if (maybeSensitive) {
- sensitives.push(maybeSensitive);
- }
- }
- }
- return sensitives;
-}
-
-function findSensitiveHsts(
- context: Rule.RuleContext,
- middleware: estree.Node,
- options: estree.ObjectExpression,
-): estree.Property | undefined {
- if (getFullyQualifiedName(context, middleware) === HELMET) {
- return getPropertyWithValue(context, options, HSTS, false);
- }
- return undefined;
-}
-
-function findSensitiveMaxAge(
- context: Rule.RuleContext,
- middleware: estree.Node,
- options: estree.ObjectExpression,
-): estree.Property | undefined {
- if (isHstsMiddlewareNode(context, middleware)) {
- const maybeMaxAgeProperty = getObjectExpressionProperty(options, MAX_AGE);
- if (maybeMaxAgeProperty) {
- const maybeMaxAgeValue = getValueOfExpression(context, maybeMaxAgeProperty.value, 'Literal');
- if (
- typeof maybeMaxAgeValue?.value === 'number' &&
- maybeMaxAgeValue.value < RECOMMENDED_MAX_AGE
- ) {
- return maybeMaxAgeProperty;
- }
- }
- }
- return undefined;
-}
-
-function findSensitiveIncludeSubDomains(
- context: Rule.RuleContext,
- middleware: estree.Node,
- options: estree.ObjectExpression,
-): estree.Property | undefined {
- if (isHstsMiddlewareNode(context, middleware)) {
- return getPropertyWithValue(context, options, INCLUDE_SUB_DOMAINS, false);
- }
- return undefined;
-}
-
-function isHstsMiddlewareNode(context: Rule.RuleContext, node: estree.Node): boolean {
- const fqn = getFullyQualifiedName(context, node);
- return fqn === `${HELMET}.${HSTS}` || fqn === HSTS;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/strings-comparison.ts b/eslint-bridge/src/linting/eslint/rules/strings-comparison.ts
deleted file mode 100644
index b137233ebd9..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/strings-comparison.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3003/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isString, isRequiredParserServices, toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- BinaryExpression: (node: estree.Node) => {
- const { operator, left, right } = node as estree.BinaryExpression;
- if (
- ['<', '<=', '>', '>='].includes(operator) &&
- isString(left, services) &&
- isString(right, services) &&
- !isLiteralException(left) &&
- !isLiteralException(right) &&
- !isWithinSortCallback(context)
- ) {
- context.report({
- message: toEncodedMessage(
- `Convert operands of this use of "${operator}" to number type.`,
- [left, right],
- ),
- loc: context
- .getSourceCode()
- .getTokensBetween(left, right)
- .find(token => token.type === 'Punctuator' && token.value === operator)!.loc,
- });
- }
- },
- };
- },
-};
-
-function isLiteralException(node: estree.Node) {
- return node.type === 'Literal' && node.raw!.length === 3;
-}
-
-function isWithinSortCallback(context: Rule.RuleContext) {
- const ancestors = context.getAncestors().reverse();
- const maybeCallback = ancestors.find(node =>
- ['ArrowFunctionExpression', 'FunctionExpression'].includes(node.type),
- );
- if (maybeCallback) {
- const callback = maybeCallback as TSESTree.Node;
- const parent = callback.parent;
- if (parent?.type === 'CallExpression') {
- const { callee, arguments: args } = parent;
- let funcName: string | undefined;
- if (callee.type === 'Identifier') {
- funcName = callee.name;
- } else if (callee.type === 'MemberExpression' && callee.property.type === 'Identifier') {
- funcName = callee.property.name;
- }
- return funcName && funcName.match(/sort/i) && args.some(arg => arg === callback);
- }
- }
- return false;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/super-invocation.ts b/eslint-bridge/src/linting/eslint/rules/super-invocation.ts
deleted file mode 100644
index efb0a4a1fc4..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/super-invocation.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3854/javascript
-
-import { Rule } from 'eslint';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { mergeRules } from './decorators/helpers';
-
-const constructorSuperRule = eslintRules['constructor-super'];
-const noThisBeforeSuperRule = eslintRules['no-this-before-super'];
-
-export const rule: Rule.RuleModule = {
- // meta of constructor-super and no-this-before-super is required for issue messages
- meta: {
- messages: { ...constructorSuperRule.meta!.messages, ...noThisBeforeSuperRule.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- const constructorSuperListener: Rule.RuleListener = constructorSuperRule.create(context);
- const notThisBeforeSuperListener: Rule.RuleListener = noThisBeforeSuperRule.create(context);
-
- return mergeRules(constructorSuperListener, notThisBeforeSuperListener);
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/switch-without-default.ts b/eslint-bridge/src/linting/eslint/rules/switch-without-default.ts
deleted file mode 100644
index d486082439d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/switch-without-default.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S131/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- switchDefault: `Add a "default" clause to this "switch" statement.`,
- },
- },
- create(context: Rule.RuleContext) {
- return {
- SwitchStatement(node: estree.Node) {
- const { cases } = node as estree.SwitchStatement;
- const defaultClause = cases.find(c => c.test === null);
- if (!defaultClause) {
- const switchKeyword = context
- .getSourceCode()
- .getFirstToken(node, token => token.type === 'Keyword' && token.value === 'switch')!;
- context.report({
- messageId: 'switchDefault',
- loc: switchKeyword.loc,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/test-check-exception.ts b/eslint-bridge/src/linting/eslint/rules/test-check-exception.ts
deleted file mode 100644
index bdc082c266d..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/test-check-exception.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5958/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getVariableFromIdentifier, isIdentifier, Mocha } from './helpers';
-
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- let catchWithDone = false;
-
- function isInsideTest() {
- return context
- .getAncestors()
- .some(n => n.type === 'CallExpression' && Mocha.isTestConstruct(n));
- }
-
- return {
- 'CatchClause CallExpression[callee.name="done"]': (_node: estree.Node) => {
- catchWithDone = true;
- },
- 'CatchClause:exit': (node: estree.Node) => {
- if (!catchWithDone || !isInsideTest()) {
- return;
- }
- catchWithDone = false;
- const { param } = node as estree.CatchClause;
- if (param && param.type === 'Identifier') {
- const exception = getVariableFromIdentifier(param, context.getScope());
- if (exception && exception.references.length === 0) {
- context.report({
- node: param,
- message:
- 'Either the exception should be passed to "done(e)", or the exception should be tested further.',
- });
- }
- }
- },
- CallExpression(node: estree.Node) {
- const callExpr = node as estree.CallExpression;
- if (
- isInsideTest() &&
- isThrowAssertWithoutNot(callExpr) &&
- (callExpr.arguments.length === 0 ||
- (callExpr.arguments.length === 1 && isIdentifier(callExpr.arguments[0], 'Error')))
- ) {
- context.report({
- node: callExpr.callee.property,
- message: 'Assert more concrete exception type or assert the message of exception.',
- });
- }
- },
- };
- },
-};
-
-// find nodes in shape expect(...).a.b.c.throw() or a.should.throw()
-function isThrowAssertWithoutNot(
- node: estree.CallExpression,
-): node is estree.CallExpression & { callee: estree.MemberExpression } {
- if (node.callee.type !== 'MemberExpression') {
- return false;
- }
- let { object, property } = node.callee;
- if (!isIdentifier(property, 'throw')) {
- return false;
- }
- while (object.type === 'MemberExpression') {
- if (isIdentifier(object.property, 'not')) {
- return false;
- }
- if (isIdentifier(object.property, 'should')) {
- return true;
- }
- object = object.object;
- }
- return object.type === 'CallExpression' && isIdentifier(object.callee, 'expect');
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/todo-tag.ts b/eslint-bridge/src/linting/eslint/rules/todo-tag.ts
deleted file mode 100644
index e360aad2683..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/todo-tag.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1135/javascript
-
-import { Rule } from 'eslint';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-const todoPattern = 'todo';
-const letterPattern = /[\p{Letter}]/u;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- completeTODO: 'Complete the task associated to this "TODO" comment.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- 'Program:exit': () => {
- reportPatternInComment(context, todoPattern, 'completeTODO');
- },
- };
- },
-};
-
-export function reportPatternInComment(
- context: Rule.RuleContext,
- pattern: string,
- messageId: string,
-) {
- const sourceCode = context.getSourceCode();
- (sourceCode.getAllComments() as TSESTree.Comment[]).forEach(comment => {
- const rawText = comment.value.toLowerCase();
-
- if (rawText.includes(pattern)) {
- const lines = rawText.split(/\r\n?|\n/);
-
- for (let i = 0; i < lines.length; i++) {
- const index = lines[i].indexOf(pattern);
- if (index >= 0 && !isLetterAround(lines[i], index, pattern)) {
- context.report({
- messageId,
- loc: getPatternPosition(i, index, comment, pattern),
- });
- }
- }
- }
- });
-}
-
-function isLetterAround(line: string, start: number, pattern: string) {
- const end = start + pattern.length;
-
- const pre = start > 0 && letterPattern.test(line.charAt(start - 1));
- const post = end <= line.length - 1 && letterPattern.test(line.charAt(end));
-
- return pre || post;
-}
-
-function getPatternPosition(
- lineIdx: number,
- index: number,
- comment: TSESTree.Comment,
- pattern: string,
-) {
- const line = comment.loc.start.line + lineIdx;
- const columnStart = lineIdx === 0 ? comment.loc.start.column + 2 : 0;
- const patternStart = columnStart + index;
-
- return {
- start: { line, column: patternStart },
- end: { line, column: patternStart + pattern.length },
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/too-many-break-or-continue-in-loop.ts b/eslint-bridge/src/linting/eslint/rules/too-many-break-or-continue-in-loop.ts
deleted file mode 100644
index f855c3db9ed..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/too-many-break-or-continue-in-loop.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S135/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let jumpTargets: JumpTarget[] = [];
-
- function enterScope() {
- jumpTargets.push(new JumpTarget());
- }
-
- function leaveScope() {
- jumpTargets.pop();
- }
-
- function increateNumberOfJumpsInScopes(jump: estree.Node, label?: string) {
- for (const jumpTarget of [...jumpTargets].reverse()) {
- jumpTarget.jumps.push(jump);
- if (label === jumpTarget.label) {
- break;
- }
- }
- }
-
- function leaveScopeAndCheckNumberOfJumps(node: estree.Node) {
- const jumps = jumpTargets.pop()?.jumps;
- if (jumps && jumps.length > 1) {
- const sourceCode = context.getSourceCode();
- const firstToken = sourceCode.getFirstToken(node);
- context.report({
- loc: firstToken!.loc,
- message: toEncodedMessage(
- 'Reduce the total number of "break" and "continue" statements in this loop to use one at most.',
- jumps,
- jumps.map(jmp =>
- jmp.type === 'BreakStatement' ? '"break" statement.' : '"continue" statement.',
- ),
- ),
- });
- }
- }
-
- return {
- Program: () => {
- jumpTargets = [];
- },
- BreakStatement: (node: estree.Node) => {
- const breakStatement = node as estree.BreakStatement;
- increateNumberOfJumpsInScopes(breakStatement, breakStatement.label?.name);
- },
- ContinueStatement: (node: estree.Node) => {
- const continueStatement = node as estree.ContinueStatement;
- increateNumberOfJumpsInScopes(continueStatement, continueStatement.label?.name);
- },
- SwitchStatement: enterScope,
- 'SwitchStatement:exit': leaveScope,
- ForStatement: enterScope,
- 'ForStatement:exit': leaveScopeAndCheckNumberOfJumps,
- ForInStatement: enterScope,
- 'ForInStatement:exit': leaveScopeAndCheckNumberOfJumps,
- ForOfStatement: enterScope,
- 'ForOfStatement:exit': leaveScopeAndCheckNumberOfJumps,
- WhileStatement: enterScope,
- 'WhileStatement:exit': leaveScopeAndCheckNumberOfJumps,
- DoWhileStatement: enterScope,
- 'DoWhileStatement:exit': leaveScopeAndCheckNumberOfJumps,
- LabeledStatement: (node: estree.Node) => {
- const labeledStatement = node as estree.LabeledStatement;
- jumpTargets.push(new JumpTarget(labeledStatement.label.name));
- },
- 'LabeledStatement:exit': leaveScope,
- };
- },
-};
-
-class JumpTarget {
- label?: string;
- jumps: estree.Node[] = [];
-
- constructor(label?: string) {
- this.label = label;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/unicode-aware-regex.ts b/eslint-bridge/src/linting/eslint/rules/unicode-aware-regex.ts
deleted file mode 100644
index bf0e448ba0f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/unicode-aware-regex.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5867/javascript
-
-import { Rule } from 'eslint';
-import { Character, Quantifier, RegExpLiteral } from 'regexpp/ast';
-import { SourceLocation } from 'estree';
-import { toEncodedMessage } from './helpers';
-import { createRegExpRule, getRegexpLocation } from './helpers/regex';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = createRegExpRule(
- context => {
- const unicodeProperties: { character: Character; offset: number }[] = [];
- const unicodeCharacters: Quantifier[] = [];
- let rawPattern: string;
- let isUnicodeEnabled = false;
- return {
- onRegExpLiteralEnter: (node: RegExpLiteral) => {
- rawPattern = node.raw;
- isUnicodeEnabled = node.flags.unicode;
- },
- onQuantifierEnter: (quantifier: Quantifier) => {
- if (isUnicodeEnabled) {
- return;
- }
- /* \u{hhhh}, \u{hhhhh} */
- const { raw, min: hex } = quantifier;
- if (
- raw.startsWith('\\u') &&
- !raw.includes(',') &&
- ['hhhh'.length, 'hhhhh'.length].includes(hex.toString().length)
- ) {
- unicodeCharacters.push(quantifier);
- }
- },
- onCharacterEnter: (character: Character) => {
- if (isUnicodeEnabled) {
- return;
- }
- const c = character.raw;
- if (c !== '\\p' && c !== '\\P') {
- return;
- }
- let state:
- | 'start'
- | 'openingBracket'
- | 'alpha'
- | 'equal'
- | 'alpha1'
- | 'closingBracket'
- | 'end' = 'start';
- let offset = character.start + c.length;
- let nextChar: string;
- do {
- nextChar = rawPattern[offset];
- offset++;
- switch (state) {
- case 'start':
- if (nextChar === '{') {
- state = 'openingBracket';
- } else {
- state = 'end';
- }
- break;
- case 'openingBracket':
- if (/[a-zA-Z]/.test(nextChar)) {
- state = 'alpha';
- } else {
- state = 'end';
- }
- break;
- case 'alpha':
- if (/[a-zA-Z]/.test(nextChar)) {
- state = 'alpha';
- } else if (nextChar === '=') {
- state = 'equal';
- } else if (nextChar === '}') {
- state = 'closingBracket';
- } else {
- state = 'end';
- }
- break;
- case 'equal':
- if (/[a-zA-Z]/.test(nextChar)) {
- state = 'alpha1';
- } else {
- state = 'end';
- }
- break;
- case 'alpha1':
- if (/[a-zA-Z]/.test(nextChar)) {
- state = 'alpha1';
- } else if (nextChar === '}') {
- state = 'closingBracket';
- } else {
- state = 'end';
- }
- break;
- case 'closingBracket':
- state = 'end';
- unicodeProperties.push({ character, offset: offset - c.length - 1 });
- break;
- }
- } while (state !== 'end');
- },
- onRegExpLiteralLeave: (regexp: RegExpLiteral) => {
- if (!isUnicodeEnabled && (unicodeProperties.length > 0 || unicodeCharacters.length > 0)) {
- const secondaryLocations: { loc: SourceLocation }[] = [];
- const secondaryMessages: string[] = [];
- unicodeProperties.forEach(p => {
- secondaryLocations.push({
- loc: getRegexpLocation(context.node, p.character, context, [0, p.offset]),
- });
- secondaryMessages.push('Unicode property');
- });
- unicodeCharacters.forEach(c => {
- secondaryLocations.push({ loc: getRegexpLocation(context.node, c, context) });
- secondaryMessages.push('Unicode character');
- });
- context.reportRegExpNode({
- message: toEncodedMessage(
- `Enable the 'u' flag for this regex using Unicode constructs.`,
- secondaryLocations,
- secondaryMessages,
- ),
- node: context.node,
- regexpNode: regexp,
- });
- }
- },
- };
- },
- {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/unused-import.ts b/eslint-bridge/src/linting/eslint/rules/unused-import.ts
deleted file mode 100644
index 3dfedb19045..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/unused-import.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1128/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { AST } from 'vue-eslint-parser';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { isRequiredParserServices, removeNodeWithLeadingWhitespaces } from './helpers';
-
-const EXCLUDED_IMPORTS = ['React'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeUnusedImport: `Remove this unused import of '{{symbol}}'.`,
- suggestRemoveWholeStatement: `Remove this import statement`,
- suggestRemoveOneVariable: `Remove this variable import`,
- },
- hasSuggestions: true,
- },
- create(context: Rule.RuleContext) {
- const isJsxPragmaSet =
- context
- .getSourceCode()
- .getAllComments()
- .findIndex(comment => comment.value.includes('@jsx jsx')) > -1;
- const unusedImports: { id: estree.Identifier; importDecl: estree.ImportDeclaration }[] = [];
- const tsTypeIdentifiers: Set = new Set();
- const vueIdentifiers: Set = new Set();
- const saveTypeIdentifier = (node: estree.Identifier) => tsTypeIdentifiers.add(node.name);
-
- function isExcluded(variable: Scope.Variable) {
- return EXCLUDED_IMPORTS.includes(variable.name);
- }
-
- function isUnused(variable: Scope.Variable) {
- return variable.references.length === 0;
- }
-
- function isImplicitJsx(variable: Scope.Variable) {
- return variable.name === 'jsx' && isJsxPragmaSet;
- }
-
- function getJsxFactories() {
- const factories = new Set();
- const parserServices = context.parserServices;
- if (isRequiredParserServices(parserServices)) {
- const compilerOptions = parserServices.program.getCompilerOptions();
- if (compilerOptions.jsxFactory) {
- factories.add(compilerOptions.jsxFactory);
- }
- if (compilerOptions.jsxFragmentFactory) {
- factories.add(compilerOptions.jsxFragmentFactory);
- }
- }
- return factories;
- }
-
- const ruleListener = {
- ImportDeclaration: (node: estree.Node) => {
- const variables = context.getDeclaredVariables(node);
- for (const variable of variables) {
- if (!isExcluded(variable) && !isImplicitJsx(variable) && isUnused(variable)) {
- unusedImports.push({
- id: variable.identifiers[0],
- importDecl: node as estree.ImportDeclaration,
- });
- }
- }
- },
- 'TSTypeReference > Identifier, TSClassImplements > Identifier, TSInterfaceHeritage > Identifier':
- (node: estree.Node) => {
- saveTypeIdentifier(node as estree.Identifier);
- },
- "TSQualifiedName[left.type = 'Identifier']": (node: estree.Node) => {
- saveTypeIdentifier((node as any as TSESTree.TSQualifiedName).left as estree.Identifier);
- },
- "TSInterfaceHeritage > MemberExpression[object.type = 'Identifier'], TSClassImplements > MemberExpression[object.type = 'Identifier']":
- (node: estree.Node) => {
- saveTypeIdentifier(
- (node as any as TSESTree.MemberExpression).object as estree.Identifier,
- );
- },
- 'Program:exit': () => {
- const jsxFactories = getJsxFactories();
- const jsxIdentifiers = context
- .getSourceCode()
- .ast.tokens.filter(token => token.type === 'JSXIdentifier')
- .map(token => token.value);
- unusedImports
- .filter(
- ({ id: unused }) =>
- !jsxIdentifiers.includes(unused.name) &&
- !tsTypeIdentifiers.has(unused.name) &&
- !vueIdentifiers.has(unused.name) &&
- !jsxFactories.has(unused.name),
- )
- .forEach(unused =>
- context.report({
- messageId: 'removeUnusedImport',
- data: {
- symbol: unused.id.name,
- },
- node: unused.id,
- suggest: [getSuggestion(context, unused)],
- }),
- );
- },
- };
-
- // @ts-ignore
- if (context.parserServices.defineTemplateBodyVisitor) {
- return context.parserServices.defineTemplateBodyVisitor(
- {
- VElement: (node: AST.VElement) => {
- const { rawName } = node;
- if (startsWithUpper(rawName)) {
- vueIdentifiers.add(rawName);
- } else if (isKebabCase(rawName)) {
- vueIdentifiers.add(toPascalCase(rawName));
- }
- },
- Identifier: (node: AST.ESLintIdentifier) => {
- vueIdentifiers.add(node.name);
- },
- },
- ruleListener,
- { templateBodyTriggerSelector: 'Program' },
- );
- }
-
- return ruleListener;
- },
-};
-
-function startsWithUpper(str: string) {
- return str.charAt(0) === str.charAt(0).toUpperCase();
-}
-
-function isKebabCase(str: string) {
- return str.includes('-');
-}
-
-function toPascalCase(str: string) {
- return str
- .replace(/\w+/g, word => word[0].toUpperCase() + word.slice(1).toLowerCase())
- .replace(/-/g, '');
-}
-
-function getSuggestion(
- context: Rule.RuleContext,
- { id, importDecl }: { id: estree.Identifier; importDecl: estree.ImportDeclaration },
-): Rule.SuggestionReportDescriptor {
- const variables = context.getDeclaredVariables(importDecl);
- if (variables.length === 1) {
- return {
- messageId: 'suggestRemoveWholeStatement',
- fix: fixer => {
- return removeNodeWithLeadingWhitespaces(context, importDecl, fixer);
- },
- };
- }
-
- const specifiers = importDecl.specifiers;
- const unusedSpecifier = specifiers.find(specifier => specifier.local === id)!;
- const code = context.getSourceCode();
- let range: [number, number];
-
- switch (unusedSpecifier.type) {
- case 'ImportDefaultSpecifier':
- const tokenAfter = code.getTokenAfter(id)!;
- // default import is always first
- range = [id.range![0], code.getTokenAfter(tokenAfter)!.range![0]];
- break;
-
- case 'ImportNamespaceSpecifier':
- // namespace import is always second
- range = [code.getTokenBefore(unusedSpecifier)!.range![0], unusedSpecifier.range![1]];
- break;
-
- case 'ImportSpecifier':
- const simpleSpecifiers = specifiers.filter(specifier => specifier.type === 'ImportSpecifier');
- const index = simpleSpecifiers.findIndex(specifier => specifier === unusedSpecifier);
- if (simpleSpecifiers.length === 1) {
- range = [specifiers[0].range![1], code.getTokenAfter(unusedSpecifier)!.range![1]];
- } else if (index === 0) {
- range = [simpleSpecifiers[0].range![0], simpleSpecifiers[1].range![0]];
- } else {
- range = [simpleSpecifiers[index - 1].range![1], simpleSpecifiers[index].range![1]];
- }
- }
-
- return {
- messageId: 'suggestRemoveOneVariable',
- fix: fixer => {
- return fixer.removeRange(range);
- },
- };
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/unused-named-groups.ts b/eslint-bridge/src/linting/eslint/rules/unused-named-groups.ts
deleted file mode 100644
index 1434f61cba2..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/unused-named-groups.ts
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5860/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import * as regexpp from 'regexpp';
-import { Backreference, CapturingGroup, RegExpLiteral } from 'regexpp/ast';
-import {
- getLhsVariable,
- getUniqueWriteUsage,
- getValueOfExpression,
- getVariableFromName,
- isDotNotation,
- isMethodCall,
- isObjectDestructuring,
- isRequiredParserServices,
- isString,
- RequiredParserServices,
- toEncodedMessage,
-} from './helpers';
-import {
- extractReferences,
- getParsedRegex,
- getRegexpLocation,
- isStringRegexMethodCall,
- isStringReplaceCall,
-} from './helpers/regex';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- const intellisense = new RegexIntelliSense(services, context);
- return {
- 'Literal[regex]:exit': (literal: estree.Literal) => {
- /* /regex/ */
- intellisense.collectKnowledge(literal);
- },
- 'NewExpression:exit': (newExpr: estree.NewExpression) => {
- /* new RegExp(regex) */
- intellisense.collectKnowledge(newExpr);
- },
- 'CallExpression:exit': (callExpr: estree.CallExpression) => {
- /* RegExp(regex), implicit regex e.g. str.match('regex') */
- intellisense.collectKnowledge(callExpr);
- /* str.match(pattern) / pattern.exec(str) */
- intellisense.collectPatternMatcher(callExpr);
- /* str.replace(pattern, substr) */
- checkStringReplaceGroupReferences(callExpr, intellisense);
- },
- 'MemberExpression:exit': (memberExpr: estree.MemberExpression) => {
- if (memberExpr.computed) {
- /* matcher[index] */
- checkIndexBasedGroupReference(memberExpr, intellisense);
- } else {
- /* matcher.groups. / matcher.indices.groups. */
- checkNonExistingGroupReference(memberExpr, intellisense);
- }
- },
- 'Program:exit': () => {
- checkUnusedGroups(intellisense);
- checkIndexedGroups(intellisense);
- },
- };
- },
-};
-
-function checkStringReplaceGroupReferences(
- callExpr: estree.CallExpression,
- intellisense: RegexIntelliSense,
-) {
- if (isStringReplaceCall(callExpr, intellisense.services)) {
- const [pattern, substr] = callExpr.arguments;
- const regex = intellisense.findRegex(pattern);
- if (regex) {
- const references = extractReferences(substr);
- const indexes = new Set();
- const names = new Set();
- references.forEach(ref =>
- isNaN(Number(ref.value)) ? names.add(ref.value) : indexes.add(Number(ref.value)),
- );
- regex.groups.forEach(group => {
- group.used ||= names.has(group.name);
- group.used ||= indexes.has(group.index);
- });
- const indexedGroups = regex.groups.filter(group => indexes.has(group.index));
- if (indexedGroups.length > 0) {
- intellisense.context.report({
- message: toEncodedMessage(
- `Directly use the group names instead of their numbers.`,
- indexedGroups.map(group => ({
- loc: getRegexpLocation(regex.node, group.node, intellisense.context),
- })),
- indexedGroups.map(group => `Group '${group.name}'`),
- ),
- node: substr,
- });
- }
- }
- }
-}
-
-function checkIndexBasedGroupReference(
- memberExpr: estree.MemberExpression,
- intellisense: RegexIntelliSense,
-) {
- const { object: matcher, property } = memberExpr;
- const regex = intellisense.resolve(matcher);
- if (regex) {
- const maybeIndex = getValueOfExpression(intellisense.context, property, 'Literal');
- if (maybeIndex && typeof maybeIndex.value === 'number') {
- const index = maybeIndex.value;
- const group = regex.groups.find(grp => grp.index === index);
- if (group) {
- group.used = true;
- intellisense.context.report({
- message: toEncodedMessage(
- `Directly use '${group.name}' instead of its group number.`,
- [{ loc: getRegexpLocation(regex.node, group.node, intellisense.context) }],
- [`Group '${group.name}'`],
- ),
- node: property,
- });
- }
- }
- }
-}
-
-function checkNonExistingGroupReference(
- memberExpr: estree.MemberExpression,
- intellisense: RegexIntelliSense,
-) {
- const { object: matcher } = memberExpr;
- const regex = intellisense.resolve(matcher);
- if (regex) {
- /* matcher.groups. / matcher.indices.groups. */
- const groupNodes = extractGroupNodes(memberExpr, intellisense);
- for (const groupNode of groupNodes) {
- const group = regex.groups.find(grp => grp.name === groupNode.name);
- if (group) {
- group.used = true;
- } else {
- intellisense.context.report({
- message: toEncodedMessage(
- `There is no group named '${groupNode.name}' in the regular expression.`,
- regex.groups.map(grp => ({
- loc: getRegexpLocation(regex.node, grp.node, intellisense.context),
- })),
- regex.groups.map(grp => `Named group '${grp.name}'`),
- ),
- node: groupNode,
- });
- }
- }
- }
-}
-
-function extractGroupNodes(
- memberExpr: estree.MemberExpression,
- intellisense: RegexIntelliSense,
-): estree.Identifier[] {
- if (isDotNotation(memberExpr)) {
- const { property } = memberExpr;
- const ancestors = intellisense.context.getAncestors();
- let parent = ancestors.pop();
- while ((parent as TSESTree.Node).type === 'TSNonNullExpression') {
- parent = ancestors.pop();
- }
- if (parent) {
- switch (property.name) {
- case 'groups':
- /* matcher.groups. */
- return extractNamedOrDestructuredGroupNodes(parent);
- case 'indices':
- /* matcher.indices.groups. */
- if (isDotNotation(parent) && parent.property.name === 'groups') {
- parent = ancestors.pop();
- if (parent) {
- return extractNamedOrDestructuredGroupNodes(parent);
- }
- }
- }
- }
- }
- return [];
-}
-
-function extractNamedOrDestructuredGroupNodes(node: estree.Node): estree.Identifier[] {
- if (isDotNotation(node)) {
- /* matcher.groups. */
- return [node.property];
- } else if (isObjectDestructuring(node)) {
- /* { ,.. } = matcher.groups */
- const destructuredGroups: estree.Identifier[] = [];
- const pattern = node.type === 'VariableDeclarator' ? node.id : node.left;
- for (const property of pattern.properties) {
- if (property.type === 'Property' && property.key.type === 'Identifier') {
- destructuredGroups.push(property.key);
- }
- }
- return destructuredGroups;
- } else {
- return [];
- }
-}
-
-function checkUnusedGroups(intellisense: RegexIntelliSense) {
- intellisense.getKnowledge().forEach(regex => {
- if (regex.matched) {
- const unusedGroups = regex.groups.filter(group => !group.used);
- if (unusedGroups.length) {
- intellisense.context.report({
- message: toEncodedMessage(
- 'Use the named groups of this regex or remove the names.',
- unusedGroups.map(grp => ({
- loc: getRegexpLocation(regex.node, grp.node, intellisense.context),
- })),
- unusedGroups.map(grp => `Named group '${grp.name}'`),
- ),
- node: regex.node,
- });
- }
- }
- });
-}
-
-function checkIndexedGroups(intellisense: RegexIntelliSense) {
- intellisense.getKnowledge().forEach(regex => {
- regex.groups.forEach(group =>
- group.node.references.forEach(reference => {
- if (typeof reference.ref === 'number') {
- intellisense.context.report({
- message: toEncodedMessage(
- `Directly use '${group.name}' instead of its group number.`,
- [{ loc: getRegexpLocation(regex.node, group.node, intellisense.context) }],
- [`Group '${group.name}'`],
- ),
- loc: getRegexpLocation(regex.node, reference, intellisense.context),
- });
- }
- }),
- );
- });
-}
-
-interface RegexKnowledge {
- node: estree.Node;
- regexp: RegExpLiteral;
- groups: GroupKnowledge[];
- matched: boolean;
-}
-
-interface GroupKnowledge {
- node: CapturingGroup;
- name: string;
- used: boolean;
- index: number;
-}
-
-function makeRegexKnowledge(node: estree.Node, regexp: RegExpLiteral): RegexKnowledge {
- const capturingGroups: CapturingGroup[] = [];
- const backreferences: Backreference[] = [];
- regexpp.visitRegExpAST(regexp, {
- onBackreferenceEnter: reference => reference.resolved.name && backreferences.push(reference),
- onCapturingGroupEnter: group => capturingGroups.push(group),
- });
- const groups: GroupKnowledge[] = [];
- capturingGroups.forEach(
- (group, index) =>
- group.name && groups.push(makeGroupKnowledge(group, backreferences, index + 1)),
- );
- return { node, regexp, groups, matched: false };
-}
-
-function makeGroupKnowledge(
- node: CapturingGroup,
- backreferences: Backreference[],
- index: number,
-): GroupKnowledge {
- const name = node.name!;
- const used = backreferences.some(backreference => backreference.resolved === node);
- return { node, name, used, index };
-}
-
-class RegexIntelliSense {
- private readonly knowledge: RegexKnowledge[] = [];
- private readonly bindings = new Map();
-
- constructor(readonly services: RequiredParserServices, readonly context: Rule.RuleContext) {}
-
- getKnowledge() {
- return this.knowledge;
- }
-
- collectKnowledge(node: estree.Node) {
- let regexNode = node;
- if (node.type === 'CallExpression' && isStringRegexMethodCall(node, this.services)) {
- /* implicit regex */
- regexNode = node.arguments[0];
- }
- const regex = getParsedRegex(regexNode, this.context);
- if (regex !== null) {
- this.knowledge.push(makeRegexKnowledge(regexNode, regex));
- }
- }
-
- collectPatternMatcher(callExpr: estree.CallExpression) {
- const { callee, arguments: args } = callExpr;
- if (isMethodCall(callExpr) && args.length > 0) {
- const target = (callee as estree.MemberExpression).object;
- const matcher = getLhsVariable(this.context);
- if (matcher) {
- const method = (callee as estree.MemberExpression).property as estree.Identifier;
- if (isString(target, this.services) && ['match', 'matchAll'].includes(method.name)) {
- /* str.match(pattern) */
- const [pattern] = args;
- this.bind(pattern, matcher);
- } else if (method.name === 'exec' && isString(args[0], this.services)) {
- /* pattern.exec(str) */
- const pattern = target;
- this.bind(pattern, matcher);
- }
- }
- }
- }
-
- resolve(matcher: estree.Node): RegexKnowledge | null {
- const variable = this.findVariable(matcher);
- if (variable) {
- return this.bindings.get(variable) || null;
- } else {
- return null;
- }
- }
-
- findRegex(node: estree.Node): RegexKnowledge | undefined {
- return this.findRegexRec(node, new Set());
- }
-
- private findRegexRec(node: estree.Node, visited: Set): RegexKnowledge | undefined {
- if (!visited.has(node)) {
- visited.add(node);
- const variable = this.findVariable(node);
- if (variable) {
- const value = getUniqueWriteUsage(this.context, variable.name);
- if (value) {
- const regex = this.findRegexRec(value, visited);
- if (regex) {
- return regex;
- }
- }
- }
- }
- return this.knowledge.find(regex => regex.node === node);
- }
-
- private bind(pattern: estree.Node, matcher: Scope.Variable) {
- const regex = this.findRegex(pattern);
- if (regex) {
- regex.matched = true;
- this.bindings.set(matcher, regex);
- }
- }
-
- private findVariable(node: estree.Node) {
- if (node.type === 'Identifier') {
- return getVariableFromName(this.context, node.name);
- }
- return null;
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/unverified-certificate.ts b/eslint-bridge/src/linting/eslint/rules/unverified-certificate.ts
deleted file mode 100644
index a2121819bad..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/unverified-certificate.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4830/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getValueOfExpression,
- getPropertyWithValue,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const MESSAGE = 'Enable server certificate validation on this SSL/TLS connection.';
- const SECONDARY_MESSAGE = 'Set "rejectUnauthorized" to "true".';
- function checkSensitiveArgument(
- callExpression: estree.CallExpression,
- sensitiveArgumentIndex: number,
- ) {
- if (callExpression.arguments.length < sensitiveArgumentIndex + 1) {
- return;
- }
- const sensitiveArgument = callExpression.arguments[sensitiveArgumentIndex];
- const secondaryLocations: estree.Node[] = [];
- const secondaryMessages: (string | undefined)[] = [];
- const argumentValue = getValueOfExpression(context, sensitiveArgument, 'ObjectExpression');
- if (!argumentValue) {
- return;
- }
- if (sensitiveArgument !== argumentValue) {
- secondaryLocations.push(argumentValue);
- secondaryMessages.push(undefined);
- }
- const unsafeRejectUnauthorizedConfiguration = getPropertyWithValue(
- context,
- argumentValue,
- 'rejectUnauthorized',
- false,
- );
- if (unsafeRejectUnauthorizedConfiguration) {
- secondaryLocations.push(unsafeRejectUnauthorizedConfiguration);
- secondaryMessages.push(SECONDARY_MESSAGE);
- context.report({
- node: callExpression.callee,
- message: toEncodedMessage(MESSAGE, secondaryLocations, secondaryMessages),
- });
- }
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- if (fqn === 'https.request') {
- checkSensitiveArgument(callExpression, 0);
- }
- if (fqn === 'request.get') {
- checkSensitiveArgument(callExpression, 0);
- }
- if (fqn === 'tls.connect') {
- checkSensitiveArgument(callExpression, 2);
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/unverified-hostname.ts b/eslint-bridge/src/linting/eslint/rules/unverified-hostname.ts
deleted file mode 100644
index fc5e9e8092f..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/unverified-hostname.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5667/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getValueOfExpression,
- getPropertyWithValue,
- getObjectExpressionProperty,
- toEncodedMessage,
- getFullyQualifiedName,
-} from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-import { childrenOf } from 'linting/eslint';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const MESSAGE = 'Enable server hostname verification on this SSL/TLS connection.';
- const SECONDARY_MESSAGE = 'Set "rejectUnauthorized" to "true".';
- function checkSensitiveArgument(
- callExpression: estree.CallExpression,
- sensitiveArgumentIndex: number,
- ) {
- if (callExpression.arguments.length < sensitiveArgumentIndex + 1) {
- return;
- }
- const sensitiveArgument = callExpression.arguments[sensitiveArgumentIndex];
- const secondaryLocations: estree.Node[] = [];
- const secondaryMessages: (string | undefined)[] = [];
- let shouldReport = false;
- const argumentValue = getValueOfExpression(context, sensitiveArgument, 'ObjectExpression');
- if (!argumentValue) {
- return;
- }
- if (sensitiveArgument !== argumentValue) {
- secondaryLocations.push(argumentValue);
- secondaryMessages.push(undefined);
- }
- const unsafeRejectUnauthorizedConfiguration = getPropertyWithValue(
- context,
- argumentValue,
- 'rejectUnauthorized',
- false,
- );
- if (unsafeRejectUnauthorizedConfiguration) {
- secondaryLocations.push(unsafeRejectUnauthorizedConfiguration);
- secondaryMessages.push(SECONDARY_MESSAGE);
- shouldReport = true;
- }
- const checkServerIdentityProperty = getObjectExpressionProperty(
- argumentValue,
- 'checkServerIdentity',
- );
- if (
- checkServerIdentityProperty &&
- shouldReportOnCheckServerIdentityCallBack(checkServerIdentityProperty)
- ) {
- secondaryLocations.push(checkServerIdentityProperty);
- secondaryMessages.push(undefined);
- shouldReport = true;
- }
- if (shouldReport) {
- context.report({
- node: callExpression.callee,
- message: toEncodedMessage(MESSAGE, secondaryLocations, secondaryMessages),
- });
- }
- }
-
- function shouldReportOnCheckServerIdentityCallBack(
- checkServerIdentityProperty: estree.Property,
- ) {
- let baseFunction: estree.BaseFunction | undefined;
- baseFunction = getValueOfExpression(
- context,
- checkServerIdentityProperty.value,
- 'FunctionExpression',
- );
- if (!baseFunction) {
- baseFunction = getValueOfExpression(
- context,
- checkServerIdentityProperty.value,
- 'ArrowFunctionExpression',
- );
- }
- if (baseFunction?.body.type === 'BlockStatement') {
- const returnStatements = ReturnStatementsVisitor.getReturnStatements(
- baseFunction.body,
- context,
- );
- if (
- returnStatements.length === 0 ||
- returnStatements.every(r => {
- return (
- !r.argument || getValueOfExpression(context, r.argument, 'Literal')?.value === true
- );
- })
- ) {
- return true;
- }
- }
- return false;
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- if (fqn === 'https.request') {
- checkSensitiveArgument(callExpression, 0);
- }
- if (fqn === 'request.get') {
- checkSensitiveArgument(callExpression, 0);
- }
- if (fqn === 'tls.connect') {
- checkSensitiveArgument(callExpression, 2);
- }
- },
- };
- },
-};
-
-class ReturnStatementsVisitor {
- private readonly returnStatements: estree.ReturnStatement[] = [];
-
- static getReturnStatements(node: estree.Node, context: Rule.RuleContext) {
- const visitor = new ReturnStatementsVisitor();
- visitor.visit(node, context);
- return visitor.returnStatements;
- }
-
- private visit(root: estree.Node, context: Rule.RuleContext) {
- const visitNode = (node: estree.Node) => {
- switch (node.type) {
- case 'ReturnStatement':
- this.returnStatements.push(node);
- break;
- case 'FunctionDeclaration':
- case 'FunctionExpression':
- case 'ArrowFunctionExpression':
- return;
- }
- childrenOf(node, context.getSourceCode().visitorKeys).forEach(visitNode);
- };
- visitNode(root);
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/updated-const-var.ts b/eslint-bridge/src/linting/eslint/rules/updated-const-var.ts
deleted file mode 100644
index 55797e8724b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/updated-const-var.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3500/javascript
-
-import { Rule, Scope } from 'eslint';
-import * as estree from 'estree';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- return {
- 'VariableDeclaration[kind="const"]': (node: estree.Node) => {
- context.getDeclaredVariables(node).forEach(variable =>
- variable.references.filter(isModifyingReference).forEach(reference =>
- context.report({
- message: toEncodedMessage(
- `Correct this attempt to modify "${reference.identifier.name}" or use "let" in its declaration.`,
- [node],
- ['Const declaration'],
- ),
- node: reference.identifier,
- }),
- ),
- );
- },
- };
- },
-};
-
-function isModifyingReference(
- reference: Scope.Reference,
- index: number,
- references: Scope.Reference[],
-) {
- const identifier = reference.identifier;
- const modifyingDifferentIdentifier =
- index === 0 || references[index - 1].identifier !== identifier;
- return (
- identifier && reference.init === false && reference.isWrite() && modifyingDifferentIdentifier
- );
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/updated-loop-counter.ts b/eslint-bridge/src/linting/eslint/rules/updated-loop-counter.ts
deleted file mode 100644
index a047d31fe75..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/updated-loop-counter.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2310/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage, getVariableFromName, resolveIdentifiers, getParent } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
-
- create(context: Rule.RuleContext) {
- function checkLoop(
- updateNode: T,
- extractCounters: (updateNode: T, counters: estree.Identifier[]) => void,
- loopBody: estree.Node,
- ) {
- const counters: estree.Identifier[] = [];
- extractCounters(updateNode, counters);
- counters.forEach(counter => checkCounter(counter, loopBody as estree.BlockStatement));
- }
-
- function checkCounter(counter: estree.Identifier, block: estree.Node) {
- const variable = getVariableFromName(context, counter.name);
- if (!variable) {
- return;
- }
- variable.references.forEach(ref => {
- if (ref.isWrite() && isUsedInsideBody(ref.identifier, block)) {
- context.report({
- node: ref.identifier,
- message: toEncodedMessage(
- `Remove this assignment of "${counter.name}".`,
- [counter as TSESTree.Node],
- ['Counter variable update'],
- ),
- });
- }
- });
- }
-
- return {
- 'ForStatement > BlockStatement': (node: estree.Node) => {
- const forLoop = getParent(context) as estree.ForStatement;
- if (forLoop.update) {
- checkLoop(forLoop.update, collectCountersFor, node);
- }
- },
- 'ForInStatement > BlockStatement, ForOfStatement > BlockStatement': (node: estree.Node) => {
- const { left } = getParent(context) as estree.ForOfStatement | estree.ForInStatement;
- checkLoop(left, collectCountersForX, node);
- },
- };
- },
-};
-
-function collectCountersForX(
- updateExpression: estree.Pattern | estree.VariableDeclaration,
- counters: estree.Identifier[],
-) {
- if (updateExpression.type === 'VariableDeclaration') {
- updateExpression.declarations.forEach(decl => collectCountersForX(decl.id, counters));
- } else {
- resolveIdentifiers(updateExpression as TSESTree.Node, true).forEach(id => counters.push(id));
- }
-}
-
-function collectCountersFor(updateExpression: estree.Expression, counters: estree.Identifier[]) {
- let counter: estree.Node | null | undefined = undefined;
-
- if (updateExpression.type === 'AssignmentExpression') {
- counter = updateExpression.left;
- } else if (updateExpression.type === 'UpdateExpression') {
- counter = updateExpression.argument;
- } else if (updateExpression.type === 'SequenceExpression') {
- updateExpression.expressions.forEach(e => collectCountersFor(e, counters));
- }
-
- if (counter && counter.type === 'Identifier') {
- counters.push(counter);
- }
-}
-
-function isUsedInsideBody(id: estree.Identifier, loopBody: estree.Node) {
- const bodyRange = loopBody.range;
- return id.range && bodyRange && id.range[0] > bodyRange[0] && id.range[1] < bodyRange[1];
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/use-type-alias.ts b/eslint-bridge/src/linting/eslint/rules/use-type-alias.ts
deleted file mode 100644
index ecf98af2dd1..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/use-type-alias.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4323/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { toEncodedMessage } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const TYPE_THRESHOLD = 2;
-const USAGE_THRESHOLD = 2;
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- let usage: Map;
- return {
- Program: () => (usage = new Map()),
- 'Program:exit': () =>
- usage.forEach(nodes => {
- if (nodes.length > USAGE_THRESHOLD) {
- const [node, ...rest] = nodes;
- const kind = node.type === 'TSUnionType' ? 'union' : 'intersection';
- const message = toEncodedMessage(
- `Replace this ${kind} type with a type alias.`,
- rest,
- Array(rest.length).fill('Following occurrence.'),
- );
- context.report({ message, loc: node.loc });
- }
- }),
- 'TSUnionType, TSIntersectionType': (node: estree.Node) => {
- const ancestors = context.getAncestors();
- const declaration = ancestors.find(
- ancestor => (ancestor as TSESTree.Node).type === 'TSTypeAliasDeclaration',
- );
- if (!declaration) {
- const composite = node as unknown as TSESTree.TSUnionType | TSESTree.TSIntersectionType;
- if (composite.types.length > TYPE_THRESHOLD) {
- const text = composite.types
- .map(typeNode => context.getSourceCode().getText(typeNode as unknown as estree.Node))
- .sort((a, b) => a.localeCompare(b))
- .join('|');
- let occurrences = usage.get(text);
- if (!occurrences) {
- occurrences = [composite];
- usage.set(text, occurrences);
- } else {
- occurrences.push(composite);
- }
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/useless-string-operation.ts b/eslint-bridge/src/linting/eslint/rules/useless-string-operation.ts
deleted file mode 100644
index 57d7455583b..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/useless-string-operation.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S1154/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import { isRequiredParserServices, getTypeFromTreeNode } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- uselessStringOp:
- '{{symbol}} is an immutable object; you must either store or return the result of the operation.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- function isString(node: estree.Node) {
- const type = getTypeFromTreeNode(node, services);
- return (type.flags & ts.TypeFlags.StringLike) !== 0;
- }
-
- function getVariable(node: estree.Node) {
- let variable = context.getSourceCode().getText(node);
- if (variable.length > 30) {
- variable = 'String';
- }
- return variable;
- }
-
- return {
- 'ExpressionStatement > CallExpression[callee.type="MemberExpression"]': (
- node: estree.Node,
- ) => {
- const { object, property } = (node as estree.CallExpression)
- .callee as estree.MemberExpression;
- if (isString(object) && property.type === 'Identifier') {
- context.report({
- messageId: 'uselessStringOp',
- data: {
- symbol: getVariable(object),
- },
- node: property,
- });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/values-not-convertible-to-numbers.ts b/eslint-bridge/src/linting/eslint/rules/values-not-convertible-to-numbers.ts
deleted file mode 100644
index 1d2802f53cd..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/values-not-convertible-to-numbers.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3758/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import * as ts from 'typescript';
-import {
- isRequiredParserServices,
- RequiredParserServices,
- getTypeFromTreeNode,
- isStringType,
-} from './helpers';
-
-const comparisonOperators = new Set(['>', '<', '>=', '<=']);
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- reEvaluateDataFlow:
- 'Re-evaluate the data flow; this operand of a numeric comparison could be of type {{type}}.',
- },
- },
- create(context: Rule.RuleContext) {
- const services: RequiredParserServices = context.parserServices;
-
- if (!isRequiredParserServices(services)) {
- return {};
- }
-
- return {
- BinaryExpression(node: estree.Node) {
- const { left, operator, right } = node as estree.BinaryExpression;
- if (!comparisonOperators.has(operator)) {
- return;
- }
- if (left.type === 'MemberExpression' || right.type === 'MemberExpression') {
- // avoid FPs on field access
- return;
- }
- const checker = services.program.getTypeChecker();
- const leftType = getTypeFromTreeNode(left, services);
- const rightType = getTypeFromTreeNode(right, services);
- if (isStringType(leftType) || isStringType(rightType)) {
- return;
- }
-
- const isLeftConvertibleToNumber = isConvertibleToNumber(leftType, checker);
- const isRightConvertibleToNumber = isConvertibleToNumber(rightType, checker);
- if (!isLeftConvertibleToNumber) {
- context.report({
- messageId: 'reEvaluateDataFlow',
- data: {
- type: checker.typeToString(leftType),
- },
- node: left,
- });
- }
- if (!isRightConvertibleToNumber) {
- context.report({
- messageId: 'reEvaluateDataFlow',
- data: {
- type: checker.typeToString(rightType),
- },
- node: right,
- });
- }
- },
- };
- },
-};
-
-function isConvertibleToNumber(typ: ts.Type, checker: ts.TypeChecker) {
- const flags = typ.getFlags();
- if ((flags & ts.TypeFlags.BooleanLike) !== 0) {
- return true;
- }
- if ((flags & ts.TypeFlags.Undefined) !== 0) {
- return false;
- }
- const valueOfSignatures = getValueOfSignatures(typ, checker);
- return (
- valueOfSignatures.length === 0 ||
- valueOfSignatures.some(signature => isNumberLike(signature.getReturnType()))
- );
-}
-
-function getValueOfSignatures(typ: ts.Type, checker: ts.TypeChecker) {
- const valueOfSymbol = typ.getProperty('valueOf');
- if (!valueOfSymbol) {
- return [];
- }
- const declarations = valueOfSymbol.getDeclarations() || [];
- return declarations
- .map(declaration => checker.getTypeAtLocation(declaration).getCallSignatures())
- .reduce((result, decl) => result.concat(decl), []);
-}
-
-function isNumberLike(typ: ts.Type) {
- return (typ.getFlags() & ts.TypeFlags.NumberLike) !== 0;
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/variable-name.ts b/eslint-bridge/src/linting/eslint/rules/variable-name.ts
deleted file mode 100644
index 5931bacbf30..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/variable-name.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S117/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { resolveIdentifiers } from './helpers';
-
-interface FunctionLike {
- declare?: boolean;
- params: TSESTree.Parameter[];
-}
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- renameSymbol: `Rename this {{symbolType}} "{{symbol}}" to match the regular expression {{format}}.`,
- },
- },
- create(context: Rule.RuleContext) {
- return {
- VariableDeclaration: (node: estree.Node) =>
- checkVariable(node as TSESTree.VariableDeclaration, context),
- 'FunctionDeclaration, FunctionExpression, ArrowFunctionExpression, TSDeclareFunction, TSMethodSignature, TSConstructSignatureDeclaration, TSEmptyBodyFunctionExpression':
- (node: estree.Node) => checkFunction(node as FunctionLike, context),
- PropertyDefinition: (node: estree.Node) =>
- checkProperty(node as unknown as TSESTree.PropertyDefinition, context),
- CatchClause: (node: estree.Node) => checkCatch(node as TSESTree.CatchClause, context),
- };
- },
-};
-
-function checkVariable(decl: TSESTree.VariableDeclaration, context: Rule.RuleContext) {
- if (decl.declare) {
- return;
- }
- decl.declarations.forEach(declaration =>
- resolveIdentifiers(declaration.id).forEach(id =>
- raiseOnInvalidIdentifier(id, 'local variable', context),
- ),
- );
-}
-
-function checkFunction(func: FunctionLike, context: Rule.RuleContext) {
- if (func.declare) {
- return;
- }
- func.params.forEach(param =>
- resolveIdentifiers(param).forEach(id => raiseOnInvalidIdentifier(id, 'parameter', context)),
- );
-}
-
-function checkProperty(prop: TSESTree.PropertyDefinition, context: Rule.RuleContext) {
- if (prop.key.type === 'Identifier') {
- raiseOnInvalidIdentifier(prop.key, 'property', context);
- }
-}
-
-function checkCatch(catchh: TSESTree.CatchClause, context: Rule.RuleContext) {
- if (catchh.param) {
- resolveIdentifiers(catchh.param).forEach(id =>
- raiseOnInvalidIdentifier(id, 'parameter', context),
- );
- }
-}
-
-function raiseOnInvalidIdentifier(
- id: TSESTree.Identifier,
- idType: string,
- context: Rule.RuleContext,
-) {
- const [{ format }] = context.options;
- const { name } = id;
- if (!name.match(format)) {
- context.report({
- messageId: 'renameSymbol',
- data: {
- symbol: name,
- symbolType: idType,
- format,
- },
- node: id,
- });
- }
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/void-use.ts b/eslint-bridge/src/linting/eslint/rules/void-use.ts
deleted file mode 100644
index 37a4f8ab0bb..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/void-use.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S3735/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { isRequiredParserServices, isThenable } from './helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- removeVoid: 'Remove this use of the "void" operator.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- function checkNode(node: estree.Node) {
- const unaryExpression: estree.UnaryExpression = node as estree.UnaryExpression;
- if (isVoid0(unaryExpression) || isIIFE(unaryExpression) || isPromiseLike(unaryExpression)) {
- return;
- }
- const operatorToken = context.getSourceCode().getTokenBefore(unaryExpression.argument);
- context.report({
- loc: operatorToken!.loc, // cannot be null due to previous checks
- messageId: 'removeVoid',
- });
- }
-
- function isVoid0(expr: estree.UnaryExpression) {
- return expr.argument.type === 'Literal' && 0 === expr.argument.value;
- }
-
- function isIIFE(expr: estree.UnaryExpression) {
- return (
- expr.argument.type === 'CallExpression' &&
- ['ArrowFunctionExpression', 'FunctionExpression'].includes(expr.argument.callee.type)
- );
- }
-
- function isPromiseLike(expr: estree.UnaryExpression) {
- return isRequiredParserServices(services) && isThenable(expr.argument, services);
- }
-
- return {
- 'UnaryExpression[operator="void"]': checkNode,
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/weak-ssl.aws.ts b/eslint-bridge/src/linting/eslint/rules/weak-ssl.aws.ts
deleted file mode 100644
index 029bcf4875e..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/weak-ssl.aws.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4423/javascript
-
-import { Rule } from 'eslint';
-import { AwsCdkCheckArguments, AwsCdkTemplate } from './helpers/aws/cdk';
-
-export const rule: Rule.RuleModule = AwsCdkTemplate(
- {
- 'aws_cdk_lib.aws_apigateway.CfnDomainName': AwsCdkCheckArguments(
- 'AWSApiGateway',
- true,
- 'securityPolicy',
- { primitives: { valid: ['TLS_1_2'] } },
- ),
- 'aws_cdk_lib.aws_apigateway.DomainName': AwsCdkCheckArguments(
- 'AWSApiGateway',
- false,
- 'securityPolicy',
- { fqns: { valid: ['aws_cdk_lib.aws_apigateway.SecurityPolicy.TLS_1_2'] } },
- ),
- 'aws_cdk_lib.aws_elasticsearch.CfnDomain': AwsCdkCheckArguments(
- ['AWSOpenElasticSearch', 'enforceTLS12'],
- true,
- ['domainEndpointOptions', 'tlsSecurityPolicy'],
- {
- primitives: { valid: ['Policy-Min-TLS-1-2-2019-07'] },
- },
- ),
- 'aws_cdk_lib.aws_opensearchservice.Domain': AwsCdkCheckArguments(
- ['AWSOpenElasticSearch', 'enforceTLS12'],
- true,
- 'tlsSecurityPolicy',
- {
- fqns: { valid: ['aws_cdk_lib.aws_opensearchservice.TLSSecurityPolicy.TLS_1_2'] },
- },
- ),
- 'aws_cdk_lib.aws_opensearchservice.CfnDomain': AwsCdkCheckArguments(
- ['AWSOpenElasticSearch', 'enforceTLS12'],
- true,
- ['domainEndpointOptions', 'tlsSecurityPolicy'],
- {
- primitives: { valid: ['Policy-Min-TLS-1-2-2019-07'] },
- },
- ),
- 'aws_cdk_lib.aws_elasticsearch.Domain': AwsCdkCheckArguments(
- ['AWSOpenElasticSearch', 'enforceTLS12'],
- true,
- 'tlsSecurityPolicy',
- {
- fqns: { valid: ['aws_cdk_lib.aws_elasticsearch.TLSSecurityPolicy.TLS_1_2'] },
- },
- ),
- },
- {
- meta: {
- messages: {
- enforceTLS12: 'Change this code to enforce TLS 1.2 or above.',
- AWSApiGateway: 'Change this code to enforce TLS 1.2 or above.',
- AWSOpenElasticSearch:
- 'Omitting "tlsSecurityPolicy" enables a deprecated version of TLS. Set it to enforce TLS 1.2 or above. Change this code to enforce TLS 1.2 or above.',
- },
- },
- },
-);
diff --git a/eslint-bridge/src/linting/eslint/rules/weak-ssl.lib.ts b/eslint-bridge/src/linting/eslint/rules/weak-ssl.lib.ts
deleted file mode 100644
index 129649170cc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/weak-ssl.lib.ts
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4423/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- getObjectExpressionProperty,
- getValueOfExpression,
- getFullyQualifiedName,
-} from './helpers';
-
-const SECURE_PROTOCOL_ALLOWED_VALUES = [
- 'TLSv1_2_method',
- 'TLSv1_2_client_method',
- 'TLSv1_2_server_method',
- 'TLS_method',
- 'TLS_client_method',
- 'TLS_server_method',
-];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- useMinimumTLS: "Change '{{option}}' to use at least TLS v1.2.",
- useSecureTLS: "Change '{{option}}' to allow only secure TLS versions.",
- AWSApiGateway: 'Change this code to enforce TLS 1.2 or above.',
- AWSOpenElasticSearch:
- 'Omitting "tlsSecurityPolicy" enables a deprecated version of TLS. Set it to enforce TLS 1.2 or above. Change this code to enforce TLS 1.2 or above.',
- },
- },
- create(context: Rule.RuleContext) {
- function getValueOfProperty(
- objectExpression: estree.ObjectExpression | undefined,
- propertyName: string,
- ) {
- const unsafeProperty = getObjectExpressionProperty(objectExpression, propertyName);
- if (unsafeProperty) {
- return getValueOfExpression(context, unsafeProperty.value, 'Literal');
- }
- return undefined;
- }
-
- function checkMinMaxVersion(propertyName: string, property: estree.Literal | undefined) {
- if (property && (property.value === 'TLSv1.1' || property.value === 'TLSv1')) {
- context.report({
- node: property,
- messageId: 'useMinimumTLS',
- data: {
- option: propertyName,
- },
- });
- }
- }
-
- function checkSslOptions(optionsNode: estree.Node | undefined) {
- const options = getValueOfExpression(context, optionsNode, 'ObjectExpression');
- const minVersion = getValueOfProperty(options, 'minVersion');
- const maxVersion = getValueOfProperty(options, 'maxVersion');
- checkMinMaxVersion('minVersion', minVersion);
- checkMinMaxVersion('maxVersion', maxVersion);
-
- const secureProtocol = getValueOfProperty(options, 'secureProtocol');
- const secureProtocolValue = secureProtocol?.value?.toString() ?? '';
- if (secureProtocol && !SECURE_PROTOCOL_ALLOWED_VALUES.includes(secureProtocolValue)) {
- context.report({
- node: secureProtocol,
- messageId: 'useMinimumTLS',
- data: {
- option: 'secureProtocol',
- },
- });
- }
-
- const secureOptions = getObjectExpressionProperty(options, 'secureOptions');
- if (secureOptions && !isValidSecureOptions(secureOptions.value)) {
- context.report({
- node: secureOptions,
- messageId: 'useSecureTLS',
- data: {
- option: 'secureOptions',
- },
- });
- }
- }
-
- function isValidSecureOptions(options: estree.Node) {
- const flags: string[] = [];
- collectIdentifiersFromBinary(options, flags);
- return (
- flags[0] === null ||
- (flags.includes('SSL_OP_NO_TLSv1') && flags.includes('SSL_OP_NO_TLSv1_1'))
- );
- }
-
- function collectIdentifiersFromBinary(node: estree.Node, acc: (string | null)[]) {
- if (node.type === 'BinaryExpression') {
- collectIdentifiersFromBinary(node.left, acc);
- collectIdentifiersFromBinary(node.right, acc);
- } else if (
- node.type === 'MemberExpression' &&
- getFullyQualifiedName(context, node.object) === 'constants' &&
- node.property.type === 'Identifier'
- ) {
- acc.push(node.property.name);
- } else {
- // if part of expression is some complex node like function call, we set null on index 0
- acc[0] = null;
- }
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const fqn = getFullyQualifiedName(context, callExpression);
- // https://nodejs.org/api/https.html#https_https_get_options_callback
- if (fqn === 'https.request') {
- checkSslOptions(callExpression.arguments[0]);
- checkSslOptions(callExpression.arguments[1]);
- }
- // https://github.com/request/request#tlsssl-protocol
- if (fqn === 'request.get') {
- checkSslOptions(callExpression.arguments[0]);
- }
- // https://nodejs.org/api/tls.html#tls_tls_connect_options_callback
- if (fqn === 'tls.connect') {
- checkSslOptions(callExpression.arguments[0]);
- checkSslOptions(callExpression.arguments[1]);
- checkSslOptions(callExpression.arguments[2]);
- }
- // https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options
- if (fqn === 'tls.createSecureContext') {
- checkSslOptions(callExpression.arguments[0]);
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/weak-ssl.ts b/eslint-bridge/src/linting/eslint/rules/weak-ssl.ts
deleted file mode 100644
index 282818b3ecc..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/weak-ssl.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4423/javascript
-
-import { Rule } from 'eslint';
-import { rule as librariesRule } from './weak-ssl.lib';
-import { rule as awsRule } from './weak-ssl.aws';
-import { mergeRules } from './decorators/helpers';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: { ...librariesRule.meta!.messages, ...awsRule.meta!.messages },
- },
- create(context: Rule.RuleContext) {
- return mergeRules(librariesRule.create(context), awsRule.create(context));
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/web-sql-database.ts b/eslint-bridge/src/linting/eslint/rules/web-sql-database.ts
deleted file mode 100644
index 842f46608ec..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/web-sql-database.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2817/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isIdentifier,
- isRequiredParserServices,
- getSymbolAtLocation,
- getTypeAsString,
-} from './helpers';
-
-const OPEN_DATABASE = 'openDatabase';
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- convertWebSQLUse: 'Convert this use of a Web SQL database to another technology.',
- },
- },
- create(context: Rule.RuleContext) {
- const services = context.parserServices;
- if (!isRequiredParserServices(services)) {
- return {};
- }
- return {
- CallExpression: (node: estree.Node) => {
- const callExpression = node as estree.CallExpression;
- const { callee } = callExpression;
- const symbol = getSymbolAtLocation(callee, services);
- if (!!symbol) {
- return;
- }
- if (isIdentifier(callee, OPEN_DATABASE)) {
- context.report({ node: callee, messageId: 'convertWebSQLUse' });
- }
- if (callee.type !== 'MemberExpression' || !isIdentifier(callee.property, OPEN_DATABASE)) {
- return;
- }
- const typeName = getTypeAsString(callee.object, services);
- if (typeName.match(/window/i) || typeName.match(/globalThis/i)) {
- context.report({ node: callee, messageId: 'convertWebSQLUse' });
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/x-powered-by.ts b/eslint-bridge/src/linting/eslint/rules/x-powered-by.ts
deleted file mode 100644
index 3259d656084..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/x-powered-by.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5689/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { Express, isMethodInvocation, getFullyQualifiedName } from './helpers';
-
-const HELMET = 'helmet';
-const HIDE_POWERED_BY = 'hide-powered-by';
-const HEADER_X_POWERED_BY = 'X-Powered-By'.toLowerCase();
-const PROTECTING_MIDDLEWARES = [HELMET, HIDE_POWERED_BY];
-/** Expected number of arguments in `app.set`. */
-const APP_SET_NUM_ARGS = 2;
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- disclosingFingerprinting:
- 'Make sure disclosing the fingerprinting of this web technology is safe here.',
- },
- },
- create(context: Rule.RuleContext) {
- let appInstantiation: estree.Identifier | null = null;
- let isSafe = false;
- return {
- Program() {
- appInstantiation = null;
- isSafe = false;
- },
- CallExpression: (node: estree.Node) => {
- if (!isSafe && appInstantiation) {
- const callExpr = node as estree.CallExpression;
- isSafe =
- Express.isUsingMiddleware(context, callExpr, appInstantiation, isProtecting(context)) ||
- isDisabledXPoweredBy(callExpr, appInstantiation) ||
- isSetFalseXPoweredBy(callExpr, appInstantiation) ||
- isAppEscaping(callExpr, appInstantiation);
- }
- },
- VariableDeclarator: (node: estree.Node) => {
- if (!isSafe && !appInstantiation) {
- const varDecl = node as estree.VariableDeclarator;
- const app = Express.attemptFindAppInstantiation(varDecl, context);
- if (app) {
- appInstantiation = app;
- }
- }
- },
- ReturnStatement: (node: estree.Node) => {
- if (!isSafe && appInstantiation) {
- const ret = node as estree.ReturnStatement;
- isSafe = isAppEscapingThroughReturn(ret, appInstantiation);
- }
- },
- 'Program:exit'() {
- if (!isSafe && appInstantiation) {
- context.report({
- node: appInstantiation,
- messageId: 'disclosingFingerprinting',
- });
- }
- },
- };
- },
-};
-
-/**
- * Checks whether node looks like `helmet.hidePoweredBy()`.
- */
-function isHidePoweredByFromHelmet(context: Rule.RuleContext, n: estree.Node): boolean {
- if (n.type === 'CallExpression') {
- return getFullyQualifiedName(context, n) === `${HELMET}.hidePoweredBy`;
- }
- return false;
-}
-
-function isProtecting(context: Rule.RuleContext): (n: estree.Node) => boolean {
- return (n: estree.Node) =>
- Express.isMiddlewareInstance(context, PROTECTING_MIDDLEWARES, n) ||
- isHidePoweredByFromHelmet(context, n);
-}
-
-function isDisabledXPoweredBy(
- callExpression: estree.CallExpression,
- app: estree.Identifier,
-): boolean {
- if (isMethodInvocation(callExpression, app.name, 'disable', 1)) {
- const arg0 = callExpression.arguments[0];
- return arg0.type === 'Literal' && String(arg0.value).toLowerCase() === HEADER_X_POWERED_BY;
- }
- return false;
-}
-
-function isSetFalseXPoweredBy(
- callExpression: estree.CallExpression,
- app: estree.Identifier,
-): boolean {
- if (isMethodInvocation(callExpression, app.name, 'set', APP_SET_NUM_ARGS)) {
- const [headerName, onOff] = callExpression.arguments;
- return (
- headerName.type === 'Literal' &&
- String(headerName.value).toLowerCase() === HEADER_X_POWERED_BY &&
- onOff.type === 'Literal' &&
- onOff.value === false
- );
- }
- return false;
-}
-
-function isAppEscaping(callExpr: estree.CallExpression, app: estree.Identifier): boolean {
- return Boolean(
- callExpr.arguments.find(arg => arg.type === 'Identifier' && arg.name === app.name),
- );
-}
-
-function isAppEscapingThroughReturn(ret: estree.ReturnStatement, app: estree.Identifier): boolean {
- const arg = ret.argument;
- return Boolean(arg && arg.type === 'Identifier' && arg.name === app.name);
-}
diff --git a/eslint-bridge/src/linting/eslint/rules/xml-parser-xxe.ts b/eslint-bridge/src/linting/eslint/rules/xml-parser-xxe.ts
deleted file mode 100644
index fba3cdc48d5..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/xml-parser-xxe.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S2755/javascript
-
-import { TSESTree } from '@typescript-eslint/experimental-utils';
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import { getObjectExpressionProperty, toEncodedMessage, getFullyQualifiedName } from './helpers';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-const XML_LIBRARY = 'libxmljs';
-const XML_PARSERS = ['parseXml', 'parseXmlString'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- // internal parameter for rules having secondary locations
- enum: [SONAR_RUNTIME],
- },
- ],
- },
- create(context: Rule.RuleContext) {
- function isXmlParserCall(call: estree.CallExpression) {
- const fqn = getFullyQualifiedName(context, call);
- return XML_PARSERS.some(parser => fqn === `${XML_LIBRARY}.${parser}`);
- }
-
- function isNoEntSet(property: estree.Property) {
- return property.value.type === 'Literal' && property.value.raw === 'true';
- }
-
- return {
- CallExpression: (node: estree.Node) => {
- const call = node as estree.CallExpression;
- if (isXmlParserCall(call)) {
- const noent = getObjectExpressionProperty(call.arguments[1], 'noent');
- if (noent && isNoEntSet(noent)) {
- context.report({
- message: toEncodedMessage('Disable access to external entities in XML parsing.', [
- call.callee as TSESTree.Node,
- ]),
- node: noent,
- });
- }
- }
- },
- };
- },
-};
diff --git a/eslint-bridge/src/linting/eslint/rules/xpath.ts b/eslint-bridge/src/linting/eslint/rules/xpath.ts
deleted file mode 100644
index 87b6c234945..00000000000
--- a/eslint-bridge/src/linting/eslint/rules/xpath.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S4817/javascript
-
-import { Rule } from 'eslint';
-import * as estree from 'estree';
-import {
- isMemberExpression,
- isMemberWithProperty,
- isLiteral,
- getFullyQualifiedName,
-} from './helpers';
-
-const xpathModule = 'xpath';
-
-const xpathEvalMethods = ['select', 'select1', 'evaluate'];
-const ieEvalMethods = ['selectNodes', 'SelectSingleNode'];
-
-export const rule: Rule.RuleModule = {
- meta: {
- messages: {
- checkXPath: 'Make sure that executing this XPATH expression is safe.',
- },
- },
- create(context: Rule.RuleContext) {
- return {
- MemberExpression: (node: estree.Node) => {
- if (isMemberExpression(node, 'document', 'evaluate')) {
- context.report({ messageId: 'checkXPath', node });
- }
- },
- CallExpression: (node: estree.Node) =>
- checkCallExpression(node as estree.CallExpression, context),
- };
- },
-};
-
-function checkCallExpression(
- { callee, arguments: args }: estree.CallExpression,
- context: Rule.RuleContext,
-) {
- if (args.length > 0 && isLiteral(args[0])) {
- return;
- }
-
- // IE
- if (isMemberWithProperty(callee, ...ieEvalMethods) && args.length === 1) {
- context.report({ messageId: 'checkXPath', node: callee });
- return;
- }
-
- // Document.evaluate
- if (
- isMemberWithProperty(callee, 'evaluate') &&
- !isMemberExpression(callee, 'document', 'evaluate') &&
- args.length >= 4
- ) {
- const resultTypeArgument = args[3];
- const argumentAsText = context.getSourceCode().getText(resultTypeArgument);
- if (argumentAsText.includes('XPathResult')) {
- context.report({ messageId: 'checkXPath', node: callee });
- return;
- }
- }
-
- // "xpath" module
- const fqn = getFullyQualifiedName(context, callee);
- if (xpathEvalMethods.some(method => fqn === `${xpathModule}.${method}`)) {
- context.report({ messageId: 'checkXPath', node: callee });
- }
-}
diff --git a/eslint-bridge/src/linting/stylelint/index.ts b/eslint-bridge/src/linting/stylelint/index.ts
deleted file mode 100644
index e855990ef0b..00000000000
--- a/eslint-bridge/src/linting/stylelint/index.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { LinterWrapper } from './linter';
-
-export * from './linter';
-export * from './rules';
-
-/**
- * The global Stylelint linter wrapper
- */
-export const linter = new LinterWrapper();
diff --git a/eslint-bridge/src/linting/stylelint/linter/config.ts b/eslint-bridge/src/linting/stylelint/linter/config.ts
deleted file mode 100644
index 34cfd2311e7..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/config.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import stylelint from 'stylelint';
-
-/**
- * A Stylelint rule configuration
- *
- * @param key the Stylelint rule key
- * @param configuration the rule specific configuration
- */
-export interface RuleConfig {
- key: string;
- configurations: any[];
-}
-
-/**
- * Creates a Stylelint configuration
- *
- * Creating a Stylelint configuration implies enabling along with specific rule
- * configuration all the rules from the active quality profile.
- *
- * @param rules the rules from the active quality profile
- * @returns the created Stylelint configuration
- */
-export function createStylelintConfig(rules: RuleConfig[]): stylelint.Config {
- const configRules: stylelint.ConfigRules = {};
- for (const { key, configurations } of rules) {
- if (configurations.length === 0) {
- configRules[key] = true;
- } else {
- configRules[key] = configurations;
- }
- }
- return { customSyntax: 'postcss-syntax', rules: configRules };
-}
diff --git a/eslint-bridge/src/linting/stylelint/linter/index.ts b/eslint-bridge/src/linting/stylelint/linter/index.ts
deleted file mode 100644
index 3573c0a3684..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './config';
-export * from './issues';
-export * from './wrapper';
diff --git a/eslint-bridge/src/linting/stylelint/linter/issues/index.ts b/eslint-bridge/src/linting/stylelint/linter/issues/index.ts
deleted file mode 100644
index 1e344fae922..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/issues/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './issue';
-export * from './transform';
diff --git a/eslint-bridge/src/linting/stylelint/linter/issues/issue.ts b/eslint-bridge/src/linting/stylelint/linter/issues/issue.ts
deleted file mode 100644
index e169ac35474..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/issues/issue.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * A SonarQube-compatible stylesheet issue
- *
- * Stylelint linting results only include partial location information,
- * namely starting line and starting column.
- *
- * It is used to send back a CSS analysis response to the plugin, which
- * eventually saves the issue data to SonarQube.
- *
- * @param ruleId the rule key
- * @param line the issue line
- * @param column the issue column
- * @param message the issue message
- */
-export interface Issue {
- ruleId: string;
- line: number;
- column: number;
- message: string;
-}
diff --git a/eslint-bridge/src/linting/stylelint/linter/issues/transform.ts b/eslint-bridge/src/linting/stylelint/linter/issues/transform.ts
deleted file mode 100644
index fb1a21f8dd0..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/issues/transform.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import stylelint from 'stylelint';
-import { debug } from 'helpers';
-import { Issue } from './issue';
-
-/**
- * Transforms Stylelint linting results into SonarQube issues
- * @param results the Stylelint linting results
- * @param filePath the path of the linted file
- * @returns the transformed SonarQube issues
- */
-export function transform(results: stylelint.LintResult[], filePath: string): Issue[] {
- const issues: Issue[] = [];
- /**
- * There should be only one element in 'results' as we are analyzing
- * only one file at a time.
- */
- results.forEach(result => {
- /** Avoids reporting on "fake" source like */
- if (result.source !== filePath) {
- debug(
- `For file [${filePath}] received issues with [${result.source}] as a source. They will not be reported.`,
- );
- return;
- }
- result.warnings.forEach(warning =>
- issues.push({
- ruleId: warning.rule,
- line: warning.line,
- column: warning.column,
- message: warning.text,
- }),
- );
- });
- return issues;
-}
diff --git a/eslint-bridge/src/linting/stylelint/linter/wrapper.ts b/eslint-bridge/src/linting/stylelint/linter/wrapper.ts
deleted file mode 100644
index b92a34cd560..00000000000
--- a/eslint-bridge/src/linting/stylelint/linter/wrapper.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import stylelint from 'stylelint';
-import { transform } from './issues';
-import { rules } from 'linting/stylelint';
-
-/**
- * A wrapper of Stylelint linter
- */
-export class LinterWrapper {
- /**
- * Constructs a Stylelint wrapper
- */
- constructor() {
- this.defineRules();
- }
-
- /**
- * Lints a stylesheet
- *
- * Linting a stylesheet implies using Stylelint linting functionality to find
- * problems in the sheet. It does not need to be provided with an abstract
- * syntax tree as Stylelint takes care of the parsing internally.
- *
- * The result of linting a stylesheet requires post-linting transformations
- * to return SonarQube issues. These transformations essentially consist in
- * transforming Stylelint results into SonarQube issues.
- *
- * Because stylesheets are far different from what a source code is, metrics
- * computation does not make sense when analyzing such file contents. Issues
- * only are returned after linting.
- *
- * @param filePath the path of the stylesheet
- * @param options the linting options
- * @returns the found issues
- */
- lint(filePath: string, options: stylelint.LinterOptions) {
- return stylelint
- .lint(options)
- .then(result => ({ issues: transform(result.results, filePath) }));
- }
-
- /**
- * Defines the wrapper's rules
- *
- * Besides Stylelint rules, the linter wrapper includes all the rules that
- * are implemented internally.
- */
- private defineRules() {
- for (const key in rules) {
- stylelint.rules[key] = rules[key];
- }
- }
-}
diff --git a/eslint-bridge/src/linting/stylelint/rules/function-calc-no-invalid.ts b/eslint-bridge/src/linting/stylelint/rules/function-calc-no-invalid.ts
deleted file mode 100644
index 6143065f175..00000000000
--- a/eslint-bridge/src/linting/stylelint/rules/function-calc-no-invalid.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// https://sonarsource.github.io/rspec/#/rspec/S5362/css
-import * as stylelint from 'stylelint';
-import postcssValueParser from 'postcss-value-parser';
-
-const ruleName = 'function-calc-no-invalid';
-const operators = ['+', '-', '*', '/'];
-
-// exported for testing purpose
-export const messages = {
- empty: "Fix this empty 'calc' expression.",
- malformed: "Fix this malformed 'calc' expression.",
- divByZero: "Fix this 'calc' expression with division by zero.",
-};
-
-const ruleImpl: stylelint.RuleBase = () => {
- return (root: any, result: any) => {
- root.walkDecls((decl: any) => {
- postcssValueParser(decl.value).walk(node => {
- if (!isCalcFunction(node)) {
- return;
- }
-
- const calc = node as postcssValueParser.FunctionNode;
-
- checkDivisionByZero(calc.nodes);
- checkMissingOperator(calc.nodes);
- checkEmpty(calc.nodes);
- });
-
- function isCalcFunction(node: postcssValueParser.Node) {
- return node.type === 'function' && node.value.toLowerCase() === 'calc';
- }
-
- function isParenthesizedExpression(
- node: postcssValueParser.Node,
- ): node is postcssValueParser.FunctionNode {
- return node.type === 'function' && node.value.toLowerCase() !== 'calc';
- }
-
- function checkDivisionByZero(nodes: postcssValueParser.Node[]): void {
- const siblings = nodes.filter(node => !isSpaceOrComment(node));
- for (const [index, node] of siblings.entries()) {
- if (isDivision(node)) {
- const operand = siblings[index + 1];
- if (operand && isZero(operand)) {
- report(messages.divByZero);
- }
- } else if (isParenthesizedExpression(node)) {
- // parenthesized expressions are represented as `function` nodes
- // they need to be visited as well if they are not `calc` calls
- checkDivisionByZero(node.nodes);
- }
- }
- }
-
- function checkMissingOperator(nodes: postcssValueParser.Node[]) {
- const siblings = nodes.filter(node => !isSpaceOrComment(node));
- for (let index = 1; index < siblings.length; index += 2) {
- const node = siblings[index];
- if (!isOperator(node)) {
- report(messages.malformed);
- }
- }
- for (const node of siblings) {
- if (isParenthesizedExpression(node)) {
- // parenthesized expressions are represented as `function` nodes
- // they need to be visited as well if they are not `calc` calls
- checkMissingOperator(node.nodes);
- }
- }
- }
-
- function checkEmpty(nodes: postcssValueParser.Node[]) {
- if (nodes.filter(node => !isSpaceOrComment(node)).length === 0) {
- report(messages.empty);
- }
- }
-
- function isSpaceOrComment(node: postcssValueParser.Node) {
- return node.type === 'space' || node.type === 'comment';
- }
-
- function isOperator(node: postcssValueParser.Node) {
- return (node.type === 'word' && operators.includes(node.value)) || node.type === 'div';
- }
-
- function isDivision(node: postcssValueParser.Node) {
- return (node.type === 'word' || node.type === 'div') && node.value === '/';
- }
-
- function isZero(node: postcssValueParser.Node) {
- return node.type === 'word' && parseFloat(node.value) === 0;
- }
-
- function report(message: string) {
- stylelint.utils.report({
- ruleName,
- result,
- message,
- node: decl,
- });
- }
- });
- };
-};
-
-export const rule = stylelint.createPlugin(
- ruleName,
- Object.assign(ruleImpl, {
- messages,
- ruleName,
- }),
-);
diff --git a/eslint-bridge/src/linting/stylelint/rules/index.ts b/eslint-bridge/src/linting/stylelint/rules/index.ts
deleted file mode 100644
index 44dd6f0c6c2..00000000000
--- a/eslint-bridge/src/linting/stylelint/rules/index.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import stylelint from 'stylelint';
-import { rule as functionCalcNoInvalid } from './function-calc-no-invalid';
-
-/**
- * The set of internal Stylelint-based rules
- */
-const rules: { [key: string]: stylelint.Rule } = {};
-
-/**
- * Maps Stylelint rule keys to rule implementations
- */
-rules[functionCalcNoInvalid.ruleName] = functionCalcNoInvalid.rule;
-
-export { rules };
diff --git a/eslint-bridge/src/parsing/jsts/builders/build-js.ts b/eslint-bridge/src/parsing/jsts/builders/build-js.ts
deleted file mode 100644
index 9331629dbd4..00000000000
--- a/eslint-bridge/src/parsing/jsts/builders/build-js.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { debug } from 'helpers';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { buildParserOptions, parsers, parseForESLint } from 'parsing/jsts';
-
-/**
- * Builds an instance of ESLint SourceCode for JavaScript
- *
- * Building an ESLint SourceCode for JavaScript implies parsing JavaScript code with
- * ESLint-based parsers. For the particular case of JavaScript code, we first try to
- * parse the code with TypeScript ESLint parser. If the input includes TSConfigs, the
- * resulting ESLint SourceCode would include a reference to TypeScript's type checker
- * in its parser services, if configured properly. Rules implemented internally could
- * then benefit from type information. If parsing fails at this point, we fallback to
- * Babel's parser and make two other attempts to parse the code by considering the two
- * possible source types: 'module' vs. 'script'.
- *
- * @param input the JavaScript analysis input
- * @param tryTypeScriptESLintParser a flag for parsing with TypeScript ESLint parser
- * @returns the parsed JavaScript code
- */
-export function buildJs(input: JsTsAnalysisInput, tryTypeScriptESLintParser: boolean): SourceCode {
- if (tryTypeScriptESLintParser) {
- try {
- return parseForESLint(
- input.fileContent,
- parsers.typescript.parse,
- buildParserOptions(input, false),
- );
- } catch (error) {
- debug(`Failed to parse ${input.filePath} with TypeScript parser: ${error.message}`);
- }
- }
-
- let moduleError;
- try {
- return parseForESLint(
- input.fileContent,
- parsers.javascript.parse,
- buildParserOptions(input, true),
- );
- } catch (error) {
- moduleError = error;
- }
-
- try {
- return parseForESLint(
- input.fileContent,
- parsers.javascript.parse,
- buildParserOptions(input, true, undefined, 'script'),
- );
- } catch (_) {
- /**
- * We prefer displaying parsing error as module if parsing as script also failed,
- * as it is more likely that the expected source type is module.
- */
- throw moduleError;
- }
-}
diff --git a/eslint-bridge/src/parsing/jsts/builders/build-ts.ts b/eslint-bridge/src/parsing/jsts/builders/build-ts.ts
deleted file mode 100644
index 6dde4ff5665..00000000000
--- a/eslint-bridge/src/parsing/jsts/builders/build-ts.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { JsTsAnalysisInput } from 'services/analysis';
-import { buildParserOptions, parsers, parseForESLint } from 'parsing/jsts';
-
-/**
- * Builds an instance of ESLint SourceCode for TypeScript
- *
- * Building an ESLint SourceCode for TypeScript implies parsing TypeScript code with
- * TypeScript ESLint parser. However, if the source code denotes TypeScript code in
- * Vue.js Single File Components, Vue.js ESLint parser is used instead to parse the
- * whole file. Furthermore, it is configured to use TypeScript ESLint parser to parse
- * the contents of the 'script' section of the component.
- *
- * @param input the TypeScript analysis input
- * @param isVueFile a flag to indicate if the input denotes Vue.js TypeScript code
- * @returns the parsed TypeScript code
- */
-export function buildTs(input: JsTsAnalysisInput, isVueFile: boolean) {
- const options = buildParserOptions(
- input,
- false,
- isVueFile ? parsers.typescript.parser : undefined,
- );
- const parse = isVueFile ? parsers.vuejs.parse : parsers.typescript.parse;
- return parseForESLint(input.fileContent, parse, options);
-}
diff --git a/eslint-bridge/src/parsing/jsts/builders/build-vue.ts b/eslint-bridge/src/parsing/jsts/builders/build-vue.ts
deleted file mode 100644
index e866965baa5..00000000000
--- a/eslint-bridge/src/parsing/jsts/builders/build-vue.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { debug } from 'helpers';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { buildParserOptions, parsers, parseForESLint } from 'parsing/jsts';
-
-/**
- * Builds an instance of ESLint SourceCode for Vue.js
- *
- * Building an ESLint SourceCode for Vue.js implies parsing the 'script' section of
- * a Vue.js Single Component (.vue) file. To this end, we use 'vue-eslint-parser',
- * which is instructed to parse that section either with TypeScript ESLint parser or
- * Babel parser. Furthermore, the Vue.js parser is also able to parse the 'template'
- * section of a .vue file.
- *
- * @param input the Vue.js JavaScript analysis input
- * @param tryTypeScriptESLintParser a flag for parsing with TypeScript ESLint parser
- * @returns the parsed Vue.js JavaScript code
- */
-export function buildVue(input: JsTsAnalysisInput, tryTypeScriptESLintParser: boolean): SourceCode {
- if (tryTypeScriptESLintParser) {
- try {
- const options = buildParserOptions(input, false, parsers.typescript.parser);
- return parseForESLint(input.fileContent, parsers.vuejs.parse, options);
- } catch (error) {
- debug(`Failed to parse ${input.filePath} with TypeScript parser: ${error.message}`);
- }
- }
- const options = buildParserOptions(input, true, parsers.javascript.parser);
- return parseForESLint(input.fileContent, parsers.vuejs.parse, options);
-}
diff --git a/eslint-bridge/src/parsing/jsts/builders/build.ts b/eslint-bridge/src/parsing/jsts/builders/build.ts
deleted file mode 100644
index 69b04e7bdef..00000000000
--- a/eslint-bridge/src/parsing/jsts/builders/build.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { getContext } from 'helpers';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { buildJs } from './build-js';
-import { buildTs } from './build-ts';
-import { buildVue } from './build-vue';
-import { Language } from 'parsing/jsts';
-
-/**
- * Builds an ESLint SourceCode for JavaScript / TypeScript
- *
- * This functions routes the parsing of the input based on the input language,
- * the file extension, and some contextual information.
- *
- * @param input the JavaScript / TypeScript analysis input
- * @param language the language of the input
- * @returns the parsed source code
- */
-export function buildSourceCode(input: JsTsAnalysisInput, language: Language) {
- const isVueFile = input.filePath.endsWith('.vue');
-
- if (language === 'ts') {
- return buildTs(input, isVueFile);
- }
-
- const tryTypeScriptParser = shouldTryTypeScriptParser();
-
- if (isVueFile) {
- return buildVue(input, tryTypeScriptParser);
- } else {
- return buildJs(input, tryTypeScriptParser);
- }
-}
-
-function shouldTryTypeScriptParser() {
- const context = getContext();
- return context ? context.shouldUseTypeScriptParserForJS : true;
-}
diff --git a/eslint-bridge/src/parsing/jsts/builders/index.ts b/eslint-bridge/src/parsing/jsts/builders/index.ts
deleted file mode 100644
index 1769028e20b..00000000000
--- a/eslint-bridge/src/parsing/jsts/builders/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './build';
diff --git a/eslint-bridge/src/parsing/jsts/index.ts b/eslint-bridge/src/parsing/jsts/index.ts
deleted file mode 100644
index e02e5a7284c..00000000000
--- a/eslint-bridge/src/parsing/jsts/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './builders';
-export * from './language';
-export * from './parsers';
diff --git a/eslint-bridge/src/parsing/jsts/language.ts b/eslint-bridge/src/parsing/jsts/language.ts
deleted file mode 100644
index 4c4d52d809a..00000000000
--- a/eslint-bridge/src/parsing/jsts/language.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * A discriminator between JavaScript and TypeScript analysis inputs
- *
- * Analyzing JavaScript and TypeScript code is rather transparent and
- * indistinguishable since we use ESLint-based APIs not only to parse
- * but also to analyze source code. However, there are minor parsing
- * details that require a clear distinction between the two.
- */
-export type Language = 'js' | 'ts';
diff --git a/eslint-bridge/src/parsing/jsts/parsers/eslint.ts b/eslint-bridge/src/parsing/jsts/parsers/eslint.ts
deleted file mode 100644
index cb7272e8c7a..00000000000
--- a/eslint-bridge/src/parsing/jsts/parsers/eslint.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as babelESLintParser from '@babel/eslint-parser';
-import * as vueESLintParser from 'vue-eslint-parser';
-import * as typescriptESLintParser from '@typescript-eslint/parser';
-
-/**
- * An ESLint-based parsing function
- *
- * ESLint-based parsing functions takes as inputs a code to parse
- * as well as options to configure the parser and returns either
- * an instance of ESLint SourceCode or a parsing error.
- */
-export type ParseFunction = (code: string, options: {}) => any;
-
-/**
- * An ESLint-based parser container
- *
- * The purpose of this type is to group together an ESLint parser
- * dependency along with its parsing function. When building the
- * parsing options of a parser, it happens sometime that we need
- * the parser dependency rather than the actual parsing function,
- * and vice versa.
- *
- * @param parser the parser dependency
- * @param parse the parsing function
- */
-export type ESLintParser = {
- parser: string;
- parse: ParseFunction;
-};
-
-/**
- * The ESLint-based parsers used to parse JavaScript, TypeScript, and Vue.js code.
- */
-export const parsers: { javascript: ESLintParser; typescript: ESLintParser; vuejs: ESLintParser } =
- {
- javascript: { parser: '@babel/eslint-parser', parse: babelESLintParser.parseForESLint },
- typescript: {
- parser: '@typescript-eslint/parser',
- parse: typescriptESLintParser.parseForESLint,
- },
- vuejs: { parser: 'vue-eslint-parser', parse: vueESLintParser.parseForESLint },
- };
-
-/**
- * Clears TypeScript ESLint parser's caches
- *
- * While analyzing multiple files that used TypeScript ESLint parser to
- * parse their respective code, raised issues may differ depending on
- * clearing or not TypeScript ESLint parser's caches. To address that,
- * the sensor requests clearing the caches for each considered TSConfig.
- */
-export function clearTypeScriptESLintParserCaches() {
- typescriptESLintParser.clearCaches();
-}
diff --git a/eslint-bridge/src/parsing/jsts/parsers/index.ts b/eslint-bridge/src/parsing/jsts/parsers/index.ts
deleted file mode 100644
index 965aab544ee..00000000000
--- a/eslint-bridge/src/parsing/jsts/parsers/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './eslint';
-export * from './options';
-export * from './parse';
diff --git a/eslint-bridge/src/parsing/jsts/parsers/options.ts b/eslint-bridge/src/parsing/jsts/parsers/options.ts
deleted file mode 100644
index 1a1a6a35ef2..00000000000
--- a/eslint-bridge/src/parsing/jsts/parsers/options.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter } from 'eslint';
-import { getProgramById } from 'services/program';
-import { JsTsAnalysisInput } from 'services/analysis';
-
-/**
- * Builds ESLint parser options
- *
- * ESLint parser options allows for customizing the behaviour of
- * the ESLint-based parser used to parse JavaScript or TypeScript
- * code. It configures the ECMAscript version, specific syntax or
- * features to consider as valid during parsing, and additional
- * contents in the abstract syntax tree, among other things.
- *
- * @param input the analysis input to parse
- * @param usingBabel a flag to indicate if we intend to parse with Babel
- * @param parser a parser dependency to use
- * @param sourceType the type of the source code
- * @returns the parser options for the input
- */
-export function buildParserOptions(
- input: JsTsAnalysisInput,
- usingBabel = false,
- parser?: string,
- sourceType: 'script' | 'module' = 'module',
-) {
- const project = 'tsConfigs' in input ? input.tsConfigs : undefined;
- const programs = 'programId' in input ? [getProgramById(input.programId)] : undefined;
-
- const options: Linter.ParserOptions = {
- tokens: true,
- comment: true,
- loc: true,
- range: true,
- ecmaVersion: 2018,
- sourceType,
- codeFrame: false,
- ecmaFeatures: {
- jsx: true,
- globalReturn: false,
- legacyDecorators: true,
- },
-
- // for Vue parser
- extraFileExtensions: ['.vue'],
- parser,
-
- // for TS parser
- filePath: input.filePath,
- project,
- programs,
- // enable logs for @typescripteslint
- // debugLevel: true,
- };
-
- if (usingBabel) {
- return babelParserOptions(options);
- }
-
- return options;
-}
-
-/**
- * Extends parser options with Babel's specific options
- *
- * Babel's parser is able to parse non-standard syntaxes and features.
- * However, the support of such constructs are extracted into dedicated
- * plugins, which need to be explictly included in the parser options,
- * among other things.
- *
- * @param options the parser options to extend
- * @returns the extend parser options
- */
-function babelParserOptions(options: Linter.ParserOptions) {
- const pluginPath = `${__dirname}/../../../../node_modules`;
- const babelOptions = {
- presets: [
- `${pluginPath}/@babel/preset-react`,
- `${pluginPath}/@babel/preset-flow`,
- `${pluginPath}/@babel/preset-env`,
- ],
- plugins: [[`${pluginPath}/@babel/plugin-proposal-decorators`, { version: '2022-03' }]],
- babelrc: false,
- configFile: false,
- parserOpts: {
- allowReturnOutsideFunction: true,
- },
- };
- return { ...options, requireConfigFile: false, babelOptions };
-}
diff --git a/eslint-bridge/src/parsing/jsts/parsers/parse.ts b/eslint-bridge/src/parsing/jsts/parsers/parse.ts
deleted file mode 100644
index 5c4203ee588..00000000000
--- a/eslint-bridge/src/parsing/jsts/parsers/parse.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { APIError } from 'errors';
-import { SourceCode } from 'eslint';
-import { ParseFunction } from './eslint';
-
-/**
- * Parses a JavaScript / TypeScript analysis input with an ESLint-based parser
- * @param code the JavaScript / TypeScript code to parse
- * @param parse the ESLint parsing function to use for parsing
- * @param options the ESLint parser options
- * @returns the parsed source code
- */
-export function parseForESLint(code: string, parse: ParseFunction, options: {}): SourceCode {
- try {
- const result = parse(code, options);
- return new SourceCode({
- ...result,
- text: code,
- parserServices: result.services,
- });
- } catch ({ lineNumber, message }) {
- if (message.startsWith('Debug Failure')) {
- throw APIError.failingTypeScriptError(message);
- } else {
- throw APIError.parsingError(message, { line: lineNumber });
- }
- }
-}
diff --git a/eslint-bridge/src/parsing/yaml/aws/index.ts b/eslint-bridge/src/parsing/yaml/aws/index.ts
deleted file mode 100644
index f70dd96ecac..00000000000
--- a/eslint-bridge/src/parsing/yaml/aws/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './parsingContexts';
-export * from './parser';
diff --git a/eslint-bridge/src/parsing/yaml/aws/parser.ts b/eslint-bridge/src/parsing/yaml/aws/parser.ts
deleted file mode 100644
index a2fcbf9ad81..00000000000
--- a/eslint-bridge/src/parsing/yaml/aws/parser.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { parseYaml } from 'parsing/yaml/parser';
-import { lambdaParsingContext, serverlessParsingContext } from './parsingContexts';
-
-/**
- * Extracts from a YAML file all the embedded JavaScript code snippets either
- * in AWS Lambda Functions or AWS Serverless Functions.
- */
-export const parseAwsFromYaml = parseYaml.bind(null, [
- lambdaParsingContext,
- serverlessParsingContext,
-]);
diff --git a/eslint-bridge/src/parsing/yaml/aws/parsingContexts.ts b/eslint-bridge/src/parsing/yaml/aws/parsingContexts.ts
deleted file mode 100644
index 2d4b32fa89b..00000000000
--- a/eslint-bridge/src/parsing/yaml/aws/parsingContexts.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { ParsingContext } from 'parsing/yaml';
-
-export const lambdaParsingContext: ParsingContext = {
- predicate: isInlineAwsLambda,
- picker: pickResourceName.bind(null, 6),
-};
-
-export const serverlessParsingContext: ParsingContext = {
- predicate: isInlineAwsServerless,
- picker: pickResourceName.bind(null, 4),
-};
-
-/**
- * Checks if the given YAML AST node is an AWS Lambda function with the following structure:
- *
- * SomeLambdaFunction:
- * Type: "AWS::Lambda::Function"
- * Properties:
- * Runtime:
- * Code:
- * ZipFile:
- */
-function isInlineAwsLambda(_key: any, pair: any, ancestors: any[]) {
- return (
- isZipFile(pair) &&
- hasCode(ancestors) &&
- hasNodeJsRuntime(ancestors) &&
- hasType(ancestors, 'AWS::Lambda::Function')
- );
-
- function isZipFile(pair: any) {
- return pair.key.value === 'ZipFile';
- }
-
- function hasCode(ancestors: any[], level = 2) {
- return ancestors[ancestors.length - level]?.key?.value === 'Code';
- }
-}
-
-/**
- * Checks if the given YAML AST node is an AWS Serverless function with the following structure:
- *
- * SomeServerlessFunction:
- * Type: "AWS::Serverless::Function"
- * Properties:
- * Runtime:
- * InlineCode:
- */
-function isInlineAwsServerless(_key: any, pair: any, ancestors: any[]) {
- return (
- isInlineCode(pair) &&
- hasNodeJsRuntime(ancestors, 1) &&
- hasType(ancestors, 'AWS::Serverless::Function', 3)
- );
-
- /**
- * We need to check the pair directly instead of ancestors,
- * otherwise it will validate all siblings.
- */
- function isInlineCode(pair: any) {
- return pair.key.value === 'InlineCode';
- }
-}
-
-function hasNodeJsRuntime(ancestors: any[], level = 3) {
- return ancestors[ancestors.length - level]?.items?.some(
- (item: any) => item?.key.value === 'Runtime' && item?.value?.value.startsWith('nodejs'),
- );
-}
-
-function hasType(ancestors: any[], value: string, level = 5) {
- return ancestors[ancestors.length - level]?.items?.some(
- (item: any) => item?.key.value === 'Type' && item?.value.value === value,
- );
-}
-
-/**
- * Picks the embeddedJS resource name for AWS lambdas and serverless functions
- */
-export function pickResourceName(level: number, _key: any, _pair: any, ancestors: any) {
- const ancestorsAtResourcesLevel = ancestors[ancestors.length - level];
- return {
- resourceName: ancestorsAtResourcesLevel.key.value,
- };
-}
diff --git a/eslint-bridge/src/parsing/yaml/builder/build.ts b/eslint-bridge/src/parsing/yaml/builder/build.ts
deleted file mode 100644
index 4ef7f0080e1..00000000000
--- a/eslint-bridge/src/parsing/yaml/builder/build.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { JsTsAnalysisInput, YamlAnalysisInput } from 'services/analysis';
-import { buildSourceCode } from 'parsing/jsts';
-import { parseAwsFromYaml } from 'parsing/yaml';
-import { patchParsingError, patchSourceCode } from './patch';
-import clone from 'lodash.clone';
-import path from 'path';
-
-export type ExtendedSourceCode = SourceCode & { syntheticFilePath: string };
-
-/**
- * Builds ESLint SourceCode instances for every embedded JavaScript snippet in the YAML file.
- *
- * The filepath is augmented with the AWS function name, returned as the syntheticFilePath property
- *
- * If there is at least one parsing error in any snippet, we return only the first error and
- * we don't even consider any parsing errors in the remaining snippets for simplicity.
- */
-export function buildSourceCodes(input: YamlAnalysisInput): ExtendedSourceCode[] {
- const embeddedJSs = parseAwsFromYaml(input.fileContent);
-
- const extendedSourceCodes: ExtendedSourceCode[] = [];
- for (const embeddedJS of embeddedJSs) {
- const { code } = embeddedJS;
-
- let syntheticFilePath: string = input.filePath;
- if (embeddedJS.extras.resourceName != null) {
- syntheticFilePath = composeSyntheticFilePath(input.filePath, embeddedJS.extras.resourceName);
- }
-
- /**
- * The file path is purposely left empty as it is ignored by `buildSourceCode` if
- * the file content is provided, which happens to be the case here since `code`
- * denotes an embedded JavaScript snippet extracted from the YAML file.
- */
- const jsTsAnalysisInput = {
- filePath: '',
- fileContent: code,
- fileType: 'MAIN',
- } as JsTsAnalysisInput;
- try {
- const sourceCode = buildSourceCode(jsTsAnalysisInput, 'js');
- const patchedSourceCode: SourceCode = patchSourceCode(sourceCode, embeddedJS);
- // We use lodash.clone here to remove the effects of Object.preventExtensions()
- const extendedSourceCode: ExtendedSourceCode = Object.assign(clone(patchedSourceCode), {
- syntheticFilePath,
- });
- extendedSourceCodes.push(extendedSourceCode);
- } catch (error) {
- throw patchParsingError(error, embeddedJS);
- }
- }
- return extendedSourceCodes;
-}
-
-/**
- * Returns the filename composed as following:
- *
- * {filepath-without-extention}-{resourceName}{filepath-extension}
- */
-export function composeSyntheticFilePath(filePath: string, resourceName: string): string {
- const { dir, name, ext } = path.parse(filePath);
- return path.format({
- dir,
- name: `${name}-${resourceName}`,
- ext,
- });
-}
diff --git a/eslint-bridge/src/parsing/yaml/builder/index.ts b/eslint-bridge/src/parsing/yaml/builder/index.ts
deleted file mode 100644
index 3437de351b9..00000000000
--- a/eslint-bridge/src/parsing/yaml/builder/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './build';
-export * from './patch';
diff --git a/eslint-bridge/src/parsing/yaml/builder/patch.ts b/eslint-bridge/src/parsing/yaml/builder/patch.ts
deleted file mode 100644
index 28fedf023e8..00000000000
--- a/eslint-bridge/src/parsing/yaml/builder/patch.ts
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { AST, SourceCode } from 'eslint';
-import { Comment, Node } from 'estree';
-import { visit } from 'linting/eslint';
-import { EmbeddedJS } from 'parsing/yaml';
-import { APIError } from 'errors';
-
-/**
- * Patches the ESLint SourceCode instance parsed with an ESLint-based parser
- *
- * Patching an ESLint SourceCode instance denoting an embedded JavaScript snippet implies
- * fixing all location-related data structures in the abstract syntax tree as well as the
- * behavior of the instance methods because they are relative to the beginning of the code
- * snippet that was parsed, not relative to the whole YAML file content. By doing so,
- * location-related information within reported issues and quick fixes will be relative to
- * the YAML file (YAML referential).
- */
-export function patchSourceCode(originalSourceCode: SourceCode, embeddedJS: EmbeddedJS) {
- /**
- * 1. Recomputes the lines from the original YAML file content, as the lines in the original
- * SourceCode include only those from the embedded JavaScript code snippet and these
- * lines are used internally by the SourceCode for various purposes.
- */
- const lines = computeLines();
-
- /**
- * 2. Overrides the values `lineStartIndices`, `text` and `lines` of the original SourceCode
- * instance from the JavaScript referential to the YAML one. To achieve that, we must use
- * `Object.create()` because these particular SourceCode's properties are frozen.
- */
- const patchedSourceCode = Object.create(originalSourceCode, {
- lineStartIndices: { value: embeddedJS.lineStarts },
- text: { value: embeddedJS.text },
- lines: { value: lines },
- });
-
- /**
- * 3. Patches the location information of the SourceCode's abstract syntax tree as it sill
- * in the JavaScript referential
- */
- patchASTLocations(patchedSourceCode, embeddedJS.offset);
-
- /**
- * 4. Rebuilds the SourceCode from the patched values because
- * it builds internal properties that are depending on them
- */
- return new SourceCode({
- text: patchedSourceCode.text,
- ast: patchedSourceCode.ast,
- parserServices: patchedSourceCode.parserServices,
- scopeManager: patchedSourceCode.scopeManager,
- visitorKeys: patchedSourceCode.visitorKeys,
- });
-
- /* Taken from eslint/lib/source-code/source-code.js#constructor */
- function computeLines() {
- const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u;
- const lineEndingPattern = new RegExp(lineBreakPattern.source, 'gu');
- const lines = [];
-
- let i = 0;
- let match;
- while ((match = lineEndingPattern.exec(embeddedJS.text))) {
- lines.push(embeddedJS.text.slice(embeddedJS.lineStarts[i], match.index));
- i++;
- }
- lines.push(embeddedJS.text.slice(embeddedJS.lineStarts[embeddedJS.lineStarts.length - 1]));
-
- return lines;
- }
-
- /**
- * Patches the location in the abstract syntax tree from the embedded JavaScript snippet
- *
- * The patching involves any kind of nodes with locations and ranges, that is, regular
- * nodes, comments, and tokens.
- */
- function patchASTLocations(sourceCode: SourceCode, offset: number) {
- visit(sourceCode, node => {
- fixNodeLocation(node);
- });
-
- const { comments } = sourceCode.ast;
- for (const comment of comments) {
- fixNodeLocation(comment);
- }
-
- const { tokens } = sourceCode.ast;
- for (const token of tokens) {
- fixNodeLocation(token);
- }
-
- function fixNodeLocation(node: Node | Comment | AST.Token) {
- if (node.loc != null && node.range != null) {
- node.loc = {
- start: sourceCode.getLocFromIndex(node.range[0] + offset),
- end: sourceCode.getLocFromIndex(node.range[1] + offset),
- };
- }
- if (node.range) {
- const [sRange, eRange] = node.range;
- node.range = [sRange + offset, eRange + offset];
- }
- }
- }
-}
-
-/**
- * Patches a parsing error in an embedded JavaScript snippet
- *
- * Patching a parsing error in such a snippet requires patching the line number of the error
- * as well as its message if it includes location information like a token position. At this,
- * point, location information in the parsing error is relative to the beginning of the code
- * snippet, which should be patched.
- */
-export function patchParsingError(parsingError: APIError, embeddedJS: EmbeddedJS): APIError {
- if (typeof parsingError.data?.line === 'number') {
- const { message, data } = parsingError;
- const patchedLine =
- embeddedJS.format === 'PLAIN' ? embeddedJS.line : embeddedJS.line + data.line;
- parsingError.message = patchParsingErrorMessage(message, patchedLine, embeddedJS);
- parsingError.data.line = patchedLine;
- }
- return parsingError;
-}
-
-/**
- * Patches the message of a parsing error in an embedded JavaScript snippet
- *
- * A parsing error reported by an ESLint-based parser generally includes location information
- * about an unexpected token, e.g., `Unexpected token ','. (7:22)`, which should be patched.
- */
-export function patchParsingErrorMessage(
- message: string,
- patchedLine: number,
- embeddedJS: EmbeddedJS,
-): string {
- /* Extracts location information of the form `(:)` */
- const regex = /((?\d+):(?\d+))/;
- const found = message.match(regex);
- if (found !== null && found.groups) {
- const line = found.groups.line;
- const column = Number(found.groups.column);
- const patchedColumn = embeddedJS.format === 'PLAIN' ? column + embeddedJS.column - 1 : column;
- return message.replace(`(${line}:${column})`, `(${patchedLine}:${patchedColumn})`);
- }
- return message;
-}
diff --git a/eslint-bridge/src/parsing/yaml/index.ts b/eslint-bridge/src/parsing/yaml/index.ts
deleted file mode 100644
index abfd491a9ce..00000000000
--- a/eslint-bridge/src/parsing/yaml/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './aws';
-export * from './builder';
-export * from './parser';
diff --git a/eslint-bridge/src/parsing/yaml/parser/embedded-js.ts b/eslint-bridge/src/parsing/yaml/parser/embedded-js.ts
deleted file mode 100644
index d4785a2d42f..00000000000
--- a/eslint-bridge/src/parsing/yaml/parser/embedded-js.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * An extracted embedded JavaScript code snippet from a YAML file
- *
- * @param code JS code
- * @param line Line where JS code starts
- * @param column Column where JS code starts
- * @param offset Offset where JS code starts
- * @param lineStarts Offset at each line start
- * @param text Whole YAML file content
- * @param format Format of the YAML string that embeds the JS code
- * @param extras Additionnal data, filled by ExtrasPicker
- */
-export type EmbeddedJS = {
- code: string;
- line: number;
- column: number;
- offset: number;
- lineStarts: number[];
- text: string;
- format: 'PLAIN' | 'BLOCK_FOLDED' | 'BLOCK_LITERAL';
- extras: {
- resourceName?: string;
- };
-};
diff --git a/eslint-bridge/src/parsing/yaml/parser/format.ts b/eslint-bridge/src/parsing/yaml/parser/format.ts
deleted file mode 100644
index 4f2d60e3dd9..00000000000
--- a/eslint-bridge/src/parsing/yaml/parser/format.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * YAML string formats given by the YAML parser
- */
-export const [PLAIN_FORMAT, BLOCK_FOLDED_FORMAT, BLOCK_LITERAL_FORMAT] = [
- 'PLAIN',
- 'BLOCK_FOLDED',
- 'BLOCK_LITERAL',
-];
-
-/**
- * The list of supported YAML string formats
- */
-export const SUPPORTED_STRING_FORMATS = [PLAIN_FORMAT, BLOCK_FOLDED_FORMAT, BLOCK_LITERAL_FORMAT];
-
-/**
- * Checks if the node denotes a supported YAML string format
- */
-export function isSupportedFormat(pair: any) {
- return SUPPORTED_STRING_FORMATS.includes(pair.value?.type);
-}
diff --git a/eslint-bridge/src/parsing/yaml/parser/index.ts b/eslint-bridge/src/parsing/yaml/parser/index.ts
deleted file mode 100644
index 97795d91cf0..00000000000
--- a/eslint-bridge/src/parsing/yaml/parser/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './embedded-js';
-export * from './format';
-export * from './parse';
diff --git a/eslint-bridge/src/parsing/yaml/parser/parse.ts b/eslint-bridge/src/parsing/yaml/parser/parse.ts
deleted file mode 100644
index 88ba161b10b..00000000000
--- a/eslint-bridge/src/parsing/yaml/parser/parse.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as yaml from 'yaml';
-import assert from 'assert';
-import { EmbeddedJS } from './embedded-js';
-import { BLOCK_FOLDED_FORMAT, BLOCK_LITERAL_FORMAT, isSupportedFormat } from './format';
-import { APIError } from 'errors';
-
-/**
- * A bundle of Yaml visitor predicate and Extras picker
- * We have bundled these together because they depend on each other
- * and should be used in pairs
- */
-export type ParsingContext = {
- predicate: YamlVisitorPredicate;
- picker: ExtrasPicker;
-};
-
-/**
- * A function predicate to select a YAML node containing JS code
- */
-export type YamlVisitorPredicate = (key: any, node: any, ancestors: any) => boolean;
-
-/**
- * A function that picks extra data to save in EmbeddedJS
- */
-export type ExtrasPicker = (key: any, node: any, ancestors: any) => {};
-
-/**
- * Parses YAML file and extracts JS code according to the provided predicate
- */
-export function parseYaml(parsingContexts: ParsingContext[], text: string): EmbeddedJS[] {
- /**
- * Builds the abstract syntax tree of the YAML file
- *
- * YAML supports a marker "---" that indicates the end of a document: a file may contain multiple documents.
- * This means that it can return multiple abstract syntax trees.
- */
- const lineCounter = new yaml.LineCounter();
- const tokens = new yaml.Parser(lineCounter.addNewLine).parse(text);
- const docs = new yaml.Composer({ keepSourceTokens: true }).compose(tokens);
-
- const embeddedJSs: EmbeddedJS[] = [];
- for (const doc of docs) {
- /**
- * Although there could be multiple parsing errors in the YAML file, we only consider
- * the first error to be consistent with how parsing errors are returned when parsing
- * standalone JavaScript source files.
- */
- if (doc.errors.length > 0) {
- const error = doc.errors[0];
- throw APIError.parsingError(error.message, { line: lineCounter.linePos(error.pos[0]).line });
- }
-
- /**
- * Extract the embedded JavaScript snippets from the YAML abstract syntax tree
- */
- yaml.visit(doc, {
- Pair(key: any, pair: any, ancestors: any) {
- for (const currentContext of parsingContexts) {
- if (currentContext.predicate(key, pair, ancestors) && isSupportedFormat(pair)) {
- const { value, srcToken } = pair;
- const code = srcToken.value.source;
- const format = pair.value.type;
-
- /**
- * This assertion should never fail because the visited node denotes either an AWS Lambda
- * or an AWS Serverless with embedded JavaScript code that can be extracted at this point.
- */
- assert(code != null, 'An extracted embedded JavaScript snippet should be defined.');
-
- const [offsetStart] = value.range;
- const { line, col: column } = lineCounter.linePos(offsetStart);
- const lineStarts = lineCounter.lineStarts;
-
- embeddedJSs.push({
- code,
- line,
- column,
- offset: fixOffset(offsetStart, value.type),
- lineStarts,
- text,
- format,
- extras: currentContext.picker(key, pair, ancestors),
- });
- }
- }
- },
- });
- }
-
- return embeddedJSs;
-
- /**
- * Fixes the offset of the beginning of the embedded JavaScript snippet in the YAML file,
- * as it changes depending on the type of the embedding format.
- */
- function fixOffset(offset: number, format: string): number {
- if ([BLOCK_FOLDED_FORMAT, BLOCK_LITERAL_FORMAT].includes(format)) {
- /* +1 for the block marker (`>` or `|`) and +1 for the line break */
- return offset + 2;
- } else {
- return offset;
- }
- }
-}
diff --git a/eslint-bridge/src/routing/errors/index.ts b/eslint-bridge/src/routing/errors/index.ts
deleted file mode 100644
index a748093f52c..00000000000
--- a/eslint-bridge/src/routing/errors/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './middleware';
diff --git a/eslint-bridge/src/routing/errors/middleware.ts b/eslint-bridge/src/routing/errors/middleware.ts
deleted file mode 100644
index 3d9ca6dcea2..00000000000
--- a/eslint-bridge/src/routing/errors/middleware.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { APIError, ErrorCode } from 'errors';
-import { JsTsAnalysisOutput } from 'services/analysis';
-
-/**
- * Express.js middleware for handling error while serving requests.
- *
- * The purpose of this middleware is to catch any error occuring within
- * the different layers of the bridge to centralize and customize error
- * information that is sent back.
- *
- * The fourth parameter is necessary to identify this as an error middleware.
- * @see https://expressjs.com/en/guide/error-handling.html
- */
-export function errorMiddleware(
- error: Error,
- _request: express.Request,
- response: express.Response,
- _next: express.NextFunction,
-) {
- const { code, message, data } =
- error instanceof APIError ? error : APIError.unexpectedError(error.message);
- switch (code) {
- case ErrorCode.Parsing:
- response.json({
- parsingError: {
- message,
- code,
- line: data?.line,
- },
- ...EMPTY_JSTS_ANALYSIS_OUTPUT,
- });
- break;
- case ErrorCode.FailingTypeScript:
- case ErrorCode.LinterInitialization:
- response.json({
- parsingError: {
- message,
- code,
- },
- });
- break;
- default:
- console.error(error.stack);
- response.json({ error: error.message });
- break;
- }
-}
-
-/**
- * An empty JavaScript / TypeScript analysis output sent back on paring errors.
- */
-export const EMPTY_JSTS_ANALYSIS_OUTPUT: JsTsAnalysisOutput = {
- issues: [],
- highlights: [],
- highlightedSymbols: [],
- metrics: {
- ncloc: [],
- commentLines: [],
- nosonarLines: [],
- executableLines: [],
- functions: 0,
- statements: 0,
- classes: 0,
- complexity: 0,
- cognitiveComplexity: 0,
- },
- cpdTokens: [],
- perf: {
- parseTime: 0,
- analysisTime: 0,
- },
-};
diff --git a/eslint-bridge/src/routing/index.ts b/eslint-bridge/src/routing/index.ts
deleted file mode 100644
index 1ebd20f8153..00000000000
--- a/eslint-bridge/src/routing/index.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import onAnalyzeCss from './on-analyze-css';
-import onAnalyzeJs from './on-analyze-js';
-import onAnalyzeTs from './on-analyze-ts';
-import onAnalyzeYaml from './on-analyze-yaml';
-import onCreateProgram from './on-create-program';
-import onDeleteProgram from './on-delete-program';
-import onInitLinter from './on-init-linter';
-import onNewTSConfig from './on-new-tsconfig';
-import onStatus from './on-status';
-import onTSConfigFiles from './on-tsconfig-files';
-import onCreateTSConfigFile from './on-create-tsconfig-file';
-
-const router = express.Router();
-
-router.post('/analyze-css', onAnalyzeCss);
-router.post('/analyze-js', onAnalyzeJs);
-router.post('/analyze-ts', onAnalyzeTs);
-router.post('/analyze-with-program', onAnalyzeTs);
-router.post('/analyze-yaml', onAnalyzeYaml);
-router.post('/create-program', onCreateProgram);
-router.post('/delete-program', onDeleteProgram);
-router.post('/init-linter', onInitLinter);
-router.post('/new-tsconfig', onNewTSConfig);
-router.get('/status', onStatus);
-router.post('/tsconfig-files', onTSConfigFiles);
-router.post('/create-tsconfig-file', onCreateTSConfigFile);
-
-export default router;
diff --git a/eslint-bridge/src/routing/on-analyze-css.ts b/eslint-bridge/src/routing/on-analyze-css.ts
deleted file mode 100644
index 37e0d5ce14e..00000000000
--- a/eslint-bridge/src/routing/on-analyze-css.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { runner, analyzeCSS, CssAnalysisInput } from 'services/analysis';
-
-/**
- * Handles CSS analysis requests
- */
-export default runner(input => analyzeCSS(input as CssAnalysisInput));
diff --git a/eslint-bridge/src/routing/on-analyze-js.ts b/eslint-bridge/src/routing/on-analyze-js.ts
deleted file mode 100644
index dac0349a3f0..00000000000
--- a/eslint-bridge/src/routing/on-analyze-js.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { runner, analyzeJSTS, JsTsAnalysisInput } from 'services/analysis';
-
-/**
- * Handles JavaScript analysis requests
- */
-export default runner(input => Promise.resolve(analyzeJSTS(input as JsTsAnalysisInput, 'js')));
diff --git a/eslint-bridge/src/routing/on-analyze-ts.ts b/eslint-bridge/src/routing/on-analyze-ts.ts
deleted file mode 100644
index 33356118e8f..00000000000
--- a/eslint-bridge/src/routing/on-analyze-ts.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { runner, analyzeJSTS, JsTsAnalysisInput } from 'services/analysis';
-
-/**
- * Handles TypeScript analysis requests
- */
-export default runner(input => Promise.resolve(analyzeJSTS(input as JsTsAnalysisInput, 'ts')));
diff --git a/eslint-bridge/src/routing/on-analyze-yaml.ts b/eslint-bridge/src/routing/on-analyze-yaml.ts
deleted file mode 100644
index bc265ff5822..00000000000
--- a/eslint-bridge/src/routing/on-analyze-yaml.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { runner, analyzeYAML, YamlAnalysisInput } from 'services/analysis';
-
-/**
- * Handles YAML analysis requests
- */
-export default runner(input => Promise.resolve(analyzeYAML(input as YamlAnalysisInput)));
diff --git a/eslint-bridge/src/routing/on-create-program.ts b/eslint-bridge/src/routing/on-create-program.ts
deleted file mode 100644
index 74856208219..00000000000
--- a/eslint-bridge/src/routing/on-create-program.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { createProgram } from 'services/program';
-
-/**
- * Handles TypeScript Program creation requests
- */
-export default async function (
- request: express.Request,
- response: express.Response,
- next: express.NextFunction,
-) {
- try {
- const { tsConfig } = request.body;
- response.json(await createProgram(tsConfig));
- } catch (error) {
- next(error);
- }
-}
diff --git a/eslint-bridge/src/routing/on-create-tsconfig-file.ts b/eslint-bridge/src/routing/on-create-tsconfig-file.ts
deleted file mode 100644
index 63da841226f..00000000000
--- a/eslint-bridge/src/routing/on-create-tsconfig-file.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { writeTSConfigFile } from 'services/tsconfig';
-
-/**
- * Handles TSConfig file creation requests
- */
-export default async function (
- request: express.Request,
- response: express.Response,
- next: express.NextFunction,
-) {
- try {
- const tsconfig = request.body;
- response.json(await writeTSConfigFile(tsconfig));
- } catch (error) {
- next(error);
- }
-}
diff --git a/eslint-bridge/src/routing/on-delete-program.ts b/eslint-bridge/src/routing/on-delete-program.ts
deleted file mode 100644
index 37870bfa9d3..00000000000
--- a/eslint-bridge/src/routing/on-delete-program.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { deleteProgram } from 'services/program';
-
-/**
- * Handles TypeScript Program deletion requests
- */
-export default function (request: express.Request, response: express.Response) {
- const { programId } = request.body;
- deleteProgram(programId);
- response.send('OK!');
-}
diff --git a/eslint-bridge/src/routing/on-init-linter.ts b/eslint-bridge/src/routing/on-init-linter.ts
deleted file mode 100644
index e81b6f9850f..00000000000
--- a/eslint-bridge/src/routing/on-init-linter.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { initializeLinter, RuleConfig } from 'linting/eslint';
-
-/**
- * Handles initialization requests of the global ESLint linter wrappers
- *
- * The bridge relies on a global ESLint linter wrapper for JavaScript
- * and TypeScript analysis. Before any analysis, the linter wrapper
- * must be initialized explicitly, which includes the rules from the
- * active quality profile the linter must consider as well as global
- * variables ann JavaScript execution environments.
- */
-export default function (request: express.Request, response: express.Response) {
- const { rules, environments, globals, linterId } = request.body;
- initializeLinter(rules as RuleConfig[], environments as string[], globals as string[], linterId);
- response.send('OK!');
-}
diff --git a/eslint-bridge/src/routing/on-new-tsconfig.ts b/eslint-bridge/src/routing/on-new-tsconfig.ts
deleted file mode 100644
index c19b07ac808..00000000000
--- a/eslint-bridge/src/routing/on-new-tsconfig.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { clearTypeScriptESLintParserCaches } from 'parsing/jsts';
-
-/**
- * Handles new TSConfig-based analysis requests
- */
-export default function (_request: express.Request, response: express.Response) {
- clearTypeScriptESLintParserCaches();
- response.send('OK!');
-}
diff --git a/eslint-bridge/src/routing/on-status.ts b/eslint-bridge/src/routing/on-status.ts
deleted file mode 100644
index f192e4e41e0..00000000000
--- a/eslint-bridge/src/routing/on-status.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-
-/**
- * Handles status requests
- *
- * This endpoint handler allows the sensor to make sure that the bridge is alive
- * and can continue handle analysis requests or any other kind of request.
- */
-export default function (_request: express.Request, response: express.Response) {
- response.send('OK!');
-}
diff --git a/eslint-bridge/src/routing/on-tsconfig-files.ts b/eslint-bridge/src/routing/on-tsconfig-files.ts
deleted file mode 100644
index b836df3882e..00000000000
--- a/eslint-bridge/src/routing/on-tsconfig-files.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { getFilesForTsConfig } from 'services/tsconfig';
-
-/**
- * Handles TSConfig files resolving requests
- *
- * TSConfig-based analysis either for JavaScript or TypeScript requires first
- * resolving the files to be analyzed based on provided TSConfigs. The logic
- * of the whole resolving lies in the bridge since it includes and bundles
- * TypeScript dependency, which is able to parse and analyze TSConfig files.
- */
-export default function (
- request: express.Request,
- response: express.Response,
- next: express.NextFunction,
-) {
- try {
- const tsconfig = request.body.tsconfig;
- response.json(getFilesForTsConfig(tsconfig));
- } catch (error) {
- next(error);
- }
-}
diff --git a/eslint-bridge/src/routing/timeout/index.ts b/eslint-bridge/src/routing/timeout/index.ts
deleted file mode 100644
index a748093f52c..00000000000
--- a/eslint-bridge/src/routing/timeout/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './middleware';
diff --git a/eslint-bridge/src/routing/timeout/middleware.ts b/eslint-bridge/src/routing/timeout/middleware.ts
deleted file mode 100644
index c9aa6d8ea4f..00000000000
--- a/eslint-bridge/src/routing/timeout/middleware.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import Timeout from './timeout';
-
-/**
- * Express.js middleware that timeouts after a lapse of time and triggers a function.
- * @param f the timeout function
- * @param delay the timeout delay
- * @returns the timeout middleware with capability to stop the internal timeout
- */
-export function timeoutMiddleware(f: () => void, delay: number) {
- const timeout = new Timeout(f, delay);
- timeout.start();
-
- return {
- middleware(_request: express.Request, response: express.Response, next: express.NextFunction) {
- timeout.stop();
-
- response.on('finish', function () {
- timeout.start();
- });
- next();
- },
- stop() {
- timeout.stop();
- },
- };
-}
diff --git a/eslint-bridge/src/routing/timeout/timeout.ts b/eslint-bridge/src/routing/timeout/timeout.ts
deleted file mode 100644
index 3ec55fa1802..00000000000
--- a/eslint-bridge/src/routing/timeout/timeout.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Wrapper of Node.js timeout.
- *
- * The purpose of this wrapper is to rely on a single reference of Node.js timeout,
- * start the timeout to execute a function at a given delay, and stop it on demand.
- */
-export default class Timeout {
- private timeout: NodeJS.Timeout | null = null;
-
- /**
- * Builds a wrapper of Node.js timeout.
- * @param f the function to be executed after the timer expires.
- * @param delay The time in milliseconds that the timer should wait.
- */
- constructor(private readonly f: () => void, private readonly delay: number) {}
-
- /**
- * Starts the timeout.
- */
- start() {
- this.stop();
- this.timeout = setTimeout(this.f, this.delay);
- }
-
- /**
- * Stops the timeout.
- */
- stop() {
- if (this.timeout) {
- clearTimeout(this.timeout);
- this.timeout = null;
- }
- }
-}
diff --git a/eslint-bridge/src/server.ts b/eslint-bridge/src/server.ts
deleted file mode 100644
index b2743e8248b..00000000000
--- a/eslint-bridge/src/server.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * `module-alias` must be imported first for module aliasing to work.
- */
-import 'module-alias/register';
-
-import express from 'express';
-import http from 'http';
-import router from 'routing';
-import { errorMiddleware } from 'routing/errors';
-import { debug } from 'helpers';
-import { timeoutMiddleware } from 'routing/timeout';
-import { AddressInfo } from 'net';
-
-/**
- * The maximum request body size
- */
-const MAX_REQUEST_SIZE = '50mb';
-
-/**
- * The default timeout to shut down server if no request is received
- *
- * Normally, the Java plugin sends keepalive requests to the eslint-bridge
- * If the Java plugin crashes, this timeout will run out and shut down
- * the eslint-bridge to prevent it from becoming an orphan process.
- */
-const SHUTDOWN_TIMEOUT = 15_000;
-
-/**
- * Starts the bridge
- *
- * The bridge is an Express.js web server that exposes several services
- * through a REST API. Once started, the bridge first begins by loading
- * any provided rule bundles and then waits for incoming requests.
- *
- * Communication between two ends is entirely done with the JSON format.
- *
- * Although a web server, the bridge is not exposed to the outside world
- * but rather exclusively communicate either with the JavaScript plugin
- * which embeds it or directly with SonarLint.
- *
- * @param port the port to listen to
- * @param host only for usage from outside of NodeJS - Java plugin, SonarLint, ...
- * @param timeout timeout in ms to shut down the server if unresponsive
- * @returns an http server
- */
-export function start(
- port = 0,
- host = '127.0.0.1',
- timeout = SHUTDOWN_TIMEOUT,
-): Promise {
- return new Promise(resolve => {
- debug(`starting eslint-bridge server at port ${port}`);
-
- const app = express();
- const server = http.createServer(app);
-
- /**
- * Builds a timeout middleware to shut down the server
- * in case the process becomes orphan.
- */
- const orphanTimeout = timeoutMiddleware(() => {
- if (server.listening) {
- server.close();
- }
- }, timeout);
-
- /**
- * The order of the middlewares registration is important, as the
- * error handling one should be last.
- */
- app.use(express.json({ limit: MAX_REQUEST_SIZE }));
- app.use(orphanTimeout.middleware);
- app.use(router);
- app.use(errorMiddleware);
-
- app.post('/close', (_request: express.Request, response: express.Response) => {
- debug('eslint-bridge server will shutdown');
- response.end(() => {
- server.close();
- });
- });
-
- server.on('close', () => {
- debug('eslint-bridge server closed');
- orphanTimeout.stop();
- });
-
- server.on('error', (err: Error) => {
- debug(`eslint-bridge server error: ${err}`);
- });
-
- server.on('listening', () => {
- /**
- * Since we use 0 as the default port, Node.js assigns a random port to the server,
- * which we get using server.address().
- */
- debug(`eslint-bridge server is running at port ${(server.address() as AddressInfo)?.port}`);
- resolve(server);
- });
-
- server.listen(port, host);
- });
-}
diff --git a/eslint-bridge/src/services/analysis/analysis.ts b/eslint-bridge/src/services/analysis/analysis.ts
deleted file mode 100644
index f1a8523d5fb..00000000000
--- a/eslint-bridge/src/services/analysis/analysis.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * An analysis function
- *
- * Every analysis consumes an input and produces an output regardless of whether
- * the analysis denotes a CSS analysis, a JavaScript one or another kind.
- *
- * _The return type is a JavaScript Promise to have a common API between all
- * types of analysis, especially because of CSS analyses which uses Stylelint._
- */
-export type Analysis = (input: AnalysisInput) => Promise;
-
-/**
- * An analysis input
- *
- * An analysis always operates on a file, be it from its path
- * or its content for any type of analysis.
- *
- * @param filePath the path of the file to analyze
- * @param fileContent the content of the file to analyze
- */
-export interface AnalysisInput {
- filePath: string;
- fileContent: string;
- linterId?: string;
-}
-
-/**
- * An analysis output
- *
- * A common interface for all kinds of analysis output.
- */
-export interface AnalysisOutput {}
diff --git a/eslint-bridge/src/services/analysis/analyzers/css/analysis.ts b/eslint-bridge/src/services/analysis/analyzers/css/analysis.ts
deleted file mode 100644
index a89f1d3dabd..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/css/analysis.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Issue, RuleConfig } from 'linting/stylelint';
-import { AnalysisInput, AnalysisOutput } from 'services/analysis';
-
-/**
- * A CSS analysis input
- *
- * A CSS analysis input only needs an input file and a set
- * of rule configurations to analyze a stylesheet.
- *
- * @param rules the rules from the active quality profile
- */
-export interface CssAnalysisInput extends AnalysisInput {
- rules: RuleConfig[];
-}
-
-/**
- * A CSS analysis output
- *
- * Computing data analysis like metrics does nit realy makes
- * sense in the context of stylesheets. Therefore, only issues
- * form the content of a CSS analysis output beside an analysis
- * error.
- *
- * @param issues
- */
-export interface CssAnalysisOutput extends AnalysisOutput {
- issues: Issue[];
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/css/analyzer.ts b/eslint-bridge/src/services/analysis/analyzers/css/analyzer.ts
deleted file mode 100644
index 48ca739d6b3..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/css/analyzer.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { createStylelintConfig, linter } from 'linting/stylelint';
-import { CssAnalysisInput, CssAnalysisOutput } from './analysis';
-
-/**
- * Analyzes a CSS analysis input
- *
- * Analyzing a CSS analysis input is rather straighforward. All that is needed
- * is to create a Stylelint configuration based on the rules from the active
- * quality profile and uses this configuration to linter the input file.
- *
- * @param input the CSS analysis input to analyze
- * @returns a promise of the CSS analysis output
- */
-export async function analyzeCSS(input: CssAnalysisInput): Promise {
- const { filePath, fileContent: code, rules } = input;
- const config = createStylelintConfig(rules);
- const options = {
- code,
- codeFilename: filePath,
- config,
- };
- return linter.lint(filePath, options);
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/css/index.ts b/eslint-bridge/src/services/analysis/analyzers/css/index.ts
deleted file mode 100644
index 5b68ee4afe3..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/css/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './analysis';
-export * from './analyzer';
diff --git a/eslint-bridge/src/services/analysis/analyzers/index.ts b/eslint-bridge/src/services/analysis/analyzers/index.ts
deleted file mode 100644
index 5aa3c0326b0..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './css';
-export * from './js';
-export * from './yaml';
diff --git a/eslint-bridge/src/services/analysis/analyzers/js/analysis.ts b/eslint-bridge/src/services/analysis/analyzers/js/analysis.ts
deleted file mode 100644
index f8a066b040a..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/js/analysis.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { FileType } from 'helpers';
-import { CpdToken, Issue, Metrics, SymbolHighlight, SyntaxHighlight } from 'linting/eslint';
-import { AnalysisInput, AnalysisOutput } from 'services/analysis';
-import { Perf } from 'services/monitoring';
-
-/**
- * A partial JavaScript / TypeScript analysis input
- *
- * _A common interface for both TSConfig-based and Program-based analysis inputs._
- *
- * @param fileType the file type to select the proper linting configuration
- * @param ignoreHeaderComments a flag used by some rules to ignore header comments
- */
-interface PartialJsTsAnalysisInput extends AnalysisInput {
- fileType: FileType;
- ignoreHeaderComments?: boolean;
-}
-
-/**
- * A TSConfig-based analysis input for JavaScript / TypeScript
- *
- * A TSConfig-based analysis relies on an automatically created TypeScript Program's
- * instance by TypeScript ESLint parser, which leaves to it the lifecycle of such an
- * instance.
- *
- * The JavaScript analyzer performs TSConfig-based analysis for JavaScript, which can
- * benefit from available type information and improve the precision of some rules.
- *
- * @param tsConfigs a list of TSConfigs
- */
-export interface TSConfigBasedAnalysisInput extends PartialJsTsAnalysisInput {
- tsConfigs: string[];
-}
-
-/**
- * A program-based analysis input for JavaScript / TypeScript
- *
- * A program-based analysis relies on a manually created TypeScript Program's
- * instance based on a TSConfig to control the lifecycle of the main internal
- * data structure used by TypeScript ESLint parser for performance reasons.
- *
- * The JavaScript analyzer performs program-based analysis for TypeScript.
- *
- * @param programId the identifier of a TypeScript Program's instance
- */
-export interface ProgramBasedAnalysisInput extends PartialJsTsAnalysisInput {
- programId: string;
-}
-
-/**
- * A JavaScript / TypeScript analysis input
- */
-export type JsTsAnalysisInput = TSConfigBasedAnalysisInput | ProgramBasedAnalysisInput;
-
-/**
- * A JavaScript / TypeScript analysis output
- */
-export interface JsTsAnalysisOutput extends AnalysisOutput {
- issues: Issue[];
- highlights?: SyntaxHighlight[];
- highlightedSymbols?: SymbolHighlight[];
- metrics?: Metrics;
- cpdTokens?: CpdToken[];
- perf?: Perf;
- ucfgPaths?: string[];
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/js/analyzer.ts b/eslint-bridge/src/services/analysis/analyzers/js/analyzer.ts
deleted file mode 100644
index 6b90e4ffd37..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/js/analyzer.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { APIError } from 'errors';
-import { SourceCode } from 'eslint';
-import { debug, getContext } from 'helpers';
-import {
- computeMetrics,
- findNoSonarLines,
- getCpdTokens,
- getSyntaxHighlighting,
- getLinter,
- SymbolHighlight,
- LinterWrapper,
-} from 'linting/eslint';
-import { buildSourceCode, Language } from 'parsing/jsts';
-import { measureDuration } from 'services/monitoring';
-import { JsTsAnalysisInput, JsTsAnalysisOutput } from './analysis';
-
-/**
- * Analyzes a JavaScript / TypeScript analysis input
- *
- * Analyzing a JavaScript / TypeScript analysis input implies building
- * an ESLint SourceCode instance, meaning parsing the actual code to get
- * an abstract syntax tree to operate on. Any parsing error is returned
- * immediately. Otherwise, the analysis proceeds with the actual linting
- * of the source code. The linting result is returned along with some
- * analysis performance data.
- *
- * The analysis requires that global linter wrapper is initialized.
- *
- * @param input the JavaScript / TypeScript analysis input to analyze
- * @param language the language of the analysis input
- * @returns the JavaScript / TypeScript analysis output
- */
-export function analyzeJSTS(input: JsTsAnalysisInput, language: Language): JsTsAnalysisOutput {
- debug(`Analyzing file "${input.filePath}" with linterId "${input.linterId}"`);
- const linter = getLinter(input.linterId);
- const building = () => buildSourceCode(input, language);
- const { result: built, duration: parseTime } = measureDuration(building);
- const analysis = () => analyzeFile(linter, input, built);
- const { result: output, duration: analysisTime } = measureDuration(analysis);
- return { ...output, perf: { parseTime, analysisTime } };
-}
-
-/**
- * Analyzes a parsed ESLint SourceCode instance
- *
- * Analyzing a parsed ESLint SourceCode instance consists in linting the source code
- * and computing extended metrics about the code. At this point, the linting results
- * are already SonarQube-compatible and can be consumed back as such by the sensor.
- *
- * @param linter the linter to use for the analysis
- * @param input the JavaScript / TypeScript analysis input to analyze
- * @param sourceCode the corresponding parsed ESLint SourceCode instance
- * @returns the JavaScript / TypeScript analysis output
- */
-function analyzeFile(
- linter: LinterWrapper,
- input: JsTsAnalysisInput,
- sourceCode: SourceCode,
-): JsTsAnalysisOutput {
- try {
- const { filePath, fileType } = input;
- const { issues, highlightedSymbols, cognitiveComplexity, ucfgPaths } = linter.lint(
- sourceCode,
- filePath,
- fileType,
- );
- const extendedMetrics = computeExtendedMetrics(
- input,
- sourceCode,
- highlightedSymbols,
- cognitiveComplexity,
- );
- return { issues, ucfgPaths, ...extendedMetrics };
- } catch (e) {
- /** Turns exceptions from TypeScript compiler into "parsing" errors */
- if (e.stack.indexOf('typescript.js:') > -1) {
- throw APIError.failingTypeScriptError(e.message);
- } else {
- throw e;
- }
- }
-}
-
-/**
- * Computes extended metrics about the analyzed code
- *
- * Computed extended metrics may differ depending on the analysis context:
- *
- * - SonarLint doesn't care about code metrics except for `NOSONAR` comments
- * - All kinds of metrics are considered for main files.
- * - Symbol highlighting, syntax highlighting and `NOSONAR` comments are only consider
- * for test files.
- *
- * @param input the JavaScript / TypeScript analysis input to analyze
- * @param sourceCode the analyzed ESLint SourceCode instance
- * @param highlightedSymbols the computed symbol highlighting of the code
- * @param cognitiveComplexity the computed cognitive complexity of the code
- * @returns the extended metrics of the code
- */
-function computeExtendedMetrics(
- input: JsTsAnalysisInput,
- sourceCode: SourceCode,
- highlightedSymbols: SymbolHighlight[],
- cognitiveComplexity?: number,
-) {
- if (getContext().sonarlint) {
- return { metrics: findNoSonarLines(sourceCode) };
- }
- const { fileType, ignoreHeaderComments } = input;
- if (fileType === 'MAIN') {
- return {
- highlightedSymbols,
- highlights: getSyntaxHighlighting(sourceCode).highlights,
- metrics: computeMetrics(sourceCode, !!ignoreHeaderComments, cognitiveComplexity),
- cpdTokens: getCpdTokens(sourceCode).cpdTokens,
- };
- } else {
- return {
- highlightedSymbols,
- highlights: getSyntaxHighlighting(sourceCode).highlights,
- metrics: findNoSonarLines(sourceCode),
- };
- }
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/js/index.ts b/eslint-bridge/src/services/analysis/analyzers/js/index.ts
deleted file mode 100644
index 5b68ee4afe3..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/js/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './analysis';
-export * from './analyzer';
diff --git a/eslint-bridge/src/services/analysis/analyzers/yaml/analysis.ts b/eslint-bridge/src/services/analysis/analyzers/yaml/analysis.ts
deleted file mode 100644
index b88255d9967..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/yaml/analysis.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Issue } from 'linting/eslint';
-import { AnalysisInput, AnalysisOutput } from 'services/analysis';
-
-/**
- * A YAML analysis input
- *
- * (currently empty but might change later on)
- */
-export interface YamlAnalysisInput extends AnalysisInput {}
-
-/**
- * A YAML analysis output
- *
- * A YAML analysis only returns issues that were found during
- * linting. Because the JavaScript analyzer doesn't "own" the
- * `YAML` language, it cannot save anything else than issues
- * using SonarQube API, especially analysis data like metrics.
- *
- * @param issues the found issues
- */
-export interface YamlAnalysisOutput extends AnalysisOutput {
- issues: Issue[];
- ucfgPaths?: string[];
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/yaml/analyzer.ts b/eslint-bridge/src/services/analysis/analyzers/yaml/analyzer.ts
deleted file mode 100644
index f04ec81af5a..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/yaml/analyzer.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { Position } from 'estree';
-import { getLinter, Issue } from 'linting/eslint';
-import { buildSourceCodes } from 'parsing/yaml';
-import { YamlAnalysisInput, YamlAnalysisOutput } from './analysis';
-import { debug } from 'helpers';
-
-/**
- * An empty YAML analysis output
- */
-export const EMPTY_YAML_ANALYSIS_OUTPUT: YamlAnalysisOutput = {
- issues: [],
-};
-
-/**
- * Analyzes a YAML analysis input
- *
- * Analyzing a YAML analysis input is part of analyzing inline JavaScript code
- * within various file formats, YAML here. The function first starts by parsing
- * the YAML fle to validate its syntax and to get in return an abstract syntax
- * tree. This abstract syntax tree is then used to extract embedded JavaScript
- * code. As YAML files might embed several JavaScript snippets, the function
- * builds an ESLint SourceCode instance for each snippet using the same utility
- * as for building source code for regular JavaScript analysis inputs. However,
- * since a YAML file can potentially produce multiple ESLint SourceCode instances,
- * the function stops to the first JavaScript parsing error and returns it without
- * considering any other. If all abstract syntax trees are valid, the function
- * then proceeds with linting each of them, aggregates, and returns the results.
- *
- * The analysis requires that global linter wrapper is initialized.
- *
- * @param input the YAML analysis input
- * @returns the YAML analysis output
- */
-export function analyzeYAML(input: YamlAnalysisInput): YamlAnalysisOutput {
- debug(`Analyzing file "${input.filePath}" with linterId "${input.linterId}"`);
- const linter = getLinter(input.linterId);
- const extendedSourceCodes = buildSourceCodes(input);
- const aggregatedIssues: Issue[] = [];
- const aggregatedUcfgPaths: string[] = [];
- for (const extendedSourceCode of extendedSourceCodes) {
- const { issues, ucfgPaths } = linter.lint(
- extendedSourceCode,
- extendedSourceCode.syntheticFilePath,
- 'MAIN',
- );
- const filteredIssues = removeYamlIssues(extendedSourceCode, issues);
- aggregatedIssues.push(...filteredIssues);
- aggregatedUcfgPaths.push(...ucfgPaths);
- }
-
- return { issues: aggregatedIssues, ucfgPaths: aggregatedUcfgPaths };
-
- /**
- * Filters out issues outside of JS code.
- *
- * This is necessary because we patch the SourceCode object
- * to include all the YAML files in its properties outside its AST.
- * So rules that operate on SourceCode.text get flagged.
- */
- function removeYamlIssues(sourceCode: SourceCode, issues: Issue[]) {
- const [jsStart, jsEnd] = sourceCode.ast.range.map(offset => sourceCode.getLocFromIndex(offset));
- return issues.filter(issue => {
- const issueStart = { line: issue.line, column: issue.column };
- return isBeforeOrEqual(jsStart, issueStart) && isBeforeOrEqual(issueStart, jsEnd);
- });
-
- function isBeforeOrEqual(a: Position, b: Position) {
- if (a.line < b.line) {
- return true;
- } else if (a.line > b.line) {
- return false;
- } else {
- return a.column <= b.column;
- }
- }
- }
-}
diff --git a/eslint-bridge/src/services/analysis/analyzers/yaml/index.ts b/eslint-bridge/src/services/analysis/analyzers/yaml/index.ts
deleted file mode 100644
index 5b68ee4afe3..00000000000
--- a/eslint-bridge/src/services/analysis/analyzers/yaml/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './analysis';
-export * from './analyzer';
diff --git a/eslint-bridge/src/services/analysis/index.ts b/eslint-bridge/src/services/analysis/index.ts
deleted file mode 100644
index 5719f3f463e..00000000000
--- a/eslint-bridge/src/services/analysis/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './analyzers';
-export * from './analysis';
-export * from './runner';
diff --git a/eslint-bridge/src/services/analysis/runner.ts b/eslint-bridge/src/services/analysis/runner.ts
deleted file mode 100644
index f8b3e1b6173..00000000000
--- a/eslint-bridge/src/services/analysis/runner.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { Analysis } from './analysis';
-import { readFile } from 'helpers';
-
-/**
- * Runs an analysis
- *
- * This function is a generic analyzer used for any kind of analysis request,
- * be it a YAML, CSS, JavaScrip or TypeScript analysis request. The point is
- * to centralize the extraction of the analysis input, executes the concrete
- * analysis function, and either return the analysis output or forward back
- * any analysis error to the requester.
- *
- * @param analysis the analysis function to run
- */
-export function runner(analysis: Analysis): express.RequestHandler {
- return async (
- request: express.Request,
- response: express.Response,
- next: express.NextFunction,
- ) => {
- try {
- const input = request.body;
- if (input.filePath && !input.fileContent) {
- input.fileContent = await readFile(input.filePath);
- }
- const output = await analysis(input);
- response.json(output);
- } catch (error) {
- next(error);
- }
- };
-}
diff --git a/eslint-bridge/src/services/monitoring/index.ts b/eslint-bridge/src/services/monitoring/index.ts
deleted file mode 100644
index 812e0e82316..00000000000
--- a/eslint-bridge/src/services/monitoring/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './measure';
-export * from './performance';
diff --git a/eslint-bridge/src/services/monitoring/measure.ts b/eslint-bridge/src/services/monitoring/measure.ts
deleted file mode 100644
index 6e6b74c68cc..00000000000
--- a/eslint-bridge/src/services/monitoring/measure.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { hrtime } from 'process';
-
-/**
- * Mesures the running time of a function
- * @param f a function to run
- * @returns the returned value of the function and its running time
- */
-export function measureDuration(f: () => T): { result: T; duration: number } {
- const start = hrtime.bigint();
- const result = f();
- const duration = Math.round(Number(hrtime.bigint() - start) / 1_000);
- return { result, duration };
-}
diff --git a/eslint-bridge/src/services/monitoring/performance.ts b/eslint-bridge/src/services/monitoring/performance.ts
deleted file mode 100644
index 128757d2125..00000000000
--- a/eslint-bridge/src/services/monitoring/performance.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * A container of performance information
- *
- * It is used for analysis monitoring purpose.
- *
- * @param parseTime the parsing time
- * @param analysisTime the analysis time
- */
-export interface Perf {
- parseTime: number;
- analysisTime: number;
-}
diff --git a/eslint-bridge/src/services/program/index.ts b/eslint-bridge/src/services/program/index.ts
deleted file mode 100644
index 1c55ae5265a..00000000000
--- a/eslint-bridge/src/services/program/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './program';
diff --git a/eslint-bridge/src/services/program/program.ts b/eslint-bridge/src/services/program/program.ts
deleted file mode 100644
index 3a3293fce8e..00000000000
--- a/eslint-bridge/src/services/program/program.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * This file provides an API to take control over TypeScript's Program instances
- * in the context of program-based analysis for JavaScript / TypeScript.
- *
- * A TypeScript's Program instance is used by TypeScript ESLint parser in order
- * to make available TypeScript's type checker for rules willing to use type
- * information for the sake of precision. It works similarly as using TSConfigs
- * except it gives the control over the lifecycle of this internal data structure
- * used by the parser and improves performance.
- */
-
-import path from 'path';
-import ts from 'typescript';
-import { addTsConfigIfDirectory, debug, toUnixPath } from 'helpers';
-
-/**
- * A cache of created TypeScript's Program instances
- *
- * It associates a program identifier to an instance of a TypeScript's Program.
- */
-const programs = new Map();
-
-/**
- * A counter of created TypeScript's Program instances
- */
-let programCount = 0;
-
-/**
- * Computes the next identifier available for a TypeScript's Program.
- * @returns
- */
-function nextId() {
- programCount++;
- return programCount.toString();
-}
-
-/**
- * Gets an existing TypeScript's Program by its identifier
- * @param programId the identifier of the TypeScript's Program to retrieve
- * @throws a runtime error if there is no such program
- * @returns the retrieved TypeScript's Program
- */
-export function getProgramById(programId: string): ts.Program {
- const program = programs.get(programId);
- if (!program) {
- throw Error(`Failed to find program ${programId}`);
- }
- return program;
-}
-
-export function createProgramOptions(
- tsConfig: string,
-): ts.CreateProgramOptions & { missingTsConfig: boolean } {
- let missingTsConfig = false;
-
- const parseConfigHost: ts.ParseConfigHost = {
- useCaseSensitiveFileNames: true,
- readDirectory: ts.sys.readDirectory,
- fileExists: file => {
- // When Typescript checks for the very last tsconfig.json, we will always return true,
- // If the file does not exist in FS, we will return an empty configuration
- if (isLastTsConfigCheck(file)) {
- return true;
- }
- return ts.sys.fileExists(file);
- },
- readFile: file => {
- const fileContents = ts.sys.readFile(file);
- // When Typescript search for tsconfig which does not exist, return empty configuration
- // only when the check is for the last location at the root node_modules
- if (!fileContents && isLastTsConfigCheck(file)) {
- missingTsConfig = true;
- console.log(
- `WARN Could not find tsconfig.json: ${file}; falling back to an empty configuration.`,
- );
- return '{}';
- }
- return fileContents;
- },
- };
- const config = ts.readConfigFile(tsConfig, parseConfigHost.readFile);
-
- if (config.error) {
- console.error(`Failed to parse tsconfig: ${tsConfig} (${diagnosticToString(config.error)})`);
- throw Error(diagnosticToString(config.error));
- }
-
- const parsedConfigFile = ts.parseJsonConfigFileContent(
- config.config,
- parseConfigHost,
- path.resolve(path.dirname(tsConfig)),
- {
- noEmit: true,
- },
- tsConfig,
- /** We can provide additional options here (property 'extraFileExtensions') to include .vue files */
- );
-
- if (parsedConfigFile.errors.length > 0) {
- const message = parsedConfigFile.errors.map(diagnosticToString).join('; ');
- throw Error(message);
- }
-
- return {
- rootNames: parsedConfigFile.fileNames,
- options: { ...parsedConfigFile.options, allowNonTsExtensions: true },
- projectReferences: parsedConfigFile.projectReferences,
- missingTsConfig,
- };
-}
-
-/**
- * Creates a TypeScript's Program instance
- *
- * TypeScript creates a Program instance per TSConfig file. This means that one
- * needs a TSConfig to create such a program. Therefore, the function expects a
- * TSConfig as an input, parses it and uses it to create a TypeScript's Program
- * instance. The program creation delegates to TypeScript the resolving of input
- * files considered by the TSConfig as well as any project references.
- *
- * @param tsConfig the TSConfig input to create a program for
- * @returns the identifier of the created TypeScript's Program along with the
- * resolved files, project references and a boolean 'missingTsConfig'
- * which is true when an extended tsconfig.json path was not found,
- * which defaulted to default Typescript configuration
- */
-export async function createProgram(tsConfig: string): Promise<{
- programId: string;
- files: string[];
- projectReferences: string[];
- missingTsConfig: boolean;
-}> {
- const programOptions = createProgramOptions(tsConfig);
-
- const program = ts.createProgram(programOptions);
- const inputProjectReferences = program.getProjectReferences() || [];
- const projectReferences: string[] = [];
-
- for (const reference of inputProjectReferences) {
- const sanitizedReference = await addTsConfigIfDirectory(reference.path);
- if (!sanitizedReference) {
- console.log(`WARN Skipping missing referenced tsconfig.json: ${reference.path}`);
- } else {
- projectReferences.push(sanitizedReference);
- }
- }
- const files = program.getSourceFiles().map(sourceFile => sourceFile.fileName);
-
- const programId = nextId();
- programs.set(programId, program);
- debug(`program from ${tsConfig} with id ${programId} is created`);
-
- return {
- programId,
- files,
- projectReferences,
- missingTsConfig: programOptions.missingTsConfig,
- };
-}
-
-/**
- * Deletes an existing TypeScript's Program by its identifier
- * @param programId the identifier of the TypeScript's Program to delete
- */
-export function deleteProgram(programId: string): void {
- programs.delete(programId);
-}
-
-function diagnosticToString(diagnostic: ts.Diagnostic): string {
- const text =
- typeof diagnostic.messageText === 'string'
- ? diagnostic.messageText
- : diagnostic.messageText.messageText;
- if (diagnostic.file) {
- return `${text} ${diagnostic.file?.fileName}:${diagnostic.start}`;
- } else {
- return text;
- }
-}
-
-/**
- * Typescript resolution will always search for extended tsconfigs in these 4 paths (in order):
- *
- * 1 - $TSCONFIG_PATH/node_modules/$EXTENDED_TSCONFIG_VALUE/package.json
- * 2 - $TSCONFIG_PATH/node_modules/$EXTENDED_TSCONFIG_VALUE/../package.json
- * 3 - $TSCONFIG_PATH/node_modules/$EXTENDED_TSCONFIG_VALUE
- * 4 - $TSCONFIG_PATH/node_modules/$EXTENDED_TSCONFIG_VALUE/tsconfig.json
- *
- * If not found in all 4, $TSCONFIG_PATH will be assigned to its parent and the same search will be performed,
- * until $TSCONFIG_PATH is the system root. Meaning, the very last search Typescript will perform is (4) when
- * TSCONFIG_PATH === '/':
- *
- * /node_modules/$EXTENDED_TSCONFIG_VALUE/tsconfig.json
- *
- * @param file
- */
-function isLastTsConfigCheck(file: string) {
- return path.basename(file) === 'tsconfig.json' && isRootNodeModules(file);
-}
-
-export function isRootNodeModules(file: string) {
- const root = process.platform === 'win32' ? file.slice(0, file.indexOf(':') + 1) : '/';
- const normalizedFile = toUnixPath(file);
- const topNodeModules = toUnixPath(path.resolve(path.join(root, 'node_modules')));
- return normalizedFile.startsWith(topNodeModules);
-}
diff --git a/eslint-bridge/src/services/tsconfig/index.ts b/eslint-bridge/src/services/tsconfig/index.ts
deleted file mode 100644
index 99fc97b7eee..00000000000
--- a/eslint-bridge/src/services/tsconfig/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './tsconfig';
diff --git a/eslint-bridge/src/services/tsconfig/tsconfig.ts b/eslint-bridge/src/services/tsconfig/tsconfig.ts
deleted file mode 100644
index b03a8d9cc1d..00000000000
--- a/eslint-bridge/src/services/tsconfig/tsconfig.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as path from 'path';
-import * as ts from 'typescript';
-import tmp from 'tmp';
-import fs from 'fs/promises';
-import { promisify } from 'util';
-
-/**
- * Gets the files resolved by a TSConfig
- *
- * The resolving of the files for a given TSConfig file is done
- * by invoking TypeScript compiler.
- *
- * @param tsConfig TSConfig to parse
- * @param parseConfigHost parsing configuration
- * @returns the resolved TSConfig files
- */
-export function getFilesForTsConfig(
- tsConfig: string,
- parseConfigHost: ts.ParseConfigHost = {
- useCaseSensitiveFileNames: true,
- readDirectory: ts.sys.readDirectory,
- fileExists: ts.sys.fileExists,
- readFile: ts.sys.readFile,
- },
-): { files: string[]; projectReferences: string[] } {
- const config = ts.readConfigFile(tsConfig, parseConfigHost.readFile);
-
- if (config.error !== undefined) {
- console.error(`Failed to parse tsconfig: ${tsConfig} (${config.error.messageText})`);
- throw Error(diagnosticToString(config.error));
- }
-
- const parsed = ts.parseJsonConfigFileContent(
- config.config,
- parseConfigHost,
- path.resolve(path.dirname(tsConfig)),
- {
- noEmit: true,
- },
- undefined,
- undefined,
- [
- {
- extension: '.vue',
- scriptKind: ts.ScriptKind.Deferred,
- isMixedContent: true,
- },
- ],
- );
-
- if (parsed.errors.length > 0) {
- let error = '';
- parsed.errors.forEach(d => {
- error += diagnosticToString(d);
- });
- throw new Error(error);
- }
-
- const projectReferences = parsed.projectReferences
- ? parsed.projectReferences.map(p => p.path)
- : [];
-
- return { files: parsed.fileNames, projectReferences };
-}
-
-/**
- * Any temporary file created with the `tmp` library will be removed once the Node.js process terminates.
- */
-tmp.setGracefulCleanup();
-
-/**
- * Create the TSConfig file and returns its path.
- *
- * The file is written in a temporary location in the file system and is marked to be removed after Node.js process terminates.
- *
- * @param tsConfig TSConfig to write
- * @returns the resolved TSConfig file path
- */
-export async function writeTSConfigFile(tsConfig: any): Promise<{ filename: string }> {
- const filename = await promisify(tmp.file)();
- await fs.writeFile(filename, JSON.stringify(tsConfig), 'utf-8');
- return { filename };
-}
-
-function diagnosticToString(diagnostic: ts.Diagnostic): string {
- if (typeof diagnostic.messageText === 'string') {
- return diagnostic.messageText;
- } else {
- return diagnostic.messageText.messageText;
- }
-}
diff --git a/eslint-bridge/src/tsconfig.json b/eslint-bridge/src/tsconfig.json
deleted file mode 100644
index f10e03f9c21..00000000000
--- a/eslint-bridge/src/tsconfig.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "module": "commonjs",
- "lib": ["es2018"],
- "declaration": true,
- "outDir": "../lib",
- "strict": true,
- "sourceMap": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "allowSyntheticDefaultImports": true,
- "composite": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "useUnknownInCatchVariables": false,
- "forceConsistentCasingInFileNames": true,
- "typeRoots": [
- "../node_modules/@types",
- "../typings"
- ],
- "baseUrl": ".",
- "paths": {
- "errors": ["./errors"],
- "helpers": ["./helpers"],
- "linting": ["./linting"],
- "parsing": ["./parsing"],
- "routing": ["./routing"],
- "services": ["./services"]
- }
- }
-}
diff --git a/eslint-bridge/tests/fixtures/routing.js b/eslint-bridge/tests/fixtures/routing.js
deleted file mode 100644
index 6aaae9db6d1..00000000000
--- a/eslint-bridge/tests/fixtures/routing.js
+++ /dev/null
@@ -1 +0,0 @@
-f(g(x));;
diff --git a/eslint-bridge/tests/helpers/context.test.ts b/eslint-bridge/tests/helpers/context.test.ts
deleted file mode 100644
index 73672f5de5a..00000000000
--- a/eslint-bridge/tests/helpers/context.test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { setContext, getContext } from 'helpers';
-
-describe('context', () => {
- const initialCtx = {
- workDir: '/',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: [],
- };
-
- beforeEach(() => {
- setContext(initialCtx);
- });
-
- it('should get context', () => {
- expect(getContext()).toEqual(initialCtx);
- });
-
- it('should set context', () => {
- const newContext = {
- workDir: '/tmp/workdir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: true,
- bundles: ['custom-rule'],
- };
- setContext(newContext);
- expect(getContext()).toEqual(newContext);
- });
-});
diff --git a/eslint-bridge/tests/helpers/debug.test.ts b/eslint-bridge/tests/helpers/debug.test.ts
deleted file mode 100644
index 9782885acd4..00000000000
--- a/eslint-bridge/tests/helpers/debug.test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { debug } from 'helpers';
-
-describe('debug', () => {
- it('should log with a `DEBUG` prefix', () => {
- console.log = jest.fn();
- debug('hello, world!');
- expect(console.log).toHaveBeenCalledWith(`DEBUG hello, world!`);
- });
-});
diff --git a/eslint-bridge/tests/helpers/files.test.ts b/eslint-bridge/tests/helpers/files.test.ts
deleted file mode 100644
index c6f7e011c9f..00000000000
--- a/eslint-bridge/tests/helpers/files.test.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { readFile } from 'helpers';
-
-describe('readFile', () => {
- it('should read a file', async () => {
- const contents = await readFile(path.join(__dirname, 'fixtures', 'file.js'));
- expect(contents).toBe('file();');
- });
-
- it('should remove any BOM header', async () => {
- const contents = await readFile(path.join(__dirname, 'fixtures', 'bom.js'));
- expect(contents).toBe('bom();');
- });
-});
diff --git a/eslint-bridge/tests/helpers/fixtures/bom.js b/eslint-bridge/tests/helpers/fixtures/bom.js
deleted file mode 100644
index 0f41d071ab1..00000000000
--- a/eslint-bridge/tests/helpers/fixtures/bom.js
+++ /dev/null
@@ -1 +0,0 @@
-bom();
\ No newline at end of file
diff --git a/eslint-bridge/tests/helpers/fixtures/file.js b/eslint-bridge/tests/helpers/fixtures/file.js
deleted file mode 100644
index 9896d9848ea..00000000000
--- a/eslint-bridge/tests/helpers/fixtures/file.js
+++ /dev/null
@@ -1 +0,0 @@
-file();
\ No newline at end of file
diff --git a/eslint-bridge/tests/linting/eslint/linter/bundle-loader.test.ts b/eslint-bridge/tests/linting/eslint/linter/bundle-loader.test.ts
deleted file mode 100755
index 9ea6a95ae4e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/bundle-loader.test.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter } from 'eslint';
-import { loadBundles, loadCustomRules } from 'linting/eslint/linter/bundle-loader';
-import { CustomRule } from 'linting/eslint';
-import path from 'path';
-import { setContext } from 'helpers';
-
-describe('BundleLoader', () => {
- it('should only load rules when requested', async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: ['custom-rule-bundle'],
- });
-
- const linter = new Linter();
-
- const customRuleId = 'custom-rule-file';
- const customRules: CustomRule[] = [
- {
- ruleId: customRuleId,
- ruleConfig: [],
- ruleModule: require(path.join(__dirname, 'fixtures', 'wrapper', 'custom-rule.ts')).rule,
- },
- ];
-
- expect(linter.getRules().get('max-params')).toBeDefined();
- expect(linter.getRules().get('sonar-max-params')).toBeUndefined();
- expect(linter.getRules().get('no-small-switch')).toBeUndefined();
- expect(linter.getRules().get('react-in-jsx-scope')).toBeUndefined();
- expect(linter.getRules().get('custom-rule-file')).toBeUndefined();
- expect(linter.getRules().get('custom-rule')).toBeUndefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadBundles(linter, ['internalRules']);
- expect(linter.getRules().get('sonar-max-params')).toBeDefined();
- expect(linter.getRules().get('no-small-switch')).toBeUndefined();
- expect(linter.getRules().get('react-in-jsx-scope')).toBeUndefined();
- expect(linter.getRules().get('custom-rule-file')).toBeUndefined();
- expect(linter.getRules().get('custom-rule')).toBeUndefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadBundles(linter, ['pluginRules']);
- expect(linter.getRules().get('no-small-switch')).toBeDefined();
- expect(linter.getRules().get('react-in-jsx-scope')).toBeUndefined();
- expect(linter.getRules().get('custom-rule-file')).toBeUndefined();
- expect(linter.getRules().get('custom-rule')).toBeUndefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadBundles(linter, ['externalRules']);
- expect(linter.getRules().get('react-in-jsx-scope')).toBeDefined();
- expect(linter.getRules().get('custom-rule-file')).toBeUndefined();
- expect(linter.getRules().get('custom-rule')).toBeUndefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadCustomRules(linter, customRules);
- expect(linter.getRules().get('custom-rule-file')).toBeDefined();
- expect(linter.getRules().get('custom-rule')).toBeUndefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadBundles(linter, ['contextRules']);
- expect(linter.getRules().get('custom-rule')).toBeDefined();
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeUndefined();
-
- loadBundles(linter, ['internalCustomRules']);
- expect(linter.getRules().get('internal-cognitive-complexity')).toBeDefined();
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/config/linter-config.test.ts b/eslint-bridge/tests/linting/eslint/linter/config/linter-config.test.ts
deleted file mode 100644
index 6a8b720f69e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/config/linter-config.test.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { setContext } from 'helpers';
-import { createLinterConfig, RuleConfig } from 'linting/eslint';
-
-describe('createLinterConfig', () => {
- beforeEach(() => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: [],
- });
- });
-
- it('should enable environments', () => {
- const { env } = createLinterConfig([], new Map(), ['node', 'jquery'], []);
- expect(env).toEqual(
- expect.objectContaining({
- node: true,
- jquery: true,
- }),
- );
- });
-
- it('should enable globals', () => {
- const { globals } = createLinterConfig([], new Map(), [], ['_', '$']);
- expect(globals).toEqual(
- expect.objectContaining({
- _: true,
- $: true,
- }),
- );
- });
-
- it('should enable rules', () => {
- const inputRules: RuleConfig[] = [{ key: 'foo', configurations: [], fileTypeTarget: ['MAIN'] }];
- const linterRules = new Map([
- ['foo', { module: 42 } as any as Rule.RuleModule],
- ['bar', { module: 24 } as any as Rule.RuleModule],
- ]);
- const { rules } = createLinterConfig(inputRules, linterRules, [], []);
- expect(rules).toEqual(
- expect.objectContaining({
- foo: ['error'],
- }),
- );
- });
-
- it('should enable internal custom rules by default', () => {
- const { rules } = createLinterConfig([], new Map(), [], []);
- expect(rules).toEqual({
- 'internal-cognitive-complexity': ['error', 'metric'],
- 'internal-symbol-highlighting': ['error'],
- });
- });
-
- it('should not enable internal custom rules in SonarLint context', () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: true,
- bundles: [],
- });
- const { rules } = createLinterConfig([], new Map(), [], []);
- expect(rules).toEqual({});
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/config/rule-config.test.ts b/eslint-bridge/tests/linting/eslint/linter/config/rule-config.test.ts
deleted file mode 100644
index 3bcf11a07e4..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/config/rule-config.test.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { setContext } from 'helpers';
-import { extendRuleConfig, RuleConfig } from 'linting/eslint';
-import { SONAR_CONTEXT, SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-describe('extendRuleConfig', () => {
- it('should include `sonar-runtime`', () => {
- const ruleModule = { meta: { schema: [{ enum: SONAR_RUNTIME }] } } as any as Rule.RuleModule;
- const inputRule: RuleConfig = {
- key: 'some-rule',
- configurations: [42],
- fileTypeTarget: ['MAIN'],
- };
-
- const config = extendRuleConfig(ruleModule, inputRule);
- expect(config).toEqual([42, SONAR_RUNTIME]);
- });
-
- it('should include the context', () => {
- const ctx = {
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- };
- setContext(ctx);
-
- const ruleModule = { meta: { schema: [{ title: SONAR_CONTEXT }] } } as any as Rule.RuleModule;
- const inputRule: RuleConfig = {
- key: 'some-rule',
- configurations: [42],
- fileTypeTarget: ['MAIN'],
- };
-
- const config = extendRuleConfig(ruleModule, inputRule);
- expect(config).toEqual([42, ctx]);
- });
-
- it('should include the context and `sonar-runtime`', () => {
- const ctx = {
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- };
- setContext(ctx);
-
- const ruleModule = {
- meta: { schema: [{ enum: SONAR_RUNTIME, title: SONAR_CONTEXT }] },
- } as any as Rule.RuleModule;
- const inputRule: RuleConfig = {
- key: 'some-rule',
- configurations: [42],
- fileTypeTarget: ['MAIN'],
- };
-
- const config = extendRuleConfig(ruleModule, inputRule);
- expect(config).toEqual([42, SONAR_RUNTIME, ctx]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/decorate.test.ts b/eslint-bridge/tests/linting/eslint/linter/decorations/decorate.test.ts
deleted file mode 100644
index f155320e5b0..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/decorate.test.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { rules as typescriptESLintRules } from '@typescript-eslint/eslint-plugin';
-import { rules as reactESLintRules } from 'eslint-plugin-react';
-import path from 'path';
-import { parseJavaScriptSourceFile, parseTypeScriptSourceFile } from '../../../../tools';
-import { decorateExternalRules } from 'linting/eslint/linter/decoration';
-
-const externalRules = { ...eslintRules, ...typescriptESLintRules, ...reactESLintRules };
-const decoratedExternalRules = decorateExternalRules(externalRules);
-
-describe('decorateExternalRules', () => {
- test.each(['comma-dangle', 'enforce-trailing-comma'])(
- 'should make `enforce-trailing-comma` an alias for `comma-dangle`',
- async ruleId => {
- const linter = new Linter();
- linter.defineRules(decoratedExternalRules);
-
- const filePath = path.join(__dirname, 'fixtures', 'decorate', 'enforce-trailing-comma.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const rules = { [ruleId]: 'error' } as any;
-
- const [message] = linter.verify(sourceCode, { rules });
- expect(message).toEqual(
- expect.objectContaining({
- ruleId,
- }),
- );
- },
- );
-
- it('should replace TypeScript ESLint `no-throw-literal` with ESLint implementation', async () => {
- const linter = new Linter();
- linter.defineRules(decoratedExternalRules);
-
- const filePath = path.join(__dirname, 'fixtures', 'decorate', 'no-throw-literal.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-throw-literal';
- const rules = { [ruleId]: 'error' } as any;
-
- const [message] = linter.verify(sourceCode, { rules });
- expect(message).toEqual(
- expect.objectContaining({
- ruleId,
- }),
- );
- });
-
- it('should sanitize TypeScript ESLint rules', async () => {
- const linter = new Linter();
- linter.defineRules(decoratedExternalRules);
-
- const filePath = path.join(__dirname, 'fixtures', 'decorate', 'sanitization.ts');
- const tsConfigs = [];
-
- const sourceCode = (await parseTypeScriptSourceFile(filePath, tsConfigs)) as SourceCode;
- expect(sourceCode.parserServices.hasFullTypeInformation).toBeDefined();
- expect(sourceCode.parserServices.hasFullTypeInformation).toEqual(false);
-
- const ruleId = 'prefer-readonly';
- const rules = { [ruleId]: 'error' } as any;
-
- const messages = linter.verify(sourceCode, { rules });
- expect(messages).toHaveLength(0);
- });
-
- test.each([{ decorate: true }, { decorate: false }])(
- 'should apply internal decorators',
- async ({ decorate }) => {
- const linter = new Linter();
- linter.defineRules(decorate ? decoratedExternalRules : externalRules);
-
- const filePath = path.join(__dirname, 'fixtures', 'decorate', 'internal-decorator.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'accessor-pairs';
- const rules = { [ruleId]: 'error' } as any;
-
- const messages = linter.verify(sourceCode, { rules });
- if (decorate) {
- expect(messages).toHaveLength(0);
- } else {
- expect(messages).toHaveLength(1);
- expect(messages[0]).toEqual(
- expect.objectContaining({
- ruleId,
- }),
- );
- }
- },
- );
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/enforce-trailing-comma.js b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/enforce-trailing-comma.js
deleted file mode 100644
index 918a4db9c51..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/enforce-trailing-comma.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const obj = {
- foo: 42,
- bar: 24,
-};
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/file.ts b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/file.ts
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/internal-decorator.js b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/internal-decorator.js
deleted file mode 100644
index 154e8f18af6..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/internal-decorator.js
+++ /dev/null
@@ -1,4 +0,0 @@
-class C {
- @Input()
- set m(a) { this.a = a; }
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/no-throw-literal.js b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/no-throw-literal.js
deleted file mode 100644
index 584b0ff1963..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/no-throw-literal.js
+++ /dev/null
@@ -1 +0,0 @@
-throw 'error';
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/sanitization.ts b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/sanitization.ts
deleted file mode 100644
index 56dbc39ccd2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/decorate/sanitization.ts
+++ /dev/null
@@ -1 +0,0 @@
-class C { private static f = 5; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/file.ts b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/file.ts
deleted file mode 100644
index 56dbc39ccd2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/file.ts
+++ /dev/null
@@ -1 +0,0 @@
-class C { private static f = 5; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/tsconfig.json b/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/tsconfig.json
deleted file mode 100644
index ad6a43ea096..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/fixtures/sanitize/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["file.ts"]
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/decorations/sanitize.test.ts b/eslint-bridge/tests/linting/eslint/linter/decorations/sanitize.test.ts
deleted file mode 100644
index 73b145aa6dd..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/decorations/sanitize.test.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rules as typescriptESLintRules } from '@typescript-eslint/eslint-plugin';
-import { Linter, SourceCode } from 'eslint';
-import { sanitizeTypeScriptESLintRule } from 'linting/eslint/linter/decoration/sanitize';
-import path from 'path';
-import { parseTypeScriptSourceFile } from '../../../../tools/helpers';
-
-const cases = [
- {
- action: 'prevent',
- typing: 'available',
- tsConfigFiles: [],
- issues: 0,
- },
- {
- action: 'let',
- typing: 'missing',
- tsConfigFiles: ['tsconfig.json'],
- issues: 1,
- },
-];
-
-describe('sanitizeTypeScriptESLintRule', () => {
- test.each(cases)(
- 'should $action a sanitized rule raise issues when type information is $typing',
- async ({ tsConfigFiles, issues }) => {
- const ruleId = 'prefer-readonly';
- const sanitizedRule = sanitizeTypeScriptESLintRule(typescriptESLintRules[ruleId]);
-
- const linter = new Linter();
- linter.defineRule(ruleId, sanitizedRule);
-
- const fixtures = path.join(__dirname, 'fixtures', 'sanitize');
- const filePath = path.join(fixtures, 'file.ts');
- const tsConfigs = tsConfigFiles.map(file => path.join(fixtures, file));
-
- const sourceCode = (await parseTypeScriptSourceFile(filePath, tsConfigs)) as SourceCode;
- const rules = { [ruleId]: 'error' } as any;
-
- const messages = linter.verify(sourceCode, { rules });
- expect(messages).toHaveLength(issues);
- },
- );
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/package.json b/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/package.json
deleted file mode 100644
index bca8f802b08..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "custom-rule-bundle",
- "version": "1.0.0",
- "main": "rules.js"
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/rules.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/rules.js
deleted file mode 100644
index 6c153221d5a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom-rule-bundle/rules.js
+++ /dev/null
@@ -1,19 +0,0 @@
-exports.rules = [
- {
- ruleId: "custom-rule",
- ruleModule: {
- create(context) {
- return {
- CallExpression(node) {
- console.log("detected call expression");
- context.report({
- node: node.callee,
- message: "call",
- });
- },
- };
- },
- },
- ruleConfig: [],
- },
-];
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom.js
deleted file mode 100644
index eb28ef4401b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/custom.js
+++ /dev/null
@@ -1 +0,0 @@
-foo()
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/regular.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/index/regular.js
deleted file mode 100644
index 6aaae9db6d1..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/index/regular.js
+++ /dev/null
@@ -1 +0,0 @@
-f(g(x));;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/cognitive-symbol.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/cognitive-symbol.js
deleted file mode 100644
index 753758136da..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/cognitive-symbol.js
+++ /dev/null
@@ -1 +0,0 @@
-if (true) if (true) if (true) return; let x = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/constructor-super.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/constructor-super.js
deleted file mode 100644
index b728ff5176d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/constructor-super.js
+++ /dev/null
@@ -1,2 +0,0 @@
-class A extends B { constructor() {this.bar();}}
-class A extends B { constructor(a) { while (a) super(); } }
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.js
deleted file mode 100644
index f6850141785..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.js
+++ /dev/null
@@ -1 +0,0 @@
-'Today here, tomorrow the world!';
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.ts
deleted file mode 100644
index f10f1399328..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/custom-rule.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Rule } from "eslint";
-
-/**
- * A rule definition used for testing purpose as a custom rule,
- * which highlights the injection of the global context
- */
-const rule: Rule.RuleModule = {
- meta: {
- schema: [
- {
- title: 'sonar-context',
- type: 'object',
- properties: {
- workDir: {
- type: 'string',
- },
- },
- },
- ],
- },
- create(context: Rule.RuleContext) {
- const [{ workDir }] = context.options
- return {
- Literal: node => {
- context.report({
- node,
- message: `Visited '${node.value}' literal from a custom rule with injected contextual workDir '${workDir}'.`
- });
- }
- };
- },
-};
-
-export { rule };
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/decorated.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/decorated.js
deleted file mode 100644
index d56a745a9a8..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/decorated.js
+++ /dev/null
@@ -1 +0,0 @@
-'foo' + 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/env.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/env.js
deleted file mode 100644
index 2d16f252d79..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/env.js
+++ /dev/null
@@ -1 +0,0 @@
-var alert = 1;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-config.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-config.js
deleted file mode 100644
index 7e616ad346c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-config.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*eslint max-params: ["error", 1]*/
-function foo(a, b){}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-react.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-react.js
deleted file mode 100644
index 390a2780042..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-react.js
+++ /dev/null
@@ -1,7 +0,0 @@
-var Welcome = createReactClass({
- render: function() {
- return (
- // empty p
- );
- }
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-sonarjs.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-sonarjs.js
deleted file mode 100644
index e87f5ae4df2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint-plugin-sonarjs.js
+++ /dev/null
@@ -1 +0,0 @@
-if (true) 42; else 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint.js
deleted file mode 100644
index 675c3dd17b9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/eslint.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log(42);;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/file-type.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/file-type.js
deleted file mode 100644
index 786900f4379..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/file-type.js
+++ /dev/null
@@ -1 +0,0 @@
-var foo = 42;;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/global.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/global.js
deleted file mode 100644
index 3373eccc5b7..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/global.js
+++ /dev/null
@@ -1 +0,0 @@
-var angular = 1;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/internal.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/internal.js
deleted file mode 100644
index 7e082f1393c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/internal.js
+++ /dev/null
@@ -1 +0,0 @@
-new Symbol(42);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/comma-dangle.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/comma-dangle.js
deleted file mode 100644
index 559622d2b5f..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/comma-dangle.js
+++ /dev/null
@@ -1 +0,0 @@
-foo(a,);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/different-types-comparison.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/different-types-comparison.js
deleted file mode 100644
index 4825e0dde6e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/different-types-comparison.js
+++ /dev/null
@@ -1 +0,0 @@
-"foo" === 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/disabled.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/disabled.js
deleted file mode 100644
index a89c8bb5c9c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/disabled.js
+++ /dev/null
@@ -1,2 +0,0 @@
-if (cond) { foo()
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/eol-last.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/eol-last.js
deleted file mode 100644
index ad4acad6f5a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/eol-last.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log(42)
\ No newline at end of file
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/inverted-assertion-arguments.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/inverted-assertion-arguments.js
deleted file mode 100644
index e4ba81a2c85..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/inverted-assertion-arguments.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const assert = require('chai').assert;
-describe('suite', () => {
- it('test', () => {
- assert.fail(42, n);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-alphabetical-sort.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-alphabetical-sort.ts
deleted file mode 100644
index 7a4b7cdbf82..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-alphabetical-sort.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const numbers = [42, 42_42, 42_42];
-numbers.sort();
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-collection-size-mischeck.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-collection-size-mischeck.js
deleted file mode 100644
index 85a47763f32..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-collection-size-mischeck.js
+++ /dev/null
@@ -1 +0,0 @@
-[].length >= 0;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-commented-code.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-commented-code.js
deleted file mode 100644
index f6e80f7e3e7..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-commented-code.js
+++ /dev/null
@@ -1 +0,0 @@
-// if (42) {};
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-dupe-keys.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-dupe-keys.js
deleted file mode 100644
index eff87dd03a6..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-dupe-keys.js
+++ /dev/null
@@ -1,4 +0,0 @@
-let o = {
- foo: 42,
- foo: 24
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-imports.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-imports.js
deleted file mode 100644
index 47f469ed138..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-imports.js
+++ /dev/null
@@ -1 +0,0 @@
-import "foo"; import "foo"
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-in-composite.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-in-composite.ts
deleted file mode 100644
index 00511dedbbb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-duplicate-in-composite.ts
+++ /dev/null
@@ -1 +0,0 @@
-type T = number | number | string;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-function.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-function.js
deleted file mode 100644
index 23a0439a996..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-function.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function f() {
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-interface.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-interface.ts
deleted file mode 100644
index ed2a0f0ecd4..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty-interface.ts
+++ /dev/null
@@ -1 +0,0 @@
-interface A extends B {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty.js
deleted file mode 100644
index 3168f13f7d5..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-empty.js
+++ /dev/null
@@ -1 +0,0 @@
-if (42) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-exclusive-tests.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-exclusive-tests.js
deleted file mode 100644
index 6d3784467fc..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-exclusive-tests.js
+++ /dev/null
@@ -1 +0,0 @@
-describe.only('exclusive test', function () {});
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-explicit-any.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-explicit-any.ts
deleted file mode 100644
index 32a76e1d2c8..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-explicit-any.ts
+++ /dev/null
@@ -1 +0,0 @@
-let x: any;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-extra-semi.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-extra-semi.js
deleted file mode 100644
index fed8a2f88b4..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-extra-semi.js
+++ /dev/null
@@ -1 +0,0 @@
-foo();;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-global-this.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-global-this.js
deleted file mode 100644
index eb840168bc0..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-global-this.js
+++ /dev/null
@@ -1 +0,0 @@
-this.window = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-in-misuse.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-in-misuse.js
deleted file mode 100644
index 74db0585b24..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-in-misuse.js
+++ /dev/null
@@ -1 +0,0 @@
-"1" in ["a", "b", "c"];
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inferrable-types.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inferrable-types.ts
deleted file mode 100644
index b8aa5adc12d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inferrable-types.ts
+++ /dev/null
@@ -1 +0,0 @@
-function foo(x: number = 42){}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inverted-boolean-check.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inverted-boolean-check.js
deleted file mode 100644
index 75b8d2fa22c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-inverted-boolean-check.js
+++ /dev/null
@@ -1 +0,0 @@
-if (!(x < 2)) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-non-null-assertion.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-non-null-assertion.js
deleted file mode 100644
index 13fafaa4998..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-non-null-assertion.js
+++ /dev/null
@@ -1 +0,0 @@
-if (x.foo!.bar) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-primitive-wrappers.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-primitive-wrappers.js
deleted file mode 100644
index 06799ed883d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-primitive-wrappers.js
+++ /dev/null
@@ -1 +0,0 @@
-let n = new Number(42);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-jump.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-jump.js
deleted file mode 100644
index 6d7f168d40a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-jump.js
+++ /dev/null
@@ -1,4 +0,0 @@
-function f() {
- console.log(42);
- return;
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-optional.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-optional.ts
deleted file mode 100644
index 5d3a5dd4dfc..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-optional.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-interface I {
- p?: string | undefined;
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-parentheses.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-parentheses.js
deleted file mode 100644
index cdcee9a2f22..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-redundant-parentheses.js
+++ /dev/null
@@ -1 +0,0 @@
-typeof ((42))
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-throw-literal.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-throw-literal.js
deleted file mode 100644
index f8aa023d8de..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-throw-literal.js
+++ /dev/null
@@ -1 +0,0 @@
-throw 'foo';
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-trailing-spaces.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-trailing-spaces.js
deleted file mode 100644
index fb3d7528405..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-trailing-spaces.js
+++ /dev/null
@@ -1,2 +0,0 @@
-foo();
-var x = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-undefined-argument.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-undefined-argument.js
deleted file mode 100644
index a6f8b1993a2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-undefined-argument.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function foo(p = 42) {};
-foo(undefined);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-arguments.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-arguments.ts
deleted file mode 100644
index 717ee7402b3..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-arguments.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-function foo() {}
-foo();
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-assertion.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-assertion.ts
deleted file mode 100644
index 85a3ee8e13d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unnecessary-type-assertion.ts
+++ /dev/null
@@ -1 +0,0 @@
-function foo(p: number) { let x = p as number; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unreachable.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unreachable.js
deleted file mode 100644
index b85055c82ca..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unreachable.js
+++ /dev/null
@@ -1,4 +0,0 @@
-function f() {
- return 42;
- console.log(24);
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unsafe-negation.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unsafe-negation.js
deleted file mode 100644
index 540221fe3ef..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unsafe-negation.js
+++ /dev/null
@@ -1 +0,0 @@
-if (!prop in obj) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unthrown-error.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unthrown-error.js
deleted file mode 100644
index 098dcec8cd7..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unthrown-error.js
+++ /dev/null
@@ -1 +0,0 @@
-new Error();
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unused-function-argument.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unused-function-argument.js
deleted file mode 100644
index d34e87b5d62..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-unused-function-argument.js
+++ /dev/null
@@ -1 +0,0 @@
-function f(p) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-var.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-var.js
deleted file mode 100644
index be92fda52c3..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/no-var.js
+++ /dev/null
@@ -1 +0,0 @@
-var foo = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/non-existent-operator.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/non-existent-operator.js
deleted file mode 100644
index 1b090d67ddb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/non-existent-operator.js
+++ /dev/null
@@ -1 +0,0 @@
-a =+ 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/object-shorthand.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/object-shorthand.js
deleted file mode 100644
index 950be598b28..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/object-shorthand.js
+++ /dev/null
@@ -1 +0,0 @@
-let x = {a: a};
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-const.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-const.js
deleted file mode 100644
index f0a998574ec..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-const.js
+++ /dev/null
@@ -1 +0,0 @@
-let x = 42; foo(x);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-for-of.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-for-of.js
deleted file mode 100644
index a71401dea74..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-for-of.js
+++ /dev/null
@@ -1 +0,0 @@
-for (let i = 0; i < a.length; ++i) console.log(a[i]);
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-immediate-return.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-immediate-return.js
deleted file mode 100644
index edfb099adb8..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-immediate-return.js
+++ /dev/null
@@ -1 +0,0 @@
-function foo() { let x = 42; return x; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-namespace-keyword.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-namespace-keyword.ts
deleted file mode 100644
index 69faee898a4..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-namespace-keyword.ts
+++ /dev/null
@@ -1 +0,0 @@
-module myModule {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-promise-shorthand.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-promise-shorthand.js
deleted file mode 100644
index 432ae1ff8fa..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-promise-shorthand.js
+++ /dev/null
@@ -1 +0,0 @@
-new Promise(resolve => resolve(42))
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-readonly.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-readonly.ts
deleted file mode 100644
index cf57fb82d64..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-readonly.ts
+++ /dev/null
@@ -1 +0,0 @@
-class A { private _x: number }
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-regex-literals.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-regex-literals.js
deleted file mode 100644
index df6b8e9fee9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-regex-literals.js
+++ /dev/null
@@ -1 +0,0 @@
-RegExp('foo');
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-single-boolean-return.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-single-boolean-return.js
deleted file mode 100644
index 929aaec13a4..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-single-boolean-return.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function f(p) {
- if (p) {
- return true;
- } else {
- return false;
- }
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-template.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-template.js
deleted file mode 100644
index f56c38cffbb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-template.js
+++ /dev/null
@@ -1 +0,0 @@
-var str = "Hello, " + name + "!";
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-type-guard.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-type-guard.ts
deleted file mode 100644
index 771cc94d059..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-type-guard.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-function isT(t: T) {
- return (t as T).t !== undefined;
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-while.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-while.js
deleted file mode 100644
index e127405bd36..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/prefer-while.js
+++ /dev/null
@@ -1 +0,0 @@
-for (;i < 0;) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/quotes.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/quotes.js
deleted file mode 100644
index ef8394d3f2c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/quotes.js
+++ /dev/null
@@ -1 +0,0 @@
-let x = 'Hey';
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/radix.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/radix.js
deleted file mode 100644
index 4c896c4ed94..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/radix.js
+++ /dev/null
@@ -1 +0,0 @@
-parseInt("42");
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/semi.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/semi.js
deleted file mode 100644
index eb28ef4401b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/semi.js
+++ /dev/null
@@ -1 +0,0 @@
-foo()
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/tsconfig.json b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/tsconfig.json
deleted file mode 100644
index 4a560157cf9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "allowJs": true
- },
- "include": ["./*.ts", "./*.js"]
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/unused-import.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/unused-import.js
deleted file mode 100644
index 96467d4f51b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/unused-import.js
+++ /dev/null
@@ -1 +0,0 @@
-import { foo } from 'foo';
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/use-isnan.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/use-isnan.js
deleted file mode 100644
index 5c0f661994b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/quickfixes/use-isnan.js
+++ /dev/null
@@ -1 +0,0 @@
-42 === NaN
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/sanitized.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/sanitized.ts
deleted file mode 100644
index 654bb15f99d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/sanitized.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-class C {
- private static p = 42;
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/secondary-location.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/secondary-location.js
deleted file mode 100644
index 29ec6ff8a85..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/secondary-location.js
+++ /dev/null
@@ -1 +0,0 @@
-var a = typeof ((42));
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/file.js b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/file.js
deleted file mode 100644
index 11bfbc29a7b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/file.js
+++ /dev/null
@@ -1,2 +0,0 @@
-let str = 'foo', num = 42;
-str === num;
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/tsconfig.json b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/tsconfig.json
deleted file mode 100644
index 778026eead3..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/type-aware/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "allowJs": true
- },
- "files": ["file.js"]
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/typescript-eslint.ts b/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/typescript-eslint.ts
deleted file mode 100644
index fe84c0b0f95..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/fixtures/wrapper/typescript-eslint.ts
+++ /dev/null
@@ -1 +0,0 @@
-const x: Array = [42, 24];
diff --git a/eslint-bridge/tests/linting/eslint/linter/index.test.ts b/eslint-bridge/tests/linting/eslint/linter/index.test.ts
deleted file mode 100644
index 16c379a6a0a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/index.test.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { SourceCode } from 'eslint';
-import { setContext } from 'helpers';
-import { initializeLinter, getLinter, LinterWrapper } from 'linting/eslint';
-import { parseJavaScriptSourceFile } from '../../../tools';
-
-describe('initializeLinter', () => {
- beforeEach(() => {
- jest.resetModules();
- });
-
- it('should initialize the linter wrapper', async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: [],
- });
-
- console.log = jest.fn();
-
- expect(getLinter).toThrow();
-
- initializeLinter([{ key: 'no-extra-semi', configurations: [], fileTypeTarget: ['MAIN'] }]);
-
- const linter = getLinter();
-
- expect(linter).toBeDefined();
- expect(linter).toBeInstanceOf(LinterWrapper);
- expect(console.log).toHaveBeenCalledWith(
- 'DEBUG Initializing linter "default" with no-extra-semi',
- );
-
- const filePath = path.join(__dirname, 'fixtures', 'index', 'regular.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const {
- issues: [issue],
- } = linter.lint(sourceCode, filePath);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-extra-semi',
- line: 1,
- column: 8,
- }),
- );
- });
-
- it('should load rule bundles', async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: ['custom-rule-bundle'],
- });
-
- console.log = jest.fn();
-
- initializeLinter([{ key: 'custom-rule', configurations: [], fileTypeTarget: ['MAIN'] }]);
-
- const linter = getLinter();
-
- expect(linter).toBeDefined();
- expect(console.log).toHaveBeenCalledWith(
- 'DEBUG Loaded rules custom-rule from custom-rule-bundle',
- );
- expect(console.log).toHaveBeenCalledWith(
- 'DEBUG Initializing linter "default" with custom-rule',
- );
-
- const filePath = path.join(__dirname, 'fixtures', 'index', 'custom.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const {
- issues: [issue],
- } = linter.lint(sourceCode, filePath);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'custom-rule',
- line: 1,
- column: 0,
- endLine: 1,
- endColumn: 3,
- message: 'call',
- }),
- );
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/decode.test.ts b/eslint-bridge/tests/linting/eslint/linter/issues/decode.test.ts
deleted file mode 100644
index 173f5a11d31..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/decode.test.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Issue } from 'linting/eslint/linter/issues';
-import { decodeSonarRuntime } from 'linting/eslint/linter/issues/decode';
-import { SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-describe('decodeSonarRuntime', () => {
- it('should decode sonar-runtime-like issues', () => {
- const rule = { meta: { schema: [{ enum: [SONAR_RUNTIME] }] } } as any;
- const encoded = {
- ruleId: 'fake',
- message: JSON.stringify({
- foo: 42,
- }),
- } as Issue;
- const decoded = decodeSonarRuntime(rule, encoded) as any;
- expect(decoded).toEqual({
- ruleId: 'fake',
- foo: 42,
- message: '{"foo":42}',
- });
- });
-
- it('should fail decoding malformed sonar-runtime-like issues', () => {
- const rule = { meta: { schema: [{ enum: [SONAR_RUNTIME] }] } } as any;
- const malformed = {
- ruleId: 'fake',
- message: '{...',
- } as Issue;
- expect(() => decodeSonarRuntime(rule, malformed)).toThrow(
- /^Failed to parse encoded issue message for rule fake/,
- );
- });
-
- it('should return undecoded issues from a rule that does not activate sonar-runtime', () => {
- const issue = { ruleId: 'fake', line: 42 } as Issue;
- expect(decodeSonarRuntime({} as any, issue)).toEqual(issue);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/extract.test.ts b/eslint-bridge/tests/linting/eslint/linter/issues/extract.test.ts
deleted file mode 100644
index 7086853c571..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/extract.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import {
- extractCognitiveComplexity,
- extractHighlightedSymbols,
- Issue,
-} from 'linting/eslint/linter/issues';
-import { rule as cognitiveComplexityRule } from 'linting/eslint/linter/custom-rules/cognitive-complexity';
-import { rule as symbolHighlightingRule } from 'linting/eslint/linter/custom-rules/symbol-highlighting';
-
-describe('extract', () => {
- it('should extract highlighted symbols', () => {
- const issues: Issue[] = [
- {
- ruleId: symbolHighlightingRule.ruleId,
- line: 1,
- column: 2,
- message: JSON.stringify({
- declaration: { startLine: 1, startCol: 2, endLine: 3, endCol: 4 },
- references: [{ startLine: 10, startCol: 20, endLine: 30, endCol: 40 }],
- }),
- secondaryLocations: [],
- },
- ];
- expect(extractHighlightedSymbols(issues)).toEqual({
- declaration: { startLine: 1, startCol: 2, endLine: 3, endCol: 4 },
- references: [{ startLine: 10, startCol: 20, endLine: 30, endCol: 40 }],
- });
- });
-
- it('should return an empty array of highlighted symbols', () => {
- expect(extractHighlightedSymbols([])).toEqual([]);
- });
-
- it('should extract cognitive complexity', () => {
- const issues: Issue[] = [
- {
- ruleId: cognitiveComplexityRule.ruleId,
- line: 1,
- column: 2,
- message: '42',
- secondaryLocations: [],
- },
- ];
- expect(extractCognitiveComplexity(issues)).toEqual(42);
- });
-
- it('should return undefined on NaN cognitive complexity', () => {
- const issues: Issue[] = [
- {
- ruleId: cognitiveComplexityRule.ruleId,
- line: 1,
- column: 2,
- message: 'nan',
- secondaryLocations: [],
- },
- ];
- expect(extractCognitiveComplexity(issues)).toEqual(undefined);
- });
-
- it('should return undefined on missing cognitive complexity', () => {
- expect(extractCognitiveComplexity([])).toEqual(undefined);
- });
-
- it('should preserve non-extracted issues', () => {
- const issues: Issue[] = [
- {
- ruleId: symbolHighlightingRule.ruleId,
- line: 1,
- column: 2,
- message: JSON.stringify({
- declaration: { startLine: 1, startCol: 2, endLine: 3, endCol: 4 },
- references: [{ startLine: 10, startCol: 20, endLine: 30, endCol: 40 }],
- }),
- secondaryLocations: [],
- },
- {
- ruleId: 'non-extracted-rule',
- line: 1,
- column: 2,
- message: 'non-extract-message',
- secondaryLocations: [],
- },
- {
- ruleId: cognitiveComplexityRule.ruleId,
- line: 1,
- column: 2,
- message: '42',
- secondaryLocations: [],
- },
- ];
- extractHighlightedSymbols(issues);
- extractCognitiveComplexity(issues);
- expect(issues).toEqual([
- {
- ruleId: 'non-extracted-rule',
- line: 1,
- column: 2,
- message: 'non-extract-message',
- secondaryLocations: [],
- },
- ]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/convert.js b/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/convert.js
deleted file mode 100644
index 6692f064fde..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/convert.js
+++ /dev/null
@@ -1 +0,0 @@
-foo(42);;
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/fix.js b/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/fix.js
deleted file mode 100644
index c15a7b742a5..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/fix.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log(foo);;
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/location.js b/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/location.js
deleted file mode 100644
index d4d157d6a75..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/location.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function f(a, b) {
- return g(b);
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/message.js b/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/message.js
deleted file mode 100644
index fc692d8ccd2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/message.js
+++ /dev/null
@@ -1 +0,0 @@
-var n = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/secondary.ts b/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/secondary.ts
deleted file mode 100644
index 00511dedbbb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/fixtures/secondary.ts
+++ /dev/null
@@ -1 +0,0 @@
-type T = number | number | string;
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/message.test.ts b/eslint-bridge/tests/linting/eslint/linter/issues/message.test.ts
deleted file mode 100644
index ce3ca897ad0..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/message.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import { convertMessage } from 'linting/eslint/linter/issues';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../tools';
-
-describe('convertMessage', () => {
- it('should convert an ESLint message into a Sonar issue', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'convert.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-extra-semi';
- const config = { rules: { [ruleId]: 'error' } } as Linter.Config;
-
- const linter = new Linter();
- const [message] = linter.verify(sourceCode, config);
-
- expect(convertMessage(sourceCode, message)).toEqual({
- ruleId,
- line: 1,
- column: 9,
- endLine: 1,
- endColumn: 10,
- message: 'Unnecessary semicolon.',
- quickFixes: [
- {
- message: 'Remove extra semicolon',
- edits: [
- {
- text: ';',
- loc: {
- line: 1,
- column: 7,
- endLine: 1,
- endColumn: 9,
- },
- },
- ],
- },
- ],
- secondaryLocations: [],
- });
- });
-
- it('should return null when an ESLint message is missing a rule id', () => {
- console.error = jest.fn();
- expect(convertMessage({} as SourceCode, {} as Linter.LintMessage)).toEqual(null);
- expect(console.error).toHaveBeenCalledWith("Illegal 'null' ruleId for eslint issue");
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/issues/transform.test.ts b/eslint-bridge/tests/linting/eslint/linter/issues/transform.test.ts
deleted file mode 100644
index 8654512beca..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/issues/transform.test.ts
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import path from 'path';
-import { parseJavaScriptSourceFile, parseTypeScriptSourceFile } from '../../../../tools';
-import { transformMessages } from 'linting/eslint/linter/issues';
-import { rule as noDuplicateInComposite } from 'linting/eslint/rules/no-duplicate-in-composite';
-import { rule as noUnusedFunctionArgument } from 'linting/eslint/rules/no-unused-function-argument';
-
-describe('transformMessages', () => {
- it('should transform ESLint messages', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'message.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-var';
- const config = { rules: { [ruleId]: 'error' } } as any;
-
- const linter = new Linter();
- const messages = linter.verify(sourceCode, config);
-
- const [issue] = transformMessages(messages, { sourceCode, rules: linter.getRules() }).issues;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId,
- line: 1,
- column: 0,
- endLine: 1,
- endColumn: 11,
- message: 'Unexpected var, use let or const instead.',
- }),
- );
- });
-
- it('should normalize ESLint locations', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'location.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-unused-function-argument';
- const config = { rules: { [ruleId]: 'error' } } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, noUnusedFunctionArgument);
-
- const messages = linter.verify(sourceCode, config);
-
- const [issue] = transformMessages(messages, { sourceCode, rules: linter.getRules() }).issues;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId,
- line: 1,
- column: 11,
- endLine: 1,
- endColumn: 12,
- }),
- );
- });
-
- it('should transform ESLint fixes', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'fix.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-extra-semi';
- const config = { rules: { [ruleId]: 'error' } } as any;
-
- const linter = new Linter();
- const messages = linter.verify(sourceCode, config);
-
- const [issue] = transformMessages(messages, { sourceCode, rules: linter.getRules() }).issues;
- expect(issue).toEqual(
- expect.objectContaining({
- quickFixes: [
- {
- message: 'Remove extra semicolon',
- edits: [
- {
- text: ';',
- loc: {
- line: 1,
- column: 16,
- endLine: 1,
- endColumn: 18,
- },
- },
- ],
- },
- ],
- }),
- );
- });
-
- it('should decode secondary locations', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'secondary.ts');
- const tsConfigs = [];
- const sourceCode = (await parseTypeScriptSourceFile(filePath, tsConfigs)) as SourceCode;
-
- const ruleId = 'no-duplicate-in-composite';
- const config = { rules: { [ruleId]: 'error' } } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, noDuplicateInComposite);
-
- const messages = linter.verify(sourceCode, config);
-
- const [{ secondaryLocations }] = transformMessages(messages, {
- sourceCode,
- rules: linter.getRules(),
- }).issues;
- expect(secondaryLocations).toEqual([
- {
- line: 1,
- column: 9,
- endLine: 1,
- endColumn: 15,
- message: 'Original',
- },
- ]);
- });
-
- it('should remove ucfg issues', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'secondary.ts');
- const tsConfigs = [];
- const sourceCode = (await parseTypeScriptSourceFile(filePath, tsConfigs)) as SourceCode;
-
- const linter = new Linter();
- const messages = [
- {
- ruleId: 'ucfg',
- message: path.join(__dirname, 'fixtures', 'secondary.ts'),
- } as Linter.LintMessage,
- ];
-
- const { issues, ucfgPaths } = transformMessages(messages as Linter.LintMessage[], {
- sourceCode,
- rules: linter.getRules(),
- });
- expect(ucfgPaths.length).toEqual(1);
- expect(issues.length).toEqual(0);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/parameters/helpers/schema.test.ts b/eslint-bridge/tests/linting/eslint/linter/parameters/helpers/schema.test.ts
deleted file mode 100644
index 631442077ea..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/parameters/helpers/schema.test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule } from 'eslint';
-import { getRuleSchema } from 'linting/eslint/linter/parameters/helpers';
-
-describe('getRuleSchema', () => {
- it('should return the schema', () => {
- expect(getRuleSchema({ meta: { schema: [42] } } as any as Rule.RuleModule, 'schema')).toEqual([
- 42,
- ]);
- });
-
- it('should return an array of the schema', () => {
- expect(getRuleSchema({ meta: { schema: 'foo' } } as any as Rule.RuleModule, 'schema')).toEqual([
- 'foo',
- ]);
- });
-
- it('should return undefined on an undefined rule', () => {
- console.log = jest.fn();
- expect(getRuleSchema(undefined, 'undefined-rule')).toBeUndefined();
- expect(console.log).toHaveBeenCalledWith(`DEBUG ruleModule not found for rule undefined-rule`);
- });
-
- it('should return undefined on a meta-less rule', () => {
- expect(getRuleSchema({ meta: undefined } as Rule.RuleModule, 'meta-less')).toBeUndefined();
- });
-
- it('should return undefined on a schema-less rule', () => {
- expect(
- getRuleSchema({ meta: { schema: undefined } } as Rule.RuleModule, 'schema-less'),
- ).toBeUndefined();
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-context.test.ts b/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-context.test.ts
deleted file mode 100644
index ad0446dad85..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-context.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { hasSonarContextOption, SONAR_CONTEXT } from 'linting/eslint/linter/parameters';
-
-describe('hasSonarContextOption', () => {
- it('should return true for a rule that has `sonar-context` option', () => {
- expect(
- hasSonarContextOption({ meta: { schema: [{ title: SONAR_CONTEXT }] } } as any, 'fake'),
- ).toEqual(true);
- });
-
- it('should return false for a rule that has not `sonar-context` option', () => {
- expect(hasSonarContextOption({ meta: { schema: [{ title: 42 }] } } as any, 'fake')).toEqual(
- false,
- );
- });
-
- it('should return false for a rule without any schema', () => {
- expect(hasSonarContextOption({ meta: {} } as any, 'fake')).toEqual(false);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-runtime.test.ts b/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-runtime.test.ts
deleted file mode 100644
index 66342fdfb79..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/parameters/sonar-runtime.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { hasSonarRuntimeOption, SONAR_RUNTIME } from 'linting/eslint/linter/parameters';
-
-describe('hasSonarRuntimeOption', () => {
- it('should return true for a rule that has `sonar-runtime` option', () => {
- expect(
- hasSonarRuntimeOption({ meta: { schema: [{ enum: [SONAR_RUNTIME] }] } } as any, 'fake'),
- ).toEqual(true);
- });
-
- it('should return false for a rule that has not `sonar-runtime` option', () => {
- expect(hasSonarRuntimeOption({ meta: { schema: [{ enum: [42] }] } } as any, 'fake')).toEqual(
- false,
- );
- });
-
- it('should return false for a rule without any schema', () => {
- expect(hasSonarRuntimeOption({ meta: {} } as any, 'fake')).toEqual(false);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/decorated.js b/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/decorated.js
deleted file mode 100644
index 0d090bd2558..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/decorated.js
+++ /dev/null
@@ -1 +0,0 @@
-function f() {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/eslint.js b/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/eslint.js
deleted file mode 100644
index 15544a94a7b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/eslint.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log('hello, world!');;
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/fixless.js b/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/fixless.js
deleted file mode 100644
index fd2f61ab381..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/fixless.js
+++ /dev/null
@@ -1,3 +0,0 @@
-myLabel: while (true) {
- foo();
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/sonarjs.js b/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/sonarjs.js
deleted file mode 100644
index d09d24dd9f1..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/sonarjs.js
+++ /dev/null
@@ -1 +0,0 @@
-describe.only('exclusive');
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/undeclared.js b/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/undeclared.js
deleted file mode 100644
index 1e8865b20bb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/fixtures/undeclared.js
+++ /dev/null
@@ -1 +0,0 @@
-24 == 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/messages.test.ts b/eslint-bridge/tests/linting/eslint/linter/quickfixes/messages.test.ts
deleted file mode 100644
index 2376ff95057..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/messages.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { getQuickFixMessage } from 'linting/eslint/linter/quickfixes';
-
-describe('messages', () => {
- it('should return a quick fix message', () => {
- expect(getQuickFixMessage('comma-dangle')).toEqual('Remove this trailing comma');
- });
-
- it('should fail returning a quick fix message for an unknown rule', () => {
- expect(() => getQuickFixMessage('no-such-rule')).toThrow(
- `Missing message for quick fix 'no-such-rule'`,
- );
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/quickfixes/transform.test.ts b/eslint-bridge/tests/linting/eslint/linter/quickfixes/transform.test.ts
deleted file mode 100644
index 068236794a9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/quickfixes/transform.test.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import path from 'path';
-import { rule as noLabelsRule } from 'linting/eslint/rules/no-labels';
-import { rule as noExclusiveTests } from 'linting/eslint/rules/no-exclusive-tests';
-import { transformFixes } from 'linting/eslint/linter/quickfixes';
-import { decorateNoEmptyFunction } from 'linting/eslint/rules/decorators/no-empty-function-decorator';
-import { parseJavaScriptSourceFile } from '../../../../tools/helpers';
-
-describe('transformFixes', () => {
- it('should transform an ESLint core fix', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'eslint.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-extra-semi';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- const [message] = linter.verify(sourceCode, { rules });
- expect(message).toEqual(expect.objectContaining({ ruleId }));
-
- const quickFixes = transformFixes(sourceCode, message);
- expect(quickFixes).toEqual([
- {
- message: 'Remove extra semicolon',
- edits: [
- {
- loc: { line: 1, column: 28, endLine: 1, endColumn: 30 },
- text: ';',
- },
- ],
- },
- ]);
- });
-
- it('should transform a SonarJS suggestion', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'sonarjs.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-exclusive-tests';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, noExclusiveTests);
-
- const [message] = linter.verify(sourceCode, { rules });
- expect(message).toEqual(expect.objectContaining({ ruleId }));
-
- const quickFixes = transformFixes(sourceCode, message);
- expect(quickFixes).toEqual([
- {
- message: `Remove ."only()".`,
- edits: [
- {
- loc: { line: 1, column: 8, endLine: 1, endColumn: 13 },
- text: '',
- },
- ],
- },
- ]);
- });
-
- it('should transform a fix from a decorated rule', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'decorated.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-empty-function';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, decorateNoEmptyFunction(linter.getRules().get(ruleId)));
-
- const [message] = linter.verify(sourceCode, { rules });
- expect(message).toEqual(expect.objectContaining({ ruleId }));
-
- const quickFixes = transformFixes(sourceCode, message);
- expect(quickFixes).toEqual([
- {
- message: `Insert placeholder comment`,
- edits: [
- {
- loc: { line: 1, column: 14, endLine: 1, endColumn: 14 },
- text: ` /* TODO document why this function 'f' is empty */ `,
- },
- ],
- },
- ]);
- });
-
- it('should ignore an undeclared rule quick fix', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'undeclared.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'eqeqeq';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- const [message] = linter.verify(sourceCode, { rules });
- expect(message.fix).toBeDefined();
-
- const quickFixes = transformFixes(sourceCode, message);
- expect(quickFixes).toEqual([]);
- });
-
- it('should not return quick fixes for a fixless rule', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'fixless.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
-
- const ruleId = 'no-labels';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, noLabelsRule);
-
- const [message] = linter.verify(sourceCode, { rules });
- expect(message.fix).toBeUndefined();
-
- const quickFixes = transformFixes(sourceCode, message);
- expect(quickFixes).toEqual([]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/cpd.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/cpd.test.ts
deleted file mode 100644
index a1adf0ff68b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/cpd.test.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { CpdToken, getCpdTokens } from 'linting/eslint/linter/visitors';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../tools/helpers';
-
-describe('getCpdTokens', () => {
- it('should find all tokens', async () => {
- expect(await tokens('token.js')).toEqual([
- token(1, 0, 1, 2, 'if'),
- token(1, 3, 1, 4, '('),
- token(1, 4, 1, 8, 'true'),
- token(1, 8, 1, 9, ')'),
- token(2, 0, 2, 3, 'foo'),
- token(2, 3, 2, 4, '('),
- token(2, 4, 2, 5, ')'),
- token(2, 5, 2, 6, ';'),
- ]);
- });
-
- it('should ignore comments', async () => {
- expect(await tokens('comment.js')).toEqual([
- token(1, 0, 1, 1, 'a'),
- token(4, 0, 4, 1, 'b'),
- token(14, 0, 14, 1, 'c'),
- ]);
- });
-
- it('should anonymize string literals', async () => {
- expect(images(await tokens('string.js'))).toEqual(
- expect.arrayContaining([
- 'LITERAL', // 'string'
- 'LITERAL', // `string`
- 'LITERAL', // "string"
- '42',
- 'true',
- ]),
- );
- });
-
- it('should find JSX tokens', async () => {
- expect(images(await tokens('jsx.js'))).toEqual(expect.arrayContaining(['<', 'foo', '/', '>']));
- });
-
- it('should preserve JSX string literals', async () => {
- expect(images(await tokens('string-jsx.js'))).toEqual(
- expect.arrayContaining([
- 'LITERAL', // 'hello'
- '"abc"',
- 'LITERAL', // "def"
- 'LITERAL', // "ghi"
- 'LITERAL', // "jkl"
- 'LITERAL', // 'str'
- ]),
- );
- });
-
- it('should ignore import statements', async () => {
- expect(images(await tokens('import.js'))).toEqual(['import', '(', 'lib', ')', ';']);
- });
-
- it('should ignore require calls', async () => {
- expect(images(await tokens('require.js'))).toEqual(['const', 'fs', '=', ';']);
- });
-});
-
-async function tokens(filename: string): Promise {
- const filePath = path.join(__dirname, 'fixtures', 'cpd', filename);
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- return getCpdTokens(sourceCode).cpdTokens;
-}
-
-function token(
- startLine: number,
- startCol: number,
- endLine: number,
- endCol: number,
- image: string,
-): CpdToken {
- return {
- location: {
- startLine,
- startCol,
- endLine,
- endCol,
- },
- image,
- };
-}
-
-function images(cpdTokens: CpdToken[]): string[] {
- return cpdTokens.map(cpdToken => cpdToken.image);
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/comment.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/comment.js
deleted file mode 100644
index e20a8d991b6..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/comment.js
+++ /dev/null
@@ -1,15 +0,0 @@
-a // comment1
-/*comment2*/
-// comment3
-b // comment4
-/**
- * comment5
- */
-/**
- * Shift down
- * @param {Array} array
- * @param {Number} i
- * @param {Number} j
- */
-c
-// comment6
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/import.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/import.js
deleted file mode 100644
index 67c2bc9ad37..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/import.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import a from "x";
-import * as b from "y";
-import { c } from "z";
-import "lib";
-import(lib);
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/jsx.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/jsx.js
deleted file mode 100644
index f1999f80cc1..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/jsx.js
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/require.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/require.js
deleted file mode 100644
index 1dfd32e9661..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/require.js
+++ /dev/null
@@ -1 +0,0 @@
-const fs = require('fs');
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string-jsx.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string-jsx.js
deleted file mode 100644
index 1149c15f7b0..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string-jsx.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const str = 'hello';
-
- {"def"}
- {..."ghi"}
-
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string.js
deleted file mode 100644
index d5a62aa158b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/string.js
+++ /dev/null
@@ -1,5 +0,0 @@
-'string';
-`string`;
-"string";
-42;
-true;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/token.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/token.js
deleted file mode 100644
index 55dba82f415..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/cpd/token.js
+++ /dev/null
@@ -1,2 +0,0 @@
-if (true)
-foo();
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/curly.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/curly.ts
deleted file mode 100644
index d8700825c07..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/curly.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-(function () {
- if (true) {
- return {};
- }
-})();
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/enum.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/enum.ts
deleted file mode 100644
index ba40815d2de..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/enum.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-enum E {
- 'foo',
- 'bar',
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/imported.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/imported.ts
deleted file mode 100644
index 61b14cc1e99..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/imported.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import { x } from "hello";
-x();
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/malformed.vue b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/malformed.vue
deleted file mode 100644
index 36e090846a0..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/malformed.vue
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/new.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/new.ts
deleted file mode 100644
index 7a806ba5492..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/new.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-var I: {
- new(): I;
-};
-interface I {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/parameter.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/parameter.ts
deleted file mode 100644
index d76cb67509a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/parameter.ts
+++ /dev/null
@@ -1 +0,0 @@
-function foo(p: number) { return p; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/template.vue b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/template.vue
deleted file mode 100644
index 50feb2b0bcd..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/template.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/typed.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/typed.ts
deleted file mode 100644
index cede40691e1..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/typed.ts
+++ /dev/null
@@ -1 +0,0 @@
-let x: number = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/undeclared.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/undeclared.ts
deleted file mode 100644
index 3aad53d8681..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/undeclared.ts
+++ /dev/null
@@ -1 +0,0 @@
-foo(x);
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/unused.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/unused.ts
deleted file mode 100644
index 2756c24c457..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/unused.ts
+++ /dev/null
@@ -1 +0,0 @@
-let x;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/variable.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/variable.ts
deleted file mode 100644
index 9c21c7f035f..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/symbol-highlighting/variable.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-let x = 32;
-foo(x);
-var x = 0;
-x = 42;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/comment.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/comment.js
deleted file mode 100644
index d844b14bb6d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/comment.js
+++ /dev/null
@@ -1,9 +0,0 @@
-a // comment1
-/*comment2*/
-// comment3
-b // comment4
-/**
- * comment5
- */
-c
-// comment6
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/keyword.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/keyword.js
deleted file mode 100644
index 991d543537a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/keyword.js
+++ /dev/null
@@ -1,9 +0,0 @@
-class A {
- get b() {
- return this.a;
- }
- static foo() {
- if (cond);
- }
- a: string;
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/number.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/number.js
deleted file mode 100644
index 91d923fd17b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/number.js
+++ /dev/null
@@ -1,4 +0,0 @@
-0;
-0.0;
--0.0;
-10e-2;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/regex.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/regex.js
deleted file mode 100644
index e67a079fb83..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/regex.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/x/;
-/42/gu;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/string.js b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/string.js
deleted file mode 100644
index a11e8aaccb6..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/string.js
+++ /dev/null
@@ -1,6 +0,0 @@
-'str';
-"str";
-`str`;
-`line1\nline2`;
-`start ${x} middle ${y} end`;
-`There are ${42} apples`;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/template.vue b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/template.vue
deleted file mode 100644
index 2e5834cdac2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/syntax-highlighting/template.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/child.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/child.ts
deleted file mode 100644
index 092f87d3687..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/child.ts
+++ /dev/null
@@ -1 +0,0 @@
-if (true);
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/children.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/children.ts
deleted file mode 100644
index d6cae5e8007..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/children.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-while (true);
-;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/tree.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/tree.ts
deleted file mode 100644
index 43acaacfd0c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/fixtures/visitor/tree.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-function factorial(n: number): number {
- if (n < 2) {
- return 1;
- }
- return n * factorial(n - 1);
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/classes.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/classes.test.ts
deleted file mode 100644
index 2e08947353e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/classes.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { countClasses } from 'linting/eslint/linter/visitors/metrics/classes';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('countClasses', () => {
- it('should count the number of classes', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'classes.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const classes = countClasses(sourceCode);
- expect(classes).toEqual(2);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/comments.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/comments.test.ts
deleted file mode 100644
index 3914b1f4978..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/comments.test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { findCommentLines } from 'linting/eslint/linter/visitors/metrics/comments';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools/helpers';
-
-const cases = [
- {
- fixture: 'file1',
- given: 'with header ignoring and no header comment',
- ignoreHeader: true,
- expectedLines: [5, 6],
- },
- {
- fixture: 'file2',
- given: 'with header ignoring and block header comment',
- ignoreHeader: true,
- expectedLines: [3, 4, 5],
- },
- {
- fixture: 'file3',
- given: 'with header ignoring and special block header comment',
- ignoreHeader: true,
- expectedLines: [3, 4, 5],
- },
- {
- fixture: 'file4',
- given: 'with header ignoring and line header comment',
- ignoreHeader: true,
- expectedLines: [3, 4, 5],
- },
- {
- fixture: 'file5',
- given: 'without header ignoring and block header comment',
- ignoreHeader: false,
- expectedLines: [1, 3, 4, 5],
- },
- {
- fixture: 'file6',
- given: 'without header ignoring and no header comment',
- ignoreHeader: false,
- expectedLines: [2, 3, 4],
- },
-];
-
-describe('findCommentLines', () => {
- test.each(cases)(
- 'should find comment lines $given',
- async ({ fixture, ignoreHeader, expectedLines }) => {
- const filePath = path.join(__dirname, 'fixtures', 'comments', `${fixture}.js`);
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const { commentLines: actualLines } = findCommentLines(sourceCode, ignoreHeader);
- expect(actualLines).toEqual(expectedLines);
- },
- );
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/compute.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/compute.test.ts
deleted file mode 100644
index 2103eae4a35..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/compute.test.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { SourceCode } from 'eslint';
-import { computeMetrics } from 'linting/eslint';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('computeMetrics', () => {
- it('should compute metrics', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'compute.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const metrics = computeMetrics(sourceCode, true, 42);
- expect(metrics).toEqual({
- classes: 1,
- commentLines: [6],
- complexity: 2,
- cognitiveComplexity: 42,
- executableLines: [8],
- functions: 1,
- ncloc: [5, 7, 8, 9, 10],
- nosonarLines: [7],
- statements: 1,
- });
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.test.ts
deleted file mode 100644
index 8741251bd63..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/cyclomatic-complexity.test.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { computeCyclomaticComplexity } from 'linting/eslint/linter/visitors/metrics/cyclomatic-complexity';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-const cases = [
- { fixture: 'conjunction', expectedComplexity: 1 },
- { fixture: 'function', expectedComplexity: 2 },
- { fixture: 'while', expectedComplexity: 1 },
- { fixture: 'if', expectedComplexity: 1 },
- { fixture: 'try', expectedComplexity: 0 },
-];
-
-describe('computeCyclomaticComplexity', () => {
- test.each(cases)(
- 'should compute complexity for $fixture',
- async ({ fixture, expectedComplexity }) => {
- const filePath = path.join(__dirname, 'fixtures', 'cyclomatic-complexity', `${fixture}.js`);
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const actualComplexity = computeCyclomaticComplexity(sourceCode);
- expect(actualComplexity).toEqual(expectedComplexity);
- },
- );
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/executable-lines.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/executable-lines.test.ts
deleted file mode 100644
index 1489c8d975d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/executable-lines.test.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { findExecutableLines } from 'linting/eslint/linter/visitors/metrics/executable-lines';
-import path from 'path';
-import { parseTypeScriptSourceFile } from '../../../../../tools';
-
-describe('findExecutableLines', () => {
- it('should find the number of executable lines', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'executable-lines.ts');
- const tsConfigs = [];
- const sourceCode = (await parseTypeScriptSourceFile(filePath, tsConfigs)) as SourceCode;
- const statements = findExecutableLines(sourceCode);
- expect(statements).toEqual([
- 4, 7, 10, 11, 13, 16, 19, 20, 21, 24, 25, 27, 30, 31, 33, 36, 38, 42, 43, 46, 47, 48, 49, 52,
- 57, 61, 64, 65, 67, 70, 71, 74, 77, 82, 86,
- ]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/classes.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/classes.js
deleted file mode 100644
index 053758c2f91..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/classes.js
+++ /dev/null
@@ -1,5 +0,0 @@
-class A { // 1
- foo() {
- return class {}; // 2
- }
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments.js
deleted file mode 100644
index 31a79a146da..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * header comment
- */
-
-foo();
-
-// single-line comment
-
-/* multi-line comment */
-
-// NOSONAR
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file1.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file1.js
deleted file mode 100644
index 8b721737ed2..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file1.js
+++ /dev/null
@@ -1,13 +0,0 @@
-x; // NoSonar foo
-y; /* NOSONAR */
-// NOSONAR
-
-z; // NOOOSONAR
-z; // some comment
-
-//
-
-/*
- */
-
-/** */
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file2.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file2.js
deleted file mode 100644
index e325f9a1315..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file2.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* header */
-x;
-y; /*
- some coment
-*/
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file3.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file3.js
deleted file mode 100644
index 9224e27472d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file3.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/** header */
-x;
-y; /*
- some coment
-*/
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file4.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file4.js
deleted file mode 100644
index 290c969bb6e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file4.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// header
-x;
-y; /*
- some coment
-*/
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file5.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file5.js
deleted file mode 100644
index 3366609c8f8..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file5.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* header */
-x;
-y; /*
-some coment
-*/
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file6.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file6.js
deleted file mode 100644
index 8ea058b263e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/comments/file6.js
+++ /dev/null
@@ -1,4 +0,0 @@
-x;
-y; /*
-some coment
-*/
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/compute.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/compute.js
deleted file mode 100644
index f8126320e1a..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/compute.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * header
- */
-
-class C {
- /* return 'foo' */
- m = function() { // NOSONAR
- return foo() || bar();
- };
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/conjunction.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/conjunction.js
deleted file mode 100644
index 14d74bb6170..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/conjunction.js
+++ /dev/null
@@ -1 +0,0 @@
-1 && 2;
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/function.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/function.js
deleted file mode 100644
index eb0173aa31d..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/function.js
+++ /dev/null
@@ -1 +0,0 @@
-function foo() { 1 || 2; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/if.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/if.js
deleted file mode 100644
index 3fdfe318516..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/if.js
+++ /dev/null
@@ -1 +0,0 @@
-if (null) { return; }
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/try.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/try.js
deleted file mode 100644
index 0ead89004c5..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/try.js
+++ /dev/null
@@ -1 +0,0 @@
-try {} catch (e) {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/while.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/while.js
deleted file mode 100644
index d13a77bc43f..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/cyclomatic-complexity/while.js
+++ /dev/null
@@ -1 +0,0 @@
-while (true) { foo(); }
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/executable-lines.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/executable-lines.ts
deleted file mode 100644
index 83d9060f575..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/executable-lines.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-// Apart from this line, only executable lines should contain non-blank comments
-
-function f() {
- return; // 1
-}
-
-console // 1
- .log("hello");
-
-label1: // 1
-console.log(""); // 1
-
-if ( // 1
- false
-) {
- throw e; // 1
-}
-
-for( // 1
- var i = 0; i < 3; i++) { // 1
- continue; // 1
-}
-
-for( // 1
- var prop in obj // 1
-) {
- console.log("") // 1
-}
-
-for( // 1
- var a of b // 1
- ) {
- console.log("") // 1
- }
-
-do // 1
-{
- console.log("") // 1
-}
-while(false);
-
-while(false) { // 1
- console.log("") // 1
-}
-
-let let1; // 1
-const const1 = 42; // 1
-var x = 1; // 1
-var y // 1
- = 2;
-
-var obj = // 1
-{
- prop1: 42
-}
-
-switch // 1
-(x)
-{
- case 1:
- console.log(1); // 1
- case
- 2:
- console.log(2); // 1
- break; // 1
- default:
- break; // 1
-}
-
-try { // 1
- console.log(1); // 1
-}
-catch(e) {
- console.log(1); // 1
-}
-finally {
- console.log(1); // 1
-}
-
-;
-
-debugger; // 1
-
-class Polygon {
- constructor(height, width) {
- this.height = height; // 1
- }
-}
-
-import 'module1';
-export { name1 };
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/functions.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/functions.js
deleted file mode 100644
index 9f091b3a826..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/functions.js
+++ /dev/null
@@ -1,12 +0,0 @@
-class A {
- foo() { // 1
- return function(){};// 2
- }
- get x() { // 3
- return 42;
- }
-}
-function bar(){ // 4
- return ()=>42; // 5
-}
-function * gen(){} // 6
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.js
deleted file mode 100644
index 2077ed5a754..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * header
- */
-class /*after first token*/ A {
-
- get b() { // comment
- return `hello
- world`;
- }
- // comment
-}
-/* multi
-line
-comment */
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.vue b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.vue
deleted file mode 100644
index cccdf837205..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/ncloc.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
Hello, world!
-
-
Howdy!
-
-
-
-
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/nosonar.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/nosonar.js
deleted file mode 100644
index 5740f721ddb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/nosonar.js
+++ /dev/null
@@ -1,5 +0,0 @@
-x; // NoSonar foo
-y; /* NOSONAR */
-// NOSONAR
-z; // NOOOSONAR
-z; // some comment
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/statements.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/statements.js
deleted file mode 100644
index e284ee7b40e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/fixtures/statements.js
+++ /dev/null
@@ -1,13 +0,0 @@
-let x = 42; // 1
-; // 2
-foo(); // 3
-if (x) {} // 4
-while(x) break // 5 + 6
-function foo() {
- debugger; // 7
- return; // 8
-}
-try { // 9
- do{} while (x); // 10
-} catch (e) {}
-finally {}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/functions.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/functions.test.ts
deleted file mode 100644
index 814a0255e76..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/functions.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { countFunctions } from 'linting/eslint/linter/visitors/metrics/functions';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('countFunctions', () => {
- it('should count the number of functions', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'functions.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const statements = countFunctions(sourceCode);
- expect(statements).toEqual(6);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/counter.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/counter.test.ts
deleted file mode 100644
index b7b734c7eb7..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/counter.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { visitAndCountIf } from 'linting/eslint/linter/visitors/metrics/helpers';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../../tools';
-
-describe('visitAndCountIf', () => {
- it('should count matching nodes', async () => {
- const filePath = path.join(__dirname, './fixtures/counter.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath, [])) as SourceCode;
- const count = visitAndCountIf(sourceCode, node => node.type === 'CallExpression');
- expect(count).toEqual(3);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/counter.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/counter.js
deleted file mode 100644
index a41bc36047b..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/counter.js
+++ /dev/null
@@ -1,3 +0,0 @@
-while (foo()) {
- if (bar()) baz();
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.js b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.js
deleted file mode 100644
index a551a581996..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/*multi-line*/
-foo('hello');
-//single-line
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.vue b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.vue
deleted file mode 100644
index d6ffa3aaea9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/fixtures/tokens.vue
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/lines.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/lines.test.ts
deleted file mode 100644
index a8400e8afbb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/lines.test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { addLines } from 'linting/eslint/linter/visitors/metrics/helpers';
-
-describe('addLines', () => {
- it('should add lines within a range', () => {
- const lines = new Set();
- addLines(1, 5, lines);
- expect(lines).toEqual(new Set([1, 2, 3, 4, 5]));
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/location.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/location.test.ts
deleted file mode 100644
index 5570552632c..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/location.test.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { convertLocation } from 'linting/eslint/linter/visitors/metrics/helpers';
-
-describe('convertLocation', () => {
- it('should convert an ESTree location', () => {
- const location: estree.SourceLocation = {
- start: {
- line: 42,
- column: 42_42,
- },
- end: {
- line: 24,
- column: 24_24,
- },
- };
- const convertedLocation = convertLocation(location);
- expect(convertedLocation).toEqual({
- startLine: 42,
- startCol: 42_42,
- endLine: 24,
- endCol: 24_24,
- });
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/tokens.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/tokens.test.ts
deleted file mode 100644
index 6e0d371046e..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/helpers/tokens.test.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { extractTokensAndComments } from 'linting/eslint/linter/visitors/metrics/helpers';
-import { SourceCode } from 'eslint';
-import { AST } from 'vue-eslint-parser';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../../tools';
-
-describe('extractTokensAndComments', () => {
- it('should extract tokens and comments', async () => {
- const filePath = path.join(__dirname, './fixtures/tokens.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath, [])) as SourceCode;
- const { tokens, comments } = parseTokensAndComments(extractTokensAndComments(sourceCode));
- expect(tokens).toEqual(['foo', '(', `'hello'`, ')', ';']);
- expect(comments).toEqual(['multi-line', 'single-line']);
- });
-
- it('should extract tokens and comments from Vue files', async () => {
- const filePath = path.join(__dirname, './fixtures/tokens.vue');
- const sourceCode = (await parseJavaScriptSourceFile(filePath, [])) as SourceCode;
- const { tokens, comments } = parseTokensAndComments(extractTokensAndComments(sourceCode));
- expect(tokens).toEqual(expect.arrayContaining(['jsCode', 'vue-tag']));
- expect(comments).toEqual(['JS comment', 'HTML comment']);
- });
-});
-
-function parseTokensAndComments({
- tokens,
- comments,
-}: {
- tokens: AST.Token[];
- comments: AST.Token[];
-}): {
- tokens: string[];
- comments: string[];
-} {
- return {
- tokens: tokens.map(comment => comment.value),
- comments: comments.map(comment => comment.value),
- };
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/ncloc.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/ncloc.test.ts
deleted file mode 100644
index 4a37156b261..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/ncloc.test.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { findNcloc } from 'linting/eslint/linter/visitors/metrics/ncloc';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('findNcloc', () => {
- it('should find the line numbers of code', async () => {
- const filePath = path.join(__dirname, 'fixtures/ncloc.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const nloc = findNcloc(sourceCode);
- expect(nloc).toEqual([4, 6, 7, 8, 9, 11]);
- });
-
- it('should find the line numbers of code in Vue.js', async () => {
- const filePath = path.join(__dirname, 'fixtures/ncloc.vue');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const nloc = findNcloc(sourceCode);
- expect(nloc).toEqual([
- 1, 2, 3, 7, 8, 9, 11, 12, 13, 14, 18, 19, 20, 21, 22, 24, 25, 30, 31, 32,
- ]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/nosonar.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/nosonar.test.ts
deleted file mode 100644
index 41d7e3c60c9..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/nosonar.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { findNoSonarLines } from 'linting/eslint/linter/visitors';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('findNoSonarLines', () => {
- it('should find NOSONAR comment lines', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'nosonar.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const { nosonarLines } = findNoSonarLines(sourceCode);
- expect(nosonarLines).toEqual([1, 2, 3]);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/statements.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/statements.test.ts
deleted file mode 100644
index 4a7f7e869cd..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/metrics/statements.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { countStatements } from 'linting/eslint/linter/visitors/metrics/statements';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../../tools';
-
-describe('countStatements', () => {
- it('should count the number of statements', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'statements.js');
- const sourceCode = (await parseJavaScriptSourceFile(filePath)) as SourceCode;
- const statements = countStatements(sourceCode);
- expect(statements).toEqual(10);
- });
-});
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/symbol-highlighting.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/symbol-highlighting.test.ts
deleted file mode 100644
index 06b6a820cdb..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/symbol-highlighting.test.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Linter, SourceCode } from 'eslint';
-import { rule, SymbolHighlight } from 'linting/eslint/linter/visitors';
-import { Location } from 'linting/eslint/linter/visitors/metrics/helpers';
-import path from 'path';
-import { parseTypeScriptSourceFile } from '../../../../tools';
-
-describe('symbol highlighting rule', () => {
- it('should highlight variables', async () => {
- expect(await highlighting('variable.ts')).toEqual([
- symbol(declaration('1:4-1:5'), references('2:4-2:5', '3:4-3:5', '4:0-4:1')),
- ]);
- });
-
- it('should highlight unused variables', async () => {
- expect(await highlighting('unused.ts')).toEqual([symbol(declaration('1:4-1:5'), references())]);
- });
-
- it('should highlight typed variables', async () => {
- expect(await highlighting('typed.ts')).toEqual([symbol(declaration('1:4-1:5'), references())]);
- });
-
- it('should not highlight undeclared variables', async () => {
- expect(await highlighting('undeclared.ts')).toEqual([]);
- });
-
- it('should highlight parameters', async () => {
- expect(await highlighting('parameter.ts')).toEqual(
- expect.arrayContaining([
- symbol(declaration('1:9-1:12'), references()),
- symbol(declaration('1:13-1:14'), references('1:33-1:34')),
- ]),
- );
- });
-
- it('should highlight imported symbols', async () => {
- expect(await highlighting('imported.ts')).toEqual(
- expect.arrayContaining([symbol(declaration('1:9-1:10'), references('2:0-2:1'))]),
- );
- });
-
- it('should highlight curly brackets', async () => {
- const increasingOrder = (a, b) => a.declaration.startLine - b.declaration.startLine;
- expect((await highlighting('curly.ts')).sort(increasingOrder)).toEqual([
- symbol(declaration('1:13-1:14'), references('5:0-5:1')),
- symbol(declaration('2:12-2:13'), references('4:2-4:3')),
- symbol(declaration('3:11-3:12'), references('3:12-3:13')),
- ]);
- });
-
- it('should highlight constructors', async () => {
- expect(await highlighting('new.ts')).toEqual(
- expect.arrayContaining([symbol(declaration('1:4-1:5'), references('2:9-2:10', '4:10-4:11'))]),
- );
- });
-
- it('should highlight TypeScript enums', async () => {
- expect(await highlighting('enum.ts')).toEqual(
- expect.arrayContaining([symbol(declaration('1:5-1:6'), references())]),
- );
- });
-
- it('should highlight Vue templates', async () => {
- expect(await highlighting('template.vue')).toEqual([
- symbol(declaration('2:2-2:6'), references('4:2-4:7')),
- symbol(declaration('1:0-1:9'), references('5:0-5:10')),
- ]);
- });
-
- it('should highlight malformed Vue templates', async () => {
- expect(await highlighting('malformed.vue')).toEqual([
- symbol(declaration('1:0-1:9'), references('2:2-2:5')),
- ]);
- });
-});
-
-async function highlighting(fixture: string): Promise {
- const filePath = path.join(__dirname, 'fixtures', 'symbol-highlighting', fixture);
- const sourceCode = (await parseTypeScriptSourceFile(filePath, [])) as SourceCode;
-
- const ruleId = 'symbol-highlighting';
- const rules = { [ruleId]: 'error' } as any;
-
- const linter = new Linter();
- linter.defineRule(ruleId, rule);
-
- const [message] = linter.verify(sourceCode, { rules });
- return JSON.parse(message.message) as SymbolHighlight[];
-}
-
-function symbol(declaration: Location, references: Location[]): SymbolHighlight {
- return { declaration, references };
-}
-
-function declaration(location: string): Location {
- return decode(location);
-}
-
-function references(...locations: string[]): Location[] {
- return locations.map(decode);
-}
-
-function decode(location: string): Location {
- const [start, end] = location.split('-');
- const [startLine, startCol] = start.split(':');
- const [endLine, endCol] = end.split(':');
- return {
- startLine: Number(startLine),
- startCol: Number(startCol),
- endLine: Number(endLine),
- endCol: Number(endCol),
- };
-}
diff --git a/eslint-bridge/tests/linting/eslint/linter/visitors/syntax-highlighting.test.ts b/eslint-bridge/tests/linting/eslint/linter/visitors/syntax-highlighting.test.ts
deleted file mode 100644
index b516095dcd5..00000000000
--- a/eslint-bridge/tests/linting/eslint/linter/visitors/syntax-highlighting.test.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import {
- getSyntaxHighlighting,
- SyntaxHighlight,
- TextType,
-} from 'linting/eslint/linter/visitors/syntax-highlighting';
-import path from 'path';
-import { parseJavaScriptSourceFile } from '../../../../tools/helpers';
-
-describe('getSyntaxHighlighting', () => {
- it('should highlight keywords', async () => {
- expect(await highlighting('keyword.js')).toEqual(
- expect.arrayContaining([
- highlight(1, 0, 1, 5, 'KEYWORD'), // class
- highlight(3, 4, 3, 10, 'KEYWORD'), // return
- highlight(3, 11, 3, 15, 'KEYWORD'), // this
- highlight(5, 2, 5, 8, 'KEYWORD'), // static
- highlight(6, 4, 6, 6, 'KEYWORD'), // if
- ]),
- );
- });
-
- it('should highlight comments', async () => {
- expect(await highlighting('comment.js')).toEqual([
- highlight(1, 2, 1, 13, 'COMMENT'), // 1
- highlight(2, 0, 2, 12, 'COMMENT'), // 2
- highlight(3, 0, 3, 11, 'COMMENT'), // 3
- highlight(4, 2, 4, 13, 'COMMENT'), // 4
- highlight(5, 0, 7, 3, 'STRUCTURED_COMMENT'), // 5
- highlight(9, 0, 9, 11, 'COMMENT'), // 6
- ]);
- });
-
- it('should highlight strings', async () => {
- expect(await highlighting('string.js')).toEqual(
- expect.arrayContaining([
- highlight(1, 0, 1, 5, 'STRING'), // 'str'
- highlight(2, 0, 2, 5, 'STRING'), // "str"
- highlight(3, 0, 3, 5, 'STRING'), // `str`
- highlight(4, 0, 4, 14, 'STRING'), // `line1\nline2`
- highlight(5, 0, 5, 9, 'STRING'), // start
- highlight(5, 10, 5, 21, 'STRING'), // middle
- highlight(5, 22, 5, 28, 'STRING'), // end
- highlight(6, 13, 6, 15, 'CONSTANT'), // 42
- ]),
- );
- });
-
- it('should highlight numbers', async () => {
- expect(await highlighting('number.js')).toEqual(
- expect.arrayContaining([
- highlight(1, 0, 1, 1, 'CONSTANT'), // 0
- highlight(2, 0, 2, 3, 'CONSTANT'), // 0.0
- highlight(3, 1, 3, 4, 'CONSTANT'), // -0.0
- highlight(4, 0, 4, 5, 'CONSTANT'), // 10e-2
- ]),
- );
- });
-
- it('should highlight regex literals', async () => {
- expect(await highlighting('regex.js')).toEqual([
- highlight(1, 0, 1, 3, 'STRING'), // /x/
- highlight(2, 0, 2, 6, 'STRING'), // /42/gu
- ]);
- });
-
- it('should highlight Vue templates', async () => {
- expect(await highlighting('template.vue')).toEqual(
- expect.arrayContaining([
- highlight(1, 0, 1, 9, 'KEYWORD'), //
- highlight(2, 2, 2, 12, 'STRUCTURED_COMMENT'), //
- highlight(3, 2, 3, 18, 'COMMENT'), //
- click here1
-
- `,
- },
- ],
- invalid: [
- {
- code: `
-
-
-
-
- `,
- errors: [
- {
- message,
- line: 3,
- column: 12,
- endLine: 3,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
-
-
-
- `,
- errors: [
- { message, line: 4, column: 12, endLine: 4, endColumn: 27 },
- { message, line: 6, column: 12, endLine: 6, endColumn: 33 },
- ],
- },
- ],
-});
-
-ruleTester.run(`${testName} JSX`, rule, {
- valid: [{ code: `let x = foo
` }],
- invalid: [
- {
- code: `
- let x =
- `,
- errors: [{ message, line: 2, column: 20, endLine: 2, endColumn: 52 }],
- },
- ],
-});
-
-ruleTester.run(`${testName} JS`, rule, {
- valid: [
- {
- code: `let x = { domProps: { }} `,
- },
- { code: `let x = { domProps: { prop: 'foo' } } ` },
- {
- code: `
- createElement({
- attrs: {
- href: tainted
- }
- },
- "click here2")
- `,
- },
- {
- code: `
- createElement('foo', {
- attrs: {
- bar: 'x'
- }
- },
- "click here2")
- `,
- },
- {
- code: `
- foo('foo', {
- attrs: {
- bar: 'x'
- }
- },
- "click here2")
- `,
- },
- ],
- invalid: [
- {
- code: `
- function f (createElement) {
- return createElement(
- 'div',
- {
- domProps: {
- innerHTML: this.url
- }
- },
- 'div test',
- );
- }
- `,
- errors: [{ message, line: 7, column: 17, endLine: 7, endColumn: 36 }],
- },
-
- {
- code: `
- Vue.component('custom-element2', {
- render: function (createElement) {
- return createElement('a', {
- attrs: {
- href: tainted // Noncompliant
- }
- },
- "click here2")}})
- `,
- errors: [{ message, line: 6, column: 21, endLine: 6, endColumn: 34 }],
- },
-
- {
- code: `
- Vue.component('custom-element2', {
- render: function (h) {
- return h('a', {
- attrs: {
- href: tainted // Noncompliant
- }
- },
- "click here2")}})
- `,
- errors: [{ message, line: 6, column: 21, endLine: 6, endColumn: 34 }],
- },
-
- {
- code: `
- createElement('foo',{
- attrs: {
- href: tainted
- }
- },
- "click here2")
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/no-weak-cipher.test.ts b/eslint-bridge/tests/linting/eslint/rules/no-weak-cipher.test.ts
deleted file mode 100644
index 8d01845252d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/no-weak-cipher.test.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/no-weak-cipher';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-
-ruleTesterJs.run('[JS] Cipher algorithms should be robust', rule, {
- valid: [
- {
- code: `
- const crypto = require('crypto');
- var key = crypto.randomBytes(16);
- var iv = Buffer.from(crypto.randomBytes(16));
- var iv8 = Buffer.from(crypto.randomBytes(8));
- const nonce = crypto.randomBytes(12);
- crypto.createCipheriv("AES-128-CFB", key, iv);
-
- crypto.createCipheriv("AES-128-CFB8", key, iv);
- crypto.createCipheriv("AES-128-CTR", key, iv);
- crypto.createCipheriv("id-aes128-GCM", key, iv);
- crypto.createCipheriv("AES-128-OCB", key, nonce, {
- authTagLength: 16
- });
- crypto.createCipheriv("AES-128-OFB", key, iv);
- crypto.createCipheriv("aes128-wrap", key, iv8); // Alias of id-aes128-wrap
- crypto.createCipheriv("id-aes128-CCM", key, nonce, {
- authTagLength: 16
- });
- crypto.createCipheriv("id-aes128-wrap", key, iv8);
- crypto.createCipheriv("AES-192-CFB", key, iv);
-
- crypto.createCipheriv("SEED-CFB", key, iv);
- `,
- },
- {
- code: `
- const crypto = require('crypto');
- var key = crypto.randomBytes(16);
- var iv = Buffer.from(crypto.randomBytes(16));
- let algorithm = "AES-128-CBC";
- if (x) {
- algorithm = "other";
- }
- crypto.createCipheriv(algorithm, key, iv);
- `,
- },
- {
- code: `
- const crypto = require('crypto');
- crypto.createCipheriv();
- `,
- },
- {
- code: `
- const crypto = require('crypto');
- var key = crypto.randomBytes(16);
- crypto.createCipheriv();
- `,
- },
- {
- code: `
- const crypto = require('crypto');
- var key = crypto.randomBytes(16);
- var iv = Buffer.from(crypto.randomBytes(16));
- crypto.createCipheriv(42, key, iv);
- `,
- },
- ],
- invalid: [
- {
- code: `
- const crypto = require('crypto');
-
- crypto.createCipheriv("DES", key, iv);
- `,
- errors: [
- {
- line: 4,
- column: 29,
- endLine: 4,
- endColumn: 34,
- message: 'Use a strong cipher algorithm.',
- },
- ],
- },
- {
- code: `
- const crypto = require('node:crypto');
-
- crypto.createCipheriv("DES", key, iv);
- `,
- errors: 1,
- },
- {
- code: `
- const crypto = require('crypto');
-
- crypto.createCipheriv("DES", key, iv);
- crypto.createCipheriv("DES-EDE", key, "");
- crypto.createCipheriv("DES-EDE3", key, "");
- crypto.createCipheriv("RC2", key, iv);
- crypto.createCipheriv("RC4", key, "");
- crypto.createCipheriv("BF", key, iv);
- crypto.createCipheriv("blowfish", key, iv);
- `,
- errors: 7,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/no-weak-keys.test.ts b/eslint-bridge/tests/linting/eslint/rules/no-weak-keys.test.ts
deleted file mode 100644
index fbb6e20436e..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/no-weak-keys.test.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/no-weak-keys';
-
-const ruleTesterJS = new RuleTester({
- parserOptions: { ecmaVersion: 2018, sourceType: 'module' },
-});
-
-ruleTesterJS.run('Cryptographic keys should be robust', rule, {
- valid: [
- {
- code: `
- crypto.generateKeyPair('rsa', {
- modulusLength: 2048, // Compliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback);
- `,
- },
- {
- code: `
- // adding coverage
- crypto.generateKeyPair('ed25519', { // unrelated algorithm
- modulusLength: 1, // Compliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback);
-
- crypto.generateKeyPair('ed25519'); // missing options
- crypto.generateKeyPair('ed25519', options()); // options not an ObjectExpression
- crypto.generateKeyPair(alg(), {}); // algorithm not Literal
- `,
- },
- {
- code: `
- const alg = 'ed25519';
- crypto.generateKeyPair(alg, { // alg not literal
- modulusLength: 1, // Compliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback);
- `,
- },
- {
- code: `
- crypto.generateKeyPair('dsa', {
- divisorLength: 224, // Compliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback);
- `,
- },
- {
- code: `
- crypto.generateKeyPair('ec', {
- namedCurve: 'secp224k1',
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback); // compliant
- `,
- },
- ],
- invalid: [
- {
- code: `
- var { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
- modulusLength: 1024, // Noncompliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }); // Noncompliant: 1024 bits is too short for a RSA key pair
- `,
- errors: [
- {
- message: `Use a modulus length of at least 2048 bits for rsa cipher algorithm.`,
- line: 3,
- endLine: 3,
- column: 11,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- const alg = 'rsa';
- var { privateKey, publicKey } = crypto.generateKeyPairSync(alg, {
- modulusLength: 1024, // Noncompliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }); // Noncompliant: 1024 bits is too short for a RSA key pair
- `,
- errors: [
- {
- message: `Use a modulus length of at least 2048 bits for rsa cipher algorithm.`,
- line: 4,
- endLine: 4,
- column: 11,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- var options = {
- modulusLength: 1024, // Noncompliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- };
-
- var { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', options); // Noncompliant
- `,
- errors: [
- {
- message: `Use a modulus length of at least 2048 bits for rsa cipher algorithm.`,
- line: 3,
- endLine: 3,
- column: 11,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- var { privateKey, publicKey } = crypto.generateKeyPairSync('dsa', {
- modulusLength: 1024, // Noncompliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }); // Noncompliant: 1024 bits is too short for a RSA key pair
- `,
- errors: [
- {
- message: `Use a modulus length of at least 2048 bits for dsa cipher algorithm.`,
- line: 3,
- endLine: 3,
- column: 11,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- crypto.generateKeyPair('dsa', {
- modulusLength: 2048, // Compliant
- divisorLength: 112, // Noncompliant
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback); // Noncompliant
- `,
- errors: [
- {
- message: `Use a divisor length of at least 224 bits for dsa cipher algorithm.`,
- line: 4,
- endLine: 4,
- column: 11,
- endColumn: 29,
- },
- ],
- },
- {
- code: `
- const crypto = require('crypto');
- crypto.generateKeyPair('ec', {
- namedCurve: 'secp112r2',
- publicKeyEncoding: { type: 'spki', format: 'pem' },
- privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
- }, callback); // Noncompliant: secp112r2 curve doesn't provide enough security
- `,
- errors: [
- {
- message: `secp112r2 doesn't provide enough security. Use a stronger curve.`,
- line: 4,
- endLine: 4,
- column: 11,
- endColumn: 34,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/no-wildcard-import.test.ts b/eslint-bridge/tests/linting/eslint/rules/no-wildcard-import.test.ts
deleted file mode 100644
index fd672257ff0..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/no-wildcard-import.test.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/no-wildcard-import';
-
-const ruleTesterJS = new RuleTester({
- parserOptions: { ecmaVersion: 2018, sourceType: 'module' },
-});
-
-ruleTesterJS.run('Wildcard imports should not be used', rule, {
- valid: [
- {
- code: `
- import a from 'aa'; // ImportDefaultSpecifier
- import { b } from 'bb'; // ImportSpecifier
- import { c, d } from 'cd'; // ImportSpecifier
- import { e as f } from 'e'; // ImportSpecifier`,
- },
- {
- code: `export { m } from "module-name";`,
- },
- ],
- invalid: [
- {
- code: `
- import * as name1 from "module-name";
- import defaultMember, * as name2 from "module-name";
- `,
- errors: [
- {
- message: `Explicitly import the specific member needed.`,
- line: 2,
- endLine: 2,
- column: 14,
- endColumn: 24,
- },
- {
- message: `Explicitly import the specific member needed.`,
- line: 3,
- endLine: 3,
- column: 29,
- endColumn: 39,
- },
- ],
- },
- {
- code: `export * from "module-name";`,
- errors: [
- {
- message: `Explicitly export the specific member needed.`,
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 29,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/non-number-in-arithmetic-expression.test.ts b/eslint-bridge/tests/linting/eslint/rules/non-number-in-arithmetic-expression.test.ts
deleted file mode 100644
index 7a742cd789e..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/non-number-in-arithmetic-expression.test.ts
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/non-number-in-arithmetic-expression';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-ruleTesterJs.run('No issues without types', rule, {
- valid: [
- {
- code: `
- var num = 42;
- var bool = true;
- num + bool;
- `,
- },
- ],
- invalid: [],
-});
-
-ruleTesterTs.run('Arithmetic operators should only have numbers as operands', rule, {
- valid: [
- {
- code: `
- function plus() {
- var str = "";
- var bool = true;
- var obj = new Foo();
- var unknown = foo();
- var num = 42;
- var d1 = new Date(), d2 = new Date();
-
- // PLUS -> concatenation
- str + unknown;
- str + num;
- str + obj;
- str + d1;
- d1 + d2;
- str += unknown; str = "";
- unknown += str; unknown = foo();
- bool + unknown; // OK, unknown might be a string
-
- // PLUS -> addition
- num + num;
- num * num;
-
- // comparisons
- str < str; str > str; str <= str; str >= str;
- str > obj;
- str < unknown; // OK, unknown
-
- // DATES
- d1 - d2; // OK
- d1 - unknown; // OK
- unknown - d2; // OK
- d1 + d2; // OK, concatenation
- d1 + bool; // OK, concatenation
-
- 42 + new String(x); // OK
-
- num++;
- +num;
- }
- `,
- },
- {
- code: `
- var bool = true;
- if (!bool) {
- console.log("hello");
- }
- `,
- },
- {
- code: `
- var num = 42;
- var other = 43;
- other = true;
- num + other; // FN
- `,
- },
- ],
- invalid: [
- {
- code: `
- var num = 42;
- var bool = true;
- num + bool;
- `,
- errors: [
- {
- line: 4,
- endLine: 4,
- column: 13,
- endColumn: 17,
- message: JSON.stringify({
- message: 'Convert this operand into a number.',
- secondaryLocations: [
- {
- column: 6,
- line: 4,
- endColumn: 9,
- endLine: 4,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- var num = 42;
- var bool = true;
- num += bool;
- `,
- errors: [
- {
- line: 4,
- endLine: 4,
- column: 14,
- endColumn: 18,
- message: JSON.stringify({
- message: 'Convert this operand into a number.',
- secondaryLocations: [
- {
- column: 6,
- line: 4,
- endColumn: 9,
- endLine: 4,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- var num = 42;
- var bool = true;
- bool += num;
- `,
- errors: 1,
- },
- {
- code: `
- var str = "";
- var num = 42;
- var bool = true;
- str < num;
- str > bool;
- bool < num;
- `,
- errors: 3,
- },
- {
- code: `
- var d1 = new Date(), d2 = new Date();
- d1/d2;
- d1*d2
- `,
- errors: 2,
- },
- {
- code: `
- var d1 = new Date(), d2 = new Date();
- d1*=d2;
- d1-=d2; // OK
- `,
- errors: [
- {
- line: 3,
- endLine: 3,
- column: 7,
- endColumn: 13,
- message: JSON.stringify({
- message: 'Convert the operands of this operation into numbers.',
- secondaryLocations: [
- {
- column: 6,
- line: 3,
- endColumn: 8,
- endLine: 3,
- },
- {
- column: 10,
- line: 3,
- endColumn: 12,
- endLine: 3,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- var d1 = new Date();
- var num = 42;
- d1 - num; // Noncompliant
- `,
- errors: [{ line: 4 }],
- },
- {
- code: `
- var str = "";
- var bool = true;
- var d1 = new Date();
- str++;
- -str;
- -bool;
- -d1;
- d1++;
- --d1;
- `,
- errors: 6,
- },
- {
- code: `
- var str = "42";
- var x = 42;
- str - 4; // Noncompliant
- `,
- errors: [{ line: 4 }],
- },
- {
- code: `
- var str = "42";
- var x;
-
- if (condition()) {
- x = 42;
- }
-
- str - 4; // Noncompliant
- foo(x);
- `,
- errors: [{ line: 9 }],
- },
- {
- code: `
- function primitive_wrappers(x) {
- -new String(x);
- -new Boolean(x);
- 42 / new String(x);
- 42 / new Boolean(x);
- 42 + new Boolean(x);
- new Number(x) + true;
- true + new Number(x);
- new Number(x) > "42";
- "42" > new Number(x);
- }
- `,
- errors: 9,
- },
- {
- code: `
- var num = 42;
- var other = true;
- other = 43;
- num + other; // FP
- `,
- errors: [{ line: 5 }],
- },
- {
- code: `
- expect(something()).toEqual(-'1');
- `,
- errors: [
- {
- message: JSON.stringify({
- message: 'Convert this operand into a number.',
- secondaryLocations: [],
- }),
- line: 2,
- endLine: 2,
- column: 36,
- endColumn: 39,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/null-dereference.test.ts b/eslint-bridge/tests/linting/eslint/rules/null-dereference.test.ts
deleted file mode 100644
index 211bafdd6af..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/null-dereference.test.ts
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { JavaScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/null-dereference';
-
-const ruleTesterJsWithTypes = new JavaScriptRuleTester();
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-
-ruleTesterJsWithTypes.run('', rule, {
- valid: [
- {
- code: `
- function builtin_property() {
- var str = "str";
- str.trim(); // OK
- }`,
- },
- {
- code: `
- function chained_properties() {
- var str = "str";
- str.trim().trim(); // OK
- str.undefinedProperty.trim(); // OK, we don't know property "undefinedProperty" and consider it to have ANY_VALUE
- }`,
- },
- {
- code: `
- function property_array() {
- var str = "str";
- str.trim().split("t")[0]; // OK
- str.trim().undefinedArray[0]; // OK
- }`,
- },
- {
- code: `
- function unknown() {
- var y;
- foo(y);
- y = foo();
- y.foo;
- }`,
- },
- {
- code: `
- function class_property() {
- class A {
- }
- A.foo = 42;
- }`,
- },
- {
- code: `
- function branch() {
- var z;
- if (cond) {
- z = foo();
- }
- z.foo(); // FN?
- }`,
- },
- {
- code: `
- function foo() { if (some) { return 42;} }
- function equal_null() {
- var x = foo();
-
- if (x != null) {
- x.foo();
- }
-
- if (null != x) {
- x.foo();
- }
-
- if (x == null) {
- x.foo(); // FN
- }
- if (x == undefined) {
- x.foo(); // FN
- }
- if (x === null) {
- x.foo(); // FN
- }
-
- if (x !== null) {
- x.foo();
- } else {
- x.foo(); // FN
- }
- }`,
- },
- {
- code: `
- function ternary() {
- var x;
- if (condition) {
- x = foo();
- }
-
- x ? x.foo() : bar(); // Compliant
- }`,
- },
- {
- code: `
- function duplicated_condition() {
- if (foo("bar")) {
- var x = bar();
- }
-
- if (foo("bar")) {
- x.foo(); // OK
- }
- }`,
- },
- {
- code: `
- function loop_at_least_once() {
- var x;
-
- while (condition()) {
- x = foo();
- }
-
- x.foo();
- }`,
- },
- {
- code: `
- function loop(arr) {
- var obj;
- for(var i = 0; i < arr.length; i++){
- if(i % 2 == 0){
- obj = foo();
- } else {
- obj.bar(); // OK
- }
- }
- }`,
- },
- {
- code: `
- function one_condition() {
- var x = foo();
-
- if (x == null) {
- foo();
- }
-
- if (x
- && x.foo != null) { // Ok
- }
- }`,
- },
- {
- code: `
- function one_more() {
- var x = foo();
- while (x != null && i < 10) {
- }
-
- if (!x) {
- return;
- }
-
- if (x.foo) { // Ok
- }
- }`,
- },
- {
- code: `function not_null_if_property_accessed() {
- var x = foo();
-
- if (x.foo) {
- if (x != null) {
- }
- x.foo(); // Ok
- }
- }`,
- },
- {
- code: `
- function tested_copy() {
- var x;
-
- if (condition) {
- x = foo();
- }
-
- var copy = x;
-
- if (!copy) {
- return;
- }
-
- x.foo();
- }`,
- },
- {
- code: `function assignment_left_first() {
- var x;
-
- foo[x=foo()] = foo(x.bar); // Compliant, we first evaluate LHS of assignment
- }`,
- },
- {
- code: `function array_assignment() {
- var x, y;
- x = 0;
- [x, y] = obj;
- x.foo;
- y.foo;
- }`,
- },
- {
- code: `function object_assignment() {
- var x, y;
- x = 0;
- ({x, y} = obj);
- x.foo;
- y.foo;
- }`,
- },
- {
- code: `function object_assignment_with_named_properties() {
- var x, y;
- x = 0;
- ({prop1:x, prop2:y} = obj);
- x.foo;
- y.foo;
- }`,
- },
- {
- code: `function null_and_not_undefined() {
- var x = null;
-
- while (condition()) {
- if (x === null) {
- x = new Obj();
- }
- x.foo();
- }
- }`,
- },
- {
- code: `function async_function_undefined() {
- async function foo_implicit_return() { console.log("foo"); } // async function always return a Promise
- async function foo_return_undefined() { console.log("foo"); return undefined; } // async function always return a Promise
- foo_implicit_return().then(); // OK
- foo_return_undefined().then(); // OK
- }`,
- },
- {
- code: `function written_in_inner_fn() {
- var x;
- function update_x() {
- x = 42
- }
- update_x()
- x.toString();
- }`,
- },
- {
- code: `
- var x;
- function update_x() {
- x = 42
- }
- update_x()
- x.toString();
- `,
- },
- {
- code: `
- function fn(ys) {
- var x;
- ys.forEach(function (y) { x = y; })
- x.foo
- }`,
- },
- {
- code: `
- var x;
- x?.foo;
- x?.y?.foo;
- x?.y?.z?.foo;
- `,
- },
- {
- code: `
- if (x != null && x.prop == 0) {}
- if (x == null || x.prop == 0) {}
- if (x != undefined && x.prop == 0) {}
- if (x == undefined || x.prop == 0) {}
- `,
- },
- {
- code: `if (x == null && x?.prop == 0) {}`,
- },
- {
- code: `if (x == null && y.prop == 0) {}`,
- },
- ],
- invalid: [
- {
- code: `
- function property() {
- var x;
- x.foo;
- //^
- }`,
- errors: [
- {
- message: `TypeError can be thrown as "x" might be null or undefined here.`,
- line: 4,
- column: 9,
- endColumn: 10,
- },
- ],
- },
- {
- code: `
- function element() {
- var x;
- x[1];
- }`,
- errors: 1,
- },
- {
- code: `
- function stop_after_NPE() {
- var x;
- var other_x;
- if (x.foo && // Noncompliant
- other_x.bar // Noncompliant FP as we can't reach this point after previous issue
- ) {
- }
- }`,
- errors: 2,
- },
- {
- code: `
- function typeof_testing() {
- var x;
-
- if (condition) {
- x = foo();
- }
-
- if (typeof x === 'function') {
- x.call();
- }
-
- if (typeof x === 'object') {
- x.call();
- }
-
- var y = foo();
-
- if (typeof y === 'undefined') {
- y.call(); // Noncompliant
- }
- }`,
- errors: [
- {
- line: 20,
- endLine: 20,
- column: 15,
- endColumn: 16,
- },
- ],
- },
- {
- code: `function one_issue_per_symbol() {
- var x;
-
- if (condition) {
- x.foo(); // Noncompliant
- } else {
- x.bar(); // no issue here as we already have issue for same symbol
- }
- }`,
- errors: 1,
- },
- {
- code: `function for_of_undefined() {
- var undefinedArray;
- for(let i of undefinedArray) { // Noncompliant
- }
-
- var nullArray = null;
- for(let i of nullArray) { // Noncompliant
- }
-
- var initializedArray = [];
- for(let i of initializedArray) { // OK
- }
-
- var x;
- for(x of obj) { // OK we should not care about x being undefined
- }
- }`,
- errors: [
- {
- line: 3,
- endLine: 3,
- column: 22,
- endColumn: 36,
- },
- {
- line: 7,
- endLine: 7,
- column: 22,
- endColumn: 31,
- },
- ],
- },
- {
- code: `
- var x;
- x.foo`,
- errors: 1,
- },
- {
- code: `if (x == null && x.prop == 0) {}`,
- errors: [
- {
- messageId: 'shortCircuitError',
- },
- ],
- },
- {
- code: `if (null != x || x.prop == 0) {}`,
- errors: [
- {
- messageId: 'shortCircuitError',
- },
- ],
- },
- {
- code: `if (undefined == x && x.prop == 0) {}`,
- errors: [
- {
- messageId: 'shortCircuitError',
- },
- ],
- },
- {
- code: `if (x.prop != undefined || x.prop.prop2 == 0) {}`,
- errors: [
- {
- line: 1,
- endLine: 1,
- column: 28,
- endColumn: 34,
- messageId: 'shortCircuitError',
- },
- ],
- },
- ],
-});
-
-ruleTesterJs.run('', rule, {
- valid: [
- {
- code: `
- function property() {
- var x;
- x.foo; // OK, no type information available
- }`,
- },
- ],
- invalid: [],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/operation-returning-nan.test.ts b/eslint-bridge/tests/linting/eslint/rules/operation-returning-nan.test.ts
deleted file mode 100644
index 95c6ff19405..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/operation-returning-nan.test.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/operation-returning-nan';
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTesterJs.run('Arithmetic operation returning NaN [NoParserServices]', rule, {
- valid: [
- {
- code: `
- let x = 42 - [1,2];
- `,
- },
- ],
- invalid: [],
-});
-
-const ruleTester = new TypeScriptRuleTester();
-ruleTester.run('Arithmetic operation returning NaN', rule, {
- valid: [
- {
- code: `
- let x = 42 - 7;
- `,
- },
- {
- code: `
- var obj1 = {}
- obj1 + 42; // concatenation
- `,
- },
- {
- code: `
- function dates() {
- var date1 = new Date();
- var date2 = new Date();
- +date1; // ok
- date1 - date2; // ok
- date1 / date2; // ok
- new Date() / 42; // ok
- 42 / new Date(); // ok
- }
- `,
- },
- {
- code: `
- null + 42; // ok
- true + 42; // ok
- `,
- },
- {
- code: `
- typeof {} == 'string';
- `,
- },
- {
- code: `
- function doSomething(something) {
- if ((typeof something === 'number' || something instanceof Number) && !isFinite(+something)) {
- console.log("hello");
- }
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- let x = 42 - [1,2];
- let y = [1,2] - 42;
- `,
- errors: [
- {
- message: `Change the expression which uses this operand so that it can't evaluate to "NaN" (Not a Number).`,
- line: 2,
- column: 22,
- endLine: 2,
- endColumn: 27,
- },
- {
- message: `Change the expression which uses this operand so that it can't evaluate to "NaN" (Not a Number).`,
- line: 3,
- column: 17,
- endLine: 3,
- endColumn: 22,
- },
- ],
- },
- {
- code: `
- var array7 = [1,2];
- array7 /= 42;
- `,
- errors: 1,
- },
- {
- code: `
- var obj1 = {}
- obj1 - 42;
- `,
- errors: 1,
- },
- {
- code: `
- var array2 = [1,2];
- array2--;
- `,
- errors: 1,
- },
- {
- code: `
- foo(+[1,2]);
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/os-command.test.ts b/eslint-bridge/tests/linting/eslint/rules/os-command.test.ts
deleted file mode 100644
index 273e0abdc41..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/os-command.test.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/os-command';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Executing OS commands is security-sensitive', rule, {
- valid: [
- {
- code: `
- const cp = require('child_process');
- cp.fork('child.js');
- `,
- },
- {
- code: `
- import { fork } from 'child_process';
- fork('child.js');`,
- },
- {
- code: `
- const cp = require('child_process');
- cp.exec('echo child_process.exec hardcoded >> output.txt');`,
- },
- {
- code: `
- const cp = require('child_process');
- cp.spawn('echo child_process.exec hardcoded >> output.txt', { shell: true });`,
- },
- {
- code: `
- const cp = require('child_process');
- cp.spawn('echo child_process.spawn ' + userinput + ' >> output.txt', { shell: false });`,
- },
- {
- code: `
- const cp = require('child_process');
- cp.spawn('echo child_process.spawn ' + userinput + ' >> output.txt');`,
- },
- {
- code: `
- const exec = require('child_process').fork;
- exec('echo child_process.exec ' + process.argv[2] + ' >> output.txt');`,
- },
- {
- code: `
- import * as cp from 'child_process';
- cp.spawn('echo child_process.exec ' + process.argv[2] + ' >> output.txt', { ...x });`,
- },
- ],
- invalid: [
- {
- code: `
- const cp = require('child_process');
- cp.exec('echo child_process.exec ' + userInput + ' >> output.txt');
- `,
- errors: [
- {
- message: 'Make sure that executing this OS command is safe here.',
- line: 3,
- endLine: 3,
- column: 9,
- endColumn: 16,
- },
- ],
- },
- {
- code: `
- import * as cp from 'child_process';
- cp.exec('echo child_process.exec ' + process.argv[2] + ' >> output.txt');`,
- errors: 1,
- },
- {
- code: `
- import { exec } from 'child_process';
- exec('echo child_process.exec ' + process.argv[2] + ' >> output.txt');`,
- errors: 1,
- },
- {
- code: `
- import * as cp from 'child_process';
- cp.spawn('echo child_process.exec ' + process.argv[2] + ' >> output.txt', { shell: true });`,
- errors: 1,
- },
- {
- code: `
- import * as cp from 'child_process';
- cp.exec('echo child_process.exec ' + process.argv[2] + ' >> output.txt', { env: "" });`,
- errors: 1,
- },
- {
- code: `
- const exec = require('child_process').exec;
- exec('echo child_process.exec ' + process.argv[2] + ' >> output.txt');`,
- errors: 1,
- },
- {
- code: `
- var execSync = require('child_process').execSync
- function exec(command) {
- execSync(command, { stdio: [0, 1, 2] })
- }
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/post-message.test.ts b/eslint-bridge/tests/linting/eslint/rules/post-message.test.ts
deleted file mode 100644
index 871fd2fddce..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/post-message.test.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/post-message';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-ruleTesterJs.run('No issues without types', rule, {
- valid: [
- {
- code: `
- var someWindow1 = window.open("url", "name");
- someWindow1.postMessage("message", "*");
- `,
- },
- ],
- invalid: [],
-});
-
-ruleTesterTs.run('Origins should be verified during cross-origin communications', rule, {
- valid: [
- {
- code: `
- var someWindow1 = window.open("url", "name");
- someWindow1.postMessage("message", "receiver");
- `,
- },
- {
- code: `
- postMessage("message", "receiver");
- `,
- },
- {
- code: `
- postMessage("message");
- postMessage("message", "*", "something", "something else");
- `,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- if (event.origin !== "http://example.org")
- return;
- console.log(event.data);
- });
- `,
- },
- {
- code: `
- window.addEventListener("missing listener");
- window.addEventListener("message", "not a function");
- not_a_win_dow.addEventListener("message", () => {});
- window.addEventListener("message", () => {}); // missing event parameter
- window.addEventListener("message", (...not_an_identifier) => {});
- `,
- },
- {
- code: `
- window.addEventListener("click", function(event) { // OK: event type is not "message"
- if (event.data !== "http://example.org")
- return;
- console.log(event.data);
- });
- `,
- },
- {
- code: `
- const processEvent = event => {
- if (event.origin !== "http://example.org") return
- }
- window.addEventListener('message', processEvent);
- `,
- },
- {
- code: `
- const processEvent = event => {
- if (event.origin !== "http://example.org") return
- }
- window.addEventListener('message', event => processEvent(event));
- `,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- if (event.originalEvent.origin !== "http://example.org")
- return;
- });
- `,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- if (event.originalEvent.origin === "http://example.org" || event.origin === "http://example.org")
- return;
- });
- `,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- const _event = event.originalEvent || event;
- if (_event.origin !== "http://example.org")
- return;
- });
- window.addEventListener("message", function(event) {
- const _event = event || event.originalEvent;
- if (_event.origin !== "http://example.org")
- return;
- });
- `,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- var origin = event.originalEvent.origin || event.origin
- if (origin !== "http://example.org")
- return;
- });
- window.addEventListener("message", function(event) {
- var origin = event.origin || event.originalEvent.origin
- if (origin !== "http://example.org")
- return;
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- var someWindow1 = window.open("url", "name");
- someWindow1.postMessage("message", "*");
- `,
- errors: [{ messageId: 'specifyTarget' }],
- },
- {
- code: `
- postMessage("message", "*");
- `,
- errors: 1,
- },
- {
- code: `
- this.postMessage("message", "*");
- `,
- errors: 1,
- },
- {
- code: `
- var someWindow2 = document.getElementById("frameId").contentWindow;
- someWindow2.postMessage("message", "*");
- `,
- errors: 1,
- },
- {
- code: `
- var someWindow3 = window.frames[1];
- someWindow3.postMessage("message", "*");
- `,
- errors: 1,
- },
- {
- code: `
- getWindow().postMessage("message", "*");
- `,
- errors: 1,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- console.log(event.data);
- });
- `,
- errors: [{ messageId: 'verifyOrigin' }],
- },
- {
- code: `
- function eventHandler(event) {
- console.log(event.data);
- }
- window.addEventListener("message", eventHandler);
- `,
- errors: 1,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- if (event.data !== "http://example.org")
- return;
- console.log(event.data);
- });
- `,
- errors: 1,
- },
- {
- code: `
- const eventType = "message";
- window.addEventListener(eventType, function(event) {
- if (event.data !== "http://example.org")
- return;
- console.log(event.data);
- });
- `,
- errors: 1,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- var origin = event.originalEvent.origin || event.origin; // coverage: must be tested
- });
- `,
- errors: 1,
- },
- {
- code: `
- window.addEventListener("message", function(event) {
- event.originalEvent.origin || event.origin; // coverage: we don't assign this anywhere
- });
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/prefer-default-last.test.ts b/eslint-bridge/tests/linting/eslint/rules/prefer-default-last.test.ts
deleted file mode 100644
index d586028e6de..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/prefer-default-last.test.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/prefer-default-last';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('"default" clauses should be last', rule, {
- valid: [
- {
- code: `switch (true) {}`,
- },
- {
- code: `
- switch (z) {
- case "foo":
- console.log("Hello World")
- break;
- case "bar":
- console.log("42");
- break;
- default:
- console.log("Default message");
- }`,
- },
- {
- code: `
- switch (z) {
- case "foo":
- console.log("Hello World")
- break;
- }`,
- },
- ],
- invalid: [
- {
- code: `
- switch (x) {
- case 1:
- console.log("1");
- default: //Nomcompliant
- console.log("0");
- case 2:
- console.log("2");
- }`,
- errors: [
- {
- message: 'Move this "default" clause to the end of this "switch" statement.',
- line: 5,
- endLine: 5,
- column: 11,
- endColumn: 18,
- },
- ],
- },
-
- {
- code: `
- switch (y) {
- default: //Nomcompliant
- console.log("Default message");
- break;
- case "foo":
- console.log("Hello World")
- break;
- case "bar":
- console.log("42");
- break;
- }`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/prefer-promise-shorthand.test.ts b/eslint-bridge/tests/linting/eslint/rules/prefer-promise-shorthand.test.ts
deleted file mode 100644
index 8d55c986fa9..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/prefer-promise-shorthand.test.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/prefer-promise-shorthand';
-
-const ruleTester = new RuleTester({
- parser: require.resolve('@typescript-eslint/parser'),
- parserOptions: { ecmaVersion: 2018 },
-});
-
-ruleTester.run('Shorthand promises should be used', rule, {
- valid: [
- {
- code: `let fulfilledPromise = new Promise(resolve => { resolve(calc(42)); console.log("foo"); });`,
- },
- {
- code: `let fulfilledPromise = Promise.resolve(42);`,
- },
- {
- code: `let fulfilledPromise = Promise.reject('fail');`,
- },
- {
- code: `
- function calc(x:number): number { return x * 2; }
- let somePromise = new Promise(() => { calc(42); }); // 0 parameters
- `,
- },
- ],
- invalid: [
- {
- code: `
- let fulfilledPromise = new Promise(resolve => resolve(calc(42)));
- `,
- errors: [
- {
- message: `Replace this trivial promise with "Promise.resolve".`,
- line: 2,
- endLine: 2,
- column: 34,
- endColumn: 41,
- },
- ],
- },
- {
- code: `let rejectedPromise = new Promise((resolve, reject) => reject(new Error('fail')));`,
- errors: [{ message: `Replace this trivial promise with "Promise.reject".` }],
- },
- {
- code: `let rejectedPromise = new Promise((p1, p2) => p2(new Error('fail')));`,
- errors: [{ message: `Replace this trivial promise with "Promise.reject".` }],
- },
- {
- code: `new Promise(resolve => resolve(calc(42)));`,
- errors: [
- {
- suggestions: [
- {
- desc: 'Replace with "Promise.resolve"',
- output: 'Promise.resolve(calc(42));',
- },
- ],
- },
- ],
- },
- {
- code: `new Promise((resolve, reject) => reject(new Error('fail')));`,
- errors: [
- {
- suggestions: [
- {
- desc: 'Replace with "Promise.reject"',
- output: `Promise.reject(new Error('fail'));`,
- },
- ],
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/prefer-type-guard.test.ts b/eslint-bridge/tests/linting/eslint/rules/prefer-type-guard.test.ts
deleted file mode 100644
index ee029e93ca4..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/prefer-type-guard.test.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/prefer-type-guard';
-
-const ruleTester = new RuleTester({
- parser: require.resolve('@typescript-eslint/parser'),
- parserOptions: { ecmaVersion: 2018 },
-});
-
-function invalid(code: string) {
- const line = code.split('\n').findIndex(str => str.includes('// Noncompliant')) + 1;
- return {
- code: code,
- errors: [
- {
- message: `Declare this function return type using type predicate "animal is Fish".`,
- line,
- endLine: line,
- },
- ],
- };
-}
-
-ruleTester.run('Type guards should be used', rule, {
- valid: [
- {
- code: `function isFish(animal: Animal): animal is Fish {
- return (animal as Fish).swim !== undefined;
- }`,
- },
- {
- code: `function isFish(animal: Animal) {
- return (animal as Fish).swim !== null;
- }`,
- },
- {
- code: `function isFish(animal: Animal) {
- console.log((animal as Fish).swim !== null);
- }`,
- },
- {
- code: `// "any" type is excluded
- function isFish(animal: Animal) {
- return (animal as any).swim != undefined;
- }`,
- },
- {
- code: `function isNotFish(animal: Animal) {
- return !((animal as Fish).swim);
- }`,
- },
- {
- code: `// OK, not a member expression
- function isFish(animal: Animal) {
- return !!(animal as Fish);
- }`,
- },
- {
- code: `// OK, more than one statement
- function isFish(animal: Animal) {
- console.log("FOO");
- return !!((animal as Fish).swim);
- }`,
- },
- {
- code: `// OK, more than one argument
- function isFish(animal: Animal, foo: String) {
- return !!((animal as Fish).swim);
- }`,
- },
- {
- code: `// OK, no type casting
- function isFish(animal: Animal) {
- return !!animal.name;
- }`,
- },
- {
- code: `// Arrow functions are ignored
- let typePredicate = (animal: Animal) => !!(animal as Fish).swim;
- let typePredicateOK = (animal: Animal): animal is Fish => !!(animal as Fish).swim;
- let animals : Animal[] = [];
- let fishes = animals.filter((animal: Animal) => !!(animal as Fish).swim);
- let fishes = animals.filter((animal: Animal) => !!(animal).swim);
- let fishesOK = animals.filter((animal: Animal): animal is Fish => !!(animal as Fish).swim);`,
- },
- {
- code: `// Function Expressions are ignored
- let isFish = function (animal: Animal) {
- return (animal as Fish).swim !== undefined;
- }
- let isFishOK = function (animal: Animal) : animal is Fish {
- return (animal as Fish).swim !== undefined;
- }`,
- },
- {
- code: `declare function isFishNoBody(): boolean`,
- },
- {
- code: `// Disjoint union types
- type A1 = {
- common: 1,
- a1: string
- };
-
- type A2 = {
- common: 2,
- a2: number
- };
-
- // FN
- function isA1(param: A1 | A2) {
- return param.common === 1;
- }
-
- // FN
- function isSomeA1(param: A1 | A2) {
- return param.common === 1 && param.a1 === "Hello";
- }`,
- },
- ],
- invalid: [
- {
- code: `function isFish(animal: Animal) {
- return (animal as Fish).swim !== undefined;
- }`,
- errors: [
- {
- message: `Declare this function return type using type predicate "animal is Fish".`,
- line: 1,
- column: 10,
- endLine: 1,
- endColumn: 16,
- },
- ],
- },
- invalid(
- `// With explicit return type
- function isFish(animal: Animal) : boolean { // Noncompliant
- return (animal as Fish).swim !== undefined;
- }`,
- ),
- invalid(
- `function isFish(animal: Animal) { // Noncompliant
- return undefined !== (animal as Fish).swim;
- }`,
- ),
- invalid(
- `// With loose inequality
- function isFish(animal: Animal) { // Noncompliant
- return (animal as Fish).swim != undefined;
- }`,
- ),
- invalid(
- `function isFish(animal: Animal) { // Noncompliant
- return ( animal).swim !== undefined;
- }`,
- ),
- invalid(
- `function isFish(animal: Animal) { // Noncompliant
- return Boolean((animal as Fish).swim);
- }`,
- ),
- invalid(
- `function isFish(animal: Animal) { // Noncompliant
- return !!((animal as Fish).swim);
- }`,
- ),
- invalid(
- `function isFish(animal: Animal) { // Noncompliant
- return (animal).swim !== undefined;
- }`,
- ),
- {
- code: `// Type predicate on "this"
- class Animal {
- swim?: Function;
- isFish(): boolean { // Noncompliant
- return !!(this as Fish).swim;
- }
-
- isFishOK() : this is Fish {
- return !!(this as Fish).swim;
- }
- }`,
- errors: [
- {
- message: `Declare this function return type using type predicate "this is Fish".`,
- line: 4,
- column: 13,
- endLine: 4,
- endColumn: 19,
- },
- ],
- },
- invalid(`// Method declarations
- class Farm {
- isFish(animal: Animal) { // Noncompliant
- return !!((animal as Fish).swim);
- }
-
- isFishOK(animal: Animal): animal is Fish {
- return !!((animal as Fish).swim);
- }
-
- get getIsFish(animal: Animal) { //OK, getter
- return !!((animal as Fish).swim);
- }
- }`),
- {
- code: `function isAnimal(animal: Animal) { return Boolean((animal as Fish).swim); }`,
- errors: [
- {
- suggestions: [
- {
- desc: 'Use type predicate',
- output:
- 'function isAnimal(animal: Animal): animal is Fish { return Boolean((animal as Fish).swim); }',
- },
- ],
- },
- ],
- },
- {
- code: `function isAnimal(animal: Animal): boolean { return Boolean((animal as Fish).swim); }`,
- errors: [
- {
- suggestions: [
- {
- output:
- 'function isAnimal(animal: Animal): animal is Fish { return Boolean((animal as Fish).swim); }',
- },
- ],
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/process-argv.test.ts b/eslint-bridge/tests/linting/eslint/rules/process-argv.test.ts
deleted file mode 100644
index 239583af696..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/process-argv.test.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/process-argv';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Using command line arguments is security-sensitive', rule, {
- valid: [
- {
- code: `foo.bar`,
- },
- {
- code: `process.argvFoo`,
- },
- {
- code: `processFoo.argv`,
- },
- {
- code: `'process.argv'`,
- },
- ],
- invalid: [
- {
- code: `let x = process.argv;`,
- errors: [
- {
- message: 'Make sure that command line arguments are used safely here.',
- line: 1,
- endLine: 1,
- column: 9,
- endColumn: 21,
- },
- ],
- },
- {
- code: `\`argument 0: \${process.argv[0]}\``,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/production-debug.test.ts b/eslint-bridge/tests/linting/eslint/rules/production-debug.test.ts
deleted file mode 100644
index ee03502f26d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/production-debug.test.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/production-debug';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-
-const message =
- 'Make sure this debug feature is deactivated before delivering the code in production.';
-
-ruleTester.run(
- 'Delivering code in production with debug features activated is security-sensitive',
- rule,
- {
- valid: [
- {
- code: `
- Debug.write("hello, world");
-
- // we report only on trivial (and mostly used) usages without object access
- this.alert("here!");
- window.alert("here!");
-
- // custom is ok
- function alert() {}
- alert("here!");
-
- import { confirm } from './confirm';
- confirm("Are you sure?");
- `,
- },
- {
- code: `
- alert("here!");
- confirm("Are you sure?");
- prompt("What's your name?", "John Doe");
- `,
- },
- {
- code: `debugger;`,
- },
- ],
- invalid: [
- {
- code: `
- const errorhandler = require('errorhandler');
- if (process.env.NODE_ENV === 'development') {
- app1.use(errorhandler()); // Compliant
- }
- app2.use(errorhandler()); // Noncompliant
- `,
- errors: [
- {
- message,
- line: 6,
- column: 18,
- endColumn: 32,
- },
- ],
- },
- {
- code: `
- import * as errorhandler from 'errorhandler';
- const handler = errorhandler();
- app1.use(handler); // Noncompliant
- if (process.env.NODE_ENV === 'development') {
- app2.use(handler); // Compliant
- } else {
- app3.use(handler); // Compliant
- }
- app4.use();
- `,
- errors: [
- {
- message,
- line: 3,
- column: 25,
- endColumn: 39,
- },
- ],
- },
- {
- code: `
- const errorhandler = require('errorhandler');
- const middlewares = [
- helmet(),
- errorhandler()
- ];
- app2.use(sth, middlewares, sthElse); // Noncompliant
- `,
- errors: [
- {
- message,
- line: 5,
- column: 11,
- endColumn: 25,
- },
- ],
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/pseudo-random.test.ts b/eslint-bridge/tests/linting/eslint/rules/pseudo-random.test.ts
deleted file mode 100644
index 900b06b0366..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/pseudo-random.test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/pseudo-random';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Using pseudorandom number generators (PRNGs) is security-sensitive', rule, {
- valid: [
- {
- code: `foo(x)`,
- },
- {
- code: `"Math.random()"`,
- },
- {
- code: `Math.foo()`,
- },
- {
- code: `Foo.random()`,
- },
- ],
- invalid: [
- {
- code: `let x = Math.random();`,
- errors: [
- {
- message: 'Make sure that using this pseudorandom number generator is safe here.',
- line: 1,
- endLine: 1,
- column: 9,
- endColumn: 22,
- },
- ],
- },
- {
- code: `foo(Math.random())`,
- errors: 1,
- },
- {
- code: `let random = Math.random; foo(random());`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/publicly-writable-directories.test.ts b/eslint-bridge/tests/linting/eslint/rules/publicly-writable-directories.test.ts
deleted file mode 100644
index 51275f6dfa3..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/publicly-writable-directories.test.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/publicly-writable-directories';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Using publicly writable directories is security-sensitive', rule, {
- valid: [
- {
- code: `
- const tmp = require('tmp');
- const tmp_promise = require('tmp-promise');
-
- let tmpFile = tmp.fileSync();
- tmp.file(function _tempFileCreated(err, path, fd, cleanupCallback) {});
-
- const tmpDir = tmp.dirSync();
- tmp.dir(function _tempDirCreated(err, path, cleanupCallback) {});
-
-
- (async () => {
- const {fd, path, cleanup} = await tmp_promise.file();
- })();
-
- tmp_promise.file().then(o => {});
-
-
- tmpFile = "/home/foo/tmp/f";
- tmpFile = "C:\\Foo\\Temp";
- tmpDir = process.other.TMP;
- tmpDir = something.env.TMP;
- tmpDir = process.env.other;
- `,
- },
- ],
- invalid: [
- {
- code: `
- tmpDir = process.env.TMPDIR;
- tmpFile = "/tmp/f";
- `,
- errors: [
- {
- message: 'Make sure publicly writable directories are used safely here.',
- line: 2,
- endLine: 2,
- column: 16,
- endColumn: 34,
- },
- {
- message: 'Make sure publicly writable directories are used safely here.',
- line: 3,
- endLine: 3,
- column: 17,
- endColumn: 25,
- },
- ],
- },
- {
- code: `
- tmpDir = process.env.TMP;
- tmpDir = process.env.TEMPDIR;
- tmpDir = process.env.TEMP;
-
- tmpFile = "/var/tmp/f";
- tmpFile = "/usr/tmp/f";
- tmpFile = "/dev/shm/f";
- tmpFile = "/dev/mqueue/f";
- tmpFile = "/run/lock/f";
- tmpFile = "/var/run/lock/f";
- tmpFile = "/Library/Caches/f";
- tmpFile = "/Users/Shared/f";
- tmpFile = "/private/tmp/f";
- tmpFile = "/private/var/tmp/f";
- tmpFile = "C:\\Windows\\Temp";
- tmpFile = "D:\\Windows\\Temp";
- tmpFile = "C:\\Temp";
- tmpFile = "C:\\TEMP";
- tmpFile = "C:\\TMP";
- `,
- errors: 18,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/regex-complexity.test.ts b/eslint-bridge/tests/linting/eslint/rules/regex-complexity.test.ts
deleted file mode 100644
index e3611fa7e4b..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/regex-complexity.test.ts
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/regex-complexity';
-
-const ruleTesterThreshold0 = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTesterThreshold0.run(
- 'Regular expressions should not be too complicated with threshold 0',
- rule,
- {
- valid: [
- {
- code: `/ /`,
- options: [0],
- },
- {
- code: `/abc/`,
- options: [0],
- },
- {
- code: `/^abc$/`,
- options: [0],
- },
- {
- code: `/(?:abc)/`,
- options: [0],
- },
- {
- code: `/(abc)/`,
- options: [0],
- },
- {
- code: `/\\w.u/`,
- options: [0],
- },
- {
- code: `RegExp('abc')`,
- options: [0],
- },
- {
- code: `new RegExp('abc')`,
- options: [0],
- },
- {
- code: 'RegExp(`abc`)',
- options: [0],
- },
- {
- code: `RegExp('[malformed')`,
- options: [0],
- },
- {
- code: `RegExp(123)`,
- options: [0],
- },
- {
- code: `RegExp(unknown)`,
- options: [0],
- },
- {
- code: `let uninitialized; RegExp(uninitialized)`,
- options: [0],
- },
- {
- code: `new Foo('abc')`,
- options: [0],
- },
- {
- code: `Foo('abc')`,
- options: [0],
- },
- {
- code: `RegExp('(a|' + 'b)')`,
- options: [0],
- },
- ],
- invalid: [
- {
- code: `/(?=abc)/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 1, line: 1, endColumn: 4, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 10,
- },
- ],
- options: [0],
- },
- {
- code: `/(?<=abc)/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 1, line: 1, endColumn: 5, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 11,
- },
- ],
- options: [0],
- },
- {
- code: `/[a-z0-9]/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 1, line: 1, endColumn: 2, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 11,
- },
- ],
- options: [0],
- },
- {
- code: `/x*/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 2, line: 1, endColumn: 3, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 5,
- },
- ],
- options: [0],
- },
- {
- code: `/x{1,2}/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 2, line: 1, endColumn: 7, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 9,
- },
- ],
- options: [0],
- },
- {
- code: `/(?:abc)*/`,
- errors: 1,
- options: [0],
- },
- {
- code: `/((?:abc)*)/`,
- errors: 1,
- options: [0],
- },
- {
- code: `/((?:abc)*)?/`,
- errors: 1,
- options: [0],
- },
- {
- code: `/a|b/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 2, line: 1, endColumn: 3, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 6,
- },
- ],
- options: [0],
- },
- {
- code: `/a|b|c/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 2 to the 0 allowed.`,
- cost: 2,
- secondaryLocations: [
- { message: `+1`, column: 2, line: 1, endColumn: 3, endLine: 1 },
- { message: `+1`, column: 4, line: 1, endColumn: 5, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 8,
- },
- ],
- options: [0],
- },
- {
- code: `/(?:a|b)*/`,
- errors: 1,
- options: [0],
- },
- {
- code: `/(?:a|b|c)*/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 4 to the 0 allowed.`,
- cost: 4,
- secondaryLocations: [
- { message: `+1`, column: 10, line: 1, endColumn: 11, endLine: 1 },
- {
- message: `+2 (incl 1 for nesting)`,
- column: 5,
- line: 1,
- endColumn: 6,
- endLine: 1,
- },
- { message: `+1`, column: 7, line: 1, endColumn: 8, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 13,
- },
- ],
- options: [0],
- },
- {
- code: `/(foo)\\1/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [{ message: `+1`, column: 6, line: 1, endColumn: 8, endLine: 1 }],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 10,
- },
- ],
- options: [0],
- },
- {
- code: `RegExp('x*')`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [
- { message: `+1`, column: 9, line: 1, endColumn: 10, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 8,
- endColumn: 12,
- },
- ],
- options: [0],
- },
- {
- code: `new RegExp('x*')`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [
- { message: `+1`, column: 13, line: 1, endColumn: 14, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 12,
- endColumn: 16,
- },
- ],
- options: [0],
- },
- {
- code: 'RegExp(`x*`)',
- errors: 1,
- options: [0],
- },
- {
- code: `
- RegExp('/s*')
- `,
- options: [0],
- errors: [
- {
- message: JSON.stringify({
- message:
- 'Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.',
- cost: 1,
- secondaryLocations: [
- {
- message: '+1',
- column: 18,
- line: 2,
- endColumn: 19,
- endLine: 2,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- RegExp('|/?[a-z]')
- `,
- options: [0],
- errors: [
- {
- message: JSON.stringify({
- message:
- 'Simplify this regular expression to reduce its complexity from 4 to the 0 allowed.',
- cost: 4,
- secondaryLocations: [
- { message: '+1', column: 16, line: 2, endColumn: 17, endLine: 2 },
- {
- message: '+2 (incl 1 for nesting)',
- column: 18,
- line: 2,
- endColumn: 19,
- endLine: 2,
- },
- { message: '+1', column: 19, line: 2, endColumn: 20, endLine: 2 },
- ],
- }),
- },
- ],
- },
- ],
- },
-);
-
-const ruleTesterThreshold1 = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTesterThreshold1.run(
- 'Regular expressions should not be too complicated with threshold 1',
- rule,
- {
- valid: [
- {
- code: `
- const part1 = 'x*';
- const part2 = 'y*';
- RegExp(part1 + part2);
- `,
- options: [1],
- },
- ],
- invalid: [
- {
- code: `RegExp('x*' + 'y*')`,
- errors: 1,
- options: [1],
- },
- {
- code: `RegExp('x*' + 'y*' + 'z*')`,
- errors: 1,
- options: [1],
- },
- {
- code: `
- const part1 = 'x*' + 'y*';
- const part2 = 'a*' + 'b*';
- RegExp(part1 + part2);
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 2 to the 1 allowed.`,
- cost: 1,
- secondaryLocations: [
- { message: `+1`, column: 24, line: 2, endColumn: 25, endLine: 2 },
- { message: `+1`, column: 31, line: 2, endColumn: 32, endLine: 2 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 23,
- endColumn: 27,
- },
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 2 to the 1 allowed.`,
- cost: 1,
- secondaryLocations: [
- { message: `+1`, column: 24, line: 3, endColumn: 25, endLine: 3 },
- { message: `+1`, column: 31, line: 3, endColumn: 32, endLine: 3 },
- ],
- }),
- line: 3,
- endLine: 3,
- column: 23,
- endColumn: 27,
- },
- ],
- options: [1],
- },
- ],
- },
-);
-
-const typeAwareRuleTester = new TypeScriptRuleTester();
-typeAwareRuleTester.run(
- 'Regular expressions should not be too complicated with type information',
- rule,
- {
- valid: [
- {
- code: `'str'.search('abc')`,
- options: [0],
- },
- ],
- invalid: [
- {
- code: `'str'.search('x*')`,
- errors: [
- {
- message: JSON.stringify({
- message: `Simplify this regular expression to reduce its complexity from 1 to the 0 allowed.`,
- cost: 1,
- secondaryLocations: [
- { message: `+1`, column: 15, line: 1, endColumn: 16, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 14,
- endColumn: 18,
- },
- ],
- options: [0],
- },
- ],
- },
-);
-
-const ruleTesterDefaultThreshold = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTesterDefaultThreshold.run(
- 'Regular expressions should not be too complicated with default threshold',
- rule,
- {
- valid: [
- {
- code: `/ /`,
- },
- ],
- invalid: [
- {
- code: `/^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[13-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$/`,
- errors: 1,
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/regular-expr.test.ts b/eslint-bridge/tests/linting/eslint/rules/regular-expr.test.ts
deleted file mode 100644
index fdc2b20b7aa..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/regular-expr.test.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/regular-expr';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-
-const message = 'Make sure that using a regular expression is safe here.';
-
-ruleTester.run('Using regular expressions is security-sensitive', rule, {
- valid: [
- {
- // not enough of special symbols
- code: `str.match("(a+)b");`,
- },
- {
- // not enough of special symbols
- code: `str.match(/(a+)b/);`,
- },
- {
- // different method
- code: `str.foo("(a+)b+");`,
- },
- {
- // argument is not hardcoded literal
- code: `str.match(foo("(a+)b+"));`,
- },
- {
- // FN
- code: `const x = "(a+)b+"; str.match(x);`,
- },
- {
- // not enough length
- code: `str.match("++");`,
- },
- {
- // missing argument
- code: `str.match();`,
- },
- ],
- invalid: [
- {
- code: `str.match("(a+)+b");`,
- errors: [
- {
- message,
- line: 1,
- endLine: 1,
- column: 11,
- endColumn: 19,
- },
- ],
- },
-
- {
- code: `str.match("+++");`,
- errors: [{ message }],
- },
- {
- code: `str.match("***");`,
- errors: [{ message }],
- },
- {
- code: `str.match("{{{");`,
- errors: [{ message }],
- },
- {
- code: `str.match(/(a+)+b/);`,
- errors: [{ message }],
- },
-
- {
- code: `str.split("(a+)+b");`,
- errors: [{ message }],
- },
- {
- code: `str.search("(a+)+b");`,
- errors: [{ message }],
- },
- {
- code: `new RegExp("(a+)+b");`,
- errors: [{ message }],
- },
-
- {
- code: `/(a+)+b/;`,
- errors: [{ message }],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/session-regeneration.test.ts b/eslint-bridge/tests/linting/eslint/rules/session-regeneration.test.ts
deleted file mode 100644
index d9692fec717..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/session-regeneration.test.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/session-regeneration';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run(
- 'Create a new session during user authentication to prevent session fixation attacks.',
- rule,
- {
- valid: [
- {
- code: `
- var passport = require('passport');
-
- app.post('/login',
- passport.authenticate('local', { failureRedirect: '/login' }),
- function(req, res) {
- let prevSession = req.session;
- req.session.regenerate((err) => { // Compliant
- Object.assign(req.session, prevSession);
- res.redirect('/');
- });
- console.log('coverage');
- });`,
- },
- {
- code: `
- var passport = require('passport');
- passport.authenticate('local', { failureRedirect: '/login' });
- `,
- },
- {
- code: `
- var passport = require('passport');
- app.post('/login', passport.authenticate('local', { failureRedirect: '/login' }), foo);
- `,
- },
- {
- code: `
- var passport = require('passport');
- app.post('/api/login',
- passport.authenticate('local', { session: false }), // Compliant - no session
- function(req, res) {
- res.redirect('/');
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- var passport = require('passport');
-
- app.post('/login',
- passport.authenticate('local', { failureRedirect: '/login' }),
- function(req, res) {
- // Sensitive - no session.regenerate after login
- res.redirect('/');
- });`,
- errors: [
- {
- message:
- 'Create a new session during user authentication to prevent session fixation attacks.',
- line: 6,
- column: 7,
- endLine: 9,
- endColumn: 8,
- },
- ],
- },
- {
- code: `
- var passport = require('passport');
- app.post('/api/login',
- passport.authenticate('local', { session: true }),
- function(req, res) {
- res.redirect('/');
- });
- `,
- errors: 1,
- },
- {
- code: `
- var passport = require('passport');
- app.post('/api/login',
- passport.authenticate('local', foo()), // could be FP if foo() sets session to false
- function(req, res) {
- res.redirect('/');
- });
- `,
- errors: 1,
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/shorthand-property-grouping.test.ts b/eslint-bridge/tests/linting/eslint/rules/shorthand-property-grouping.test.ts
deleted file mode 100644
index 85018fe628b..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/shorthand-property-grouping.test.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/shorthand-property-grouping';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run(
- 'Shorthand object properties should be grouped at the beginning or end of an object declaration',
- rule,
- {
- valid: [
- {
- code: `
- let obj2 = {
- foo,
- color,
- judyGarland,
- a: 1,
- b: 2
- }
-
- let obj3 = {
- a: 1,
- b: 2,
- foo,
- color,
- judyGarland
- }
-
- let obj4 = {
- a: 1,
- bar() {},
- b: 2,
- foo,
- color,
- judyGarland
- }
-
- var obj = {
- ...otherObj,
- prop1, // we can't move shorthand properties as they might overwrite values in "otherObj"
- prop2,
- prop3 : value3
- }`,
- },
- ],
- invalid: [
- {
- code: `let obj1 = { // Main location
- foo, // Secondary location
- a: 1,
- color, // Secondary location
- b: 2,
- judyGarland // Secondary location
- }`,
- errors: [
- {
- message: `{\"message\":\"Group all shorthand properties at either the beginning or end of this object declaration.\",\"secondaryLocations\":[{\"message\":\"Move to either the beginning or end\",\"column\":12,\"line\":2,\"endColumn\":15,\"endLine\":2},{\"message\":\"Move to either the beginning or end\",\"column\":12,\"line\":4,\"endColumn\":17,\"endLine\":4},{\"message\":\"Move to either the beginning or end\",\"column\":12,\"line\":6,\"endColumn\":23,\"endLine\":6}]}`,
- line: 1,
- endLine: 1,
- column: 12,
- endColumn: 13,
- },
- ],
- },
- {
- code: `let obj1 = { // Main location
- foo,
- color,
- a: 1,
- c, // Secondary location
- b: 2,
- judyGarland // Secondary location
- }`,
- errors: [
- {
- message: `{\"message\":\"Group all shorthand properties at the beginning of this object declaration.\",\"secondaryLocations\":[{\"message\":\"Move to the beginning\",\"column\":20,\"line\":5,\"endColumn\":21,\"endLine\":5},{\"message\":\"Move to the beginning\",\"column\":20,\"line\":7,\"endColumn\":31,\"endLine\":7}]}`,
- line: 1,
- endLine: 1,
- column: 12,
- endColumn: 13,
- },
- ],
- },
- {
- code: `let obj6 = { // Main location
- a: 1,
- foo, // Secondary location
- color, // Secondary location
- b: 2,
- c,
- judyGarland
- }`,
- errors: [
- {
- message: `{"message":"Group all shorthand properties at the end of this object declaration.","secondaryLocations":[{"message":"Move to the end","column":20,"line":3,"endColumn":23,"endLine":3},{"message":"Move to the end","column":20,"line":4,"endColumn":25,"endLine":4}]}`,
- line: 1,
- endLine: 1,
- column: 12,
- endColumn: 13,
- },
- ],
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/single-character-alternation.test.ts b/eslint-bridge/tests/linting/eslint/rules/single-character-alternation.test.ts
deleted file mode 100644
index 3cc16319997..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/single-character-alternation.test.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/single-character-alternation';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Single-character alternation', rule, {
- valid: [
- {
- code: `const str = 'abc123';`,
- },
- {
- code: `const str = /[abc]/;`,
- },
- {
- code: `const re = /ab|cd/;`,
- },
- {
- code: `const re = /a|\\b|c/;`,
- },
- {
- code: `const re = /^|$/;`,
- },
- {
- code: `const re = /|/;`,
- },
- {
- code: `/(s)*/`,
- },
- ],
- invalid: [
- {
- code: `
- const re = /a|b|c/;
- //^^^^^^^
- `,
- errors: [
- {
- message: 'Replace this alternation with a character class.',
- line: 2,
- endLine: 2,
- column: 23,
- endColumn: 28,
- },
- ],
- },
- {
- code: `const re = /a|(b|c)/;`,
- errors: [
- {
- message: 'Replace this alternation with a character class.',
- line: 1,
- endLine: 1,
- column: 15,
- endColumn: 20,
- },
- ],
- },
- {
- code: `const re = /abcd|(e|f)gh/;`,
- errors: 1,
- },
- {
- code: `const re = /(a|b|c)*/;`,
- errors: 1,
- },
- {
- code: `const re = /(?:a|b)/;`,
- errors: 1,
- },
- {
- code: `const re = /a(?=b|c)/;`,
- errors: 1,
- },
- {
- code: `const re = /a(?!b|c)/;`,
- errors: 1,
- },
- {
- code: `const re = /(?<=a|b)c/;`,
- errors: 1,
- },
- {
- code: `const re = /(?.*?),(?.*?)(?:#(?.*))?$/.exec(urlString);
- const match = /^data:(?[^,]*?),(?[^#]*?)(?:#(?.*))?$/.exec(urlString); // OK, fix for previous one
- `,
- errors: [
- {
- line: 2,
- },
- {
- line: 3,
- },
- {
- line: 4,
- },
- {
- line: 5,
- },
- {
- line: 6,
- },
- {
- line: 7,
- },
- {
- line: 8,
- },
- {
- line: 9,
- },
- {
- line: 10,
- },
- {
- line: 11,
- },
- {
- line: 13,
- },
- ],
- },
- {
- // fails on Node 10
- code: `new RegExp('[\\x09\\x0A]*$');`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sockets.test.ts b/eslint-bridge/tests/linting/eslint/rules/sockets.test.ts
deleted file mode 100644
index d6eaa177b03..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sockets.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sockets';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Handling files is security-sensitive', rule, {
- valid: [
- {
- code: `
- const net = require('net');
- net.createServer();
- `,
- },
- {
- code: `
- new net.Socket();
- `,
- },
- ],
- invalid: [
- {
- code: `
- const net = require('net');
- new net.Socket();
- `,
- errors: [
- {
- message: 'Make sure that sockets are used safely here.',
- line: 3,
- endLine: 3,
- column: 13,
- endColumn: 23,
- },
- ],
- },
- {
- code: `
- const net = require('net');
- net.createConnection({ port: port }, () => {});`,
- errors: 1,
- },
- {
- code: `
- import { connect } from 'net'
- connect({ port: port }, () => {});;
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-block-scoped-var.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-block-scoped-var.test.ts
deleted file mode 100644
index 9896dd0817a..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-block-scoped-var.test.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-block-scoped-var';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Variables should be used in the blocks where they are declared', rule, {
- valid: [
- {
- code: `
- function fun() {
-
- if (cond) {
- let a = 42;
- }
- if (cond) {
- let a = 0;
- }
-
- var b = 42;
- if (cond) {
- foo(b);
- } else {
- bar(b);
- }
-
- var build;
- var f;
-
- try {
- build = 1;
- } catch (e) {
- f = build;
- }
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- function fun() {
- if (cond) {
- var a = 42;
- }
- if (cond) {
- var a = 0;
- }
- }
- `,
- errors: [
- {
- message: `{"message":"Consider moving declaration of 'a' as it is referenced outside current binding context.","secondaryLocations":[{"message":"Outside reference.","column":16,"line":7,"endColumn":17,"endLine":7}]}`,
- line: 4,
- endLine: 4,
- column: 17,
- endColumn: 18,
- },
- ],
- },
- {
- code: `
- function fun() {
- if (cond) {
- var a = 42; // nok
- }
- console.log(a);
- }
- `,
- errors: [
- {
- message: `{"message":"Consider moving declaration of 'a' as it is referenced outside current binding context.","secondaryLocations":[{"message":"Outside reference.","column":20,"line":6,"endColumn":21,"endLine":6}]}`,
- line: 4,
- },
- ],
- },
- {
- code: `
- function fun() {
- for (var i = 0; ;) {}
- foo(i);
- return i;
- }
- `,
- errors: [
- {
- message: `{"message":"Consider moving declaration of 'i' as it is referenced outside current binding context.","secondaryLocations":[{"message":"Outside reference.","column":14,"line":4,"endColumn":15,"endLine":4},{"message":"Outside reference.","column":17,"line":5,"endColumn":18,"endLine":5}]}`,
- line: 3,
- endLine: 3,
- column: 20,
- endColumn: 21,
- },
- ],
- },
- {
- code: `
- function fun() {
- for (var i in smth) {}
- foo(i);
-
- for (var j of smth) {}
- foo(j);
-
- switch(42) {
- case 0:
- var k = 42;
- }
- foo(k);
- }
- `,
- errors: [
- {
- line: 3,
- },
- {
- line: 6,
- },
- {
- line: 11,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-jsx-no-leaked-render.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-jsx-no-leaked-render.test.ts
deleted file mode 100644
index 2a48f520685..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-jsx-no-leaked-render.test.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-jsx-no-leaked-render';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const ruleTesterTs = new TypeScriptRuleTester();
-const ruleTesterJs = new RuleTester({
- parserOptions: { ecmaVersion: 2018, sourceType: 'module', ecmaFeatures: { jsx: true } },
-});
-
-ruleTesterTs.run('', rule, {
- valid: [
- {
- code: `
- const Component = (count, collection) => {
- count = 1;
- return (
-
- {count &&
}
-
- )
- }
- `,
- },
- {
- code: `
- const Component = (count: boolean, collection) => {
- return (
-
- {count &&
}
-
- )
- }
- `,
- },
- {
- code: `
- const Component = (collection) => {
- let test = '';
- return (
-
- {test &&
}
-
- )
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- const Component = (count: number, collection) => {
- return (
-
- {count &&
}
-
- )
- }
- `,
- errors: [
- {
- message: 'Convert the conditional to a boolean to avoid leaked value',
- line: 5,
- column: 16,
- endLine: 5,
- endColumn: 21,
- suggestions: [
- {
- output: `
- const Component = (count: number, collection) => {
- return (
-
- {!!(count) &&
}
-
- )
- }
- `,
- },
- ],
- },
- ],
- },
- {
- code: `
- const Component = (collection) => {
- const count = 0;
- return (
-
- {count &&
}
-
- )
- }
- `,
- errors: [
- {
- line: 6,
- column: 16,
- endLine: 6,
- endColumn: 21,
- suggestions: [
- {
- output: `
- const Component = (collection) => {
- const count = 0;
- return (
-
- {!!(count) &&
}
-
- )
- }
- `,
- },
- ],
- },
- ],
- },
- {
- code: `
- const Component = (collection: Array) => {
- return (
-
- {collection.length &&
}
-
- )
- }
- `,
- errors: [
- {
- line: 5,
- column: 16,
- endLine: 5,
- endColumn: 33,
- suggestions: [
- {
- output: `
- const Component = (collection: Array) => {
- return (
-
- {!!(collection.length) &&
}
-
- )
- }
- `,
- },
- ],
- },
- ],
- },
- {
- code: `
- const Component = (test: number, count: number, collection) => {
- return (
-
- {(test || (count)) &&
}
-
- )
- }
- `,
- errors: [
- {
- line: 5,
- column: 17,
- endLine: 5,
- endColumn: 21,
- suggestions: [
- {
- output: `
- const Component = (test: number, count: number, collection) => {
- return (
-
- {(!!(test) || (count)) &&
}
-
- )
- }
- `,
- },
- ],
- },
- {
- line: 5,
- column: 26,
- endLine: 5,
- endColumn: 31,
- suggestions: [
- {
- output: `
- const Component = (test: number, count: number, collection) => {
- return (
-
- {(test || !!(count)) &&
}
-
- )
- }
- `,
- },
- ],
- },
- ],
- },
- {
- code: `
- import react from 'react-native';
- const Component = (collection) => {
- let test = '';
- return (
-
- {test &&
}
-
- )
- }
- `,
- errors: 1,
- },
- {
- code: `
- const react = require('react-native');
- const Component = (collection) => {
- let test = '';
- return (
-
- {test &&
}
-
- )
- }
- `,
- errors: 1,
- },
- ],
-});
-
-ruleTesterJs.run('', rule, {
- valid: [
- {
- code: `
- const Component = (collection) => {
- const count = 0;
- return (
-
- {count &&
/*OK, no type information available*/ }
-
- )
- }
- `,
- },
- ],
- invalid: [],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines-per-function.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines-per-function.test.ts
deleted file mode 100644
index e1288d56619..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines-per-function.test.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-max-lines-per-function';
-
-const ruleTester = new RuleTester({
- parserOptions: { ecmaVersion: 2018, ecmaFeatures: { jsx: true } },
-});
-
-ruleTester.run('Too many lines in functions', rule, {
- valid: [
- {
- code: `function f() {
- console.log("a");
- }`,
- options: [3],
- },
- {
- code: `function f() {
-
- console.log("a");
-
-
- }`,
- options: [3],
- },
- {
- code: `function f() {
- // comment
- console.log("a");
- /*
- multi
- line
- comment
- */
- }`,
- options: [3],
- },
- {
- code: `function foo() {
- console.log("a"); // End of line comment
- }`,
- options: [3],
- },
- {
- code: `
- console.log("a");
- function foo() {
- console.log("a");
- }
- console.log("a");
- `,
- options: [3],
- },
- {
- code: `function f() {
- function g() {
- console.log("a");
- }
- }`,
- options: [5],
- },
- {
- code: `(
-function
-()
-{
-}
-)
-()`, //IIFE are ignored
- options: [6],
- },
- {
- // React Function Component
- code: `
- function Welcome() {
- const greeting = 'Hello, world!';
-
- return {greeting}
- }`,
- options: [2],
- },
- {
- // React Function Component using function expressions and JSXFragments
- code: `
- let a = function Welcome() {
- const greeting = 'Hello, world!';
-
- return <>{greeting} >
- }`,
- options: [2],
- },
- ],
- invalid: [
- {
- code: `function foo() {
- console.log("a");
- console.log("a");
- }`,
- options: [3],
- errors: [
- {
- message: `This function has 4 lines, which is greater than the 3 lines authorized. Split it into smaller functions.`,
- line: 1,
- endLine: 1,
- column: 10,
- endColumn: 13,
- },
- ],
- },
- {
- code: `function foo() {
- console.log("a");
- console.log("a");
- console.log("b");
- }`,
- options: [4],
- errors: [
- {
- message: `This function has 5 lines, which is greater than the 4 lines authorized. Split it into smaller functions.`,
- line: 1,
- endLine: 1,
- column: 10,
- endColumn: 13,
- },
- ],
- },
- {
- // React Function Component
- code: `
- function Welcome() {
- const greeting = 'Hello, world!';
-
- const doSomething = () => {
- console.log('foo');
- console.log('bar');
- console.log('baz');
- }
-
- return {greeting}
- }`,
- options: [2],
- errors: [
- {
- line: 5,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines.test.ts
deleted file mode 100644
index ac4cfdb43cd..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-max-lines.test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-max-lines';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Too many lines in file', rule, {
- valid: [
- {
- code: `a;
- b;
- c;`,
- options: [3],
- },
- {
- code: `a;
-
- b;
- // comment
- c;`,
- options: [3],
- },
- ],
- invalid: [
- {
- code: `a;
- b;
-
- c;
- // comment
- d;`,
- options: [3],
- errors: [
- {
- message: `This file has 4 lines, which is greater than 3 authorized. Split it into smaller files.`,
- line: 0,
- column: 1,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-max-params.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-max-params.test.ts
deleted file mode 100644
index 14dd5e6f1a3..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-max-params.test.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/sonar-max-params';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const MAX_PARAMS_3 = 3;
-const MAX_PARAMS_5 = 5;
-
-const ruleTester = new TypeScriptRuleTester();
-ruleTester.run(``, rule, {
- valid: [
- {
- code: `function f(a, b) {}`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `function f(a, b, c, d, e) {}`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `function f(a: any, b: any): any;`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `function f(a: any, b: any, c: any, d: any, e: any): any;`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `class C { m(a: any, b: any): any; }`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `class C { constructor(private a: any, public b: any) {} }`,
- options: [MAX_PARAMS_5],
- },
- {
- code: `
- import { Component } from '@angular/core';
- @Component({/* ... */})
- class AppComponent {
- constructor(a, b, c, d, e, f) {}
- }
- `,
- options: [MAX_PARAMS_3],
- },
- ],
- invalid: [
- {
- code: `function f(a, b, c, d, e) {}`,
- options: [MAX_PARAMS_3],
- errors: [
- {
- message: "Function 'f' has too many parameters (5). Maximum allowed is 3.",
- line: 1,
- column: 1,
- endLine: 1,
- endColumn: 11,
- },
- ],
- },
- {
- code: `function f(a: any, b: any, c: any, d: any, e: any): any;`,
- options: [MAX_PARAMS_3],
- errors: [
- {
- message: "Function declaration 'f' has too many parameters (5). Maximum allowed is 3.",
- line: 1,
- column: 1,
- endLine: 1,
- endColumn: 11,
- },
- ],
- },
- {
- code: `class C { m(a: any, b: any, c: any, d: any, e: any): any; }`,
- options: [MAX_PARAMS_3],
- errors: [
- {
- message: "Empty function 'm' has too many parameters (5). Maximum allowed is 3.",
- line: 1,
- column: 11,
- endLine: 1,
- endColumn: 12,
- },
- ],
- },
- {
- code: `class C { constructor(a: any, b: any, c: any, d: any, e: any); }`,
- options: [MAX_PARAMS_3],
- errors: [
- {
- message:
- "Empty function 'constructor' has too many parameters (5). Maximum allowed is 3.",
- line: 1,
- column: 11,
- endLine: 1,
- endColumn: 22,
- },
- ],
- },
- {
- code: `class C { constructor(private a: any, b: any, c: any, d: any, e: any) {} }`,
- options: [MAX_PARAMS_3],
- errors: [
- {
- message: 'Constructor has too many parameters (5). Maximum allowed is 3.',
- line: 1,
- column: 11,
- endLine: 1,
- endColumn: 22,
- },
- ],
- },
- {
- code: `
- import { NotComponent } from '@angular/core';
- import { Component } from 'not-angular-core';
-
- @NotComponent({/* ... */})
- class C1 {
- constructor(a, b, c, d, e, f) {}
- }
-
- @Component({/* ... */})
- class C2 {
- constructor(a, b, c, d, e, f) {}
- }
-
- @DoesNotExist({/* ... */})
- class C3 {
- constructor(a, b, c, d, e, f) {}
- }
-
- class C4 {
- constructor(a, b, c, d, e, f) {}
- }
- `,
- options: [MAX_PARAMS_3],
- errors: 4,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-control-regex.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-control-regex.test.ts
deleted file mode 100644
index 779bbb8100c..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-control-regex.test.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-no-control-regex';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('No control characters in regular expressions', rule, {
- valid: [
- {
- code: `/0/`,
- },
- {
- code: `/\\0/`,
- },
- {
- code: `/\\x20/`,
- },
- {
- code: `/\\u0020/`,
- },
- {
- code: `/\\u{001F}/`,
- },
- {
- code: `/\\cA/`,
- },
- ],
- invalid: [
- {
- code: `/\\x00/`,
- errors: [
- {
- message: 'Remove this control character: \\x00.',
- line: 1,
- endLine: 1,
- column: 2,
- endColumn: 6,
- },
- ],
- },
- {
- code: `/\\u001F/`,
- errors: [
- {
- message: 'Remove this control character: \\u001F.',
- line: 1,
- endLine: 1,
- column: 2,
- endColumn: 8,
- },
- ],
- },
- {
- code: `/\\u{001F}/u`,
- errors: [
- {
- message: 'Remove this control character: \\u{001F}.',
- line: 1,
- endLine: 1,
- column: 2,
- endColumn: 10,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-fallthrough.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-fallthrough.test.ts
deleted file mode 100644
index bc2341bac1d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-fallthrough.test.ts
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-no-fallthrough';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('No fallthrough in switch statement', rule, {
- valid: [
- {
- code: `
- switch (x) {
- case 0:
- process.exit(1);
- default:
- doSomething();
- }
- `,
- },
- {
- code: `
- switch (x) {
- case 0:
- if (foo()) {
- hello();
- process.exit(1);
- } else {
- there();
- process.exit(1);
- }
- default:
- doSomething();
- }
- `,
- },
- {
- code: `
- switch (x) {
- case 0:
- if (foo()) {
- hello();
- process.exit(1);
- } else {
- there();
- process.exit(1);
- }
- if (bar()) {
- console.log("unreachable");
- }
- default:
- doSomething();
- }
- `,
- },
- {
- code: `
- switch (param) {}
-
- // with not executable clause
- switch(x) {
- case a:
- break;
- case a:
- function f () {}
- }
-
- // with 0 case clauses
- switch(x) {
- default:
- foo();
- }
-
- // case with parentheses
- switch(x) {
- case (a):
- break;
- case (b):
- break;
- }
- `,
- },
- {
- code: `
- switch ( x ) {
- case 0:
- while ( isTrue() ) {
- doSomething();
- }
- /* falls through */
- default:
- console.log("hello");
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- function func(){
- while(condition) {
- switch (param) {
- case 0: // OK
- case 1: // OK
- break;
- case 2: // OK
- return;
- case 3: // OK
- throw new Error();
- case 4: // Noncompliant
- doSomething();
- case 5: // OK
- continue;
- default: // OK
- doSomethingElse();
- }
- }
- }`,
- errors: [
- {
- message:
- 'End this switch case with an unconditional break, continue, return or throw statement.',
- line: 12,
- column: 13,
- endLine: 12,
- endColumn: 17,
- },
- ],
- },
-
- {
- code: `
- switch (param) {
- default: // Noncompliant
- doSomething();
- case 0: // OK
- doSomethingElse();
- }`,
- errors: [{ line: 3 }],
- },
- {
- code: `
- function fun() {
- switch (param) {
- case 0: // OK
- doSomething(); break;
- case 1: // OK
- { break; }
- case 2: // Noncompliant
- { }
- case 3: // Noncompliant
- { doSomething(); }
- case 4: // OK
- { { return; } }
- case 5: // OK
- ;
- break;
- default: // OK
- doSomethingElse();
- }
- }
- `,
- errors: [{ line: 8 }, { line: 10 }],
- },
- {
- code: `
- function fun(){
- switch (param) {
- case a:
- break;
- case c:
- while(d) { doSomething(); }
- break;
- case g:
- break;
- case h || i:
- break;
- case g2:
- break;
- case j && k:
- break;
- case l ? m : n:
- break;
- case x: // Noncompliant
- if (f) {
- break;
- }
- case y: // OK
- if (condition) {
- return 0;
- } else {
- return 1;
- }
- default:
- doSomething();
- }
- }
- `,
- errors: [{ line: 19 }],
- },
- {
- code: `
- function fun() {
- switch (param) {
- case 0: // Noncompliant
- doSomethingElse();
- case 1:
- break;
- default:
- doSomething();
- }
- }
- `,
- errors: [{ line: 4 }],
- },
- {
- code: `
- function fun() {
- // OK with comment
- switch (x) {
- case 0:
- foo(); // fallthrough
-
- case 2:
- foo();
- // fall-through
-
- case 3:
- foo();
- // one more comment
- // fall through
-
- case 4:
- if (condition) {
- return foo();
- }
- /* falls through */
-
- case 5:
- foo();
- // passthrough because of this and that
-
- case 6:
- foo();
- // nobreak
-
- case 7:
- foo();
- // proceed
-
- case 8: // Noncompliant
- if (condition) {
- return foo();
- }
- case 9: // some comment
- case 10:
- bar();
- }
- }
- `,
- errors: [{ line: 35 }],
- },
- {
- code: `
- switch (x) {
- case 0:
- if (foo()) {
- process.exit(1);
- }
- default:
- doSomething();
- }
- `,
- errors: [{ line: 3 }],
- },
- {
- code: `
- switch (x) {
- case 0:
- if (foo()) {
- process.exit(1);
- }
- doSomething();
- default:
- doSomething();
- }
- `,
- errors: [{ line: 3 }],
- },
- {
- code: `
- process.exit(1);
- switch (x) {
- case 0:
- doSomething();
- default:
- doSomethingElse();
- }
- `,
- errors: [{ line: 4 }],
- },
- {
- code: `
- switch (x) {
- case 0:
- doSomething();
- ForEachRecord(target, function(options) {
- doSomethingElse();
- });
- break;
- case 1:
- doSomething();
- default:
- doSomethingElse();
- }
-
- `,
- errors: [{ line: 9 }],
- },
- {
- code: `
- function doSomething() {
- doSmth();
- }
- switch (x) {
- case 0:
- doSomething();
- case 1:
- doSomething();
- default:
- doSomethingElse();
- }
- `,
- errors: [{ line: 6 }, { line: 8 }],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-invalid-regexp.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-invalid-regexp.test.ts
deleted file mode 100644
index 5d6ea264f71..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-invalid-regexp.test.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/sonar-no-invalid-regexp';
-
-const ruleTesterTs = new TypeScriptRuleTester();
-ruleTesterTs.run('Malformed regular expressions', rule, {
- valid: [
- {
- code: `new RegExp("\\\\(\\\\[");`,
- },
- {
- code: `new RegExp("\\\\(\\\\[", "g");`,
- },
- {
- code: `str.match("\\\\(\\\\[");`,
- },
- {
- code: `str.replace("([", "{");`,
- },
- {
- code: `'xxx'.match();`,
- },
- {
- code: `foo.match('[');`,
- },
- {
- code: `
- new RegExp();
- new RegExp('foo', 4);
- `,
- },
- ],
- invalid: [
- {
- code: `new RegExp("([");`,
- errors: [
- {
- message: 'Invalid regular expression: /([/: Unterminated character class',
- line: 1,
- column: 1,
- endLine: 1,
- endColumn: 17,
- },
- ],
- },
- {
- code: `'xxx'.match("([");`,
- errors: [
- {
- message: 'Invalid regular expression: /([/: Unterminated character class',
- line: 1,
- column: 1,
- endLine: 1,
- endColumn: 18,
- },
- ],
- },
- {
- code: `new RegExp("\\\\(\\\\[", "a");`,
- errors: [
- {
- message: "Invalid flags supplied to RegExp constructor 'a'",
- line: 1,
- column: 1,
- endLine: 1,
- endColumn: 26,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-misleading-character-class.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-misleading-character-class.test.ts
deleted file mode 100644
index b20111343ac..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-misleading-character-class.test.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-no-misleading-character-class';
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-
-const combiningClass = c => `Move this Unicode combined character '${c}' outside of [...]`;
-
-ruleTester.run('', rule, {
- valid: [
- 'var r = /[\\uD83D\\d\\uDC4D]/',
- 'var r = /[\\uD83D-\\uDC4D]/',
- 'var r = /[👍]/u',
- 'var r = /[\\uD83D\\uDC4D]/u',
- 'var r = /[\\u{1F44D}]/u',
- 'var r = /❇️/',
- 'var r = /Á/',
- 'var r = /[❇]/',
- 'var r = /👶🏻/',
- 'var r = /[👶]/u',
- 'var r = /🇯🇵/',
- 'var r = /[JP]/',
- 'var r = /👨👩👦/',
-
- // Ignore solo lead/tail surrogate.
- 'var r = /[\\uD83D]/',
- 'var r = /[\\uDC4D]/',
- 'var r = /[\\uD83D]/u',
- 'var r = /[\\uDC4D]/u',
-
- // Ignore solo combining char.
- 'var r = /[\\u0301]/',
- 'var r = /[\\uFE0F]/',
- 'var r = /[\\u0301]/u',
- 'var r = /[\\uFE0F]/u',
-
- // Coverage
- 'var r = /[x\\S]/u',
- 'var r = /[xa-z]/u',
- ],
- invalid: [
- {
- code: 'var r = /[\\u0041\\u0301-\\u0301]/',
- errors: [{ column: 17, endColumn: 23, message: combiningClass('\\u0041\\u0301') }],
- },
- {
- code: 'var r = /[Á]/',
- errors: [{ message: combiningClass('Á') }],
- },
- {
- code: 'var r = /[Á]/u',
- errors: [{ message: combiningClass('Á') }],
- },
- {
- code: 'var r = /[\\u0041\\u0301]/',
- errors: [{ message: combiningClass('\\u0041\\u0301') }],
- },
- {
- code: 'var r = /[\\u0041\\u0301]/u',
- errors: [{ message: combiningClass('\\u0041\\u0301') }],
- },
- {
- code: 'var r = /[\\u{41}\\u{301}]/u',
- errors: [{ message: combiningClass('\\u{41}\\u{301}') }],
- },
- {
- code: 'var r = /[❇️]/',
- errors: [{ message: combiningClass('❇️') }],
- },
- {
- code: 'var r = /[❇️]/u',
- errors: [{ message: combiningClass('❇️') }],
- },
- {
- code: 'var r = /[\\u2747\\uFE0F]/',
- errors: [{ message: combiningClass('\\u2747\\uFE0F') }],
- },
- {
- code: 'var r = /[\\u2747\\uFE0F]/u',
- errors: [{ message: combiningClass('\\u2747\\uFE0F') }],
- },
- {
- code: 'var r = /[\\u{2747}\\u{FE0F}]/u',
- errors: [{ message: combiningClass('\\u{2747}\\u{FE0F}') }],
- },
- {
- code: String.raw`var r = new globalThis.RegExp("[❇️]", "")`,
- errors: [{ message: combiningClass('❇️') }],
- },
- {
- code: String.raw`"cc̈d̈d".replaceAll(RegExp("[c̈d̈]"), "X")`,
- errors: [{ message: combiningClass('c̈') }],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-regex-spaces.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-regex-spaces.test.ts
deleted file mode 100644
index 4e20b174482..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-regex-spaces.test.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-no-regex-spaces';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Regex with multiple spaces', rule, {
- valid: [
- {
- code: `/ /`,
- },
- {
- code: `/ {2}/`,
- },
- {
- code: `/ a /`,
- },
- {
- // will be reported by S5869
- code: `/[ ]/`,
- },
- {
- code: `
- / ( )/;
- /a | b/;
- / .* /;
- / \\w /;
- / . /;
- / \\b /;`,
- },
- ],
- invalid: [
- {
- code: `/a b /`,
- errors: [
- {
- message: 'If multiple spaces are required here, use number quantifier ({3}).',
- line: 1,
- endLine: 1,
- column: 3,
- endColumn: 6,
- },
- ],
- },
- {
- code: `/ a /`,
- errors: 2,
- },
- {
- code: `/ */; / +/; / {2}/; / ?/ `,
- errors: 4,
- },
- {
- code: `/(a b)/ `,
- errors: 1,
- },
- {
- code: `
- / ( )/;
- /a | b/;
- / .* /;
- / \\w /;
- / . /;
- / \\b /;`,
- errors: 6,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sonar-no-unused-vars.test.ts b/eslint-bridge/tests/linting/eslint/rules/sonar-no-unused-vars.test.ts
deleted file mode 100644
index 9b4ba51edcf..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sonar-no-unused-vars.test.ts
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sonar-no-unused-vars';
-
-const ruleTester = new RuleTester({
- parserOptions: { sourceType: 'module', ecmaVersion: 2018, ecmaFeatures: { jsx: true } },
-});
-
-ruleTester.run('Local variables should be used', rule, {
- valid: [
- {
- code: `
- var a = 0; // OK, global
- export let b = 0 // OK, global
-
- function fun() {
- function f1() { console.log("f1"); } // OK
- f1();
- }
-
- function bar(){
- try {
- } catch (e) { // OK
- }
-
- bar(function unusedFunctionExpression() {}); // OK, ignore function expression
- }
-
- function foo(){
- var x1 = 1, // OK
- y1 = -x1; // OK
- foo(y1);
- }
-
- function Person() {
- this.name = null;
-
- this.getName = function() { // OK
- return name;
- }
- }
-
- function used_in_template_string() {
- const foo = '.';
- return new RegExp(\`\${foo}\`);
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- function fun() {
- var a = 0; // Noncompliant
- var b = 1; // OK
- return b;
- }`,
- errors: [
- {
- message: `Remove the declaration of the unused 'a' variable.`,
- line: 3,
- endLine: 3,
- column: 13,
- endColumn: 14,
- },
- ],
- },
- {
- code: `
- function fun1() {
- var a = 0; // OK
- function nested() { // Noncompliant
- a = 1;
- }
- }
-
- function fun2() {
- var a = 0; // Noncompliant
- function nested(a) { // Noncompliant
- a = 1;
- }
- }
-
- function fun3() {
- let a = 0; // Noncompliant
- const b = 1; // Noncompliant
- let c // OK
- return c;
- }
-
- function* fun4() {
- var a = 0; // Noncompliant
- var b = 1; // OK
- return b;
- }`,
- errors: [
- {
- message: `Remove unused function 'nested'.`,
- line: 4,
- },
- {
- line: 10,
- },
- {
- line: 11,
- },
- {
- line: 17,
- },
- {
- line: 18,
- },
- {
- line: 24,
- },
- ],
- },
- {
- code: `
- function fun1() {
- var f1 = function() { console.log("f1"); } // Noncompliant
- }
-
- function fun2() {
- function f1() { console.log("f1"); } // Noncompliant
- }
-
- class C {
- f() {
- var a; // Noncompliant
- }
- }
-
- var f = (p) => {
- var x; // Noncompliant
- var y = p.y; // Noncompliant
- }
-
- var f = p => {
- var x; // Noncompliant
- }
-
- function foo(){
- var x = 1; // Noncompliant
- var x = 2; // Noncompliant
-
- class A {} // OK, ignore anything except variables and functions
- }
- `,
- errors: [
- {
- line: 3,
- },
- {
- line: 7,
- },
- {
- line: 12,
- },
- {
- line: 17,
- },
- {
- line: 18,
- },
- {
- line: 22,
- },
- {
- line: 26,
- },
- {
- line: 27,
- },
- ],
- },
- {
- code: `
- function objectDestructuringException(obj) {
- var {a, b, c, ...interestingProps} = obj; // OK
- foo(interestingProps);
-
- var {a1, b1, c1} = obj; // Noncompliant, b1
-
- foo(a1, c1);
-
- var {a2, b2, c2, ...interestingProps2} = obj; // Noncompliant, interestingProps2
-
-
- var {a3, b: b3, c3, ...interestingProps3} = obj; // Noncompliant, b3
-
- foo(interestingProps3);
-
- var {} = obj;
- }`,
- errors: [
- {
- message: `Remove the declaration of the unused 'b1' variable.`,
- line: 6,
- column: 18,
- },
- {
- message: `Remove the declaration of the unused 'interestingProps2' variable.`,
- line: 10,
- column: 29,
- },
- {
- message: `Remove the declaration of the unused 'b3' variable.`,
- line: 13,
- column: 21,
- },
- ],
- },
- {
- code: `
- const constUsed = "this is used";
- let letUsed = "this is used";
- var varUsed = "this is used";
- if(constUsed && letUsed && varUsed) {
- const constUsed = "unused"; // Noncompliant
- let letUsed = "unused"; // Noncompliant
- var varUsed = "used";
-
- function unusedFunc() { // Noncompliant
-
- }
- }`,
- errors: [{ line: 6 }, { line: 7 }, { line: 10 }],
- },
- {
- code: `
- function used_in_jsx(icon) {
- const UsedIcon = icon;
- const UnusedIcon = icon; // Noncompliant
- const lowerCased = icon;
- const tagContent = "content"
- const tagAttribute = "attribute";
-
- // even if React requires user-defined components to start from capital letter
- // let's test name starting from lower-cased letter
- ;
- return {tagContent} ;
- }
- `,
- errors: [
- { line: 4, message: `Remove the declaration of the unused \'UnusedIcon\' variable.` },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/sql-queries.test.ts b/eslint-bridge/tests/linting/eslint/rules/sql-queries.test.ts
deleted file mode 100644
index 1a62be157e2..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/sql-queries.test.ts
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/sql-queries';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Formatting SQL queries is security-sensitive', rule, {
- valid: [
- {
- code: `
- const mysql = require('mysql');
- conn.query(sql, [userInput], (err, res) => {});
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query(sql, (err, res) => {});
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query(sql);
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query();
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query("SELECT * FROM FOO");
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query("SELECT *" + " FROM FOO" + " WHERE BAR");
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query(foo("SELECT *" + userInput));
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- conn.query(\`SELECT * FROM FOO\`);
- `,
- },
- {
- code: `
- const mysql = require('mysql');
- sql = "select from " + userInput;
- conn.query(sql);
- `,
- },
- {
- code: `
- const pg = require('pg');
- conn.query(sql);
- `,
- },
- {
- code: `
- const mysql2 = require('mysql2');
- conn.query(sql);
- `,
- },
- {
- code: `
- const sequelize = require('sequelize');
- conn.query(sql);
- `,
- },
- {
- code: `
- import { query } from 'myDB';
- conn.query("select from " + userInput);
- `,
- },
- {
- // FN, userId is not escaped
- code: `
- const mysql = require('mysql');
- conn.query("SELECT * FROM users WHERE id = ' + userId", [userInput], (err, res) => {});
- `,
- },
- {
- code: `
- require('mysql');
- conn.query(x.foo());`,
- },
- {
- code: `
- require('mysql');
- conn.query(foo());`,
- },
- {
- code: `
- require('mysql');
- conn.query(concat());`,
- },
- ],
- invalid: [
- {
- code: `
- const mysql = require('mysql');
- conn.query('SELECT * FROM users WHERE id = ' + userId, (err, res) => {});`,
- errors: [
- {
- message: 'Make sure that executing SQL queries is safe here.',
- line: 3,
- endLine: 3,
- column: 7,
- endColumn: 17,
- },
- ],
- },
- {
- code: `
- import { query } from 'pg';
- conn.query('SELECT * FROM users WHERE id = ' + userId, (err, res => {}));
- `,
- errors: 1,
- },
- {
- code: `
- import { query } from 'mysql2';
- conn.query('SELECT * FROM users WHERE id = ' + userId, (err, res => {}));
- `,
- errors: 1,
- },
- {
- code: `
- import { query } from 'sequelize';
- conn.query('SELECT * FROM users WHERE id = ' + userId, (err, res => {}));
- `,
- errors: 1,
- },
- // FP, parameters are escaped
- {
- code: `
- const mysql = require('mysql');
- conn.query('SELECT * FROM users WHERE id = ' + connection.escape(userId), (err, res => {}));
- `,
- errors: 1,
- },
-
- {
- code: `
- require('mysql');
- conn.query('a' + 'b' + x);`,
- errors: 1,
- },
- {
- code: `
- require('mysql');
- conn.query('a' + x + 'b');`,
- errors: 1,
- },
- {
- code: `
- require('mysql');
- conn.query(x + 'a' + 'b');`,
- errors: 1,
- },
-
- {
- code: `
- require('mysql');
- conn.query(\`a \${x} b\`);`,
- errors: 1,
- },
-
- {
- code: `
- require('mysql');
- conn.query(x.concat());`,
- errors: 1,
- },
-
- {
- code: `
- require('mysql');
- conn.query(x.replace());`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/standard-input.test.ts b/eslint-bridge/tests/linting/eslint/rules/standard-input.test.ts
deleted file mode 100644
index 88625d7568e..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/standard-input.test.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/standard-input';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Reading the Standard Input is security-sensitive', rule, {
- valid: [
- {
- code: `foo.bar`,
- },
- {
- code: `process.stdout`,
- },
- {
- code: `processFoo.stdin`,
- },
- {
- code: `'process.stdin'`,
- },
- ],
- invalid: [
- {
- code: `let x = process.stdin;`,
- errors: [
- {
- message: 'Make sure that reading the standard input is safe here.',
- line: 1,
- endLine: 1,
- column: 9,
- endColumn: 22,
- },
- ],
- },
- {
- code: `process.stdin.on('readable', () => {});`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/stateful-regex.test.ts b/eslint-bridge/tests/linting/eslint/rules/stateful-regex.test.ts
deleted file mode 100644
index e72ab5db5a3..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/stateful-regex.test.ts
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/stateful-regex';
-import { RuleTester } from 'eslint';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Regular expressions with the global flag should be used with caution', rule, {
- valid: [
- {
- code: `/none/;`,
- },
- {
- code: `/unicode/u;`,
- },
- {
- code: `/global/g;`,
- },
- {
- code: `RegExp('none');`,
- },
- {
- code: `RegExp('global', 'g');`,
- },
- {
- code: `new RegExp('global', 'g');`,
- },
- {
- code: `/sticky/y; `,
- },
- {
- code: `RegExp('sticky', 'y');`,
- },
- {
- code: `new RegExp('sticky', 'y');`,
- },
- {
- code: `while (condition) {/foo/g.exec(input);}`,
- },
- {
- code: `while (() => /foo/g.exec(input)) {}`,
- },
- {
- code: `const re = /foo/g; while (re.exec(input)) {}`,
- },
- {
- code: `while (exec(input)) {}`,
- },
- {
- code: `while (/foo/g.execute(input)) {}`,
- },
- {
- code: `while (/foo/u.exec(input)) {}`,
- },
- {
- code: `while (RegExp('foo').exec(input)) {}`,
- },
- {
- code: `
- const re = /foo/;
- re.test('foo');
- re.test('bar');
- `,
- },
- {
- code: `
- const re = /foo/;
- re.exec('foo');
- re.exec('bar');
- `,
- },
- {
- code: `
- const re = /foo/g;
- re.test('foo');
- `,
- },
- {
- code: `
- const re = /foo/g;
- re.exec('foo');
- `,
- },
- {
- code: `
- const re = /foo/g;
- re.test(input);
- re.test(input);
- `,
- },
- {
- code: `re.test(input);`,
- },
- {
- code: `
- const re = /foo/g;
- re.test(input1);
- re.lastIndex = 0;
- re.test(input2);
- `,
- },
- {
- code: `let re; re.lastIndex = 0;`,
- },
- {
- code: `re.lastIndex = 0;`,
- },
- {
- code: `foo = re.lastIndex;`,
- },
- {
- code: `
- const re = /foo/g;
- re.test('foo');
- re.test(''); // ok, empty string is used to reset the pattern
- re.test('bar');
-
- const re2 = /foo/g;
- re2.test('foo');
- re2.test(""); // ok, empty string is used to reset the pattern
- re2.test('bar');
- `,
- },
- ],
- invalid: [
- {
- code: `/globalsticky/gy;`,
- errors: [
- {
- message: JSON.stringify({
- message: `Remove the 'g' flag from this regex as it is shadowed by the 'y' flag.`,
- secondaryLocations: [],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 17,
- },
- ],
- },
- {
- code: `RegExp('globalsticky', 'gy');`,
- errors: 1,
- },
- {
- code: `new RegExp('globalsticky', 'gy');`,
- errors: 1,
- },
- {
- code: `while (/foo/g.exec(input)) {}`,
- errors: [
- {
- message: JSON.stringify({
- message: `Extract this regular expression to avoid infinite loop.`,
- secondaryLocations: [],
- }),
- line: 1,
- endLine: 1,
- column: 8,
- endColumn: 14,
- },
- ],
- },
- {
- code: `do {} while (/foo/g.exec(input));`,
- errors: 1,
- },
- {
- code: `while ((/foo/g.exec(input)) !== null) {}`,
- errors: 1,
- },
- {
- code: `while (RegExp('foo', 'g').exec(input)) {}`,
- errors: 1,
- },
- {
- code: `while (new RegExp('foo', 'g').exec(input)) {}`,
- errors: 1,
- },
- {
- code: `
- const re = /foo/g;
- re.test('foo');
- re.test('bar');
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `Remove the 'g' flag from this regex as it is used on different inputs.`,
- secondaryLocations: [
- { message: 'Usage 1', column: 8, line: 3, endColumn: 22, endLine: 3 },
- { message: 'Usage 2', column: 8, line: 4, endColumn: 22, endLine: 4 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 20,
- endColumn: 26,
- },
- ],
- },
- {
- code: `
- const re = RegExp('foo', 'g');
- re.test('foo');
- re.test('bar');
- `,
- errors: 1,
- },
- {
- code: `
- const re = new RegExp('foo', 'g');
- re.test('foo');
- re.test('bar');
- `,
- errors: 1,
- },
- {
- code: `
- const re = /foo/g;
- re.exec('foo');
- re.exec('bar');
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/strict-transport-security.test.ts b/eslint-bridge/tests/linting/eslint/rules/strict-transport-security.test.ts
deleted file mode 100644
index bb3d2390cef..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/strict-transport-security.test.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/strict-transport-security';
-import { RuleTester } from 'eslint';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Disabling Strict-Transport-Security policy is security-sensitive', rule, {
- valid: [
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet()
- );`,
- },
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet({
- hsts: true,
- })
- );`,
- },
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet.hsts({})
- );`,
- },
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet.hsts({
- maxAge: 31536000,
- })
- );`,
- },
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet.hsts({
- maxAge: 31536000,
- includeSubDomains: true,
- })
- );`,
- },
- {
- code: `
- const hsts = require('hsts');
- const express = require('express');
- const app = express();
- app.use(
- hsts({})
- );`,
- },
- {
- code: `
- const hsts = require('hsts');
- const express = require('express');
- const app = express();
- app.use(
- hsts({
- maxAge: 31536000,
- })
- );`,
- },
- {
- code: `
- const hsts = require('hsts');
- const express = require('express');
- const app = express();
- app.use(
- hsts({
- maxAge: 31536000,
- includeSubDomains: true,
- })
- );`,
- },
- {
- code: `
- const hsts = require('hsts');
- const express = require('express');
- const app = express();
- app.use(
- hsts({
- maxAge: unknown,
- includeSubDomains: true,
- })
- );`,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- whatever({
- maxAge: 31536000,
- includeSubDomains: true,
- })
- );`,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- unknown.whatever({
- maxAge: 31536000,
- includeSubDomains: true,
- })
- );`,
- },
- ],
- invalid: [
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet({
- hsts: false,
- })
- );`,
- errors: [
- {
- message: JSON.stringify({
- message: `Disabling Strict-Transport-Security policy is security-sensitive.`,
- secondaryLocations: [
- {
- column: 14,
- line: 7,
- endColumn: 25,
- endLine: 7,
- },
- ],
- }),
- line: 5,
- endLine: 9,
- column: 11,
- endColumn: 12,
- },
- ],
- },
- {
- code: `
- const helmet = require('helmet')
- const express = require('express');
- const app = express();
- app.use(
- helmet.hsts({
- maxAge: 3153600,
- includeSubDomains: false,
- })
- );`,
- errors: [
- {
- message: JSON.stringify({
- message: `Disabling Strict-Transport-Security policy is security-sensitive.`,
- secondaryLocations: [
- {
- column: 14,
- line: 7,
- endColumn: 29,
- endLine: 7,
- },
- ],
- }),
- line: 5,
- endLine: 10,
- column: 11,
- endColumn: 12,
- },
- {
- message: JSON.stringify({
- message: `Disabling Strict-Transport-Security policy is security-sensitive.`,
- secondaryLocations: [
- {
- column: 14,
- line: 8,
- endColumn: 38,
- endLine: 8,
- },
- ],
- }),
- line: 5,
- endLine: 10,
- column: 11,
- endColumn: 12,
- },
- ],
- },
- {
- code: `
- const hsts = require('hsts');
- const express = require('express');
- const app = express();
- app.use(
- hsts({
- maxAge: 3153600,
- includeSubDomains: false,
- })
- );`,
- errors: 2,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/strings-comparison.test.ts b/eslint-bridge/tests/linting/eslint/rules/strings-comparison.test.ts
deleted file mode 100644
index 98550d04a74..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/strings-comparison.test.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/strings-comparison';
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTesterJs.run('Comparison operators should not be used with strings [js]', rule, {
- valid: [
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 < str2; // not reported without type information`,
- },
- ],
- invalid: [],
-});
-
-const ruleTesterTs = new TypeScriptRuleTester();
-ruleTesterTs.run(`Comparison operators should not be used with strings [ts]`, rule, {
- valid: [
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 == str2;`,
- },
- {
- code: `
- let str = 'hello', num = 5;
- str < num;`,
- },
- {
- code: `
- let str = 'hello', num = 5;
- num < str;`,
- },
- {
- code: `
- let str = 'hello';
- str < 'h';`,
- },
- {
- code: `
- let str = 'hello';
- 'h' < str;`,
- },
- {
- code: `
- ['foo', 'bar', 'baz'].sort((a, b) => a < b);
- `,
- },
- {
- code: `
- sort((a: string, b: string) => a < b)
- `,
- },
- ],
- invalid: [
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 < str2;`,
- errors: [
- {
- message:
- '{"message":"Convert operands of this use of \\"<\\" to number type.","secondaryLocations":[{"column":8,"line":3,"endColumn":12,"endLine":3},{"column":15,"line":3,"endColumn":19,"endLine":3}]}',
- line: 3,
- column: 14,
- endLine: 3,
- endColumn: 15,
- },
- ],
- },
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 <= str2;`,
- errors: 1,
- },
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 > str2;`,
- errors: 1,
- },
- {
- code: `
- let str1 = 'hello', str2 = 'world';
- str1 >= str2;`,
- errors: 1,
- },
- {
- code: `
- (function () {})((a: string, b: string) => a < b)
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/super-invocation.test.ts b/eslint-bridge/tests/linting/eslint/rules/super-invocation.test.ts
deleted file mode 100644
index fea4a0b0c88..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/super-invocation.test.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/super-invocation';
-import { RuleTester } from 'eslint';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('"super()" should be invoked appropriately', rule, {
- valid: [
- {
- code: `
- var B1b = class extends A1 {
- constructor() {
- super(); // OK
- super.x = 1;
- }
- }
- `,
- },
- ],
- invalid: [
- {
- code: `class A extends B { constructor() {this.bar();}}`,
- errors: 2,
- },
- {
- code: `class A extends B { constructor(a) { while (a) super(); } }`,
- errors: 2,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/switch-without-default.test.ts b/eslint-bridge/tests/linting/eslint/rules/switch-without-default.test.ts
deleted file mode 100644
index 62488a2e6ae..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/switch-without-default.test.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/switch-without-default';
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const tests = {
- valid: [
- {
- code: `
- switch (param) {
- case 0:
- break;
- default:
- break;
- }`,
- },
- ],
- invalid: [
- {
- code: `
- switch (param) {
- case 0:
- break;
- }`,
- errors: [
- {
- message: `Add a "default" clause to this "switch" statement.`,
- line: 2,
- endLine: 2,
- column: 9,
- endColumn: 15,
- },
- ],
- },
- ],
-};
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-ruleTesterJs.run('"switch" statements should have "default" clauses [js]', rule, tests);
-ruleTesterTs.run('"switch" statements should have "default" clauses [ts]', rule, tests);
diff --git a/eslint-bridge/tests/linting/eslint/rules/todo-tag.test.ts b/eslint-bridge/tests/linting/eslint/rules/todo-tag.test.ts
deleted file mode 100644
index aaf4fd5636a..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/todo-tag.test.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/todo-tag';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Track uses of TODO tags', rule, {
- valid: [
- {
- code: `// Just a regular comment`,
- },
- {
- code: `
- // This is not aTODO comment
-
- // notatodo comment
-
- // a todolist
-
- // método
- `,
- },
- {
- code: '// todos',
- },
- {
- code: '// todos ',
- },
- ],
- invalid: [
- {
- code: `// TODO`,
- errors: [
- {
- message: 'Complete the task associated to this "TODO" comment.',
- line: 1,
- endLine: 1,
- column: 4,
- endColumn: 8,
- },
- ],
- },
-
- {
- code: `/*TODO Multiline comment
- TODO: another todo
- (this line is not highlighted)
- with three todo
- */`,
- errors: [
- {
- message: 'Complete the task associated to this "TODO" comment.',
- line: 1,
- endLine: 1,
- column: 3,
- endColumn: 7,
- },
- {
- message: 'Complete the task associated to this "TODO" comment.',
- line: 2,
- endLine: 2,
- column: 7,
- endColumn: 11,
- },
- {
- message: 'Complete the task associated to this "TODO" comment.',
- line: 4,
- endLine: 4,
- column: 18,
- endColumn: 22,
- },
- ],
- },
- {
- code: `// TODO TODO`,
- errors: 1,
- },
- {
- code: `
- // TODO just do it
-
- // Todo just do it
-
- //todo comment
-
- // This is a TODO just do it
-
- // todo: things to do
-
- // :TODO: things to do
-
- // valid end of line todo
-
- /*
- TODO Multiline comment
- */
-
- /*
- TODO Multiline comment
-
- with two todo
- */
-
- // valid end of file TODO
- `,
- errors: 11,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/too-many-break-or-continue-in-loop.test.ts b/eslint-bridge/tests/linting/eslint/rules/too-many-break-or-continue-in-loop.test.ts
deleted file mode 100644
index d6f5ae649f8..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/too-many-break-or-continue-in-loop.test.ts
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/too-many-break-or-continue-in-loop';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-const testCases = {
- valid: [
- {
- code: `
- for (i = 0; i < 10; i++) {
- if (i % 3 == 0) {
- break;
- }
- }
- `,
- },
- {
- code: `
- for (i = 0; i < 10; i++) {
- switch (i) {
- case 0:
- break;
- default:
- break;
- }
- }
- `,
- },
- {
- code: `
- for (i = 0; i < 10; i++) {
- label1: if (i % 3 == 0) {
- break label1;
- }
- label2: if (i % 3 == 0) {
- break label2;
- }
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- for (i = 0; i < 10; i++) {
- if (i % 3 == 0) {
- break;
- }
- if (i % 3 == 0) {
- continue;
- }
- }
- `,
- errors: [
- {
- line: 2,
- endLine: 2,
- column: 13,
- endColumn: 16,
- message: JSON.stringify({
- message:
- 'Reduce the total number of "break" and "continue" statements in this loop to use one at most.',
- secondaryLocations: [
- {
- message: '"break" statement.',
- column: 16,
- line: 4,
- endColumn: 22,
- endLine: 4,
- },
- {
- message: '"continue" statement.',
- column: 16,
- line: 7,
- endColumn: 25,
- endLine: 7,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- label: for (i = 0; i < 10; i++) {
- for (j = 0; j < 10; j++) {
- break label;
- }
- if (i % 3 == 0) {
- break;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- label: for (i = 0; i < 10; i++) {
- for (j = 0; j < 10; j++) {
- continue label;
- }
- if (i % 3 == 0) {
- break;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- label: for (i = 0; i < 10; i++) {
- switch (i) {
- case 0:
- break label;
- default:
- break label;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- for (i = 0; i < 10; i++) {
- (function() {
- for (i = 0; i < 10; i++) {
- if (i % 3 == 0) {
- break;
- }
- if (i % 3 == 0) {
- break;
- }
- }
- })();
- if (i % 3 == 0) {
- break;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- for (i = 0; i < 10; i++) {
- (function*() {
- for (i = 0; i < 10; i++) {
- if (i % 3 == 0) {
- break;
- }
- if (i % 3 == 0) {
- break;
- }
- }
- })();
- if (i % 3 == 0) {
- break;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- for (i = 0; i < 10; i++) {
- if (i % 3 == 1) {
- break;
- }
- if (i % 3 == 2) {
- continue;
- }
- if (i % 3 == 0) {
- continue;
- }
- }
- `,
- errors: 1,
- },
- {
- code: `
- for (var property in obj) {
- if (foo()) continue;
- if (bar) continue;
- }
- `,
- errors: 1,
- },
- {
- code: `
- for (const elem of array) {
- if (foo()) continue;
- if (bar) continue;
- }
- `,
- errors: 1,
- },
- ],
-};
-ruleTesterJs.run(
- 'Loops should not contain more than a single "break" or "continue" statement JS',
- rule,
- testCases,
-);
-ruleTesterTs.run(
- 'Loops should not contain more than a single "break" or "continue" statement TS',
- rule,
- testCases,
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/unicode-aware-regex.test.ts b/eslint-bridge/tests/linting/eslint/rules/unicode-aware-regex.test.ts
deleted file mode 100644
index 7205d13583a..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/unicode-aware-regex.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/unicode-aware-regex';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run(`Regular expressions using Unicode constructs with the 'u' flag`, rule, {
- valid: [
- {
- code: `/\\u{1234}/u`,
- },
- {
- code: `/\\u{12346}/u`,
- },
- {
- code: `/\\p{Alpha}/u`,
- },
- {
- code: `/\\p{Script=Latin}/u`,
- },
- {
- code: `/\\P{Alpha}/u`,
- },
- {
- code: `/[\\p{Alpha}]/u`,
- },
- {
- code: `/\\p/`,
- },
- {
- code: `/\\p{/`,
- },
- {
- code: `/\\p{a/`,
- },
- {
- code: `/\\p{a=/`,
- },
- {
- code: `/\\p{a=b/`,
- },
- {
- code: `/a+/u`,
- },
- {
- code: `/\\u{12}/`,
- },
- {
- code: `/\\u{12,34}/`,
- },
- ],
- invalid: [
- {
- code: `/\\u{1234}/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Enable the 'u' flag for this regex using Unicode constructs.`,
- secondaryLocations: [
- { message: `Unicode character`, column: 1, line: 1, endColumn: 9, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 11,
- },
- ],
- },
- {
- code: `/\\u{12346}/`,
- errors: 1,
- },
- {
- code: `/\\p{Alpha}/`,
- errors: [
- {
- message: JSON.stringify({
- message: `Enable the 'u' flag for this regex using Unicode constructs.`,
- secondaryLocations: [
- { message: `Unicode property`, column: 1, line: 1, endColumn: 11, endLine: 1 },
- ],
- }),
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 12,
- },
- ],
- },
- {
- code: `/\\P{Alpha}/`,
- errors: 1,
- },
- {
- code: `/\\P{Script=Latin}/`,
- errors: 1,
- },
- {
- code: `/[\\p{Alpha}]/`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/unused-import.test.ts b/eslint-bridge/tests/linting/eslint/rules/unused-import.test.ts
deleted file mode 100644
index f4d2eba4188..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/unused-import.test.ts
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/unused-import';
-import path from 'path';
-import { BabelRuleTester } from '../../../tools';
-
-const babelRuleTester = BabelRuleTester();
-
-babelRuleTester.run('Unnecessary imports should be removed', rule, {
- valid: [
- {
- code: `
- import a from 'b';
- console.log(a);
- `,
- },
- {
- code: `
- import { a } from 'b';
- console.log(a);
- `,
- },
- {
- code: `
- import { a, b } from 'c';
- console.log(a);
- console.log(b);
- `,
- },
- {
- code: `
- import { a as b } from 'c';
- console.log(b);
- `,
- },
- {
- code: `import React from 'react';`,
- },
- {
- code: `
- import { a } from 'b';
-
- `,
- },
- {
- code: `
- import type { a } from 'b';
- function f(param: a) {}
- `,
- },
- {
- code: `
- /** @jsx jsx */
- import { jsx } from '@emotion/core'`,
- },
- {
- code: `
- /** @jsx jsx */
- import { jsx } from 'any'`,
- },
- ],
- invalid: [
- {
- code: `import a from 'b';`,
- errors: [
- {
- message: `Remove this unused import of 'a'.`,
- line: 1,
- endLine: 1,
- column: 8,
- endColumn: 9,
- suggestions: [
- {
- desc: `Remove this import statement`,
- output: ``,
- },
- ],
- },
- ],
- },
- {
- code: `import a, {b} from 'b'; console.log(b)`,
- errors: [
- {
- suggestions: [
- {
- desc: `Remove this variable import`,
- output: `import {b} from 'b'; console.log(b)`,
- },
- ],
- },
- ],
- },
- {
- code: `import a, {b} from 'b'; console.log(a)`,
- errors: [errorWithSuggestion(`import a from 'b'; console.log(a)`)],
- },
- {
- code: `import a, * as c from 'b'; console.log(a)`,
- errors: [errorWithSuggestion(`import a from 'b'; console.log(a)`)],
- },
- {
- code: `import { a } from 'b';`,
- errors: 1,
- },
- {
- code: `import { a, b, c } from 'c';`,
- errors: [
- errorWithSuggestion(`import { b, c } from 'c';`),
- errorWithSuggestion(`import { a, c } from 'c';`),
- errorWithSuggestion(`import { a, b } from 'c';`),
- ],
- },
- {
- code: `
- import { a, b } from 'c';
- console.log(b);
- `,
- errors: 1,
- },
- {
- code: `import * as a from 'b';`,
- errors: 1,
- },
- {
- code: `import { a as b, c } from 'c'; console.log(c);`,
- errors: [errorWithSuggestion(`import { c } from 'c'; console.log(c);`)],
- },
- {
- code: `import typeof a from 'b';`,
- errors: [errorWithSuggestion(``)],
- },
- {
- code: `import type { a, b } from 'b'; console.log(b);`,
- errors: [errorWithSuggestion(`import type { b } from 'b'; console.log(b);`)],
- },
- {
- code: `
-// comment
-import Foo from "foo";
-import bar from "bar";
-
-bar();`,
- errors: [
- errorWithSuggestion(`
-// comment
-import bar from "bar";
-
-bar();`),
- ],
- },
- {
- code: `import React, { Component } from 'react';`,
- errors: 1,
- },
- {
- code: `import { jsx } from '@emotion/core'`,
- errors: 1,
- },
- {
- code: `
- import { h } from 'some/lib'; // no 'h' jsxFactory
- export class Component {
- render() {
- return Hello, world!
- }
- }
- `,
- errors: 1,
- },
- ],
-});
-
-const ruleTesterTS = new RuleTester({
- parserOptions: { ecmaVersion: 2018, sourceType: 'module' },
- parser: require.resolve('@typescript-eslint/parser'),
-});
-
-ruleTesterTS.run('Unnecessary imports should be removed', rule, {
- valid: [
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo.Bar;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo.Bar.Baz;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Bar;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo | Bar;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Foo & Bar;
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- interface I extends Foo {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- interface I extends Foo.Bar {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- interface I extends Foo {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- class C implements Foo {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- class C implements Foo.Bar {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- class C implements Foo {}
- `,
- },
- {
- code: `
- import * as Foo from 'foobar';
- class C extends Foo {}
- `,
- },
- ],
- invalid: [
- {
- code: `import * as Foo from 'foobar';`,
- errors: 1,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Bar.Foo;
- `,
- errors: 1,
- },
- {
- code: `
- import * as Foo from 'foobar';
- let k: Baz.Bar.Foo;
- `,
- errors: 1,
- },
- {
- code: `
- import * as Foo from 'foobar';
- interface I extends Bar.Foo {};
- `,
- errors: 1,
- },
- {
- code: `
- import * as Foo from 'foobar';
- class C implements Bar.Foo {};
- `,
- errors: 1,
- },
- ],
-});
-
-const ruleTesterJsxFactory = new RuleTester({
- parserOptions: {
- ecmaVersion: 2018,
- sourceType: 'module',
- ecmaFeatures: { jsx: true },
- project: path.resolve(`${__dirname}/fixtures/unused-import/tsconfig.json`),
- },
- parser: require.resolve('@typescript-eslint/parser'),
-});
-
-const filename = path.resolve(`${__dirname}/fixtures/unused-import/file.tsx`);
-
-ruleTesterJsxFactory.run('Unused imports denoting jsx factory should be ignored', rule, {
- valid: [
- {
- filename,
- code: `
- import { h } from 'some/lib';
- export class Component {
- render() {
- return Hello, world!
- }
- }
- `,
- },
- {
- filename,
- code: `
- import { h } from 'some/lib';
- /* does something */
- `,
- },
- {
- filename,
- code: `
- import { Fragment } from 'some/lib';
- /* does something */
- `,
- },
- ],
- invalid: [
- {
- filename,
- code: `
- import { g } from 'some/lib';
- export class Component {
- render() {
- return Hello, world!
- }
- }
- `,
- errors: 1,
- },
- {
- filename,
- code: `
- import { g, h } from 'some/lib';
- export class Component {
- render() {
- return Hello, world!
- }
- }
- `,
- errors: [{ message: `Remove this unused import of 'g'.` }],
- },
- ],
-});
-
-const ruleTesterVue = new RuleTester({
- parserOptions: { ecmaVersion: 2018, sourceType: 'module' },
- parser: require.resolve('vue-eslint-parser'),
-});
-
-ruleTesterVue.run('Unnecessary imports should be removed', rule, {
- valid: [
- {
- code: `
-
-
-
-
- `,
- },
- {
- code: `
-
-
-
-
- `,
- },
- {
- code: `
-
-
-
-
- `,
- },
- {
- code: `
-
-
-
-
- `,
- },
- {
- code: `
-
-
-
-
- `,
- },
- ],
- invalid: [
- {
- code: `
-
-
-
-
- `,
- errors: 1,
- },
- ],
-});
-
-function errorWithSuggestion(output: string) {
- return {
- suggestions: [
- {
- output,
- },
- ],
- };
-}
diff --git a/eslint-bridge/tests/linting/eslint/rules/unused-named-groups.test.ts b/eslint-bridge/tests/linting/eslint/rules/unused-named-groups.test.ts
deleted file mode 100644
index a6fd197ff0c..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/unused-named-groups.test.ts
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/unused-named-groups';
-import { RuleTester } from 'eslint';
-import { JavaScriptRuleTester } from '../../../tools';
-
-const typeAwareRuleTester = new JavaScriptRuleTester();
-typeAwareRuleTester.run('Regular expressions named groups should be used', rule, {
- valid: [
- {
- code: `
- const pattern = /(?\\w)/;
- const matched = 'str'.matchAll(pattern);
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groups.foo;
- matched.groups.bar;
- matched.groups.baz;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- const matched = pattern.exec('str');
- if (matched) {
- matched.indices.groups.foo;
- }
- `,
- },
- {
- code: `
- const pattern = 12345;
- const matched = 'str'.matchAll(pattern);
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const matched = 'str'.matchAll(unknownPattern);
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const matched = 'str'.matchAll(/(?\\w)/);
- if (matched) {
- matched.groups!.foo;
- }
- `,
- },
- {
- code: `
- function foo(unknownPattern) {
- const matched = 'str'.matchAll(unknownPattern);
- if (matched) {
- matched.groups.foo;
- }
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- const result = 'str'.replace(pattern, '$');
- `,
- },
- {
- code: `
- const result = 'str'.replace(unknownPattern, '$');
- `,
- },
- {
- code: `/(?\\w)/ // unused 'foo': ignored because pattern never matched`,
- },
- {
- code: `RegExp('(?\\w)') // unused 'foo': ignored because pattern never matched`,
- },
- {
- code: `new RegExp('(?\\w)') // unused 'foo': ignored because pattern never matched`,
- },
- {
- code: `
- const pattern = /(?\\w)/; // unused 'foo': ignored because pattern never matched
- const matched = 'str'.matchAll(/* missing pattern */);
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/; // unused 'foo': ignored because pattern never
- const matched = match(pattern); // not 'String.prototype.match' method call
- if (matched) {
- matched.groups.foo;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/; // unused 'foo': ignored because pattern never matched
- const found = pattern.test('str'); // using 'RegExp.prototype.test'
- if (found) {
- /* ... */
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/; // unused 'foo': ignored because pattern never matched
- const result = 'str'.replace(pattern, '$ $');
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/; // unused 'foo': ignored because undeclared pattern
- undeclaredMatch = 'str'.match(pattern);
- if (matched) {
- undeclaredMatch[1];
- undeclaredMatch.groups.foo;
- }
- `,
- },
- {
- code: `
- let pattern;
- pattern = pattern;
- const matched = 'str'.matchAll(pattern);
- `,
- },
- {
- code: `
- let pattern1, pattern2, pattern3;
- pattern1 = pattern3;
- pattern2 = pattern1;
- pattern3 = pattern2;
- const matched = 'str'.matchAll(pattern3);
- `,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- const { foo, bar: b } = matched.groups;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- ({ foo, bar } = matched.groups);
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- const pattern = /(?\\w)/;
- const matched = 'str'.matchAll(pattern);
- if (matched) {
- matched[1]; // Noncompliant: 'foo' referenced by index
- matched[2]; // ignored as it doesn't exist
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- // ^^^^^^^^^^^
- const matched = 'str'.match(pattern);
- if (matched) {
- matched[1]; // Noncompliant: 'foo' referenced by index
- // ^
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `Directly use 'foo' instead of its group number.`,
- secondaryLocations: [
- { message: `Group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 6,
- endLine: 6,
- column: 19,
- endColumn: 20,
- },
- ],
- },
- {
- code: `
- const FOO_IDX = 1;
- const pattern = /(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- matched[FOO_IDX]; // Noncompliant: 'foo' referenced by index
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(abc)(?\\w)/;
- const matched = 'str'.match(pattern);
- if (matched) {
- matched[1]; // unnamed capturing group
- matched[2]; // Noncompliant: 'foo' referenced by index
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/; // Noncompliant: unused 'foo'
- // ^^^^^^^^^^^
- // ^^^^^^^^^^^^^^^^^^^^^^^^
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groups.bar;
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: 'Use the named groups of this regex or remove the names.',
- secondaryLocations: [
- { message: `Named group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 25,
- endColumn: 47,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = 'str'.match(pattern);
- if (matched) {
- matched[UNKNOWN_IDX];
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = 'str'.match(pattern);
- if (matched) {
- matched['non-number index'];
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- // ^^^^^^^^^^^
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groups.foo;
- matched.groups.bar; // Noncompliant: 'bar' doesn't exist
- // ^^^
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `There is no group named 'bar' in the regular expression.`,
- secondaryLocations: [
- { message: `Named group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 7,
- endLine: 7,
- column: 26,
- endColumn: 29,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)(?\\w)/; // Noncompliant: unused 'foo', 'baz'
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groups.bar;
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = pattern.exec('str');
- if (matched) {
- matched[groups].foo;
- matched.groups[foo];
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = 'str'.match(pattern);
- if (matched) {
- matched.groupz.foo; // Intentional typo 'groupz'
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = pattern.exec('str');
- if (matched) {
- matched.indices.groupz.foo; // Intentional typo 'groupz'
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- const matched = pattern.exec('str');
- if (matched) {
- matched[1]; // Noncompliant: 'foo' referenced by index
- matched[2];
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- // ^^^^^^^^^^^
- const matched = pattern.exec('str');
- if (matched) {
- matched.indices.groups.foo;
- matched.indices.groups.bar; // Noncompliant: 'bar' doesn't exist
- // ^^^
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `There is no group named 'bar' in the regular expression.`,
- secondaryLocations: [
- { message: `Named group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 7,
- endLine: 7,
- column: 34,
- endColumn: 37,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)/; // Noncompliant: unused 'foo'
- const matched = pattern.exec('str');
- if (matched) {
- matched[indices].groups.foo;
- matched.indices[groups].foo;
- matched.indices.groups[foo];
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/;
- const result = 'str'.replace(pattern, '$2 $3'); // Noncompliant: 'foo' referenced by index
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)/;
- // ^^^^^^^^^^
- const result = 'str'.replace(pattern, '$1'); // Noncompliant: 'foo' referenced by index
- // ^^^^
- `,
- errors: [
- {
- message: JSON.stringify({
- message: 'Directly use the group names instead of their numbers.',
- secondaryLocations: [
- { message: `Group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 4,
- endLine: 4,
- column: 47,
- endColumn: 51,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)/;
- let declaredMatch;
- declaredMatch = 'str'.match(pattern);
- if (matched) {
- declaredMatch[1]; // Noncompliant: 'foo' referenced by index
- }
- `,
- errors: 1,
- },
- {
- code: `
- const pattern = '(?\\w)(?\\w)(?\\w)'; // Noncompliant: unused 'baz'
- const matched = 'str'.match(pattern);
- if (matched) {
- matched[1]; // Noncompliant: 'foo' referenced by index
- matched.indices.groups.bar;
- matched.indices.groups.qux; // Noncompliant: 'qux' doesn't exist
- }
- `,
- errors: 3,
- },
- {
- code: `
- /(?\\w)\\1(?\\w)\\k(?\\w)/; // Noncompliant: 'foo' referenced by index
- // ^^^
- // ^^^^^^^^^^^
- `,
- errors: [
- {
- message: JSON.stringify({
- message: `Directly use 'foo' instead of its group number.`,
- secondaryLocations: [
- { message: `Group 'foo'`, column: 9, line: 2, endColumn: 19, endLine: 2 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 20,
- endColumn: 22,
- },
- ],
- },
- {
- code: `'str'.search('(?\\w)\\\\1(?\\w)\\\\k(?\\w)'); // Noncompliant: 'foo' referenced by index`,
- errors: 1,
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/; // Noncompliant: unused 'foo'
- // ^^^^^^^^^^^
- // ^^^^^^^^^^^^^^^^^^^^^^^^
- const matched = 'str'.match(pattern);
- if (matched) {
- const { bar } = matched.groups;
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: 'Use the named groups of this regex or remove the names.',
- secondaryLocations: [
- { message: `Named group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 25,
- endColumn: 47,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/; // Noncompliant: unused 'foo'
- // ^^^^^^^^^^^
- // ^^^^^^^^^^^^^^^^^^^^^^^^
- const matched = 'str'.match(pattern);
- if (matched) {
- ({ bar } = matched.groups);
- }
- `,
- errors: [
- {
- message: JSON.stringify({
- message: 'Use the named groups of this regex or remove the names.',
- secondaryLocations: [
- { message: `Named group 'foo'`, column: 25, line: 2, endColumn: 35, endLine: 2 },
- ],
- }),
- line: 2,
- endLine: 2,
- column: 25,
- endColumn: 47,
- },
- ],
- },
- {
- code: `
- const pattern = /(?\\w)(?\\w)/; // Noncompliant: unused 'foo', 'bar'
- const matched = 'str'.match(pattern);
- if (matched) {
- ({ [abc]: def, ...hij} = matched.groups);
- }
- `,
- errors: 2,
- },
- ],
-});
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('"unused-named-groups" reports nothing without types', rule, {
- valid: [
- {
- code: `
- const pattern = /(?\\w)/
- const matched = 'str'.matchAll(pattern);
- if (matched) {
- matched[1];
- matched.groups.foo;
- matched.groups.bar;
- }
- `,
- },
- {
- code: `
- const pattern = /(?\\w)/
- const matched = pattern.exec('str');
- if (matched) {
- matched[1];
- matched.indices.groups.foo;
- matched.indices.groups.bar;
- }
- `,
- },
- ],
- invalid: [],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/unverified-certificate.test.ts b/eslint-bridge/tests/linting/eslint/rules/unverified-certificate.test.ts
deleted file mode 100644
index f6cded0bf2d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/unverified-certificate.test.ts
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/unverified-certificate';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-
-const testCasesHttps = {
- valid: [
- {
- code: `
- const https = require('https');
-
- var options = {
- hostname: 'self-signed.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: true
- };
-
- var req = https.request(options, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- }); // Compliant
- `,
- },
- {
- code: `
- const https = require('https');
-
- var options = {
- hostname: 'self-signed.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1
- };
-
- var req = https.request(options, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- }); // Compliant
- `,
- },
- {
- code: `
- const https = require('https');
- var req = https.request();
- `,
- },
- {
- code: `
- const https = require('https');
-
- var options = getOptions();
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'self-signed.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: false // Noncompliant
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant
- `,
- errors: [
- {
- line: 14,
- endLine: 14,
- column: 15,
- endColumn: 28,
- message: JSON.stringify({
- message: 'Enable server certificate validation on this SSL/TLS connection.',
- secondaryLocations: [
- {
- column: 18,
- line: 5,
- endColumn: 5,
- endLine: 12,
- },
- {
- message: 'Set "rejectUnauthorized" to "true".',
- column: 6,
- line: 11,
- endColumn: 31,
- endLine: 11,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- const https = require('node:https');
- const constants = require('node:constants');
-
- var options = {
- hostname: 'self-signed.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: false // Noncompliant
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant
- `,
- errors: 1,
- },
- ],
-};
-const testCasesRequest = {
- valid: [
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://self-signed.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- rejectUnauthorized: true
- }); // Compliant
- `,
- },
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://self-signed.badssl.com',
- secureProtocol: 'TLSv1_2_method'
- //rejectUnauthorized: true // by default is set to true
- }); // Compliant
- `,
- },
- ],
- invalid: [
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://self-signed.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- rejectUnauthorized: false // Noncompliant
- }); // Noncompliant
- `,
- errors: 1,
- },
- ],
-};
-const testCasesTls = {
- valid: [
- {
- code: `
- var options = {
- rejectUnauthorized: true
- };
-
- var socket = tls.connect(443, "self-signed.badssl.com", options, () => {}); // Compliant
- `,
- },
- ],
- invalid: [
- {
- code: `
- const tls = require('tls');
-
- var options = {
- rejectUnauthorized: false // Noncompliant
- };
- var socket = tls.connect(443, "self-signed.badssl.com", options, () => {}); // Noncompliant
- `,
- errors: 1,
- },
- {
- code: `
- const tls = require('node:tls');
-
- var options = {
- rejectUnauthorized: false // Noncompliant
- };
- var socket = tls.connect(443, "self-signed.badssl.com", options, () => {}); // Noncompliant
- `,
- errors: 1,
- },
- ],
-};
-ruleTesterJs.run(
- '[https] Server certificates should be verified during SSL⁄TLS connections',
- rule,
- testCasesHttps,
-);
-ruleTesterJs.run(
- '[request] Server certificates should be verified during SSL⁄TLS connections',
- rule,
- testCasesRequest,
-);
-ruleTesterJs.run(
- '[tls] Server certificates should be verified during SSL⁄TLS connections',
- rule,
- testCasesTls,
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/unverified-hostname.test.ts b/eslint-bridge/tests/linting/eslint/rules/unverified-hostname.test.ts
deleted file mode 100644
index 23919f7b247..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/unverified-hostname.test.ts
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/unverified-hostname';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-
-const testCasesHttps = {
- valid: [
- {
- code: `
- const https = require('https');
- const constants = require('constants');
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: true,
- checkServerIdentity: (servername, peer) => {
- console.log("test2: checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Compliant: rejectUnauthorized to true and some checks inside checkServerIdentity
- `,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- checkServerIdentity: (servername, peer) => {
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Compliant: rejectUnauthorized is true by default and some checks inside checkServerIdentity
- `,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Compliant: rejectUnauthorized is true by default and default checkServerIdentity
- `,
- },
- {
- code: `
- const https = require('https');
- var req = https.request();
- `,
- },
- {
- code: `
- const https = require('https');
- var options = {hostname: 'wrong.host.badssl.com',}
- if (x) {
- options = {port: 443,};
- }
- var req = https.request(options, (res) => {});
- `,
- },
- {
- code: `
- const https = require('https');
- rejectUnauthorized = false;
- if (x) {
- rejectUnauthorized = true;
- }
- var options = {rejectUnauthorized};
- var req = https.request(options, (res) => {});
- `,
- },
- {
- code: `
- const https = require('https');
- https.unknown();
- `,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- checkServerIdentity: (a, b) => checkIdentity(a, b)
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- });
- `,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- checkServerIdentity: function() {
- return (function() {
- return new Error();
- })();
- }
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: false,
- checkServerIdentity: (servername, peer) => {
- console.log("test1: checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant: rejectUnauthorized is false
- `,
- errors: [
- {
- line: 20,
- endLine: 20,
- column: 17,
- endColumn: 30,
- message: JSON.stringify({
- message: 'Enable server hostname verification on this SSL/TLS connection.',
- secondaryLocations: [
- {
- column: 20,
- line: 5,
- endColumn: 7,
- endLine: 18,
- },
- {
- message: 'Set "rejectUnauthorized" to "true".',
- column: 8,
- line: 11,
- endColumn: 33,
- endLine: 11,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- const https = require('node:https');
- const constants = require('node:constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- rejectUnauthorized: false,
- checkServerIdentity: (servername, peer) => {
- console.log("test1: checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant: rejectUnauthorized is false
- `,
- errors: 1,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- checkServerIdentity: function() {} // Noncompliant: there is no test cases
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant
- `,
- errors: [
- {
- line: 14,
- endLine: 14,
- column: 17,
- endColumn: 30,
- message: JSON.stringify({
- message: 'Enable server hostname verification on this SSL/TLS connection.',
- secondaryLocations: [
- {
- column: 20,
- line: 5,
- endColumn: 7,
- endLine: 12,
- },
- {
- column: 8,
- line: 11,
- endColumn: 42,
- endLine: 11,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'wrong.host.badssl.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1,
- checkServerIdentity: function() {
- function doSomething() {
- return new Error();
- }
- } // Noncompliant: there is no test cases
- };
-
- var req = https.request(options, (res) => {
- res.on('data', (d) => {});
- }); // Noncompliant
- `,
- errors: 1,
- },
- ],
-};
-
-const testCasesRequest = {
- valid: [
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- rejectUnauthorized: true,
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- });
- `,
- },
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- });
- `,
- },
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method'
- });
- `,
- },
- {
- code: `
- const request = require('request');
- request.unknown();
- `,
- },
- ],
- invalid: [
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- rejectUnauthorized: false, // Noncompliant
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- }
- }); // Noncompliant: rejectUnauthorized to true
- `,
- errors: [
- {
- line: 4,
- endLine: 4,
- column: 20,
- endColumn: 31,
- message: JSON.stringify({
- message: 'Enable server hostname verification on this SSL/TLS connection.',
- secondaryLocations: [
- {
- message: 'Set "rejectUnauthorized" to "true".',
- column: 8,
- line: 7,
- endColumn: 33,
- endLine: 7,
- },
- ],
- }),
- },
- ],
- },
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- checkServerIdentity: function() {} // Noncompliant: there is no test cases
- });
- `,
- errors: 1,
- },
- {
- code: `
- const request = require('request');
-
- var socket = request.get({
- url: 'https://wrong.host.badssl.com',
- secureProtocol: 'TLSv1_2_method',
- checkServerIdentity: function() {
- return true;
- } // Noncompliant: there is no test cases
- });
- `,
- errors: 1,
- },
- ],
-};
-
-const testCasesTls = {
- valid: [
- {
- code: `
- const tls = require('tls');
-
- var options = {
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error'); // Compliant: there is at least one check on the servername argument and rejectUnauthorized: true
- }
- },
- rejectUnauthorized: true
- };
-
- var socket = tls.connect(443, "www.google.fr", options, () => {
- process.stdin.pipe(socket);
- process.stdin.resume();
- });
- `,
- },
- {
- code: `
- const tls = require('tls');
-
- var options = {
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error'); // Compliant: there is at least one check on the servername argument that throw Error and rejectUnauthorized: true
- }
- }
- };
-
- var socket = tls.connect(443, "www.google.fr", options, () => {
- process.stdin.pipe(socket);
- process.stdin.resume();
- });
- `,
- },
- {
- code: `
- const tls = require('tls');
- tls.unknown();
- `,
- },
- ],
- invalid: [
- {
- code: `
- const tls = require('tls');
-
- var options = {
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- },
- rejectUnauthorized: false // Noncompliant
- };
-
- var socket = tls.connect(443, "www.google.fr", options, () => {
- process.stdin.pipe(socket);
- process.stdin.resume();
- });
- `,
- errors: 1,
- },
- {
- code: `
- const tls = require('node:tls');
-
- var options = {
- checkServerIdentity: (servername, peer) => {
- console.log("checkServerIdentity");
- if (servername !== "www.google.com") {
- return new Error ('Error');
- }
- },
- rejectUnauthorized: false // Noncompliant
- };
-
- var socket = tls.connect(443, "www.google.fr", options, () => {
- process.stdin.pipe(socket);
- process.stdin.resume();
- });
- `,
- errors: 1,
- },
- {
- code: `
- const tls = require('tls');
-
- var options = {
- checkServerIdentity: function() {} // Noncompliant: there is no test cases
- };
-
- var socket = tls.connect(443, "www.google.fr", options, () => {
- process.stdin.pipe(socket);
- process.stdin.resume();
- });
- `,
- errors: 1,
- },
- ],
-};
-
-ruleTesterJs.run(
- '[JS-https] Server hostnames should be verified during SSL/TLS connections',
- rule,
- testCasesHttps,
-);
-
-ruleTesterJs.run(
- '[JS-request] Server hostnames should be verified during SSL/TLS connections',
- rule,
- testCasesRequest,
-);
-
-ruleTesterJs.run(
- '[JS-tls] Server hostnames should be verified during SSL/TLS connections',
- rule,
- testCasesTls,
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/updated-const-var.test.ts b/eslint-bridge/tests/linting/eslint/rules/updated-const-var.test.ts
deleted file mode 100644
index b7a9e7b9f2c..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/updated-const-var.test.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/updated-const-var';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-ruleTester.run('Attempts should not be made to update "const" variables', rule, {
- valid: [],
- invalid: [
- {
- code: `
- const c = 1;
- c = 2;`,
- errors: [
- {
- message:
- '{"message":"Correct this attempt to modify \\"c\\" or use \\"let\\" in its declaration.","secondaryLocations":[{"message":"Const declaration","column":8,"line":2,"endColumn":20,"endLine":2}]}',
- line: 3,
- column: 9,
- endLine: 3,
- endColumn: 10,
- },
- ],
- },
- {
- code: `
- const c = 1;
- var x = c++;`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/updated-loop-counter.test.ts b/eslint-bridge/tests/linting/eslint/rules/updated-loop-counter.test.ts
deleted file mode 100644
index 02eb9c7a1c8..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/updated-loop-counter.test.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/updated-loop-counter';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Loop counter should not be updated inside loop', rule, {
- valid: [
- {
- code: `
- let fl = false;
-
- for (; i < m && !fl; i++) {
- fl = true; // Compliant
- m = 10; // Compliant
- }
- `,
- },
- ],
- invalid: [
- {
- code: `
- for (var i = 0, j = 2; i < 5; i++) {
- i = 5; // Noncompliant
- j = 5; // compliant, not in update section
- }
- `,
- errors: [
- {
- line: 3,
- column: 11,
- endColumn: 12,
- message: `{"message":"Remove this assignment of \\"i\\".","secondaryLocations":[{"message":"Counter variable update","column":38,"line":2,"endColumn":39,"endLine":2}]}`,
- },
- ],
- },
- {
- code: `
- for (var i; i < 5; i++) {
- i = 5; // Noncompliant
- }
- `,
- errors: [{ line: 3 }],
- },
- {
- code: `
- var i;
- i = 0;
- for (; i < 5; i++) {
- i = 5; // Noncompliant
- }
- `,
- errors: [{ line: 5 }],
- },
- {
- code: `
- var k, t, l, m;
- for (k = 0, t = 6, l = 2; k < 5; k++) {
- k = 5; // Noncompliant
- l = 5; // Compliant
- }
-
- for (m = 0; m < 5; m++) {
- m = 5; // Noncompliant
- }
- `,
- errors: [{ line: 4 }, { line: 9 }],
- },
- {
- code: `
- var x = 5;
-
- for (x += 2; x < 5; x++) {
- x = 5; // Noncompliant
- }
- `,
- errors: [
- {
- line: 5,
- message: `{"message":"Remove this assignment of \\"x\\".","secondaryLocations":[{"message":"Counter variable update","column":28,"line":4,"endColumn":29,"endLine":4}]}`,
- },
- ],
- },
- {
- code: `
- let i = 0, j = 0, k = 0;
- for (;; i++, --j) {
- i++; // Noncompliant
- j++; // Noncompliant
- }
-
- for (;; ++i, j--, k++) {
- i = 5; // Noncompliant
- j = 5; // Noncompliant
- k = 5; // Noncompliant
- }
-
- for (;; i+=2, j-=3, k*=5) {
- i++; // Noncompliant
- j++; // Noncompliant
- k++; // Noncompliant
- }
- `,
- errors: 8,
- },
- {
- code: `
- for (var x = foo(); ; x=next()) {
- x = next(); // Noncompliant
- }
- `,
- errors: [{ line: 3 }],
- },
- {
- code: `
- function foo_of_loop(obj) {
- for (var prop1 of obj) {
- prop1 = 1 // Noncompliant
- }
-
- for (let prop2 of obj) {
- prop2 = 1 // Noncompliant
- }
-
- let prop3;
- for (prop3 of obj) {
- prop3 = 1 // Noncompliant
- }
-
- }
- `,
- errors: 3,
- },
- {
- code: `
- function foo_in_loop(obj) {
- for (var value1 in obj) {
- value1 = 1 // Noncompliant
- }
-
- for (const value2 in obj) {
- value2 = 1 // Noncompliant
- }
-
- let value3;
- for (value3 in obj) {
- value3 = 1 // Noncompliant
- }
- }
- `,
- errors: 3,
- },
- {
- code: `
- function description_sample_code() {
- var names = [ "Jack", "Jim", "", "John" ];
- for (var i = 0; i < names.length; i++) {
- if (!names[i]) {
- i = names.length; // Noncompliant
- } else {
- console.log(names[i]);
- }
- }
-
- i = 42; // Compliant, out of loop
-
- for (var name of names) {
- if (!name) {
- break;
- } else {
- console.log(name);
- }
- }
-
- }
- `,
- errors: [{ line: 6 }],
- },
- {
- code: `
- function same_counter_in_nested_loop(obj1, obj2) {
- for (var i in obj1) {
- for (i of obj2) { // Noncompliant
- foo(i);
- }
- }
- }
- `,
- errors: [{ line: 4 }],
- },
- {
- code: `
- function assigned_several_times(obj) {
- for (var value in obj) {
- value = 1; // Noncompliant
- value = 1; // Noncompliant
- }
- }
-
- `,
- errors: 2,
- },
- {
- code: `
- function used_several_times(obj) {
- for (var i = 0; i < 10; i++) {
- for (var j = 0; j < 10; j++, i++) { // Noncompliant
- i = 10; // Noncompliant x2
- }
- }
- }
- `,
- errors: [
- {
- line: 4,
- column: 40,
- message: `{"message":"Remove this assignment of \\"i\\".","secondaryLocations":[{"message":"Counter variable update","column":32,"line":3,"endColumn":33,"endLine":3}]}`,
- },
- {
- line: 5,
- column: 13,
- message: `{"message":"Remove this assignment of \\"i\\".","secondaryLocations":[{"message":"Counter variable update","column":32,"line":3,"endColumn":33,"endLine":3}]}`,
- },
- {
- line: 5,
- column: 13,
- message: `{"message":"Remove this assignment of \\"i\\".","secondaryLocations":[{"message":"Counter variable update","column":39,"line":4,"endColumn":40,"endLine":4}]}`,
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/use-type-alias.test.ts b/eslint-bridge/tests/linting/eslint/rules/use-type-alias.test.ts
deleted file mode 100644
index f8c2c940828..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/use-type-alias.test.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/use-type-alias';
-
-const ruleTester = new RuleTester({
- parser: require.resolve('@typescript-eslint/parser'),
- parserOptions: { ecmaVersion: 2018 },
-});
-
-ruleTester.run('Type aliases should be used', rule, {
- valid: [
- {
- code: `type MyType = string | null | number;`,
- },
- {
- code: `
- type MyType = string | null | number;
- const another: MyType | undefined = "";`,
- },
- {
- code: `
- let x: number | string;
- let y: number | string;
- let z: number | string; // this fine because only 2 types in the union`,
- },
- {
- code: `
- interface A {
- name: string;
- a: number;
- }
-
- interface B {
- name: string;
- b: number;
- }
-
- interface C {
- name: string;
- b: number;
- }`,
- },
- {
- code: `
- // ok, ignore usage inside type alias
- type Alias = number | number[] | undefined;
- function one(x: number | number[] | undefined) {}
- function two(x: number | number[] | undefined) {}`,
- },
- {
- code: `
- let x: number | string | undefined;
- let y: number | string | undefined;
- let z: number | String | undefined; // this fine because case-sensitive`,
- },
- ],
- invalid: [
- {
- code: `
- function foo(x: string | null | number) {}
- const bar: string | null | number = null;
- function zoo(): string | null | number {}
- `,
- errors: [
- {
- message:
- '{"message":"Replace this union type with a type alias.","secondaryLocations":[{"message":"Following occurrence.","column":17,"line":3,"endColumn":39,"endLine":3},{"message":"Following occurrence.","column":22,"line":4,"endColumn":44,"endLine":4}]}',
- line: 2,
- endLine: 2,
- column: 23,
- endColumn: 45,
- },
- ],
- },
- {
- code: `
- function foo(x: string & null & number) {}
- const bar: string & null & number = null;
- function zoo(): string & null & number {}
- `,
- errors: [
- {
- message:
- '{"message":"Replace this intersection type with a type alias.","secondaryLocations":[{"message":"Following occurrence.","column":17,"line":3,"endColumn":39,"endLine":3},{"message":"Following occurrence.","column":22,"line":4,"endColumn":44,"endLine":4}]}',
- line: 2,
- endLine: 2,
- column: 23,
- endColumn: 45,
- },
- ],
- },
- {
- code: `
- let x: string | null | number;
- let y: number | string | null ;
- let z: null |number| string ;
- `,
- errors: [
- {
- message:
- '{"message":"Replace this union type with a type alias.","secondaryLocations":[{"message":"Following occurrence.","column":13,"line":3,"endColumn":35,"endLine":3},{"message":"Following occurrence.","column":15,"line":4,"endColumn":40,"endLine":4}]}',
- },
- ],
- },
- {
- code: `
- let x: string & null & number;
- let y: number & string & null ;
- let z: null &number& string ;
- `,
- errors: [
- {
- message:
- '{"message":"Replace this intersection type with a type alias.","secondaryLocations":[{"message":"Following occurrence.","column":13,"line":3,"endColumn":35,"endLine":3},{"message":"Following occurrence.","column":15,"line":4,"endColumn":40,"endLine":4}]}',
- },
- ],
- },
- {
- code: `
- let x: A | B | C;
- let y: A | B | C;
- let z: A | B | C;
- `,
- errors: [
- {
- message:
- '{"message":"Replace this union type with a type alias.","secondaryLocations":[{"message":"Following occurrence.","column":13,"line":3,"endColumn":22,"endLine":3},{"message":"Following occurrence.","column":13,"line":4,"endColumn":22,"endLine":4}]}',
- },
- ],
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/useless-string-operation.test.ts b/eslint-bridge/tests/linting/eslint/rules/useless-string-operation.test.ts
deleted file mode 100644
index f82ad0446df..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/useless-string-operation.test.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/useless-string-operation';
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTesterJs.run('Results of operations on strings should not be ignored [js]', rule, {
- valid: [
- {
- code: `
- let str = 'hello';
- str.toUpperCase(); // not raised without type information`,
- },
- ],
- invalid: [],
-});
-
-const ruleTesterTs = new TypeScriptRuleTester();
-ruleTesterTs.run(`Results of operations on strings should not be ignored [ts]`, rule, {
- valid: [
- {
- code: `let res = 'hello'.toUpperCase();`,
- },
- {
- code: `let res = 'hello'.substr(1, 2).toUpperCase();`,
- },
- {
- code: `
- let str = 'hello';
- let res = str.toUpperCase();
- `,
- },
- {
- code: `'hello'['whatever']();`,
- },
- ],
- invalid: [
- {
- code: `'hello'.toUpperCase();`,
- errors: [
- {
- message: `'hello' is an immutable object; you must either store or return the result of the operation.`,
- line: 1,
- column: 9,
- endLine: 1,
- endColumn: 20,
- },
- ],
- },
- {
- code: `
- let str = 'hello';
- str.toUpperCase();`,
- errors: [
- {
- message: `str is an immutable object; you must either store or return the result of the operation.`,
- line: 3,
- column: 13,
- endLine: 3,
- endColumn: 24,
- },
- ],
- },
- {
- code: `
- let str = 'hello';
- str.toLowerCase().toUpperCase().toLowerCase();`,
- errors: [
- {
- message: `String is an immutable object; you must either store or return the result of the operation.`,
- line: 3,
- column: 41,
- endLine: 3,
- endColumn: 52,
- },
- ],
- },
- {
- code: `'hello'.substr(1, 2).toUpperCase();`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/utils-express.test.ts b/eslint-bridge/tests/linting/eslint/rules/utils-express.test.ts
deleted file mode 100644
index 5240d686a11..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/utils-express.test.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Rule, RuleTester } from 'eslint';
-import * as estree from 'estree';
-import { Express, getObjectExpressionProperty } from 'linting/eslint/rules/helpers';
-
-const rule = Express.SensitiveMiddlewarePropertyRule(
- (_context: Rule.RuleContext, node: estree.CallExpression): estree.Property[] => {
- const sensitives: estree.Property[] = [];
- const { callee, arguments: args } = node;
- if (callee.type === 'Identifier' && callee.name === 'middleware' && args.length === 1) {
- const [options] = args;
- const maybeFoo = getObjectExpressionProperty(options, 'foo');
- if (maybeFoo) {
- sensitives.push(maybeFoo);
- }
- const maybeBar = getObjectExpressionProperty(options, 'bar');
- if (maybeBar) {
- sensitives.push(maybeBar);
- }
- }
- return sensitives;
- },
- `Make sure sensitive property is safe here.`,
-);
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run(
- 'Express.js rule template for middlewares configured with sensitive settings',
- rule,
- {
- valid: [
- {
- code: `
- const express = require('express');
- const app = express();`,
- },
- ],
- invalid: [
- {
- code: `
- module.exports.sensitiveFoo = function (app) {
- app.use(
- middleware({
- foo: whatever
- })
- );
- }`,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- middleware({
- foo: whatever
- })
- ); `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- middleware({
- bar: whatever
- })
- ); `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- middleware({
- foo: whatever,
- bar: whatever
- })
- );`,
- errors: 2,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(
- middleware({
- foo: whatever
- })
- );
- app.use(
- middleware({
- bar: whatever
- })
- );`,
- errors: 2,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- module.exports.sensitiveFoo = function() {
- app.use(
- middleware({
- foo: whatever
- })
- );
- }`,
- errors: 1,
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/values-not-convertible-to-numbers.test.ts b/eslint-bridge/tests/linting/eslint/rules/values-not-convertible-to-numbers.test.ts
deleted file mode 100644
index cb50f72b4b2..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/values-not-convertible-to-numbers.test.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const ruleTesterTs = new TypeScriptRuleTester();
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-
-import { rule } from 'linting/eslint/rules/values-not-convertible-to-numbers';
-
-ruleTesterTs.run(
- 'Values not convertible to numbers should not be used in numeric comparisons [TS]',
- rule,
- {
- valid: [
- {
- code: `42 > 41`,
- },
- {
- code: `
- const n1 = 42;
- const n2 = 0;
- n1 >= 0`,
- },
- {
- code: `
- const date = new Date();
- date > 42;
- `,
- },
- {
- code: `42 > NaN`, // FN,
- },
- {
- code: `"foo" > "hello"`,
- },
- {
- code: 'true > false',
- },
- {
- code: `
- const a = 42 === 42;
- const b = 'str';
- a < b;
- `,
- },
- {
- code: `42 > null`,
- },
- {
- code: `42 > unknown`,
- },
- {
- code: `
- const undef;
- undef > 42;`, // FN
- },
- {
- code: `"hello" <= new Object()`,
- },
- {
- code: `
- var undefinedVariable;
- var nan = undefinedVariable + 42;
- nan >= 42;`, // FN
- },
- {
- code: `
- let x = { };
- x.a >= 42;`, // FN
- },
- ],
- invalid: [
- {
- code: `new Object() > 0`,
- errors: [
- {
- message:
- 'Re-evaluate the data flow; this operand of a numeric comparison could be of type Object.',
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 13,
- },
- ],
- },
- {
- code: `
- const obj1 = new Object();
- const obj2 = new Object();
- obj1 < obj2;`,
- errors: 2,
- },
- {
- code: `42 > undefined`,
- errors: [
- {
- message:
- 'Re-evaluate the data flow; this operand of a numeric comparison could be of type undefined.',
- },
- ],
- },
- {
- code: `1 < function(){}`,
- errors: 1,
- },
- {
- code: `
- var array = [3,2];
- array > 42;`,
- errors: 1,
- },
- {
- code: `
- var obj = {};
- obj <= 42;`,
- errors: 1,
- },
- ],
- },
-);
-
-ruleTesterJs.run(
- 'Values not convertible to numbers should not be used in numeric comparisons [JS]',
- rule,
- {
- valid: [{ code: `new Object() > 0` }], // no type information
- invalid: [],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/variable-name.test.ts b/eslint-bridge/tests/linting/eslint/rules/variable-name.test.ts
deleted file mode 100644
index 8d9a78f181d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/variable-name.test.ts
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/variable-name';
-
-const ruleTester = new RuleTester({
- parser: require.resolve('@typescript-eslint/parser'),
- parserOptions: { ecmaVersion: 2018 },
-});
-
-const DEFAULT_FORMAT = '^[_$A-Za-z][$A-Za-z0-9]*$|^[_$A-Z][_$A-Z0-9]+$';
-const CUSTOM_FORMAT = '^[a-z][a-z0-9]+$';
-
-ruleTester.run(
- 'Local variable and function parameter names should comply with a naming convention',
- rule,
- {
- valid: [
- {
- code: `
- var foo;
- let lowerCamelCase;
- let _leadingUnderScore;
- let PascalCase;
- const UPPER_CASE = "UPPER_CASE";`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `let [ foo, [ bar, [ baz, [ qux = quux_quuz, ...corge ] ] ] ] = arr;`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `let { foo, foo_foo, bar: bar, bar_bar: bar, baz: { qux: { quux: Quux, quuz: { corge: Corge = grault_garply, ...waldo } } } } = obj;`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `declare var foo_bar: number // declare are ignored`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `
- try {} catch {}
- try {} catch (foo) {}
- try {} catch ([ foo ]) {}
- try {} catch ({ foo: Foo }) {}
- try {} finally {}`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `
- declare function f(foo_bar);
- function f(foo) {}
- function f(foo = 5) {}
- function f(...foo: number[]) {}
- function f([foo, bar]: number[]) {}
- function f({a: foo, b: bar}: {a: number, b: number}) {}
- foo => foo;
- let f = function (foo: number) {};`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `
- let foo = bar_baz`,
- options: [{ format: DEFAULT_FORMAT }],
- },
- {
- code: `
- let custom;
- let custom1;`,
- options: [{ format: CUSTOM_FORMAT }],
- },
- ],
- invalid: [
- {
- code: `let foo_bar`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- {
- message: `Rename this local variable "foo_bar" to match the regular expression ${DEFAULT_FORMAT}.`,
- line: 1,
- endLine: 1,
- column: 5,
- endColumn: 12,
- },
- ],
- },
- {
- code: `
- var foo_foo;
- const bar_bar = 5;`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_foo', 'local variable', DEFAULT_FORMAT),
- error('bar_bar', 'local variable', DEFAULT_FORMAT),
- ],
- },
- {
- code: `let [ foo_foo, [ bar_bar, [ baz_baz, ...qux_qux ] ] ] = arr;`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_foo', 'local variable', DEFAULT_FORMAT),
- error('bar_bar', 'local variable', DEFAULT_FORMAT),
- error('baz_baz', 'local variable', DEFAULT_FORMAT),
- error('qux_qux', 'local variable', DEFAULT_FORMAT),
- ],
- },
- {
- code: `let { foo, bar: bar_bar, baz: { qux: { quux: quux_quux }, ...corge_corge } } = obj;`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('bar_bar', 'local variable', DEFAULT_FORMAT),
- error('quux_quux', 'local variable', DEFAULT_FORMAT),
- error('corge_corge', 'local variable', DEFAULT_FORMAT),
- ],
- },
- {
- code: `
- try {} catch (foo_bar1) {}
- try {} catch ([ foo_bar2 ]) {}
- try {} catch ({ foo: foo_bar3 }) {}`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_bar1', 'parameter', DEFAULT_FORMAT),
- error('foo_bar2', 'parameter', DEFAULT_FORMAT),
- error('foo_bar3', 'parameter', DEFAULT_FORMAT),
- ],
- },
- {
- code: `
- function f(foo_bar1: number) {}
- function f(foo_bar2 = 5) {}
- function f(...foo_bar3: number[]) {}
- function f([foo_bar4, foo_bar5]: number[]) {}
- function f({a: foo_bar6, b: foo_bar7, foo_bar8}: {a: a_a, b: number}) {}
- foo_bar9 => foo_bar9;
- let f = function (foo_bar10: number) {};`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_bar1', 'parameter', DEFAULT_FORMAT),
- error('foo_bar2', 'parameter', DEFAULT_FORMAT),
- error('foo_bar3', 'parameter', DEFAULT_FORMAT),
- error('foo_bar4', 'parameter', DEFAULT_FORMAT),
- error('foo_bar5', 'parameter', DEFAULT_FORMAT),
- error('foo_bar6', 'parameter', DEFAULT_FORMAT),
- error('foo_bar7', 'parameter', DEFAULT_FORMAT),
- error('foo_bar9', 'parameter', DEFAULT_FORMAT),
- error('foo_bar10', 'parameter', DEFAULT_FORMAT),
- ],
- },
- {
- code: `
- interface i {
- new(foo_bar1: number);
- m(foo_bar2: number);
- }`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_bar1', 'parameter', DEFAULT_FORMAT),
- error('foo_bar2', 'parameter', DEFAULT_FORMAT),
- ],
- },
- {
- code: `
- class c {
- "foo_bar": number; // Compliant
- foo_bar1: number;
- constructor(foo_bar2: number, readonly foo_bar3: number) {}
- m(foo_bar4: number) {}
- n(foo_bar5: number)
- }`,
- options: [{ format: DEFAULT_FORMAT }],
- errors: [
- error('foo_bar1', 'property', DEFAULT_FORMAT),
- error('foo_bar2', 'parameter', DEFAULT_FORMAT),
- error('foo_bar3', 'parameter', DEFAULT_FORMAT),
- error('foo_bar4', 'parameter', DEFAULT_FORMAT),
- error('foo_bar5', 'parameter', DEFAULT_FORMAT),
- ],
- },
- {
- code: `let custom_format`,
- options: [{ format: CUSTOM_FORMAT }],
- errors: [error('custom_format', 'local variable', CUSTOM_FORMAT)],
- },
- ],
- },
-);
-
-function error(symbol: string, symbolType: string, format: string) {
- return {
- message: `Rename this ${symbolType} "${symbol}" to match the regular expression ${format}.`,
- };
-}
diff --git a/eslint-bridge/tests/linting/eslint/rules/void-use.test.ts b/eslint-bridge/tests/linting/eslint/rules/void-use.test.ts
deleted file mode 100644
index 116f8c29dbd..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/void-use.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/void-use';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-const testCases = {
- valid: [
- {
- code: `
- (function() {
- })()
- `,
- },
- {
- code: `
- void 0;
- `,
- },
- {
- code: `
- void (0);
- `,
- },
- {
- code: `
- void function() {
- }()
- `,
- },
- {
- code: `
- void (() => 42) ()
- `,
- },
- ],
- invalid: [
- {
- code: `
- foo(void 42);
- `,
- errors: [
- {
- message: `Remove this use of the \"void\" operator.`,
- line: 2,
- endLine: 2,
- column: 17,
- endColumn: 21,
- },
- ],
- },
- {
- code: `
- const f = () => { return new Promise(() => {}); };
- void f(); // FP: should be ignored since 'f()' is a promise but we are missing type information
- `,
- errors: 1,
- },
- ],
-};
-ruleTesterJs.run('"void" should not be used JS', rule, testCases);
-ruleTesterTs.run('"void" should not be used TS', rule, {
- valid: [
- {
- code: `void 0;`,
- },
- {
- code: `
- const p = new Promise(() => {});
- void p;
- `,
- },
- {
- code: `
- const f = () => { return new Promise(() => {}); };
- void f();
- `,
- },
- ],
- invalid: [
- {
- code: `void 42;`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/weak-ssl.test.ts b/eslint-bridge/tests/linting/eslint/rules/weak-ssl.test.ts
deleted file mode 100644
index 83bdc4ca4a5..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/weak-ssl.test.ts
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/weak-ssl';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-
-const minMaxVersion = {
- valid: [
- {
- code: `
- const tls = require('tls');
- const constants = require('constants');
- tls.connect({
- minVersion: 'TLSv1.2',
- maxVersion: 'TLSv1.2'
- });
-
- tls.connect(port, {
- minVersion: 'TLSv1.2',
- maxVersion: 'TLSv1.3'
- });
-
- tls.connect(port, url, {
- minVersion: 'TLSv1.3',
- maxVersion: 'TLSv1.3'
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- const tls = require('node:tls');
- const constants = require('constants');
- tls.connect({
- minVersion: 'TLSv1.1',
- });
- `,
- errors: 1,
- },
- {
- code: `
- const tls = require('tls');
- const constants = require('constants');
- tls.connect({
- minVersion: 'TLSv1.1',
- maxVersion: 'TLSv1.2'
- });
- `,
- errors: [
- {
- message: "Change 'minVersion' to use at least TLS v1.2.",
- line: 5,
- column: 21,
- endLine: 5,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- const tls = require('tls');
- const constants = require('constants');
- tls.connect({
- minVersion: 'TLSv1.1',
- maxVersion: 'TLSv1.1'
- });
-
- tls.connect(port, {
- minVersion: 'TLSv1.1',
- });
-
- tls.connect(port, url, {
- maxVersion: 'TLSv1.1'
- });
- `,
- errors: 4,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options23 = {
- minVersion: 'TLSv1.1', // Noncompliant
- maxVersion: 'TLSv1.1' // Noncompliant
- }
-
- var req23 = https.request(options23);
- `,
- errors: [
- {
- message: "Change 'minVersion' to use at least TLS v1.2.",
- line: 6,
- column: 21,
- endLine: 6,
- endColumn: 30,
- },
- {
- message: "Change 'maxVersion' to use at least TLS v1.2.",
- line: 7,
- column: 21,
- endLine: 7,
- endColumn: 30,
- },
- ],
- },
- {
- code: `
- const https = require('node:https');
- const constants = require('node:constants');
-
- var options23 = {
- minVersion: 'TLSv1.1', // Noncompliant
- maxVersion: 'TLSv1.1' // Noncompliant
- }
-
- var req23 = https.request(options23);
- `,
- errors: 2,
- },
- {
- code: `
- const request = require('request');
- const constants = require('constants');
-
- var socket25 = request.get({
- url: 'https://www.google.com/',
- minVersion: 'TLSv1.1', // Noncompliant
- maxVersion: 'TLSv1.1' // Noncompliant
- }); // Noncompliant
- `,
- errors: 2,
- },
- ],
-};
-
-const secureProtocol = {
- valid: [
- {
- code: `
- const request = require('request');
- const constants = require('constants');
-
- var socket5 = request.get({
- url: 'https://www.google.com/',
-
- secureProtocol: 'TLSv1_2_method' // Compliant
- });
- `,
- },
- {
- code: `
- const https = require('https');
-
- var options17 = {
- hostname: 'www.google.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureProtocol: 'TLSv1_2_method'
- };
-
- https.request(options17, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- }); `,
- },
- ],
- invalid: [
- {
- code: `
- const https = require('https');
- const constants = require('constants');
- var options5 = {
- secureProtocol: 'SSLv3_method'
- }
-
- var req5 = https.request(options5);
- `,
- errors: [
- {
- message: "Change 'secureProtocol' to use at least TLS v1.2.",
- line: 5,
- column: 25,
- endLine: 5,
- endColumn: 39,
- },
- ],
- },
- {
- code: `
- const request = require('request');
- const constants = require('constants');
-
- var socket18 = request.get({
- url: 'https://www.google.com/',
- secureProtocol: 'DTLSv1_client_method' // Noncompliant
- });
- `,
- errors: 1,
- },
- ],
-};
-
-const secureOptions = {
- valid: [
- {
- code: `
- var options3 = {
- hostname: 'www.google.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1
- };
-
- var req3 = https.request(options3, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- }); // Compliant
- `,
- },
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'www.google.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: opts() | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1
- };
-
- var req = https.request(options, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- });
- `,
- },
- ],
- invalid: [
- {
- code: `
- const https = require('https');
- const constants = require('constants');
-
- var options = {
- hostname: 'www.google.com',
- port: 443,
- path: '/',
- method: 'GET',
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1
- };
-
- var req = https.request(options, (res) => {
- console.log('statusCode:', res.statusCode);
- console.log('headers:', res.headers);
-
- res.on('data', (d) => {
- process.stdout.write(d);
- });
- });
- `,
- errors: [
- {
- line: 10,
- column: 9,
- endLine: 10,
- endColumn: 105,
- message: "Change 'secureOptions' to allow only secure TLS versions.",
- },
- ],
- },
- {
- code: `
- const tls = require('tls');
- const constants = require('constants');
- var options1 = {
- secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_TLSv1
- };
-
- tls.createSecureContext(options1);
- `,
- errors: 1,
- },
- {
- code: `
- const tls = require('tls');
- const c = require('constants');
- var options1 = {
- secureOptions: c.SSL_OP_NO_SSLv2 | c.SSL_OP_NO_SSLv3 | c.SSL_OP_NO_TLSv1
- };
-
- tls.createSecureContext(options1);
- `,
- errors: 1,
- },
- ],
-};
-
-ruleTesterJs.run('Should use strong TLS: minMaxVersion', rule, minMaxVersion);
-ruleTesterJs.run('Should use strong TLS: secureProtocol', rule, secureProtocol);
-ruleTesterJs.run('Should use strong TLS: secureOptions', rule, secureOptions);
diff --git a/eslint-bridge/tests/linting/eslint/rules/web-sql-database.test.ts b/eslint-bridge/tests/linting/eslint/rules/web-sql-database.test.ts
deleted file mode 100644
index 9d61a522245..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/web-sql-database.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-import { rule } from 'linting/eslint/rules/web-sql-database';
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-ruleTesterJs.run('No issues without types', rule, {
- valid: [
- {
- code: `
- var db2 = openDatabase("myDb", "1.0", "P", 2*1024*1024);
- `,
- },
- {
- code: `
- var db3 = this.openDatabase("myDb", "1.0", "P", 2*1024*1024, callback);
- `,
- },
- {
- code: `
- var win = window;
- win.openDatabase("db","1.0","stuff",2*1024*1024);
- `,
- },
- ],
- invalid: [],
-});
-
-ruleTesterTs.run('Web SQL databases should not be used', rule, {
- valid: [
- {
- code: `
- var deb = getDb();
- var db4 = db.openDatabase("myDb", "1.0", "P", 2*1024*1024);
- `,
- },
- {
- code: `
- function openDatabase() {
- }
- openDatabase();
- `,
- },
- {
- code: `
- var win = window;
- win.somethingElse(); // OK
- `,
- },
- ],
- invalid: [
- {
- code: `
- var win = window;
- win.openDatabase("db","1.0","stuff",2*1024*1024);
- `,
- errors: [
- {
- line: 3,
- column: 7,
- endLine: 3,
- endColumn: 23,
- message: 'Convert this use of a Web SQL database to another technology.',
- },
- ],
- },
- {
- code: `
- var db2 = openDatabase("myDb", "1.0", "P", 2*1024*1024);
- `,
- errors: 1,
- },
- {
- code: `
- var db2 = openDatabase("myDb", "1.0", "P", 2*1024*1024);
- `,
- errors: 1,
- },
- {
- code: `
- var db3 = this.openDatabase("myDb", "1.0", "P", 2*1024*1024, callback);
- `,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/eslint/rules/x-powered-by.test.ts b/eslint-bridge/tests/linting/eslint/rules/x-powered-by.test.ts
deleted file mode 100644
index d0f26452624..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/x-powered-by.test.ts
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/x-powered-by';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run(
- 'Recovering fingerprints from web application technologies should not be possible',
- rule,
- {
- valid: [
- {
- code: `
- const express = require('express');
- const app = express();
- app.disable("x-powered-by"); // Compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const hidePoweredBy = require('hide-powered-by');
- const app = express();
- app.use(hidePoweredBy()); // Compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.set("x-powered-by", false); // Compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.set("X-PoWeReD-bY", false); // Compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(require('helmet')()); // Compliant
- `,
- },
- {
- code: `
- import express from 'express';
- import disableXPoweredBy from 'hide-powered-by';
- const app = express();
- app.use(disableXPoweredBy()); // Compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- const helmet = require('helmet');
- const h = helmet();
- app.use(h);
- `,
- },
- {
- code: `
- // middleware instance is saved to variable instead of directly passed to 'app.use()'
- const express = require('express');
- const helmet = require('helmet');
- const helmetInstance = helmet();
- const app = express();
- app.use(helmetInstance); // compliant
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- configure(app); // app escapes, probably configured elsewhere.
- `,
- },
- {
- code: `
- const express = require('express');
- const helmet = require('helmet');
- const app = express();
- app.use(helmet.hidePoweredBy());
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(require('helmet').hidePoweredBy());
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(a, b, [c, d, require('helmet')(), e, f], g, h);
- `,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- const helmet = require('helmet');
- const securityMiddlewares = [
- armor(),
- helmet(),
- sword(),
- horse(),
- ];
- app.use(usefulStuff, securityMiddlewares, moreStuff);
- `,
- },
- {
- code: `
- const { app } = apps[42]; // Compliant (not obviously an express-app, ignored)
- const app2 = apps[42];
- const { subcomponent } = require('express')();
- apps[42] = require('express')(); // Limitation: we don't keep track of 'app' here.
- `,
- },
- {
- code: `
- const express = require('express');
- module.exports.createExpressApp = function() {
- var appEscaping = express(); // should be compliant, because express object is returned from the function
- return appEscaping;
- };
- `,
- },
- {
- code: `
- const express = require('express');
- function f() {
- return 42; // a return before the application is discovered, for coverage
- }
- module.exports.createExpressApp = function() {
- var appEscaping = express();
- return appEscaping;
- };
- `,
- },
- ],
- invalid: [
- {
- code: `
- const express = require('express');
- const app = express(); // Noncompliant
- `,
- errors: [
- {
- message: 'Make sure disclosing the fingerprinting of this web technology is safe here.',
- line: 3,
- endLine: 3,
- column: 15,
- endColumn: 18,
- },
- ],
- },
- {
- code: `
- import * as express from 'express';
- const app = express(); // Noncompliant
- `,
- errors: [
- {
- message: 'Make sure disclosing the fingerprinting of this web technology is safe here.',
- line: 3,
- endLine: 3,
- column: 15,
- endColumn: 18,
- },
- ],
- },
- {
- code: `
- const app = require('express')(); // Noncompliant
- `,
- errors: [
- {
- message: 'Make sure disclosing the fingerprinting of this web technology is safe here.',
- line: 2,
- endLine: 2,
- column: 15,
- endColumn: 18,
- },
- ],
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.set("x-powered-by", true); // Noncompliant
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const theforce = require('the-force');
- const app = express();
- app.use(theforce()); // That doesn't help here.
- app.use(somethingunknown()); // That doesn't help either.
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const helmet = require('helmet');
- const helmetInst = helmet();
- const app = express();
- // imported, but forgot to use helmet
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- app.use(a, b, [c, d, require('sth-useless')(), e, f], g, h);
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- const app = express();
- const securityMiddlewares = [
- armor(),
- sword(),
- horse(),
- ];
- app.use(usefulStuff, securityMiddlewares, something.unknown());
- `,
- errors: 1,
- },
- {
- code: `
- const express = require('express');
- module.exports.createExpressApp = function() {
- var appEscaping = express();
- return appEscaping.someSubproperty; // that's not sufficient, does not count as escaped app.
- };
- `,
- errors: 1,
- },
- ],
- },
-);
diff --git a/eslint-bridge/tests/linting/eslint/rules/xml-parser-xxe.test.ts b/eslint-bridge/tests/linting/eslint/rules/xml-parser-xxe.test.ts
deleted file mode 100644
index 68a9697b080..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/xml-parser-xxe.test.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from 'linting/eslint/rules/xml-parser-xxe';
-import { RuleTester } from 'eslint';
-import { TypeScriptRuleTester } from '../../../tools';
-
-const tests = {
- valid: [
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXml(xml, { noblanks: true, nocdata: true });`,
- },
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXmlString(xml, { noblanks: true, nocdata: true });`,
- },
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXmlString(xml, { noblanks: true, noent: false, nocdata: true });`,
- },
- {
- code: `
- import * as libxmljs from "libxmljs";
- var xmlDoc = libxmljs.parseXmlString(xml, { noblanks: true, nocdata: true });`,
- },
- {
- code: `
- import { parseXmlString } from "libxmljs";
- var xmlDoc = parseXmlString(xml, { noblanks: true, noent: false, nocdata: true });`,
- },
- {
- code: `
- var xmlDoc = parseXmlString(xml, { noblanks: true, noent: true, nocdata: true });`,
- },
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXmlString({ noblanks: true, noent: true, nocdata: true });`,
- errors: 1,
- },
- ],
- invalid: [
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXml(xml, { noblanks: true, noent: true, nocdata: true });`,
- errors: [
- {
- message:
- '{"message":"Disable access to external entities in XML parsing.","secondaryLocations":[{"column":21,"line":3,"endColumn":38,"endLine":3}]}',
- line: 3,
- endLine: 3,
- column: 63,
- endColumn: 74,
- },
- ],
- },
- {
- code: `
- const libxmljs = require("libxmljs");
- var xmlDoc = libxmljs.parseXmlString(xml, { noblanks: true, noent: true, nocdata: true });`,
- errors: 1,
- },
- {
- code: `
- import * as libxmljs from "libxmljs";
- var xmlDoc = libxmljs.parseXmlString(xml, { noblanks: true, noent: true, nocdata: true });`,
- errors: 1,
- },
- {
- code: `
- import { parseXmlString } from "libxmljs";
- var xmlDoc = parseXmlString(xml, { noblanks: true, noent: true, nocdata: true });`,
- errors: 1,
- },
- ],
-};
-
-const ruleTesterJs = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-const ruleTesterTs = new TypeScriptRuleTester();
-
-ruleTesterJs.run('XML parsers should not be vulnerable to XXE attacks [js]', rule, tests);
-ruleTesterTs.run('XML parsers should not be vulnerable to XXE attacks [ts]', rule, tests);
diff --git a/eslint-bridge/tests/linting/eslint/rules/xpath.test.ts b/eslint-bridge/tests/linting/eslint/rules/xpath.test.ts
deleted file mode 100644
index df08d63485d..00000000000
--- a/eslint-bridge/tests/linting/eslint/rules/xpath.test.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { rule } from 'linting/eslint/rules/xpath';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('Executing XPath expressions is security-sensitive', rule, {
- valid: [
- {
- code: `
- const xpath = require('xpath');
- xpath.parse(expr);`,
- },
- {
- code: `
- const xpath = require('x');
- xpath.select(expr);`,
- },
- {
- code: `
- const select = require('xpath').parse;
- select(expr);`,
- },
- {
- code: `
- import * as foo from 'xpath';
- foo.parse(expr);`,
- },
- {
- code: `a.selectNodesFoo(expr)`,
- },
- {
- code: `a.selectNodes(expr1, expr2)`,
- },
- {
- code: `document.evaluateFoo(userInput, xmlDoc, null, XPathResult.ANY_TYPE, null);`,
- },
- {
- code: `foo.evaluate(userInput, xmlDoc, null, foo);`,
- },
- {
- code: `
- const xpath = require('xpath');
- xpath.select('foo/bar');
- xpath.select1('foo/bar');
- xpath.evaluate('foo/bar');
- a.selectNodes('foo/bar');
- a.SelectSingleNode('foo/bar')`,
- },
- ],
- invalid: [
- {
- code: `
- const xpath = require('xpath');
- xpath.select(expr);`,
- errors: [
- {
- message: 'Make sure that executing this XPATH expression is safe.',
- line: 3,
- endLine: 3,
- column: 9,
- endColumn: 21,
- },
- ],
- },
- {
- code: `
- const xpath = require('xpath');
- xpath.select1(expr);`,
- errors: 1,
- },
- {
- code: `
- const select = require('xpath').select;
- select(expr);`,
- errors: 1,
- },
- {
- code: `
- import { select1 } from 'xpath';
- select1(expr);`,
- errors: 1,
- },
- {
- code: `
- import { evaluate } from 'xpath';
- evaluate(expr);`,
- errors: 1,
- },
- {
- code: `a.selectNodes(expr)`,
- errors: [
- {
- message: 'Make sure that executing this XPATH expression is safe.',
- line: 1,
- endLine: 1,
- column: 1,
- endColumn: 14,
- },
- ],
- },
- {
- code: `a.b.selectNodes(expr)`,
- errors: 1,
- },
- {
- code: `a.b().SelectSingleNode(expr)`,
- errors: 1,
- },
- {
- code: `document.evaluate(userInput, xmlDoc, null, XPathResult.ANY_TYPE, null);`,
- errors: 1,
- },
- {
- code: `foo.bar.evaluate(userInput, xmlDoc, null, XPathResult.STRING_TYPE);`,
- errors: 1,
- },
- {
- code: `foo(document.evaluate)`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/linting/stylelint/linter/config.test.ts b/eslint-bridge/tests/linting/stylelint/linter/config.test.ts
deleted file mode 100644
index 255656295e1..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/config.test.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { createStylelintConfig, RuleConfig } from 'linting/stylelint';
-
-describe('createStylelintConfig', () => {
- it('should create a Stylelint config', () => {
- const rules: RuleConfig[] = [
- { key: 'foo', configurations: [] },
- { key: 'bar', configurations: [42] },
- ];
- const config = createStylelintConfig(rules);
- expect(config).toEqual({
- customSyntax: 'postcss-syntax',
- rules: {
- foo: true,
- bar: [42],
- },
- });
- });
-});
diff --git a/eslint-bridge/tests/linting/stylelint/linter/fixtures/block.css b/eslint-bridge/tests/linting/stylelint/linter/fixtures/block.css
deleted file mode 100644
index 802e4f0e16a..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/fixtures/block.css
+++ /dev/null
@@ -1 +0,0 @@
-p { }
diff --git a/eslint-bridge/tests/linting/stylelint/linter/fixtures/calc.css b/eslint-bridge/tests/linting/stylelint/linter/fixtures/calc.css
deleted file mode 100644
index e6532db8e53..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/fixtures/calc.css
+++ /dev/null
@@ -1 +0,0 @@
-.p { width: calc(100% 80px); }
diff --git a/eslint-bridge/tests/linting/stylelint/linter/fixtures/font-family.css b/eslint-bridge/tests/linting/stylelint/linter/fixtures/font-family.css
deleted file mode 100644
index e61a6bde45c..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/fixtures/font-family.css
+++ /dev/null
@@ -1,2 +0,0 @@
-a { font-family: foo; }
-a { font-family: bar; }
diff --git a/eslint-bridge/tests/linting/stylelint/linter/issues/transform.test.ts b/eslint-bridge/tests/linting/stylelint/linter/issues/transform.test.ts
deleted file mode 100644
index d6606eaa71a..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/issues/transform.test.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import stylelint from 'stylelint';
-import { transform } from 'linting/stylelint/linter/issues';
-
-describe('transform', () => {
- it('should transform Stylelint results into issues', () => {
- const filePath = '/tmp/path';
- const results = [
- {
- source: filePath,
- warnings: [
- {
- rule: 'some-rule',
- text: 'some-text',
- line: 42,
- column: 4242,
- },
- ],
- },
- ] as stylelint.LintResult[];
-
- const issues = transform(results, filePath);
-
- expect(issues).toEqual([
- {
- ruleId: 'some-rule',
- message: 'some-text',
- line: 42,
- column: 4242,
- },
- ]);
- });
-
- it('should not transform Stylelint results from a different file', () => {
- console.log = jest.fn();
-
- const filePath = '/tmp/path';
- const source = '/some/fake/source';
- const results = [
- {
- source,
- warnings: [
- {
- rule: 'some-rule',
- text: 'some-text',
- line: 42,
- column: 4242,
- },
- ],
- },
- ] as stylelint.LintResult[];
-
- const issues = transform(results, filePath);
-
- expect(issues).toHaveLength(0);
- expect(console.log).toHaveBeenCalledWith(
- `DEBUG For file [${filePath}] received issues with [${source}] as a source. They will not be reported.`,
- );
- });
-});
diff --git a/eslint-bridge/tests/linting/stylelint/linter/wrapper.test.ts b/eslint-bridge/tests/linting/stylelint/linter/wrapper.test.ts
deleted file mode 100644
index d94a3423604..00000000000
--- a/eslint-bridge/tests/linting/stylelint/linter/wrapper.test.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import stylelint from 'stylelint';
-import { readFile } from 'helpers';
-import { createStylelintConfig, LinterWrapper, RuleConfig } from 'linting/stylelint';
-
-describe('LinterWrapper', () => {
- it('should lint with a stylelint rule', async () => {
- const filePath = path.join(__dirname, './fixtures/block.css');
- const rules = [{ key: 'block-no-empty', configurations: [] }];
- const options = await createStylelintOptions(filePath, rules);
-
- const linter = new LinterWrapper();
- const { issues } = await linter.lint(filePath, options);
-
- expect(issues).toEqual([
- {
- ruleId: 'block-no-empty',
- line: 1,
- column: 3,
- message: 'Unexpected empty block (block-no-empty)',
- },
- ]);
- });
-
- it('should lint with an internal rule', async () => {
- const filePath = path.join(__dirname, './fixtures/calc.css');
- const rules = [{ key: 'function-calc-no-invalid', configurations: [] }];
- const options = await createStylelintOptions(filePath, rules);
-
- const linter = new LinterWrapper();
- const { issues } = await linter.lint(filePath, options);
-
- expect(issues).toEqual([
- {
- ruleId: 'function-calc-no-invalid',
- line: 1,
- column: 6,
- message: `Fix this malformed 'calc' expression.`,
- },
- ]);
- });
-
- it('should lint with a configured rule', async () => {
- const filePath = path.join(__dirname, './fixtures/font-family.css');
- const rules = [
- {
- key: 'font-family-no-missing-generic-family-keyword',
- configurations: [true, { ignoreFontFamilies: ['foo'] }],
- },
- ];
- const options = await createStylelintOptions(filePath, rules);
-
- const linter = new LinterWrapper();
- const { issues } = await linter.lint(filePath, options);
-
- expect(issues).toEqual([
- {
- ruleId: 'font-family-no-missing-generic-family-keyword',
- line: 2,
- column: 18,
- message:
- 'Unexpected missing generic font family (font-family-no-missing-generic-family-keyword)',
- },
- ]);
- });
-
- it('should not lint with a disabled rule', async () => {
- const filePath = path.join(__dirname, './fixtures/block.css');
- const rules = [];
- const options = await createStylelintOptions(filePath, rules);
-
- const linter = new LinterWrapper();
- const { issues } = await linter.lint(filePath, options);
-
- expect(issues).toHaveLength(0);
- });
-});
-
-async function createStylelintOptions(
- filePath: string,
- rules: RuleConfig[],
-): Promise {
- const code = await readFile(filePath);
- const config = createStylelintConfig(rules);
- return { code, codeFilename: filePath, config };
-}
diff --git a/eslint-bridge/tests/linting/stylelint/rules/function-calc-no-invalid.test.ts b/eslint-bridge/tests/linting/stylelint/rules/function-calc-no-invalid.test.ts
deleted file mode 100644
index 0ba428a8105..00000000000
--- a/eslint-bridge/tests/linting/stylelint/rules/function-calc-no-invalid.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { StylelintRuleTester } from '../../../tools';
-import { messages, rule } from 'linting/stylelint/rules/function-calc-no-invalid';
-
-const ruleTester = new StylelintRuleTester(rule);
-ruleTester.run('function-calc-no-invalid', {
- valid: [
- {
- description: 'single expression',
- code: '.foo {width: calc(100%);}',
- },
- {
- description: 'compound expression',
- code: '.foo {width: calc(100% - 80px + 60pt);}',
- },
- {
- description: 'division by 1',
- code: '.foo {width: calc(100% / 1);}',
- },
- {
- description: 'division by 0.1',
- code: '.foo {width: calc(100% / 0.1);}',
- },
- {
- description: 'division by 1px',
- code: '.foo {width: calc(100% / 1px);}',
- },
- {
- description: 'comma divider',
- code: '.foo {width: calc(100% + var(--text-color, 0px));}',
- },
- ],
- invalid: [
- {
- description: 'empty expression',
- code: '.foo {width: calc();}',
- errors: [{ text: messages.empty, line: 1, column: 7 }],
- },
- {
- description: 'space-only expression',
- code: '.foo {width: calc( );}',
- errors: [{ text: messages.empty }],
- },
- {
- description: 'comment-only expression',
- code: '.foo {width: calc(/* this a comment */);}',
- errors: [{ text: messages.empty }],
- },
- {
- description: 'missing operator',
- code: '.foo {width: calc(100% 80px);}',
- errors: [{ text: messages.malformed }],
- },
- {
- description: 'division by 0',
- code: '.foo {width: calc(100% / 0);}',
- errors: [{ text: messages.divByZero }],
- },
- {
- description: 'division by 0.0',
- code: '.foo {width: calc(100% / 0.0);}',
- errors: [{ text: messages.divByZero }],
- },
- {
- description: 'division by 0px',
- code: '.foo {width: calc(100% / 0px);}',
- errors: [{ text: messages.divByZero }],
- },
- {
- description: 'sibling calc-s',
- code: '.foo {width: calc() + calc(100% / 0px);}',
- errors: [
- { text: messages.empty, line: 1, column: 7 },
- { text: messages.divByZero, line: 1, column: 7 },
- ],
- },
- {
- description: 'nested calc-s',
- code: '.foo {width: calc(100% / 0px + calc());}',
- errors: [{ text: messages.divByZero }, { text: messages.empty }],
- },
- {
- description: 'nested expressions',
- code: '.foo {width: calc(100 + ("foo" / (-0.9) * abs(80%) (70px+"bar")));}',
- errors: [{ text: messages.malformed }, { text: messages.malformed }],
- },
- ],
-});
diff --git a/eslint-bridge/tests/parsing/jsts/builders/build-js.test.ts b/eslint-bridge/tests/parsing/jsts/builders/build-js.test.ts
deleted file mode 100644
index dc4c54dbc86..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/build-js.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { APIError } from 'errors';
-import { SourceCode } from 'eslint';
-import { buildJs } from 'parsing/jsts/builders/build-js';
-import path from 'path';
-import { jsTsInput } from '../../../tools';
-
-describe('buildJs', () => {
- it('should build JavaScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'file.js');
- const tryTypeScriptParser = false;
- const {
- ast: {
- body: [stmt],
- },
- } = buildJs(await jsTsInput({ filePath }), tryTypeScriptParser) as SourceCode;
-
- expect(stmt.type).toEqual('FunctionDeclaration');
- });
-
- it('should fail building malformed JavaScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'malformed.js');
-
- const analysisInput = await jsTsInput({ filePath });
- const tryTypeScriptParser = false;
-
- expect(() => buildJs(analysisInput, tryTypeScriptParser)).toThrow(
- APIError.parsingError('Unexpected token (3:0)', { line: 3 }),
- );
- });
-
- it('should build JavaScript code with TypeScript ESLint parser', async () => {
- console.log = jest.fn();
-
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'file.js');
- const tryTypeScriptParser = true;
- const {
- ast: {
- body: [stmt],
- },
- } = buildJs(await jsTsInput({ filePath }), tryTypeScriptParser) as SourceCode;
-
- expect(stmt.type).toEqual('FunctionDeclaration');
- expect(console.log).not.toHaveBeenCalled();
- });
-
- it('should fail building JavaScript code with TypeScript ESLint parser', async () => {
- console.log = jest.fn();
-
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'malformed.js');
- const analysisInput = await jsTsInput({ filePath });
- const tryTypeScriptParser = true;
- expect(() => buildJs(analysisInput, tryTypeScriptParser)).toThrow();
-
- const log = `DEBUG Failed to parse ${filePath} with TypeScript parser: '}' expected.`;
- expect(console.log).toHaveBeenCalledWith(log);
- });
-
- it('should build module JavaScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'module.js');
- const tryTypeScriptParser = false;
- const sourceCode = buildJs(await jsTsInput({ filePath }), tryTypeScriptParser) as SourceCode;
-
- expect(sourceCode.ast.sourceType).toEqual('module');
- });
-
- it('should build script JavaScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'script.js');
- const tryTypeScriptParser = false;
- const sourceCode = buildJs(await jsTsInput({ filePath }), tryTypeScriptParser) as SourceCode;
-
- expect(sourceCode.ast.sourceType).toEqual('script');
- });
-
- it('should support JavaScript decorators', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-js', 'decorator.js');
- const tryTypeScriptParser = false;
- const {
- ast: {
- body: [stmt],
- },
- } = buildJs(await jsTsInput({ filePath }), tryTypeScriptParser) as SourceCode;
-
- expect((stmt as any).decorators).toHaveLength(1);
- expect((stmt as any).decorators[0].expression.name).toEqual('annotation');
- expect((stmt as any).decorators[0].type).toEqual('Decorator');
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/builders/build-ts.test.ts b/eslint-bridge/tests/parsing/jsts/builders/build-ts.test.ts
deleted file mode 100644
index 20924c240bb..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/build-ts.test.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { buildTs } from 'parsing/jsts/builders/build-ts';
-import path from 'path';
-import { AST } from 'vue-eslint-parser';
-import { APIError } from 'errors';
-import { jsTsInput } from '../../../tools';
-
-describe('buildTs', () => {
- it('should build TypeScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-ts', 'file.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build-ts', 'tsconfig.json')];
-
- const isVueFile = false;
- const sourceCode = buildTs(await jsTsInput({ filePath, tsConfigs }), isVueFile);
-
- const {
- ast: {
- body: [stmt],
- },
- } = sourceCode as AST.ESLintExtendedProgram;
- expect(stmt.type).toEqual('FunctionDeclaration');
- });
-
- it('should fail building malformed TypeScript code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-ts', 'malformed.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build-ts', 'tsconfig.json')];
- const isVueFile = false;
- const analysisInput = await jsTsInput({ filePath, tsConfigs });
- expect(() => buildTs(analysisInput, isVueFile)).toThrow(
- APIError.parsingError(`'}' expected.`, { line: 2 }),
- );
- });
-
- it('should build TypeScript Vue.js code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-ts', 'file.vue');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build-ts', 'tsconfig.json')];
- const isVueFile = true;
- const sourceCode = buildTs(
- await jsTsInput({ filePath, tsConfigs }),
- isVueFile,
- ) as AST.ESLintExtendedProgram;
-
- const {
- ast: {
- body: [stmt],
- templateBody,
- },
- } = sourceCode as AST.ESLintExtendedProgram;
- expect(stmt.type).toEqual('ImportDeclaration');
- expect(templateBody).toBeDefined();
- });
-
- it('should fail building excluded TypeScript code from TSConfig', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-ts', 'excluded.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build-ts', 'tsconfig.json')];
-
- const analysisInput = await jsTsInput({ filePath, tsConfigs });
- const isVueFile = false;
- expect(() => buildTs(analysisInput, isVueFile)).toThrow(/TSConfig does not include this file./);
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/builders/build-vue.test.ts b/eslint-bridge/tests/parsing/jsts/builders/build-vue.test.ts
deleted file mode 100644
index a9a076b3674..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/build-vue.test.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { buildVue } from 'parsing/jsts/builders/build-vue';
-import path from 'path';
-import { AST } from 'vue-eslint-parser';
-import { APIError } from 'errors';
-import { jsTsInput } from '../../../tools';
-
-describe('buildVue', () => {
- it('should build Vue.js code with JavaScript parser', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-vue', 'js.vue');
- const tryTypeScriptParser = false;
- const sourceCode = buildVue(await jsTsInput({ filePath }), tryTypeScriptParser);
-
- const {
- ast: {
- body: [stmt],
- templateBody,
- },
- } = sourceCode as AST.ESLintExtendedProgram;
- expect(stmt.type).toEqual('ExpressionStatement');
- expect(templateBody).toBeDefined();
- });
-
- it('should fail building malformed Vue.js code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-vue', 'malformed.vue');
-
- const analysisInput = await jsTsInput({ filePath });
- const tryTypeScriptParser = false;
- expect(() => buildVue(analysisInput, tryTypeScriptParser)).toThrow(
- APIError.parsingError('Unexpected token (3:0)', { line: 7 }),
- );
- });
-
- it('should build Vue.js code with TypeScript ESLint parser', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build-vue', 'ts.vue');
- const tryTypeScriptParser = true;
- const sourceCode = buildVue(
- await jsTsInput({ filePath }),
- tryTypeScriptParser,
- ) as AST.ESLintExtendedProgram;
-
- expect(sourceCode.ast).toBeDefined();
- });
-
- it('should fail building malformed Vue.js code with TypeScript ESLint parser', async () => {
- console.log = jest.fn();
-
- const filePath = path.join(__dirname, 'fixtures', 'build-vue', 'malformed.vue');
- const analysisInput = await jsTsInput({ filePath });
- const tryTypeScriptParser = true;
- expect(() => buildVue(analysisInput, tryTypeScriptParser)).toThrow();
-
- const log = `DEBUG Failed to parse ${filePath} with TypeScript parser: Expression expected.`;
- expect(console.log).toHaveBeenCalledWith(log);
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/builders/build.test.ts b/eslint-bridge/tests/parsing/jsts/builders/build.test.ts
deleted file mode 100644
index f821c0cb87e..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/build.test.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { setContext } from 'helpers';
-import { buildSourceCode } from 'parsing/jsts';
-import path from 'path';
-import { AST } from 'vue-eslint-parser';
-import { jsTsInput } from '../../../tools';
-
-describe('buildSourceCode', () => {
- it('should build JavaScript source code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build', 'file.js');
- const {
- ast: {
- body: [stmt],
- },
- } = buildSourceCode(await jsTsInput({ filePath }), 'js') as SourceCode;
-
- expect(stmt.type).toEqual('VariableDeclaration');
- });
-
- it('should build JavaScript source code with TypeScript ESLint parser', async () => {
- console.log = jest.fn();
-
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- });
-
- const filePath = path.join(__dirname, 'fixtures', 'build', 'file.js');
- const {
- ast: {
- body: [stmt],
- },
- } = buildSourceCode(await jsTsInput({ filePath }), 'js') as SourceCode;
-
- expect(stmt.type).toEqual('VariableDeclaration');
- expect(console.log).not.toHaveBeenCalled();
- });
-
- it('should build JavaScript Vue.js source code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build', 'js.vue');
- const sourceCode = buildSourceCode(await jsTsInput({ filePath }), 'js');
-
- const {
- ast: {
- body: [stmt],
- },
- } = sourceCode as AST.ESLintExtendedProgram;
- expect(stmt.type).toEqual('ExportDefaultDeclaration');
- });
-
- it('should build TypeScript source code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build', 'file.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build', 'tsconfig.json')];
- const {
- ast: {
- body: [stmt],
- },
- } = buildSourceCode(await jsTsInput({ filePath, tsConfigs }), 'ts') as SourceCode;
-
- expect(stmt.type).toEqual('TSTypeAliasDeclaration');
- });
-
- it('should build TypeScript Vue.js source code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'build', 'ts.vue');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'build', 'tsconfig.json')];
- const sourceCode = buildSourceCode(await jsTsInput({ filePath, tsConfigs }), 'ts');
-
- const {
- ast: {
- body: [stmt],
- },
- } = sourceCode as AST.ESLintExtendedProgram;
- expect(stmt.type).toEqual('ExportDefaultDeclaration');
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/decorator.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/decorator.js
deleted file mode 100644
index ea1688b9715..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/decorator.js
+++ /dev/null
@@ -1,6 +0,0 @@
-@annotation
-class MyClass {}
-
-function annotation(target) {
- target.annotated = true;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/file.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/file.js
deleted file mode 100644
index 8c6cb4ee602..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/file.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function f() {
- return 42;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/malformed.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/malformed.js
deleted file mode 100644
index c9b9fe60cfa..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/malformed.js
+++ /dev/null
@@ -1,2 +0,0 @@
-while (true) {
- ;
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/module.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/module.js
deleted file mode 100644
index c0940ffbe91..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/module.js
+++ /dev/null
@@ -1 +0,0 @@
-export const n = 42;
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/script.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/script.js
deleted file mode 100644
index 6454ab38ee7..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-js/script.js
+++ /dev/null
@@ -1 +0,0 @@
-eval = 42;
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/excluded.ts b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/excluded.ts
deleted file mode 100644
index 22282135076..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/excluded.ts
+++ /dev/null
@@ -1 +0,0 @@
-/* Excluded from the TSConfig */
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.ts b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.ts
deleted file mode 100644
index fbedb135715..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-function hello(name: string): any {
- return `Hello, ${name}`;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.vue
deleted file mode 100644
index bc77826bd8f..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/file.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-
- {{background}}
-
-
-
-
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/malformed.ts b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/malformed.ts
deleted file mode 100644
index 48a02c859ad..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/malformed.ts
+++ /dev/null
@@ -1 +0,0 @@
-function hello(name: string): any {
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/tsconfig.json b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/tsconfig.json
deleted file mode 100644
index c176488507c..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-ts/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "allowJs": true
- },
- "exclude": ["excluded.ts"],
- "include": [
- "**/*.ts",
- "**/*.vue"
- ]
-}
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/js.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/js.vue
deleted file mode 100644
index 07bd71adca1..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/js.vue
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/malformed.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/malformed.vue
deleted file mode 100644
index 717910835c3..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/malformed.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/ts.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/ts.vue
deleted file mode 100644
index bc77826bd8f..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build-vue/ts.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-
- {{background}}
-
-
-
-
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.js b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.js
deleted file mode 100644
index 97dc3252b02..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.js
+++ /dev/null
@@ -1 +0,0 @@
-const [a, b] = [1, 2, 3];
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.ts b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.ts
deleted file mode 100644
index f2230d4d645..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/file.ts
+++ /dev/null
@@ -1 +0,0 @@
-type T = number | string;
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/js.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/js.vue
deleted file mode 100644
index 95b6df815bd..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/js.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/ts.vue b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/ts.vue
deleted file mode 100644
index 2911a1759cb..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/ts.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/tsconfig.json b/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/tsconfig.json
deleted file mode 100644
index fa1b79aaf97..00000000000
--- a/eslint-bridge/tests/parsing/jsts/builders/fixtures/build/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "include": ["./*.ts", "./*.vue",]
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/eslint.test.ts b/eslint-bridge/tests/parsing/jsts/parsers/eslint.test.ts
deleted file mode 100644
index 1c64329bb6d..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/eslint.test.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { SourceCode } from 'eslint';
-import { buildSourceCode, Language } from 'parsing/jsts';
-import path from 'path';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { readFile } from 'helpers';
-
-const cases = [
- { syntax: 'ECMAScript 2015', fixture: 'es2015.js', language: 'js' },
- { syntax: 'ECMAScript 2016', fixture: 'es2016.js', language: 'js' },
- { syntax: 'ECMAScript 2017', fixture: 'es2017.js', language: 'js' },
- { syntax: 'ECMAScript 2018', fixture: 'es2018.js', language: 'js' },
- { syntax: 'ECMAScript 2019', fixture: 'es2019.js', language: 'js' },
- { syntax: 'ECMAScript 2020', fixture: 'es2020.js', language: 'js' },
- { syntax: 'JSX', fixture: 'jsx.jsx', language: 'js' },
- { syntax: 'Flow', fixture: 'flow.js', language: 'js' },
- { syntax: 'Vue.js', fixture: 'vue.vue', language: 'js' },
- { syntax: 'decorator @', fixture: 'decorator.js', language: 'js' },
- { syntax: 'private #', fixture: 'private.js', language: 'js' },
- { syntax: 'TypeScript', fixture: 'typescript.ts', language: 'ts' },
-];
-
-describe('ESLint-based parsers', () => {
- test.each(cases)('should parse $syntax syntax', async ({ fixture, language }) => {
- const filePath = path.join(__dirname, 'fixtures', 'eslint', fixture);
- const fileContent = await readFile(filePath);
- const fileType = 'MAIN';
-
- const input = { filePath, fileType, fileContent } as JsTsAnalysisInput;
- const sourceCode = buildSourceCode(input, language as Language) as SourceCode;
-
- expect(sourceCode).toBeDefined();
- expect(sourceCode.ast).toBeDefined();
- expect(sourceCode.ast.body.length).toBeGreaterThan(0);
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/decorator.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/decorator.js
deleted file mode 100644
index 8fdf4f3fe0d..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/decorator.js
+++ /dev/null
@@ -1,5 +0,0 @@
-@X()
-class C {
- @Z('demo')
- m() {}
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2009.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2009.js
deleted file mode 100644
index 05b4b66d2e7..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2009.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"hello, \
-world!";
-' foo '.trim();
-[1, 2, 3].map(console.log);
-JSON.parse('{ "foo": 42 }');
-var o = { p: 42, get m() { return this.p; } };
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2015.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2015.js
deleted file mode 100644
index 7726f198a87..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2015.js
+++ /dev/null
@@ -1,7 +0,0 @@
-let m = 42;
-n => n + 1;
-`hello ${arrow}`;
-class c {};
-const [a, b] = [1, 2]
-for (const x of xs) {}
-function f(p = 42) {}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2016.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2016.js
deleted file mode 100644
index 6b077d0cbde..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2016.js
+++ /dev/null
@@ -1,2 +0,0 @@
-x ** 42;
-['foo', 'bar', 'baz'].includes('bar');
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2017.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2017.js
deleted file mode 100644
index 3354ca007b0..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2017.js
+++ /dev/null
@@ -1,2 +0,0 @@
-'foo'.padStart(5, 0);
-Object.entries({ a: 42, b: 24 });
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2018.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2018.js
deleted file mode 100644
index 7c5100cf24e..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2018.js
+++ /dev/null
@@ -1,3 +0,0 @@
-let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
-(new Promise()).finally();
-for await (const a of as) {}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2019.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2019.js
deleted file mode 100644
index dad334bbed0..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2019.js
+++ /dev/null
@@ -1 +0,0 @@
-try {} catch {}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2020.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2020.js
deleted file mode 100644
index 4b8e2e64ee0..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/es2020.js
+++ /dev/null
@@ -1,4 +0,0 @@
-foo() ?? bar();
-o?.p;
-for (a in b) {}
-export * as f from 'g';
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/flow.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/flow.js
deleted file mode 100644
index dc758bfdc8b..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/flow.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/* @flow */ const foo: string = 'hello';
-/* @flow */ var eval = 42;
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/jsx.jsx b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/jsx.jsx
deleted file mode 100644
index 9c173babee7..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/jsx.jsx
+++ /dev/null
@@ -1,3 +0,0 @@
-function Welcome(msg) {
- return msg
;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/private.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/private.js
deleted file mode 100644
index 0bab959ec61..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/private.js
+++ /dev/null
@@ -1,3 +0,0 @@
-class C {
- #foo = 42;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/typescript.ts b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/typescript.ts
deleted file mode 100644
index da783848ebd..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/typescript.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-type T = number | string;
-
-function f(t: T): number {
- return t as number;
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/vue.vue b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/vue.vue
deleted file mode 100644
index ec1434af120..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/eslint/vue.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/options/file.ts b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/options/file.ts
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/options/tsconfig.json b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/options/tsconfig.json
deleted file mode 100644
index ad6a43ea096..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/options/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["file.ts"]
-}
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/invalid.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/invalid.js
deleted file mode 100644
index 4b2fea867a2..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/invalid.js
+++ /dev/null
@@ -1 +0,0 @@
-'hello
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/valid.js b/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/valid.js
deleted file mode 100644
index 318c0272911..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/fixtures/parse/valid.js
+++ /dev/null
@@ -1 +0,0 @@
-'howdy';
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/options.test.ts b/eslint-bridge/tests/parsing/jsts/parsers/options.test.ts
deleted file mode 100644
index a0ecc974cf1..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/options.test.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { buildParserOptions } from 'parsing/jsts';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { createProgram, getProgramById } from 'services/program';
-import path from 'path';
-
-describe('buildParserOptions', () => {
- it('should build parser options', () => {
- const filePath = '/tmp/dir';
- const input = { filePath } as JsTsAnalysisInput;
- const usingBabel = false;
- const parserOption = '/some/parser';
- const sourceType = 'module';
- expect(buildParserOptions(input, usingBabel, parserOption, sourceType)).toEqual({
- tokens: true,
- comment: true,
- loc: true,
- range: true,
- ecmaVersion: 2018,
- sourceType,
- codeFrame: false,
- ecmaFeatures: {
- jsx: true,
- globalReturn: false,
- legacyDecorators: true,
- },
- extraFileExtensions: ['.vue'],
- parser: parserOption,
- filePath: input.filePath,
- project: undefined,
- programs: undefined,
- });
- });
-
- it('should include Babel parser options', () => {
- const filePath = '/tmp/dir';
- const input = { filePath } as JsTsAnalysisInput;
- const usingBabel = true;
- const parserOptions = buildParserOptions(input, usingBabel);
- expect(parserOptions).toEqual(
- expect.objectContaining({
- requireConfigFile: false,
- }),
- );
- expect(parserOptions.babelOptions).toEqual(
- expect.objectContaining({
- babelrc: false,
- configFile: false,
- }),
- );
- });
-
- it('should build parser options with TSConfig', () => {
- const tsConfigs = ['/some/tsconfig'];
- const filePath = '/tmp/dir';
- const input = { filePath, tsConfigs: tsConfigs } as JsTsAnalysisInput;
- expect(buildParserOptions(input)).toEqual(
- expect.objectContaining({
- project: tsConfigs,
- }),
- );
- });
-
- it('should build parser options with TypeScript program', async () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'options', 'tsconfig.json');
-
- const { programId } = await createProgram(tsConfig);
- const program = getProgramById(programId);
-
- const filePath = '/tmp/dir';
- const input = { filePath, programId } as JsTsAnalysisInput;
- expect(buildParserOptions(input)).toEqual(
- expect.objectContaining({
- programs: [program],
- }),
- );
- });
-});
diff --git a/eslint-bridge/tests/parsing/jsts/parsers/parse.test.ts b/eslint-bridge/tests/parsing/jsts/parsers/parse.test.ts
deleted file mode 100644
index e43d2b2f842..00000000000
--- a/eslint-bridge/tests/parsing/jsts/parsers/parse.test.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { APIError } from 'errors';
-import { SourceCode } from 'eslint';
-import { buildParserOptions, parseForESLint, parsers } from 'parsing/jsts';
-import path from 'path';
-import { JsTsAnalysisInput } from 'services/analysis';
-import { readFile } from 'helpers';
-
-const parseFunctions = [
- {
- parser: parsers.javascript,
- usingBabel: true,
- errorMessage: 'Unterminated string constant. (1:0)',
- },
- { parser: parsers.typescript, usingBabel: false, errorMessage: 'Unterminated string literal.' },
-];
-
-describe('parseForESLint', () => {
- test.each(parseFunctions)(
- 'should parse a valid input with $parser.parser',
- async ({ parser, usingBabel }) => {
- const filePath = path.join(__dirname, 'fixtures', 'parse', 'valid.js');
- const fileContent = await readFile(filePath);
- const fileType = 'MAIN';
-
- const input = { filePath, fileType, fileContent } as JsTsAnalysisInput;
- const options = buildParserOptions(input, usingBabel);
- const sourceCode = parseForESLint(fileContent, parser.parse, options) as SourceCode;
-
- expect(sourceCode).toBeDefined();
- expect(sourceCode.ast).toBeDefined();
- },
- );
-
- test.each(parseFunctions)(
- 'should parse a valid input with $parser.parser',
- ({ parser, usingBabel }) => {
- const fileContent = 'if (foo()) bar();';
- const fileType = 'MAIN';
-
- const input = { fileContent, fileType } as JsTsAnalysisInput;
- const options = buildParserOptions(input, usingBabel);
- const sourceCode = parseForESLint(fileContent, parser.parse, options) as SourceCode;
-
- expect(sourceCode).toBeDefined();
- expect(sourceCode.ast).toBeDefined();
- },
- );
-
- test.each(parseFunctions)(
- 'should fail parsing an invalid input with $parser.parser',
- async ({ parser, usingBabel, errorMessage }) => {
- const filePath = path.join(__dirname, 'fixtures', 'parse', 'invalid.js');
- const fileContent = await readFile(filePath);
- const fileType = 'MAIN';
-
- const input = { filePath, fileType, fileContent } as JsTsAnalysisInput;
- const options = buildParserOptions(input, usingBabel);
-
- expect(() => parseForESLint(fileContent, parser.parse, options)).toThrow(
- APIError.parsingError(errorMessage, { line: 1 }),
- );
- },
- );
-});
diff --git a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/invalid.yaml b/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/invalid.yaml
deleted file mode 100644
index 6142d193da1..00000000000
--- a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/invalid.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "
diff --git a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/resource-names.yaml b/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/resource-names.yaml
deleted file mode 100644
index b65ef60a4c7..00000000000
--- a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/resource-names.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: console.log("hello")
- SomeServerlessFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: console.log("there")
-
diff --git a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/valid.yaml b/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/valid.yaml
deleted file mode 100644
index 35dee18ef65..00000000000
--- a/eslint-bridge/tests/parsing/yaml/aws/fixtures/parser/valid.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
- someProp: hello there
diff --git a/eslint-bridge/tests/parsing/yaml/aws/parser.test.ts b/eslint-bridge/tests/parsing/yaml/aws/parser.test.ts
deleted file mode 100644
index 79061786b6e..00000000000
--- a/eslint-bridge/tests/parsing/yaml/aws/parser.test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { parseAwsFromYaml } from 'parsing/yaml';
-import { APIError } from 'errors';
-import { readFile } from 'helpers';
-
-describe('parseAwsFromYaml()', () => {
- it('should parse valid YAML syntax', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'parser', 'valid.yaml');
- const fileContent = await readFile(filePath);
- const embedded = parseAwsFromYaml(fileContent);
- expect(embedded).toBeDefined();
- expect(embedded).toHaveLength(1);
- expect(embedded[0]).toEqual(
- expect.objectContaining({
- code: `if (foo()) bar(); else bar();`,
- line: 8,
- column: 18,
- offset: 177,
- }),
- );
- });
-
- it('should extract the resource name', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'parser', 'resource-names.yaml');
- const fileContent = await readFile(filePath);
- const [firstEmbedded, secondEmbedded] = parseAwsFromYaml(fileContent);
- expect(firstEmbedded).toEqual(
- expect.objectContaining({
- extras: {
- resourceName: 'SomeLambdaFunction',
- },
- }),
- );
- expect(secondEmbedded).toEqual(
- expect.objectContaining({
- extras: {
- resourceName: 'SomeServerlessFunction',
- },
- }),
- );
- });
-
- it('should fail parsing invalid YAML syntax', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'parser', 'invalid.yaml');
- const fileContent = await readFile(filePath);
- expect(() => parseAwsFromYaml(fileContent)).toThrow(
- APIError.parsingError('Missing closing "quote', { line: 7 }),
- );
- });
-});
diff --git a/eslint-bridge/tests/parsing/yaml/builder/build.test.ts b/eslint-bridge/tests/parsing/yaml/builder/build.test.ts
deleted file mode 100644
index b150e5b3ca8..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/build.test.ts
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { join } from 'path';
-import { buildSourceCodes, composeSyntheticFilePath } from 'parsing/yaml';
-import { APIError } from 'errors';
-import { yamlInput } from '../../../tools';
-
-describe('buildSourceCodes()', () => {
- const fixturesPath = join(__dirname, 'fixtures', 'build');
- it('should build source code from YAML lambda file', async () => {
- const filePath = join(fixturesPath, 'valid-lambda.yaml');
- const sourceCodes = buildSourceCodes(await yamlInput({ filePath }));
- expect(sourceCodes).toHaveLength(1);
- expect(sourceCodes[0].ast.loc.start).toEqual({ line: 8, column: 17 });
- });
-
- it('should build source code from YAML serverless file', async () => {
- const filePath = join(fixturesPath, 'valid-serverless.yaml');
- const sourceCodes = buildSourceCodes(await yamlInput({ filePath }));
- expect(sourceCodes).toHaveLength(1);
- expect(sourceCodes[0].ast.loc.start).toEqual({ line: 7, column: 18 });
- });
-
- it('should return YAML parsing errors on invalid YAML file', async () => {
- const analysisInput = await yamlInput({ filePath: join(fixturesPath, 'malformed.yaml') });
- expect(() => buildSourceCodes(analysisInput)).toThrow(
- APIError.parsingError('Map keys must be unique', { line: 2 }),
- );
- });
-
- it('should return a parsing error on invalid plain inline JS', async () => {
- const analysisInput = await yamlInput({
- filePath: join(fixturesPath, 'invalid-plain-inline-js.yaml'),
- });
- expect(() => buildSourceCodes(analysisInput)).toThrow(
- APIError.parsingError(`Unexpected token ','. (7:22)`, { line: 7 }),
- );
- });
-
- it('should return a parsing error on invalid block inline JS', async () => {
- const analysisInput = await yamlInput({
- filePath: join(fixturesPath, 'invalid-block-inline-js.yaml'),
- });
- expect(() => buildSourceCodes(analysisInput)).toThrow(
- APIError.parsingError(`Unexpected token ','. (8:15)`, { line: 8 }),
- );
- });
-
- it('it should not build a source code for an unsupported format', async () => {
- const filePath = join(fixturesPath, 'unsupported-format.yaml');
- const sourceCodes = buildSourceCodes(await yamlInput({ filePath }));
- expect(sourceCodes).toHaveLength(0);
- });
-
- it('should fix plain-based format locations', async () => {
- const filePath = join(fixturesPath, 'flow-plain.yaml');
- const [{ ast }] = buildSourceCodes(await yamlInput({ filePath }));
-
- const {
- body: [ifStmt],
- } = ast;
- expect(ifStmt.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 7,
- column: 18,
- },
- end: {
- line: 7,
- column: 67,
- },
- }),
- );
- expect(ifStmt.range).toEqual([170, 219]);
-
- const { alternate } = ifStmt as estree.IfStatement;
- expect(alternate.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 7,
- column: 57,
- },
- end: {
- line: 7,
- column: 67,
- },
- }),
- );
- expect(alternate.range).toEqual([209, 219]);
-
- const {
- comments: [comment],
- } = ast;
- expect(comment.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 7,
- column: 38,
- },
- end: {
- line: 7,
- column: 49,
- },
- }),
- );
- expect(comment.range).toEqual([190, 201]);
-
- const elseToken = ast.tokens.find(token => token.value === 'else');
- expect(elseToken.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 7,
- column: 52,
- },
- end: {
- line: 7,
- column: 56,
- },
- }),
- );
- expect(elseToken.range).toEqual([204, 208]);
- });
-
- it('should fix block-folded-based format locations', async () => {
- const filePath = join(fixturesPath, 'block-folded.yaml');
- const [{ ast }] = buildSourceCodes(await yamlInput({ filePath }));
- const {
- body: [ifStmt],
- } = ast;
- expect(ifStmt.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 8,
- column: 8,
- },
- end: {
- line: 12,
- column: 9,
- },
- }),
- );
- expect(ifStmt.range).toEqual([180, 265]);
-
- const { alternate } = ifStmt as estree.IfStatement;
- expect(alternate.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 10,
- column: 15,
- },
- end: {
- line: 12,
- column: 9,
- },
- }),
- );
- expect(alternate.range).toEqual([237, 265]);
-
- const {
- comments: [comment],
- } = ast;
- expect(comment.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 9,
- column: 17,
- },
- end: {
- line: 9,
- column: 28,
- },
- }),
- );
- expect(comment.range).toEqual([210, 221]);
-
- const elseToken = ast.tokens.find(token => token.value === 'else');
- expect(elseToken.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 10,
- column: 10,
- },
- end: {
- line: 10,
- column: 14,
- },
- }),
- );
- expect(elseToken.range).toEqual([232, 236]);
- });
-
- it('should fix block-literal-based format locations', async () => {
- const filePath = join(fixturesPath, 'block-literal.yaml');
- const [{ ast }] = buildSourceCodes(await yamlInput({ filePath }));
- const {
- body: [ifStmt],
- } = ast;
- expect(ifStmt.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 8,
- column: 8,
- },
- end: {
- line: 12,
- column: 9,
- },
- }),
- );
- expect(ifStmt.range).toEqual([180, 265]);
-
- const { alternate } = ifStmt as estree.IfStatement;
- expect(alternate.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 10,
- column: 15,
- },
- end: {
- line: 12,
- column: 9,
- },
- }),
- );
- expect(alternate.range).toEqual([237, 265]);
-
- const {
- comments: [comment],
- } = ast;
- expect(comment.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 9,
- column: 17,
- },
- end: {
- line: 9,
- column: 28,
- },
- }),
- );
- expect(comment.range).toEqual([210, 221]);
-
- const elseToken = ast.tokens.find(token => token.value === 'else');
- expect(elseToken.loc).toEqual(
- expect.objectContaining({
- start: {
- line: 10,
- column: 10,
- },
- end: {
- line: 10,
- column: 14,
- },
- }),
- );
- expect(elseToken.range).toEqual([232, 236]);
- });
-
- it('should compose a synthetic file path', async () => {
- const filePath = join(fixturesPath, 'synthetic-filename.yaml');
- const [firstExtendedSourceCode, secondExtendedSourceCode] = buildSourceCodes(
- await yamlInput({ filePath }),
- );
- const firstFunctionName = composeSyntheticFilePath(filePath, 'SomeLambdaFunction');
- const secondFunctionName = composeSyntheticFilePath(filePath, 'SomeServerlessFunction');
- expect(firstExtendedSourceCode.syntheticFilePath).toEqual(firstFunctionName);
- expect(secondExtendedSourceCode.syntheticFilePath).toEqual(secondFunctionName);
- });
-});
-
-describe('composeSyntheticFilePath()', () => {
- it('should append the function name at the end of the filename, before the extension', () => {
- const composedFilename = composeSyntheticFilePath('hello.yaml', 'there');
- expect(composedFilename).toEqual('hello-there.yaml');
- });
-});
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-folded.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-folded.yaml
deleted file mode 100644
index 373e0c90d09..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-folded.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- if (foo()) {
- bar(); /* howdy */
- } else {
- bar();
- }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-literal.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-literal.yaml
deleted file mode 100644
index a88d6c6d61c..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/block-literal.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: |
- if (foo()) {
- bar(); /* howdy */
- } else {
- bar();
- }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/flow-plain.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/flow-plain.yaml
deleted file mode 100644
index 8e46ddcc917..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/flow-plain.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: if (foo()) { bar(); /* howdy */ } else { bar(); }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-block-inline-js.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-block-inline-js.yaml
deleted file mode 100644
index da5891a8db2..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-block-inline-js.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Code:
- ZipFile: >
- foo(,)
- Runtime: "nodejs16.0"
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-plain-inline-js.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-plain-inline-js.yaml
deleted file mode 100644
index bc68845d7ae..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/invalid-plain-inline-js.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Code:
- ZipFile: foo(,)
- Runtime: "nodejs16.0"
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/malformed.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/malformed.yaml
deleted file mode 100644
index 571459324d5..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/malformed.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-a: 1st
-a: duplicate key 'a' should throw an error at parsing on line 2
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/synthetic-filename.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/synthetic-filename.yaml
deleted file mode 100644
index b65ef60a4c7..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/synthetic-filename.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: console.log("hello")
- SomeServerlessFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: console.log("there")
-
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/unsupported-format.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/unsupported-format.yaml
deleted file mode 100644
index 980aa6a38fd..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/unsupported-format.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile:
- Fn::Sub: |
- console.log('unsupported format');
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-lambda.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-lambda.yaml
deleted file mode 100644
index d94e3c71a38..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-lambda.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
- someProp: hello there
- Description: "The branch duplication should be reported at 14:53"
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-serverless.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-serverless.yaml
deleted file mode 100644
index a12b7ab3093..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/build/valid-serverless.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: if (foo()) bar(); else bar();
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.js b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.js
deleted file mode 100644
index ee937f3ad80..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.js
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
- if (foo)
- bar;
- else
- baz;
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.yaml
deleted file mode 100644
index b89b09e6535..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/body.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- if (foo)
- bar;
- else
- baz;
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.js b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.js
deleted file mode 100644
index b70d755cb86..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.js
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
- /**
- * header comment
- */
-
- // one-line comment
-
- /*
- multi-line comment
- */
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.yaml
deleted file mode 100644
index 43b87663bc0..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/comments.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- /**
- * header comment
- */
-
- // one-line comment
-
- /*
- multi-line comment
- */
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.js b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.js
deleted file mode 100644
index d344d44a7ef..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.js
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
- if (foo
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.yaml
deleted file mode 100644
index 07eb1a2edc2..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/parsing-error.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- if (foo
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/source-code.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/source-code.yaml
deleted file mode 100644
index 2440acac854..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/source-code.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- function f(g, x) {
- return g(x);
- }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.js b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.js
deleted file mode 100644
index 966e144353c..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.js
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
- while (true)
- {
- ;
- }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.yaml b/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.yaml
deleted file mode 100644
index bcd673a7857..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/fixtures/patch/tokens.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- while (true)
- {
- ;
- }
diff --git a/eslint-bridge/tests/parsing/yaml/builder/patch.test.ts b/eslint-bridge/tests/parsing/yaml/builder/patch.test.ts
deleted file mode 100644
index 393023c0e82..00000000000
--- a/eslint-bridge/tests/parsing/yaml/builder/patch.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { readFile, setContext } from 'helpers';
-import { buildSourceCode } from 'parsing/jsts';
-import { buildSourceCodes, EmbeddedJS, patchParsingErrorMessage } from 'parsing/yaml';
-import { JsTsAnalysisInput, YamlAnalysisInput } from 'services/analysis';
-
-describe('patchSourceCode', () => {
- beforeAll(() => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- });
- });
-
- it('should patch source code', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'patch', 'source-code.yaml');
- const text = await readFile(filePath);
- const [patchedSourceCode] = buildSourceCodes({
- filePath,
- fileContent: text,
- } as YamlAnalysisInput);
- expect(patchedSourceCode).toEqual(
- expect.objectContaining({
- text,
- lineStartIndices: [0, 37, 48, 70, 108, 124, 152, 172, 199, 222, 232],
- lines: [
- 'AWSTemplateFormatVersion: 2010-09-09',
- 'Resources:',
- ' SomeLambdaFunction:',
- ' Type: "AWS::Serverless::Function"',
- ' Properties:',
- ' Runtime: "nodejs16.0"',
- ' InlineCode: >',
- ' function f(g, x) {',
- ' return g(x);',
- ' }',
- '',
- ],
- }),
- );
- });
-
- test.each(['body', 'tokens', 'comments'])('should patch ast %s', async property => {
- const fixture = path.join(__dirname, 'fixtures', 'patch', property);
-
- let filePath = `${fixture}.yaml`;
- let fileContent = await readFile(filePath);
- const [patchedSourceCode] = buildSourceCodes({ filePath, fileContent } as YamlAnalysisInput);
- const patchedNodes = patchedSourceCode.ast[property];
-
- filePath = `${fixture}.js`;
- fileContent = await readFile(filePath);
- const input = { filePath, fileContent } as JsTsAnalysisInput;
- const referenceSourceCode = buildSourceCode(input, 'js');
- const referenceNodes = referenceSourceCode.ast[property];
-
- expect(patchedNodes).toEqual(referenceNodes);
- });
-
- it('should patch parsing errors', async () => {
- const fixture = path.join(__dirname, 'fixtures', 'patch', 'parsing-error');
-
- let filePath = `${fixture}.yaml`;
- let fileContent = await readFile(filePath);
- let patchedParsingError;
- try {
- buildSourceCodes({ filePath, fileContent } as YamlAnalysisInput);
- } catch (error) {
- patchedParsingError = error;
- }
-
- filePath = `${fixture}.js`;
- fileContent = await readFile(filePath);
- const input = { filePath, fileContent } as JsTsAnalysisInput;
- expect(() => buildSourceCode(input, 'js')).toThrow(patchedParsingError);
- });
-
- it('should patch parsing error messages', () => {
- const message = `Unexpected parsing error`;
- const patchedLine = 3;
- const embeddedJS = { code: 'f(x', line: 4, column: 10, format: 'PLAIN' } as EmbeddedJS;
- const patchedMessage = patchParsingErrorMessage(message, patchedLine, embeddedJS);
- expect(patchedMessage).toEqual(`Unexpected parsing error`);
- });
-});
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_FOLDED.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_FOLDED.yaml
deleted file mode 100644
index 023b5951363..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_FOLDED.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-folded: >
- Hello, world
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_LITERAL.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_LITERAL.yaml
deleted file mode 100644
index 750a99a054b..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/BLOCK_LITERAL.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-literal: |
- Hello, world
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/PLAIN.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/PLAIN.yaml
deleted file mode 100644
index 8f2a4e2a0ff..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/PLAIN.yaml
+++ /dev/null
@@ -1 +0,0 @@
-plain: Hello, world!
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/unsupported.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/unsupported.yaml
deleted file mode 100644
index 3c96029b136..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/format/unsupported.yaml
+++ /dev/null
@@ -1 +0,0 @@
-unsupported: 'Hello, world!'
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/embedded.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/embedded.yaml
deleted file mode 100644
index 95dd4358d5e..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/embedded.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-foo:
- embedded: f(x)
-bar:
- embbeded: g(y)
diff --git a/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/error.yaml b/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/error.yaml
deleted file mode 100644
index ed7c0b4ad74..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/fixtures/parse/error.yaml
+++ /dev/null
@@ -1 +0,0 @@
-malformed: "Hello, world
diff --git a/eslint-bridge/tests/parsing/yaml/parser/format.test.ts b/eslint-bridge/tests/parsing/yaml/parser/format.test.ts
deleted file mode 100644
index 3c36ce0cc6e..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/format.test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as yaml from 'yaml';
-import path from 'path';
-import { readFile } from 'helpers';
-import { isSupportedFormat, SUPPORTED_STRING_FORMATS } from 'parsing/yaml';
-
-describe('isSupportedFormat', () => {
- const fixtures = path.join(__dirname, 'fixtures', 'format');
-
- test.each(SUPPORTED_STRING_FORMATS)('should support the string format %o', async format => {
- const filePath = path.join(fixtures, `${format}.yaml`);
- const fileContents = await readFile(filePath);
- const tokens = new yaml.Parser().parse(fileContents);
- const [doc] = new yaml.Composer().compose(tokens);
- const {
- contents: {
- items: [pair],
- },
- } = doc as any;
- expect(isSupportedFormat(pair)).toBeTruthy();
- });
-
- it('should not support an unsupported string format', async () => {
- const filePath = path.join(fixtures, 'unsupported.yaml');
- const fileContents = await readFile(filePath);
- const tokens = new yaml.Parser().parse(fileContents);
- const [doc] = new yaml.Composer().compose(tokens);
- const {
- contents: {
- items: [pair],
- },
- } = doc as any;
- expect(isSupportedFormat(pair)).toBeFalsy();
- });
-});
diff --git a/eslint-bridge/tests/parsing/yaml/parser/parse.test.ts b/eslint-bridge/tests/parsing/yaml/parser/parse.test.ts
deleted file mode 100644
index 812a17de8b9..00000000000
--- a/eslint-bridge/tests/parsing/yaml/parser/parse.test.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { parseYaml } from 'parsing/yaml';
-import { APIError } from 'errors';
-import { readFile } from 'helpers';
-
-function noOpPicker(_key: any, _node: any, _ancestors: any) {
- return {};
-}
-
-describe('parseYaml', () => {
- it('should return embedded JavaScript', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'parse', 'embedded.yaml');
- const fileContent = await readFile(filePath);
- const parsingContexts = [
- {
- predicate: (_key: any, node: any, _ancestors: any) => node.key.value === 'embedded',
- picker: noOpPicker,
- },
- ];
- const [embedded] = parseYaml(parsingContexts, fileContent);
- expect(embedded).toEqual(
- expect.objectContaining({
- code: 'f(x)',
- line: 2,
- column: 13,
- offset: 17,
- lineStarts: [0, 5, 22, 27, 44],
- text: fileContent,
- }),
- );
- });
-
- it('should return parsing errors', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'parse', 'error.yaml');
- const fileContent = await readFile(filePath);
- const parsingContexts = [
- {
- predicate: (_key: any, _node: any, _ancestors: any) => false,
- picker: noOpPicker,
- },
- ];
- expect(() => parseYaml(parsingContexts, fileContent)).toThrow(
- APIError.parsingError('Missing closing "quote', { line: 2 }),
- );
- });
-});
diff --git a/eslint-bridge/tests/routing/errors/middleware.test.ts b/eslint-bridge/tests/routing/errors/middleware.test.ts
deleted file mode 100644
index 2ac4516c68b..00000000000
--- a/eslint-bridge/tests/routing/errors/middleware.test.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { ErrorCode, APIError } from 'errors';
-import * as express from 'express';
-import { EMPTY_JSTS_ANALYSIS_OUTPUT, errorMiddleware } from 'routing/errors';
-
-describe('errorMiddleware', () => {
- const mockRequest = {} as express.Request;
- const mockNext = {} as express.NextFunction;
-
- let mockResponse: Partial;
- beforeEach(() => {
- mockResponse = {
- json: jest.fn(),
- };
- });
-
- it('should return empty JS/TS analysis properties and a complete parsingError for PARSING errors', () => {
- errorMiddleware(
- APIError.parsingError('Unexpected token "{"', { line: 42 }),
- mockRequest,
- mockResponse as express.Response,
- mockNext,
- );
- expect(mockResponse.json).toBeCalledWith({
- parsingError: {
- message: 'Unexpected token "{"',
- line: 42,
- code: ErrorCode.Parsing,
- },
- ...EMPTY_JSTS_ANALYSIS_OUTPUT,
- });
- });
-
- it('should return a parsingError with properties "message" and "code" for FAILING_TYPESCRIPT errors', () => {
- errorMiddleware(
- APIError.failingTypeScriptError('TypeScript failed for some reason'),
- mockRequest,
- mockResponse as express.Response,
- mockNext,
- );
- expect(mockResponse.json).toBeCalledWith({
- parsingError: {
- message: 'TypeScript failed for some reason',
- code: ErrorCode.FailingTypeScript,
- },
- });
- });
-
- it('should return a parsingError with properties "message" and "code" for LINTER_INITIALIZATION errors', () => {
- errorMiddleware(
- APIError.linterError('Uninitialized linter'),
- mockRequest,
- mockResponse as express.Response,
- mockNext,
- );
- expect(mockResponse.json).toBeCalledWith({
- parsingError: {
- message: 'Uninitialized linter',
- code: ErrorCode.LinterInitialization,
- },
- });
- });
-
- it('should return a propery "error" containing the error message for any other error', () => {
- errorMiddleware(
- new Error('Something unexpected happened.'),
- mockRequest,
- mockResponse as express.Response,
- mockNext,
- );
- expect(mockResponse.json).toBeCalledWith({
- error: 'Something unexpected happened.',
- });
- });
-});
diff --git a/eslint-bridge/tests/routing/fixtures/file.css b/eslint-bridge/tests/routing/fixtures/file.css
deleted file mode 100644
index e6532db8e53..00000000000
--- a/eslint-bridge/tests/routing/fixtures/file.css
+++ /dev/null
@@ -1 +0,0 @@
-.p { width: calc(100% 80px); }
diff --git a/eslint-bridge/tests/routing/fixtures/file.js b/eslint-bridge/tests/routing/fixtures/file.js
deleted file mode 100644
index 244ab2a4d06..00000000000
--- a/eslint-bridge/tests/routing/fixtures/file.js
+++ /dev/null
@@ -1 +0,0 @@
-new RegExp('foo');
diff --git a/eslint-bridge/tests/routing/fixtures/file.ts b/eslint-bridge/tests/routing/fixtures/file.ts
deleted file mode 100644
index 1b421e93a2c..00000000000
--- a/eslint-bridge/tests/routing/fixtures/file.ts
+++ /dev/null
@@ -1 +0,0 @@
-type T = boolean | number | boolean;
diff --git a/eslint-bridge/tests/routing/fixtures/file.yaml b/eslint-bridge/tests/routing/fixtures/file.yaml
deleted file mode 100644
index 35dee18ef65..00000000000
--- a/eslint-bridge/tests/routing/fixtures/file.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
- someProp: hello there
diff --git a/eslint-bridge/tests/routing/fixtures/malformed.json b/eslint-bridge/tests/routing/fixtures/malformed.json
deleted file mode 100644
index 15f0db89bfd..00000000000
--- a/eslint-bridge/tests/routing/fixtures/malformed.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "include": [
- "./*.ts",
diff --git a/eslint-bridge/tests/routing/fixtures/parsing-error.js b/eslint-bridge/tests/routing/fixtures/parsing-error.js
deleted file mode 100644
index cf23d4feba2..00000000000
--- a/eslint-bridge/tests/routing/fixtures/parsing-error.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function f() {
- return;
diff --git a/eslint-bridge/tests/routing/fixtures/tsconfig.json b/eslint-bridge/tests/routing/fixtures/tsconfig.json
deleted file mode 100644
index 510057577f6..00000000000
--- a/eslint-bridge/tests/routing/fixtures/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "include": [
- "./*.ts",
- ]
-}
diff --git a/eslint-bridge/tests/routing/routing.test.ts b/eslint-bridge/tests/routing/routing.test.ts
deleted file mode 100644
index b728dcc58fa..00000000000
--- a/eslint-bridge/tests/routing/routing.test.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { setContext, toUnixPath } from 'helpers';
-import http from 'http';
-import { initializeLinter } from 'linting/eslint';
-import path from 'path';
-import { start } from 'server';
-import { createProgram } from 'services/program';
-import { promisify } from 'util';
-import { request } from '../tools';
-import * as fs from 'fs';
-
-describe('router', () => {
- const port = 0;
-
- let server: http.Server;
- let close: () => Promise;
-
- beforeEach(async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- });
- jest.setTimeout(60 * 1000);
- server = await start(port, '127.0.0.1', 60 * 60 * 1000);
- close = promisify(server.close.bind(server));
- });
-
- afterEach(async () => {
- await close();
- });
-
- it('should route /analyze-css requests', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'file.css');
- const rules = [{ key: 'function-calc-no-invalid', configurations: [] }];
- const data = { filePath, rules };
- const response = (await request(server, '/analyze-css', 'POST', data)) as string;
- expect(JSON.parse(response)).toEqual({
- issues: [
- {
- ruleId: 'function-calc-no-invalid',
- line: 1,
- column: 6,
- message: `Fix this malformed 'calc' expression.`,
- },
- ],
- });
- });
-
- it('should route /analyze-js requests', async () => {
- initializeLinter([
- { key: 'prefer-regex-literals', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const filePath = path.join(__dirname, 'fixtures', 'file.js');
- const fileType = 'MAIN';
- const data = { filePath, fileType, tsConfigs: [] };
- const response = (await request(server, '/analyze-js', 'POST', data)) as string;
- const {
- issues: [issue],
- } = JSON.parse(response);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'prefer-regex-literals',
- line: 1,
- column: 0,
- endLine: 1,
- endColumn: 17,
- message: `Use a regular expression literal instead of the 'RegExp' constructor.`,
- }),
- );
- });
-
- it('should route /analyze-ts requests', async () => {
- initializeLinter([
- { key: 'no-duplicate-in-composite', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const filePath = path.join(__dirname, 'fixtures', 'file.ts');
- const fileType = 'MAIN';
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const data = { filePath, fileType, tsConfigs: [tsConfig] };
- const response = (await request(server, '/analyze-ts', 'POST', data)) as string;
- const {
- issues: [issue],
- } = JSON.parse(response);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-duplicate-in-composite',
- line: 1,
- column: 28,
- endLine: 1,
- endColumn: 35,
- message: `Remove this duplicated type or replace with another one.`,
- }),
- );
- });
-
- it('should route /analyze-with-program requests', async () => {
- initializeLinter([
- { key: 'no-duplicate-in-composite', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const filePath = path.join(__dirname, 'fixtures', 'file.ts');
- const fileType = 'MAIN';
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const { programId } = await createProgram(tsConfig);
- const data = { filePath, fileType, programId };
- const response = (await request(server, '/analyze-with-program', 'POST', data)) as string;
- const {
- issues: [issue],
- } = JSON.parse(response);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-duplicate-in-composite',
- line: 1,
- column: 28,
- endLine: 1,
- endColumn: 35,
- message: `Remove this duplicated type or replace with another one.`,
- }),
- );
- });
-
- it('should route /analyze-yaml requests', async () => {
- initializeLinter([
- { key: 'no-all-duplicated-branches', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const filePath = path.join(__dirname, 'fixtures', 'file.yaml');
- const data = { filePath };
- const response = (await request(server, '/analyze-yaml', 'POST', data)) as string;
- const {
- issues: [issue],
- } = JSON.parse(response);
- expect(issue).toEqual({
- ruleId: 'no-all-duplicated-branches',
- line: 8,
- column: 17,
- endLine: 8,
- endColumn: 46,
- message:
- "Remove this conditional structure or edit its code blocks so that they're not all the same.",
- quickFixes: [],
- secondaryLocations: [],
- });
- });
-
- it('should route /create-program requests', async () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const data = { tsConfig };
- const response = (await request(server, '/create-program', 'POST', data)) as string;
- const programId = Number(JSON.parse(response).programId);
- expect(programId).toBeDefined();
- expect(programId).toBeGreaterThan(0);
- });
-
- it('should forward /create-program failures', async () => {
- console.error = jest.fn();
- const tsConfig = path.join(__dirname, 'fixtures', 'malformed.json');
- const data = { tsConfig };
- const response = (await request(server, '/create-program', 'POST', data)) as string;
- const { error } = JSON.parse(response);
- expect(error).toBeDefined();
- expect(console.error).toHaveBeenCalled();
- });
-
- it('should route /delete-program requests', async () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const { programId } = await createProgram(tsConfig);
- const data = { programId };
- const response = (await request(server, '/delete-program', 'POST', data)) as string;
- expect(response).toEqual('OK!');
- });
-
- it('should route /init-linter requests', async () => {
- const data = { rules: [], environments: [], globals: [] };
- const response = await request(server, '/init-linter', 'POST', data);
- expect(response).toEqual('OK!');
- });
-
- it('should route /new-tsconfig requests', async () => {
- /**
- * There is no easy way to test that a module was unloaded, because jest is modifying require calls for tests
- * @see https://github.com/facebook/jest/issues/6725
- */
- const data = {};
- const response = await request(server, '/new-tsconfig', 'POST', data);
- expect(response).toEqual('OK!');
- });
-
- it('should route /status requests', async () => {
- const response = await request(server, '/status', 'GET');
- expect(response).toEqual('OK!');
- });
-
- it('should route /tsconfig-files requests', async () => {
- const tsconfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const data = { tsconfig };
- const response = (await request(server, '/tsconfig-files', 'POST', data)) as string;
- expect(JSON.parse(response)).toEqual({
- files: [toUnixPath(path.join(__dirname, 'fixtures', 'file.ts'))],
- projectReferences: [],
- });
- });
-
- it('should forward /tsconfig-files failures', async () => {
- console.error = jest.fn();
- const tsConfig = path.join(__dirname, 'fixtures', 'malformed.json');
- const data = { tsConfig };
- const response = (await request(server, '/tsconfig-files', 'POST', data)) as string;
- const { error } = JSON.parse(response);
- expect(error).toEqual('Debug Failure.');
- expect(console.error).toHaveBeenCalled();
- });
-
- it('should write tsconfig.json file', async () => {
- const response = (await request(server, '/create-tsconfig-file', 'POST', {
- include: ['/path/to/project/**/*'],
- })) as string;
- const json = JSON.parse(response);
- expect(json).toBeTruthy();
- expect(json.filename).toBeTruthy();
- expect(fs.existsSync(json.filename)).toBe(true);
- });
-});
diff --git a/eslint-bridge/tests/routing/timeout/timeout.test.ts b/eslint-bridge/tests/routing/timeout/timeout.test.ts
deleted file mode 100644
index 98fac2a3304..00000000000
--- a/eslint-bridge/tests/routing/timeout/timeout.test.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import Timeout from 'routing/timeout/timeout';
-
-describe('timeout', () => {
- it('should start the timeout', () => {
- expect.assertions(1);
-
- jest.useFakeTimers();
-
- const fn = jest.fn();
- const timeout = new Timeout(fn, 0);
- timeout.start();
-
- jest.advanceTimersByTime(1);
-
- expect(fn).toHaveBeenCalled();
- });
-
- it('should stop the timeout', () => {
- expect.assertions(1);
-
- const fn = jest.fn();
- const timeout = new Timeout(fn, 10_000);
- timeout.start();
- timeout.stop();
-
- expect(fn).toHaveBeenCalledTimes(0);
- });
-});
diff --git a/eslint-bridge/tests/server.test.ts b/eslint-bridge/tests/server.test.ts
deleted file mode 100644
index 7612b29c3e5..00000000000
--- a/eslint-bridge/tests/server.test.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { start } from 'server';
-import { promisify } from 'util';
-import path from 'path';
-import { setContext } from 'helpers';
-import { AddressInfo } from 'net';
-import { request } from './tools';
-import http from 'http';
-
-describe('server', () => {
- const port = 0;
-
- beforeAll(() => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: [],
- });
- });
-
- it('should start', async () => {
- expect.assertions(4);
-
- console.log = jest.fn();
-
- const server = await start(undefined, undefined);
- const close = promisify(server.close.bind(server));
-
- expect(server.listening).toBeTruthy();
- expect(console.log).toHaveBeenCalledTimes(2);
- expect(console.log).toHaveBeenNthCalledWith(
- 1,
- `DEBUG starting eslint-bridge server at port ${port}`,
- );
- expect(console.log).toHaveBeenNthCalledWith(
- 2,
- `DEBUG eslint-bridge server is running at port ${(server.address() as AddressInfo)?.port}`,
- );
-
- await close();
- });
-
- it('should fail when linter is not initialized', async () => {
- expect.assertions(3);
-
- const server = await start(port);
- const close = promisify(server.close.bind(server));
-
- const ruleId = 'no-extra-semi';
- const fileType = 'MAIN';
-
- expect(JSON.parse(await requestAnalyzeJs(server, fileType))).toStrictEqual({
- parsingError: {
- code: 'LINTER_INITIALIZATION',
- message: 'Linter default does not exist. Did you call /init-linter?',
- },
- });
-
- expect(await requestInitLinter(server, fileType, ruleId)).toBe('OK!');
-
- const {
- issues: [issue],
- } = JSON.parse(await requestAnalyzeJs(server, fileType));
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId,
- }),
- );
-
- await close();
- });
-
- it('should route service requests', async () => {
- expect.assertions(2);
-
- const server = await start(port);
- const close = promisify(server.close.bind(server));
-
- expect(server.listening).toBeTruthy();
-
- const ruleId = 'no-extra-semi';
- const fileType = 'MAIN';
-
- await requestInitLinter(server, fileType, ruleId);
- const response = await requestAnalyzeJs(server, fileType);
-
- const {
- issues: [issue],
- } = JSON.parse(response);
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId,
- }),
- );
-
- await close();
- });
-
- it('should close', async () => {
- expect.assertions(2);
-
- console.log = jest.fn();
-
- const server = await start(port);
-
- const closeRequest = request(server, '/close', 'POST');
- await closeRequest;
-
- expect(server.listening).toBeFalsy();
- expect(console.log).toHaveBeenCalledWith('DEBUG eslint-bridge server will shutdown');
- });
-
- it('should timeout', async () => {
- console.log = jest.fn();
-
- const server = await start(port, '127.0.0.1', 500);
-
- await new Promise(r => setTimeout(r, 100));
- expect(server.listening).toBeTruthy();
- await request(server, '/status', 'GET');
-
- await new Promise(r => setTimeout(r, 100));
- expect(server.listening).toBeTruthy();
- await request(server, '/status', 'GET');
-
- await new Promise(r => setTimeout(r, 600));
- expect(server.listening).toBeFalsy();
-
- expect(console.log).toHaveBeenCalledWith('DEBUG eslint-bridge server closed');
- });
-});
-
-async function requestAnalyzeJs(server: http.Server, fileType: string): Promise {
- const filePath = path.join(__dirname, 'fixtures', 'routing.js');
- const analysisInput = { filePath, fileType };
-
- return await request(server, '/analyze-js', 'POST', analysisInput);
-}
-
-function requestInitLinter(server: http.Server, fileType: string, ruleId: string) {
- const config = {
- rules: [{ key: ruleId, configurations: [], fileTypeTarget: fileType }],
- };
-
- return request(server, '/init-linter', 'POST', config);
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/css/analyzer.test.ts b/eslint-bridge/tests/services/analysis/analyzers/css/analyzer.test.ts
deleted file mode 100644
index 6bc08f5574d..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/css/analyzer.test.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { analyzeCSS, CssAnalysisInput } from 'services/analysis';
-import { RuleConfig } from 'linting/stylelint';
-import path from 'path';
-import { readFile } from 'helpers';
-
-const rules = [{ key: 'block-no-empty', configurations: [] }];
-
-describe('analyzeCSS', () => {
- it('should analyze a css file', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'file.css');
- expect(analyzeCSS(await input(filePath, undefined, rules))).resolves.toEqual({
- issues: [
- {
- ruleId: 'block-no-empty',
- line: 1,
- column: 3,
- message: 'Unexpected empty block (block-no-empty)',
- },
- ],
- });
- });
-
- it('should analyze css content', async () => {
- const fileContent = 'p {}';
- expect(analyzeCSS(await input('/some/fake/path', fileContent, rules))).resolves.toEqual({
- issues: [
- expect.objectContaining({
- ruleId: 'block-no-empty',
- }),
- ],
- });
- });
-
- it('should analyze less syntax', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'file.less');
- expect(analyzeCSS(await input(filePath, undefined, rules))).resolves.toEqual({
- issues: [
- expect.objectContaining({
- ruleId: 'block-no-empty',
- }),
- ],
- });
- });
-
- it('should return a parsing error in the form of an issue', async () => {
- const filePath = path.join(__dirname, 'fixtures', 'malformed.css');
- expect(analyzeCSS(await input(filePath))).resolves.toEqual({
- issues: [
- {
- ruleId: 'CssSyntaxError',
- line: 2,
- column: 3,
- message: 'Unclosed block (CssSyntaxError)',
- },
- ],
- });
- });
-});
-
-async function input(
- filePath?: string,
- fileContent?: string,
- rules: RuleConfig[] = [],
-): Promise {
- return { filePath, fileContent: fileContent || (await readFile(filePath)), rules };
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.css b/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.css
deleted file mode 100644
index fdc4961014b..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.css
+++ /dev/null
@@ -1 +0,0 @@
-p {}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.less b/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.less
deleted file mode 100644
index 669ed93e454..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/file.less
+++ /dev/null
@@ -1 +0,0 @@
-.foo { .bar { } }
diff --git a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/malformed.css b/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/malformed.css
deleted file mode 100644
index 86cbe36b956..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/css/fixtures/malformed.css
+++ /dev/null
@@ -1,2 +0,0 @@
-
- p {
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/analyzer.test.ts b/eslint-bridge/tests/services/analysis/analyzers/js/analyzer.test.ts
deleted file mode 100644
index abd5b1bd49f..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/analyzer.test.ts
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import { setContext } from 'helpers';
-import { initializeLinter, RuleConfig } from 'linting/eslint';
-import { analyzeJSTS, JsTsAnalysisOutput } from 'services/analysis';
-import { createProgram } from 'services/program';
-import { APIError } from 'errors';
-import { jsTsInput } from '../../../../tools';
-
-describe('analyzeJSTS', () => {
- beforeEach(() => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: false,
- bundles: [],
- });
- });
-
- it('should fail on uninitialized linter', async () => {
- const input = {} as any;
- const language = 'js';
- expect(() => analyzeJSTS(input, language)).toThrow(
- APIError.linterError('Linter default does not exist. Did you call /init-linter?'),
- );
- });
-
- it('should analyze JavaScript code with the given linter', async () => {
- const rules = [
- { key: 'prefer-default-last', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
- initializeLinter([], [], [], 'empty');
-
- const filePath = path.join(__dirname, 'fixtures', 'code.js');
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
-
- const { issues } = analyzeJSTS(
- await jsTsInput({ filePath, linterId: 'empty' }),
- language,
- ) as JsTsAnalysisOutput;
-
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'prefer-default-last',
- }),
- );
-
- expect(issues).toHaveLength(0);
- });
-
- it('should analyze TypeScript code', async () => {
- const rules = [
- { key: 'bool-param-default', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
- initializeLinter([], [], [], 'empty');
-
- const filePath = path.join(__dirname, 'fixtures', 'code.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'tsconfig.json')];
- const language = 'ts';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath, tsConfigs }), language) as JsTsAnalysisOutput;
- const { issues } = analyzeJSTS(
- await jsTsInput({ filePath, tsConfigs, linterId: 'empty' }),
- language,
- ) as JsTsAnalysisOutput;
-
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'bool-param-default',
- }),
- );
- expect(issues).toHaveLength(0);
- });
-
- it('should analyze Vue.js code', async () => {
- const rules = [
- { key: 'no-dupe-keys', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'code.vue');
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-dupe-keys',
- }),
- );
- });
-
- it('should analyze main files', async () => {
- const rules = [
- { key: 'prefer-promise-shorthand', configurations: [], fileTypeTarget: ['MAIN'] },
- { key: 'no-same-argument-assert', configurations: [], fileTypeTarget: ['TEST'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'main.js');
- const language = 'js';
-
- const { issues } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(issues).toHaveLength(1);
- expect(issues[0]).toEqual(
- expect.objectContaining({
- ruleId: 'prefer-promise-shorthand',
- }),
- );
- });
-
- it('should analyze test files', async () => {
- const rules = [
- { key: 'no-with', configurations: [], fileTypeTarget: ['MAIN'] },
- { key: 'no-same-argument-assert', configurations: [], fileTypeTarget: ['TEST'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'test.js');
- const fileType = 'TEST';
-
- const language = 'js';
-
- const { issues } = analyzeJSTS(
- await jsTsInput({ filePath, fileType }),
- language,
- ) as JsTsAnalysisOutput;
- expect(issues).toHaveLength(1);
- expect(issues[0]).toEqual(
- expect.objectContaining({
- ruleId: 'no-same-argument-assert',
- }),
- );
- });
-
- it('should analyze main and test files', async () => {
- const rules = [
- { key: 'no-throw-literal', configurations: [], fileTypeTarget: ['MAIN', 'TEST'] },
- { key: 'no-exclusive-tests', configurations: [], fileTypeTarget: ['TEST'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'mixed.js');
- const fileType = 'TEST';
- const language = 'js';
-
- const { issues } = analyzeJSTS(
- await jsTsInput({ filePath, fileType }),
- language,
- ) as JsTsAnalysisOutput;
- expect(issues).toHaveLength(2);
- expect(issues.map(issue => issue.ruleId)).toEqual(
- expect.arrayContaining(['no-exclusive-tests', 'no-throw-literal']),
- );
- });
-
- it('should analyze shebang files', async () => {
- const rules = [
- { key: 'object-shorthand', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'shebang.js');
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'object-shorthand',
- }),
- );
- });
-
- it('should analyze BOM files', async () => {
- const rules = [
- { key: 'no-extra-semi', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'bom.js');
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-extra-semi',
- }),
- );
- });
-
- it('should analyze file contents', async () => {
- const rules = [
- { key: 'prefer-template', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = '/tmp/dir';
- const fileContent = `'foo' + bar + 'baz'`;
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath, fileContent }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'prefer-template',
- }),
- );
- });
-
- it('should analyze using TSConfig', async () => {
- const rules = [
- { key: 'no-useless-intersection', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'tsconfig.ts');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'tsconfig.json')];
- const language = 'ts';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath, tsConfigs }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-useless-intersection',
- }),
- );
- });
-
- it('should analyze using TypeScript program', async () => {
- const rules = [
- { key: 'no-array-delete', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'program.ts');
-
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.json');
- const { programId } = await createProgram(tsConfig);
- const language = 'ts';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath, programId }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-array-delete',
- }),
- );
- });
-
- it('should analyze using type information', async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- });
- const rules = [
- { key: 'different-types-comparison', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'type.js');
- const tsConfigs = [path.join(__dirname, 'fixtures', 'tsconfig.json')];
- const language = 'js';
-
- const {
- issues: [issue],
- } = analyzeJSTS(await jsTsInput({ filePath, tsConfigs }), language) as JsTsAnalysisOutput;
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'different-types-comparison',
- }),
- );
- });
-
- it('should report issues', async () => {
- const rules = [
- { key: 'no-octal', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'issue.js');
- const language = 'js';
-
- const { issues } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(issues).toEqual([
- {
- ruleId: 'no-octal',
- line: 1,
- column: 8,
- endLine: 1,
- endColumn: 11,
- message: 'Octal literals should not be used.',
- quickFixes: [],
- secondaryLocations: [],
- },
- ]);
- });
-
- it('should report secondary locations', async () => {
- const rules = [
- { key: 'destructuring-assignment-syntax', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'secondary.js');
- const language = 'js';
-
- const {
- issues: [{ secondaryLocations }],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(secondaryLocations).toEqual([
- {
- line: 3,
- column: 6,
- endLine: 3,
- endColumn: 19,
- message: 'Replace this assignment.',
- },
- ]);
- });
-
- it('should report quick fixes', async () => {
- const rules = [
- { key: 'no-unused-function-argument', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'quickfix.js');
- const language = 'js';
-
- const {
- issues: [{ quickFixes }],
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(quickFixes).toEqual([
- {
- message: 'Rename "b" to "_b"',
- edits: [
- {
- text: '_',
- loc: {
- line: 1,
- column: 14,
- endLine: 1,
- endColumn: 14,
- },
- },
- ],
- },
- {
- message: 'Remove "b" (beware of call sites)',
- edits: [
- {
- text: '',
- loc: {
- line: 1,
- column: 14,
- endLine: 1,
- endColumn: 17,
- },
- },
- ],
- },
- ]);
- });
-
- it('should compute metrics on main files', async () => {
- const rules = [] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'metrics.js');
- const language = 'js';
-
- const { highlights, highlightedSymbols, metrics, cpdTokens } = analyzeJSTS(
- await jsTsInput({ filePath }),
- language,
- ) as JsTsAnalysisOutput;
-
- const extendedMetrics = { highlights, highlightedSymbols, metrics, cpdTokens };
- expect(extendedMetrics).toEqual({
- highlights: [
- { textType: 'KEYWORD', location: { startLine: 1, startCol: 0, endLine: 1, endCol: 5 } },
- { textType: 'KEYWORD', location: { startLine: 4, startCol: 4, endCol: 10, endLine: 4 } },
- { textType: 'COMMENT', location: { startLine: 2, startCol: 2, endCol: 25, endLine: 2 } },
- { textType: 'COMMENT', location: { startLine: 4, startCol: 25, endCol: 35, endLine: 4 } },
- ],
- highlightedSymbols: [
- { declaration: { startLine: 1, startCol: 6, endLine: 1, endCol: 7 }, references: [] },
- { declaration: { startLine: 1, startCol: 6, endLine: 1, endCol: 7 }, references: [] },
- {
- declaration: { startLine: 3, startCol: 4, endLine: 3, endCol: 5 },
- references: [
- { startLine: 4, startCol: 13, endLine: 4, endCol: 14 },
- { startLine: 4, startCol: 21, endLine: 4, endCol: 22 },
- ],
- },
- {
- declaration: { startLine: 3, startCol: 7, endLine: 3, endCol: 8 },
- references: [{ startLine: 5, startCol: 2, endLine: 5, endCol: 3 }],
- },
- {
- declaration: { startLine: 1, startCol: 8, endLine: 1, endCol: 9 },
- references: [{ startLine: 6, startCol: 0, endLine: 6, endCol: 1 }],
- },
- ],
- metrics: {
- classes: 1,
- cognitiveComplexity: 1,
- commentLines: [2],
- complexity: 2,
- executableLines: [4],
- functions: 1,
- ncloc: [1, 3, 4, 5, 6],
- nosonarLines: [4],
- statements: 1,
- },
- cpdTokens: [
- {
- image: 'class',
- location: {
- endCol: 5,
- endLine: 1,
- startCol: 0,
- startLine: 1,
- },
- },
- {
- image: 'C',
- location: {
- endCol: 7,
- endLine: 1,
- startCol: 6,
- startLine: 1,
- },
- },
- {
- image: '{',
- location: {
- endCol: 9,
- endLine: 1,
- startCol: 8,
- startLine: 1,
- },
- },
- {
- image: 'm',
- location: {
- endCol: 3,
- endLine: 3,
- startCol: 2,
- startLine: 3,
- },
- },
- {
- image: '(',
- location: {
- endCol: 4,
- endLine: 3,
- startCol: 3,
- startLine: 3,
- },
- },
- {
- image: 'p',
- location: {
- endCol: 5,
- endLine: 3,
- startCol: 4,
- startLine: 3,
- },
- },
- {
- image: ')',
- location: {
- endCol: 6,
- endLine: 3,
- startCol: 5,
- startLine: 3,
- },
- },
- {
- image: '{',
- location: {
- endCol: 8,
- endLine: 3,
- startCol: 7,
- startLine: 3,
- },
- },
- {
- image: 'return',
- location: {
- endCol: 10,
- endLine: 4,
- startCol: 4,
- startLine: 4,
- },
- },
- {
- image: 'f',
- location: {
- endCol: 12,
- endLine: 4,
- startCol: 11,
- startLine: 4,
- },
- },
- {
- image: '(',
- location: {
- endCol: 13,
- endLine: 4,
- startCol: 12,
- startLine: 4,
- },
- },
- {
- image: 'p',
- location: {
- endCol: 14,
- endLine: 4,
- startCol: 13,
- startLine: 4,
- },
- },
- {
- image: ')',
- location: {
- endCol: 15,
- endLine: 4,
- startCol: 14,
- startLine: 4,
- },
- },
- {
- image: '&&',
- location: {
- endCol: 18,
- endLine: 4,
- startCol: 16,
- startLine: 4,
- },
- },
- {
- image: 'g',
- location: {
- endCol: 20,
- endLine: 4,
- startCol: 19,
- startLine: 4,
- },
- },
- {
- image: '(',
- location: {
- endCol: 21,
- endLine: 4,
- startCol: 20,
- startLine: 4,
- },
- },
- {
- image: 'p',
- location: {
- endCol: 22,
- endLine: 4,
- startCol: 21,
- startLine: 4,
- },
- },
- {
- image: ')',
- location: {
- endCol: 23,
- endLine: 4,
- startCol: 22,
- startLine: 4,
- },
- },
- {
- image: ';',
- location: {
- endCol: 24,
- endLine: 4,
- startCol: 23,
- startLine: 4,
- },
- },
- {
- image: '}',
- location: {
- endCol: 3,
- endLine: 5,
- startCol: 2,
- startLine: 5,
- },
- },
- {
- image: '}',
- location: {
- endCol: 1,
- endLine: 6,
- startCol: 0,
- startLine: 6,
- },
- },
- ],
- });
- });
-
- it('should compute metrics on test files', async () => {
- const rules = [] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'metrics.js');
- const fileType = 'TEST';
- const language = 'js';
-
- const { highlights, highlightedSymbols, metrics, cpdTokens } = analyzeJSTS(
- await jsTsInput({ filePath, fileType }),
- language,
- ) as JsTsAnalysisOutput;
-
- const extendedMetrics = { highlights, highlightedSymbols, metrics, cpdTokens };
- expect(extendedMetrics).toEqual({
- cpdTokens: undefined,
- highlights: [
- { textType: 'KEYWORD', location: { startLine: 1, startCol: 0, endLine: 1, endCol: 5 } },
- { textType: 'KEYWORD', location: { startLine: 4, startCol: 4, endCol: 10, endLine: 4 } },
- { textType: 'COMMENT', location: { startLine: 2, startCol: 2, endCol: 25, endLine: 2 } },
- { textType: 'COMMENT', location: { startLine: 4, startCol: 25, endCol: 35, endLine: 4 } },
- ],
- highlightedSymbols: [
- { declaration: { startLine: 1, startCol: 6, endLine: 1, endCol: 7 }, references: [] },
- { declaration: { startLine: 1, startCol: 6, endLine: 1, endCol: 7 }, references: [] },
- {
- declaration: { startLine: 3, startCol: 4, endLine: 3, endCol: 5 },
- references: [
- { startLine: 4, startCol: 13, endLine: 4, endCol: 14 },
- { startLine: 4, startCol: 21, endLine: 4, endCol: 22 },
- ],
- },
- {
- declaration: { startLine: 3, startCol: 7, endLine: 3, endCol: 8 },
- references: [{ startLine: 5, startCol: 2, endLine: 5, endCol: 3 }],
- },
- {
- declaration: { startLine: 1, startCol: 8, endLine: 1, endCol: 9 },
- references: [{ startLine: 6, startCol: 0, endLine: 6, endCol: 1 }],
- },
- ],
- metrics: {
- nosonarLines: [4],
- },
- });
- });
-
- it('should compute metrics in SonarLint context', async () => {
- setContext({
- workDir: '/tmp/dir',
- shouldUseTypeScriptParserForJS: false,
- sonarlint: true,
- bundles: [],
- });
-
- const rules = [] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'metrics.js');
- const language = 'js';
-
- const { highlights, highlightedSymbols, metrics, cpdTokens } = analyzeJSTS(
- await jsTsInput({ filePath }),
- language,
- ) as JsTsAnalysisOutput;
-
- const extendedMetrics = { highlights, highlightedSymbols, metrics, cpdTokens };
- expect(extendedMetrics).toEqual({
- metrics: {
- nosonarLines: [4],
- },
- });
- });
-
- it('should measure analysis duration', async () => {
- const rules = [
- { key: 'no-extra-smi', configurations: [], fileTypeTarget: ['MAIN'] },
- { key: 'no-duplicate-string', configurations: [], fileTypeTarget: ['MAIN'] },
- { key: 'sonar-no-regex-spaces', configurations: [], fileTypeTarget: ['MAIN'] },
- ] as RuleConfig[];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'measure.js');
- const language = 'js';
-
- const {
- perf: { parseTime, analysisTime },
- } = analyzeJSTS(await jsTsInput({ filePath }), language) as JsTsAnalysisOutput;
- expect(parseTime).toBeGreaterThan(0);
- expect(analysisTime).toBeGreaterThan(0);
- });
-
- it('should return parsing errors', async () => {
- const rules = [];
- initializeLinter(rules);
-
- const filePath = path.join(__dirname, 'fixtures', 'parsing-error.js');
- const language = 'js';
- const analysisInput = await jsTsInput({ filePath });
- expect(() => analyzeJSTS(analysisInput, language)).toThrow(
- APIError.parsingError('Unexpected token (3:0)', { line: 3 }),
- );
- });
-});
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/bom.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/bom.js
deleted file mode 100644
index ec2564f4966..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/bom.js
+++ /dev/null
@@ -1 +0,0 @@
-bom();;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.js
deleted file mode 100644
index 86dcbbc8856..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function f(c) {
- switch (c) {
- default:
- return -1;
- case 1:
- return 1;
- }
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.ts b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.ts
deleted file mode 100644
index afc9937fabc..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-function foo(b?: boolean) {
- if (b) {
- return bar();
- }
- return baz();
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.vue b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.vue
deleted file mode 100644
index 4d3f3d34291..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/code.vue
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/issue.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/issue.js
deleted file mode 100644
index e380e0de57b..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/issue.js
+++ /dev/null
@@ -1 +0,0 @@
-let n = 042;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/main.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/main.js
deleted file mode 100644
index fbbc0c016ad..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/main.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const assert = require('chai').assert;
-const promise = new Promise((resolve) => resolve(42));
-assert.equal(promise, promise);
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/measure.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/measure.js
deleted file mode 100644
index 239ea3b5cda..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/measure.js
+++ /dev/null
@@ -1,3 +0,0 @@
-'hello'; 'hello'; 'hello';
-foo();; foo();; foo();;
-/bar /; /bar /; /bar /;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/metrics.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/metrics.js
deleted file mode 100644
index 586698b8912..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/metrics.js
+++ /dev/null
@@ -1,6 +0,0 @@
-class C {
- /* this is a comment */
- m(p) {
- return f(p) && g(p); // NOSONAR
- }
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/mixed.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/mixed.js
deleted file mode 100644
index d31c9fc79d7..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/mixed.js
+++ /dev/null
@@ -1,5 +0,0 @@
-describe('suite', () => {
- it.only('test', () => {
- throw 'not implemented yet';
- })
-})
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/parsing-error.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/parsing-error.js
deleted file mode 100644
index cf23d4feba2..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/parsing-error.js
+++ /dev/null
@@ -1,2 +0,0 @@
-function f() {
- return;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/program.ts b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/program.ts
deleted file mode 100644
index b7557b033a9..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/program.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-let a = ['a', 'b', 'c', 'd'];
-delete a[1];
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/quickfix.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/quickfix.js
deleted file mode 100644
index dcec2124524..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/quickfix.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function f(a, b, c) {
- return a + c;
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/secondary.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/secondary.js
deleted file mode 100644
index e290587bca4..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/secondary.js
+++ /dev/null
@@ -1,4 +0,0 @@
-function f(obj) {
- let foo = obj.foo;
- let bar = obj.bar;
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/shebang.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/shebang.js
deleted file mode 100644
index c1d54df8c29..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/shebang.js
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env node
-function f(p) {
- return {
- p: p
- };
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/test.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/test.js
deleted file mode 100644
index 2227768507f..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/test.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const assert = require('chai').assert;
-with (42) {
- assert.equal(promise, promise);
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.json b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.json
deleted file mode 100644
index 73012705cc3..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "compilerOptions": {
- "allowJs": true
- },
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.ts b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.ts
deleted file mode 100644
index bd6f6fd364c..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/tsconfig.ts
+++ /dev/null
@@ -1 +0,0 @@
-let x: string & null;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/type.js b/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/type.js
deleted file mode 100644
index 5f8f9429888..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/js/fixtures/type.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const str = 'str', bool = false;
-if (str === bool) {
- fun();
-}
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/analyzer.test.ts b/eslint-bridge/tests/services/analysis/analyzers/yaml/analyzer.test.ts
deleted file mode 100644
index afeed8b1164..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/analyzer.test.ts
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { join } from 'path';
-import { setContext } from 'helpers';
-import { analyzeYAML } from 'services/analysis';
-import { initializeLinter, getLinter } from 'linting/eslint';
-import { APIError } from 'errors';
-import { Rule } from 'eslint';
-import { composeSyntheticFilePath } from 'parsing/yaml';
-import { yamlInput } from '../../../../tools';
-
-describe('analyzeYAML', () => {
- const fixturesPath = join(__dirname, 'fixtures');
-
- beforeAll(() => {
- setContext({
- workDir: '/tmp/workdir',
- shouldUseTypeScriptParserForJS: true,
- sonarlint: false,
- bundles: [],
- });
- });
-
- it('should fail on uninitialized linter', async () => {
- const input = {} as any;
- expect(() => analyzeYAML(input)).toThrow(
- APIError.linterError('Linter default does not exist. Did you call /init-linter?'),
- );
- });
-
- it('should analyze YAML file', async () => {
- initializeLinter([
- { key: 'no-all-duplicated-branches', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const {
- issues: [issue],
- } = analyzeYAML(await yamlInput({ filePath: join(fixturesPath, 'file.yaml') }));
- expect(issue).toEqual(
- expect.objectContaining({
- ruleId: 'no-all-duplicated-branches',
- line: 8,
- column: 17,
- endLine: 8,
- endColumn: 46,
- }),
- );
- });
-
- it('should return an empty issues list on parsing error', async () => {
- initializeLinter([
- { key: 'no-all-duplicated-branches', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const analysisInput = await yamlInput({ filePath: join(fixturesPath, 'malformed.yaml') });
- expect(() => analyzeYAML(analysisInput)).toThrow(
- APIError.parsingError('Map keys must be unique', { line: 2 }),
- );
- });
-
- it('should not break when using a rule with a quickfix', async () => {
- initializeLinter([{ key: 'no-extra-semi', configurations: [], fileTypeTarget: ['MAIN'] }]);
- const result = analyzeYAML(await yamlInput({ filePath: join(fixturesPath, 'quickfix.yaml') }));
- const {
- issues: [
- {
- quickFixes: [quickFix],
- },
- ],
- } = result;
- expect(quickFix.edits).toEqual([
- {
- text: ';',
- loc: {
- line: 7,
- column: 58,
- endLine: 7,
- endColumn: 60,
- },
- },
- ]);
- });
-
- it('should not break when using "enforce-trailing-comma" rule', async () => {
- initializeLinter([
- {
- key: 'enforce-trailing-comma',
- configurations: ['always-multiline'],
- fileTypeTarget: ['MAIN'],
- },
- ]);
- const { issues } = analyzeYAML(
- await yamlInput({ filePath: join(fixturesPath, 'enforce-trailing-comma.yaml') }),
- );
- expect(issues).toHaveLength(2);
- expect(issues[0]).toEqual(
- expect.objectContaining({
- line: 30,
- column: 28,
- endLine: 31,
- endColumn: 0,
- }),
- );
- expect(issues[1]).toEqual(
- expect.objectContaining({
- line: 31,
- column: 19,
- endLine: 32,
- endColumn: 0,
- }),
- );
- });
-
- it('should not break when using a rule with secondary locations', async () => {
- initializeLinter([{ key: 'no-new-symbol', configurations: [], fileTypeTarget: ['MAIN'] }]);
- const result = analyzeYAML(await yamlInput({ filePath: join(fixturesPath, 'secondary.yaml') }));
- const {
- issues: [
- {
- secondaryLocations: [secondaryLocation],
- },
- ],
- } = result;
- expect(secondaryLocation).toEqual({
- line: 7,
- column: 35,
- endLine: 7,
- endColumn: 41,
- });
- });
-
- it('should not break when using a regex rule', async () => {
- initializeLinter([
- { key: 'sonar-no-regex-spaces', configurations: [], fileTypeTarget: ['MAIN'] },
- ]);
- const result = analyzeYAML(await yamlInput({ filePath: join(fixturesPath, 'regex.yaml') }));
- const {
- issues: [issue],
- } = result;
- expect(issue).toEqual(
- expect.objectContaining({
- line: 7,
- column: 41,
- endLine: 7,
- endColumn: 44,
- }),
- );
- });
-
- it('should not return issues outside of the embedded JS', async () => {
- initializeLinter([
- { key: 'no-trailing-spaces', configurations: [], fileTypeTarget: ['MAIN'] },
- { key: 'file-header', configurations: [{ headerFormat: '' }], fileTypeTarget: ['MAIN'] },
- ]);
- const { issues } = analyzeYAML(
- await yamlInput({ filePath: join(fixturesPath, 'outside.yaml') }),
- );
- expect(issues).toHaveLength(0);
- });
-
- it('should provide a synthetic filename to the rule context', async () => {
- expect.assertions(1);
- const resourceName = 'SomeLambdaFunction';
- const filePath = join(fixturesPath, 'synthetic-filename.yaml');
- const syntheticFilename = composeSyntheticFilePath(filePath, resourceName);
- const rule = {
- key: 'synthetic-filename',
- module: {
- create(context: Rule.RuleContext) {
- return {
- Program: () => {
- const filename = context.getFilename();
- expect(filename).toEqual(syntheticFilename);
- },
- };
- },
- },
- };
- initializeLinter([{ key: rule.key, configurations: [], fileTypeTarget: ['MAIN'] }]);
- getLinter().linter.defineRule(rule.key, rule.module);
- analyzeYAML(await yamlInput({ filePath }));
- });
-});
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/enforce-trailing-comma.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/enforce-trailing-comma.yaml
deleted file mode 100644
index d66d82b61b8..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/enforce-trailing-comma.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# copied from
-# https://github.com/aws-samples/aws-serverless-vending-machine/blob/b2898f3ac097e91fedfd021c87968c4266800f15/scripts/deployServerlessVendingMachine.yaml#L260
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
-#lambdas
- GetDeployDataDynamoSF:
- Type: AWS::Lambda::Function
- Properties:
- Handler: index.handler
- Timeout: 15
- Role: !GetAtt
- - LambdaExecutionRole
- - Arn
- Runtime: nodejs12.x
- Code:
- ZipFile: |
- // 1
- const AWS = require('aws-sdk');
- const dynamo = new AWS.DynamoDB.DocumentClient();
- exports.handler = function(event, context, callback) {
- console.log('Received event:', JSON.stringify(event));
- var data = event.Input;
- var id = data.id
- if (data.productId) {
- id = data.productId;
- }
- const params = {
- TableName: "deploy",
- Key: {
- "id": id
- }
- };
- console.log('DATA:', JSON.stringify(data));
- dynamo.get(params, callback);
- };
-
-
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/file.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/file.yaml
deleted file mode 100644
index 35dee18ef65..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/file.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
- someProp: hello there
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/malformed.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/malformed.yaml
deleted file mode 100644
index 571459324d5..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/malformed.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-a: 1st
-a: duplicate key 'a' should throw an error at parsing on line 2
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/outside.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/outside.yaml
deleted file mode 100644
index c37ea2bceac..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/outside.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-Resources:
- SomeLambdaFunction:
- # trailing spaces on line below
- Type: "AWS::Lambda::Function"
- # trailing spaces on line below
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
- OtherLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: if (foo()) bar(); else bar();
-
-
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/quickfix.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/quickfix.yaml
deleted file mode 100644
index f7cc256b140..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/quickfix.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: if (foo()) bar(); /* howdy */ else bar();;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/regex.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/regex.yaml
deleted file mode 100644
index ea0a99d27dc..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/regex.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: const pattern = /Hello, world!/;
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/secondary.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/secondary.yaml
deleted file mode 100644
index e6a7a2cd086..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/secondary.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: var symbol = new Symbol("foo");
diff --git a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/synthetic-filename.yaml b/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/synthetic-filename.yaml
deleted file mode 100644
index c3eff3ac174..00000000000
--- a/eslint-bridge/tests/services/analysis/analyzers/yaml/fixtures/synthetic-filename.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Runtime: "nodejs16.0"
- Code:
- ZipFile: console.log("hello there")
diff --git a/eslint-bridge/tests/services/analysis/runner.test.ts b/eslint-bridge/tests/services/analysis/runner.test.ts
deleted file mode 100644
index e4667bb69b9..00000000000
--- a/eslint-bridge/tests/services/analysis/runner.test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import express from 'express';
-import { AnalysisOutput, runner } from 'services/analysis';
-
-describe('runner', () => {
- it('should run an analysis', async () => {
- const mockRequest = () => ({ body: 'done' } as express.Request);
- const mockResponse = () => ({ json: jest.fn() } as any as express.Response);
-
- const analysis = input => Promise.resolve(input.toUpperCase() as AnalysisOutput);
-
- const request = mockRequest();
- const response = mockResponse();
-
- const handler = runner(analysis) as (
- request: express.Request,
- response: express.Response,
- ) => Promise;
- await handler(request, response);
-
- expect(response.json).toHaveBeenCalledWith('DONE');
- });
-
- it('should forward the caught runtime error to the next middleware', async () => {
- const mockRequest = () => ({ body: 'whatever' } as express.Request);
- const mockResponse = () =>
- ({
- json: () => {
- throw 'Something went wrong';
- },
- } as any as express.Response);
-
- const analysis = input => Promise.resolve(input as AnalysisOutput);
-
- const request = mockRequest();
- const response = mockResponse();
- const next = jest.fn();
-
- const handler = runner(analysis) as (
- request: express.Request,
- response: express.Response,
- next: express.NextFunction,
- ) => Promise;
- await handler(request, response, next);
-
- expect(next).toHaveBeenCalledWith('Something went wrong');
- });
-});
diff --git a/eslint-bridge/tests/services/monitoring/measure.test.ts b/eslint-bridge/tests/services/monitoring/measure.test.ts
deleted file mode 100644
index 88bdba92973..00000000000
--- a/eslint-bridge/tests/services/monitoring/measure.test.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { hrtime } from 'process';
-import { measureDuration } from 'services/monitoring';
-
-describe('measureDuration', () => {
- it('should measure the running time of a function', () => {
- const spy = jest.spyOn(hrtime, 'bigint');
-
- const f = () => 'done';
- const { result, duration } = measureDuration(f);
-
- expect(result).toEqual(f());
- expect(duration).toBeGreaterThanOrEqual(0);
- expect(spy).toHaveBeenCalled();
-
- spy.mockRestore();
- });
-});
diff --git a/eslint-bridge/tests/services/program/fixtures/file.ts b/eslint-bridge/tests/services/program/fixtures/file.ts
deleted file mode 100644
index 6bd7fecceb0..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/file.ts
+++ /dev/null
@@ -1 +0,0 @@
-console.log('howdy');
diff --git a/eslint-bridge/tests/services/program/fixtures/node_modules/@tsconfig/node30/tsconfig.json b/eslint-bridge/tests/services/program/fixtures/node_modules/@tsconfig/node30/tsconfig.json
deleted file mode 100644
index d1d75514921..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/node_modules/@tsconfig/node30/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig",
- "display": "Node 14",
-
- "compilerOptions": {
- "lib": ["es2020"],
- "module": "commonjs",
- "target": "es2020",
-
- "strict": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- "moduleResolution": "node"
- }
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/reference/file.ts b/eslint-bridge/tests/services/program/fixtures/reference/file.ts
deleted file mode 100644
index 81afa3157c1..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/reference/file.ts
+++ /dev/null
@@ -1 +0,0 @@
-console.log('foo');
diff --git a/eslint-bridge/tests/services/program/fixtures/reference/tsconfig.json b/eslint-bridge/tests/services/program/fixtures/reference/tsconfig.json
deleted file mode 100644
index 65a202b7199..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/reference/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "include": [
- "**/*.ts",
- ]
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig.json b/eslint-bridge/tests/services/program/fixtures/tsconfig.json
deleted file mode 100644
index 77e60bfc4f4..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "references": [ { "path": "./reference" }]
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig.semantic.json b/eslint-bridge/tests/services/program/fixtures/tsconfig.semantic.json
deleted file mode 100644
index f662353c1e0..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig.semantic.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "targetSomething": "es6" // non-existing property
- },
- "exclude": ["excluded.ts"]
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig.syntax.json b/eslint-bridge/tests/services/program/fixtures/tsconfig.syntax.json
deleted file mode 100644
index 16eedf104c3..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig.syntax.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6" // missing a comma
- "allowJs": true
- },
- "exclude": ["excluded.ts"]
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig_found.json b/eslint-bridge/tests/services/program/fixtures/tsconfig_found.json
deleted file mode 100644
index a5d9b249859..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig_found.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "@tsconfig/node30/tsconfig.json"
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig_missing.json b/eslint-bridge/tests/services/program/fixtures/tsconfig_missing.json
deleted file mode 100644
index 7074aa2a40c..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig_missing.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "@tsconfig/node_missing/tsconfig.json"
-}
diff --git a/eslint-bridge/tests/services/program/fixtures/tsconfig_missing_reference.json b/eslint-bridge/tests/services/program/fixtures/tsconfig_missing_reference.json
deleted file mode 100644
index 3a38a30781e..00000000000
--- a/eslint-bridge/tests/services/program/fixtures/tsconfig_missing_reference.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "references": [ { "path": "./reference_missing" }]
-}
diff --git a/eslint-bridge/tests/services/program/program.test.ts b/eslint-bridge/tests/services/program/program.test.ts
deleted file mode 100644
index 505b8c26062..00000000000
--- a/eslint-bridge/tests/services/program/program.test.ts
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import path from 'path';
-import {
- createProgram,
- createProgramOptions,
- deleteProgram,
- getProgramById,
- isRootNodeModules,
-} from 'services/program';
-import { toUnixPath } from 'helpers';
-import ts, { ModuleKind, ScriptTarget } from 'typescript';
-
-describe('program', () => {
- it('should create a program', async () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const reference = path.join(fixtures, 'reference');
- const tsConfig = path.join(fixtures, 'tsconfig.json');
-
- const { programId, files, projectReferences } = await createProgram(tsConfig);
-
- expect(programId).toBeDefined();
- expect(files).toEqual(
- expect.arrayContaining([
- toUnixPath(path.join(fixtures, 'file.ts')),
- toUnixPath(path.join(reference, 'file.ts')),
- ]),
- );
- expect(projectReferences).toEqual([path.join(reference, 'tsconfig.json')]);
- });
-
- it('should skip missing reference of a program', async () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfig = path.join(fixtures, `tsconfig_missing_reference.json`);
-
- const { programId, files, projectReferences, missingTsConfig } = await createProgram(tsConfig);
-
- expect(programId).toBeDefined();
- expect(files).toEqual(expect.arrayContaining([toUnixPath(path.join(fixtures, 'file.ts'))]));
- expect(projectReferences).toEqual([]);
- expect(missingTsConfig).toBe(false);
- });
-
- it('should fail creating a program with a syntactically incorrect tsconfig', async () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.syntax.json');
- const error = await createProgram(tsConfig).catch(err => err);
- expect(error).toBeInstanceOf(Error);
- });
-
- it('should fail creating a program with a semantically incorrect tsconfig', async () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig.semantic.json');
- const error = await createProgram(tsConfig).catch(err => err);
- expect(error.message).toMatch(/^Unknown compiler option 'targetSomething'./);
- });
-
- it('should still create a program when extended tsconfig does not exist', async () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfig = path.join(fixtures, 'tsconfig_missing.json');
-
- const { programId, files, projectReferences, missingTsConfig } = await createProgram(tsConfig);
-
- expect(programId).toBeDefined();
- expect(files).toEqual(expect.arrayContaining([toUnixPath(path.join(fixtures, 'file.ts'))]));
- expect(projectReferences).toEqual([]);
- expect(missingTsConfig).toBe(true);
- });
-
- it('On missing external tsconfig, Typescript should generate default compilerOptions', () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfigMissing = path.join(fixtures, 'tsconfig_missing.json');
-
- const { options, missingTsConfig } = createProgramOptions(tsConfigMissing);
-
- expect(missingTsConfig).toBe(true);
- expect(options).toEqual({
- configFilePath: toUnixPath(path.join(fixtures, 'tsconfig_missing.json')),
- noEmit: true,
- allowNonTsExtensions: true,
- });
- });
-
- it('External tsconfig should provide expected compilerOptions', () => {
- const tsConfig = path.join(__dirname, 'fixtures', 'tsconfig_found.json');
-
- const { options, missingTsConfig } = createProgramOptions(tsConfig);
-
- expect(missingTsConfig).toBe(false);
- expect(options).toBeDefined();
- expect(options.target).toBe(ScriptTarget['ES2020']);
- expect(options.module).toBe(ModuleKind['CommonJS']);
- });
-
- /**
- * Empty tsconfig.json fallback relies on Typescript resolution logic. This unit test
- * asserts typescript resolution logic. If it changes, we will need to adapt our logic inside
- * program.ts (createProgramOptions in program.ts)
- */
- it('typescript tsconfig resolution should check all paths until root node_modules', async () => {
- const configHost = {
- useCaseSensitiveFileNames: true,
- readDirectory: ts.sys.readDirectory,
- fileExists: jest.fn((_file: string) => false),
- readFile: ts.sys.readFile,
- };
-
- const tsConfigMissing = path.join(__dirname, 'fixtures', 'tsconfig_missing.json');
- const searchedFiles = [];
- let nodeModulesFolder = path.join(__dirname, 'fixtures');
- let searchFolder;
- do {
- searchFolder = path.join(nodeModulesFolder, 'node_modules', '@tsconfig', 'node_missing');
- searchedFiles.push(path.join(searchFolder, 'tsconfig.json', 'package.json'));
- searchedFiles.push(path.join(searchFolder, 'package.json'));
- searchedFiles.push(path.join(searchFolder, 'tsconfig.json'));
- searchedFiles.push(path.join(searchFolder, 'tsconfig.json', 'tsconfig.json'));
- nodeModulesFolder = path.dirname(nodeModulesFolder);
- } while (!isRootNodeModules(searchFolder));
-
- const config = ts.readConfigFile(tsConfigMissing, configHost.readFile);
- const parsedConfigFile = ts.parseJsonConfigFileContent(
- config.config,
- configHost,
- path.resolve(path.dirname(tsConfigMissing)),
- {
- noEmit: true,
- },
- tsConfigMissing,
- );
-
- expect(parsedConfigFile.errors).not.toHaveLength(0);
- expect(configHost.fileExists).toHaveBeenCalledTimes(searchedFiles.length);
- searchedFiles.forEach((file, index) => {
- expect(configHost.fileExists).toHaveBeenNthCalledWith(index + 1, toUnixPath(file));
- });
- });
-
- it('should find an existing program', async () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfig = path.join(fixtures, 'tsconfig.json');
- const { programId, files } = await createProgram(tsConfig);
-
- const program = getProgramById(programId);
-
- expect(program.getCompilerOptions().configFilePath).toEqual(toUnixPath(tsConfig));
- expect(program.getRootFileNames()).toEqual(
- files.map(toUnixPath).filter(file => file.startsWith(toUnixPath(fixtures))),
- );
- });
-
- it('should fail finding a non-existing program', () => {
- const programId = '$#&/()=?!£@~+°';
- expect(() => getProgramById(programId)).toThrow(`Failed to find program ${programId}`);
- });
-
- it('should delete a program', async () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfig = path.join(fixtures, 'tsconfig.json');
- const { programId } = await createProgram(tsConfig);
-
- deleteProgram(programId);
- expect(() => getProgramById(programId)).toThrow(`Failed to find program ${programId}`);
- });
-});
diff --git a/eslint-bridge/tests/services/tsconfig/fixtures/file.vue b/eslint-bridge/tests/services/tsconfig/fixtures/file.vue
deleted file mode 100644
index 6ffdf63937b..00000000000
--- a/eslint-bridge/tests/services/tsconfig/fixtures/file.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
diff --git a/eslint-bridge/tests/services/tsconfig/fixtures/tsconfig.json b/eslint-bridge/tests/services/tsconfig/fixtures/tsconfig.json
deleted file mode 100644
index 653664dcb09..00000000000
--- a/eslint-bridge/tests/services/tsconfig/fixtures/tsconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "include": [
- "./**/*"
- ]
-}
diff --git a/eslint-bridge/tests/services/tsconfig/tsconfig.test.ts b/eslint-bridge/tests/services/tsconfig/tsconfig.test.ts
deleted file mode 100644
index b5efa9a1e04..00000000000
--- a/eslint-bridge/tests/services/tsconfig/tsconfig.test.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as ts from 'typescript';
-import * as path from 'path';
-import { getFilesForTsConfig, writeTSConfigFile } from 'services/tsconfig';
-import { toUnixPath } from 'helpers';
-import * as fs from 'fs/promises';
-
-const defaultParseConfigHost: ts.ParseConfigHost = {
- useCaseSensitiveFileNames: true,
- readDirectory: ts.sys.readDirectory,
- fileExists: ts.sys.fileExists,
- readFile: ts.sys.readFile,
-};
-
-describe('getFilesForTsConfig', () => {
- it('should return files', () => {
- const readFile = _path => `{ "files": ["/foo/file.ts"] }`;
- const result = getFilesForTsConfig('tsconfig.json', { ...defaultParseConfigHost, readFile });
- expect(result).toEqual({
- files: ['/foo/file.ts'],
- projectReferences: [],
- });
- });
-
- it('should report errors', () => {
- const readFile = _path => `{ "files": [] }`;
- expect(() =>
- getFilesForTsConfig('tsconfig.json', { ...defaultParseConfigHost, readFile }),
- ).toThrow(`The 'files' list in config file 'tsconfig.json' is empty.`);
- });
-
- it('should return projectReferences', () => {
- const readFile = _path => `{ "files": [], "references": [{ "path": "foo" }] }`;
- const result = getFilesForTsConfig('tsconfig.json', { ...defaultParseConfigHost, readFile });
- const cwd = process.cwd().split(path.sep).join(path.posix.sep);
- expect(result).toEqual({
- files: [],
- projectReferences: [`${cwd}/foo`],
- });
- });
-
- it('should return Vue files', () => {
- const fixtures = path.join(__dirname, 'fixtures');
- const tsConfig = path.join(fixtures, 'tsconfig.json');
- const result = getFilesForTsConfig(tsConfig, { ...defaultParseConfigHost });
- expect(result).toEqual(
- expect.objectContaining({
- files: expect.arrayContaining([toUnixPath(path.join(fixtures, 'file.vue'))]),
- }),
- );
- });
-
- it('should write tsconfig file', async () => {
- const { filename } = await writeTSConfigFile({
- compilerOptions: { allowJs: true, noImplicitAny: true },
- include: ['/path/to/project/**/*'],
- });
- const content = await fs.readFile(filename, { encoding: 'utf-8' });
- expect(content).toBe(
- '{"compilerOptions":{"allowJs":true,"noImplicitAny":true},"include":["/path/to/project/**/*"]}',
- );
- });
-});
diff --git a/eslint-bridge/tests/tools/helpers/files.ts b/eslint-bridge/tests/tools/helpers/files.ts
deleted file mode 100644
index a16b4377be9..00000000000
--- a/eslint-bridge/tests/tools/helpers/files.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { constants, promises as fs } from 'fs';
-
-/**
- * Asynchronous check if file is readable.
- *
- * @param path the file path
- * @returns true if file is readable. false otherwise
- */
-export async function fileReadable(path: string) {
- try {
- await fs.access(path, constants.R_OK);
- return true;
- } catch {
- return false;
- }
-}
diff --git a/eslint-bridge/tests/tools/helpers/index.ts b/eslint-bridge/tests/tools/helpers/index.ts
deleted file mode 100644
index 2240785c8b3..00000000000
--- a/eslint-bridge/tests/tools/helpers/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './parsing';
-export * from './request';
-export * from './input';
diff --git a/eslint-bridge/tests/tools/helpers/input.ts b/eslint-bridge/tests/tools/helpers/input.ts
deleted file mode 100755
index 44180b7e6c7..00000000000
--- a/eslint-bridge/tests/tools/helpers/input.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { FileType, readFile } from 'helpers';
-import { JsTsAnalysisInput, YamlAnalysisInput } from 'services/analysis';
-
-export async function jsTsInput({
- filePath = '',
- fileContent = undefined,
- fileType = 'MAIN' as FileType,
- tsConfigs = [],
- programId = undefined,
- linterId = 'default',
-}): Promise {
- return programId
- ? {
- filePath,
- fileContent: fileContent || (await readFile(filePath)),
- fileType,
- programId,
- linterId,
- }
- : {
- filePath,
- fileContent: fileContent || (await readFile(filePath)),
- fileType,
- tsConfigs,
- linterId,
- };
-}
-
-export async function yamlInput({
- filePath = '',
- fileContent = undefined,
- linterId = 'default',
-}): Promise {
- return { filePath, fileContent: fileContent || (await readFile(filePath)), linterId };
-}
diff --git a/eslint-bridge/tests/tools/helpers/parsing.ts b/eslint-bridge/tests/tools/helpers/parsing.ts
deleted file mode 100644
index aa872ab98d1..00000000000
--- a/eslint-bridge/tests/tools/helpers/parsing.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { FileType, readFile } from 'helpers';
-import { buildSourceCode } from 'parsing/jsts';
-
-export async function parseTypeScriptSourceFile(
- filePath: string,
- tsConfigs: string[],
- fileType: FileType = 'MAIN',
-) {
- const fileContent = await readFile(filePath);
- return buildSourceCode({ fileContent, filePath, tsConfigs, fileType }, 'ts');
-}
-
-export async function parseJavaScriptSourceFile(
- filePath: string,
- tsConfigs: string[] = [],
- fileType: FileType = 'MAIN',
-) {
- const fileContent = await readFile(filePath);
- return buildSourceCode({ fileContent, filePath, tsConfigs, fileType }, 'js');
-}
diff --git a/eslint-bridge/tests/tools/helpers/request.ts b/eslint-bridge/tests/tools/helpers/request.ts
deleted file mode 100644
index 065e4823090..00000000000
--- a/eslint-bridge/tests/tools/helpers/request.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { AddressInfo } from 'net';
-import http from 'http';
-
-/**
- * Sends an HTTP request to a server's endpoint running on localhost.
- */
-export function request(server: http.Server, path: string, method: string, data: any = {}) {
- const options = {
- host: '127.0.0.1',
- path,
- method,
- port: (server.address()).port,
- headers: {
- 'Content-Type': 'application/json',
- },
- timeout: 10000,
- };
-
- return new Promise((resolve, reject) => {
- const request = http.request(options, res => {
- let response = '';
- res.on('data', chunk => {
- response += chunk;
- });
-
- res.on('end', () => resolve(response));
- });
- request.on('error', reject);
-
- request.write(JSON.stringify(data));
- request.end();
- });
-}
diff --git a/eslint-bridge/tests/tools/index.ts b/eslint-bridge/tests/tools/index.ts
deleted file mode 100644
index 6bcff30da2c..00000000000
--- a/eslint-bridge/tests/tools/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './helpers';
-export * from './testers';
diff --git a/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.test.ts b/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.test.ts
deleted file mode 100644
index 50ae0dc6303..00000000000
--- a/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.test.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rule } from './no-missing-sonar-runtime';
-import { RuleTester } from 'eslint';
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: 'module' } });
-ruleTester.run('sonar-runtime configuration for secondary locations', rule, {
- valid: [
- {
- code: ``,
- },
- {
- code: `
- import { toEncodedMessage } from './helpers';`,
- },
- {
- code: `
- toEncodedMessage();`,
- },
- {
- code: `
- unknown.toEncodedMessage();`,
- },
- {
- code: `const config = {};`,
- },
- {
- code: `const config =
- {
- alpha: whatever
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- whatever: something
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: whatever
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [{}]
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [
- {
- enum: whatever
- }
- ]
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [
- {
- enum: []
- }
- ]
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [
- {
- enum: [whatever]
- }
- ]
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [
- {
- enum: ['whatever']
- }
- ]
- }
- };`,
- },
- {
- code: `const config =
- {
- meta: {
- schema: [
- {
- enum: ['sonar-runtime']
- }
- ]
- }
- };`,
- },
- ],
- invalid: [
- {
- code: `
- import { toEncodedMessage } from './helpers';
- /* ... */
- toEncodedMessage(whatever);`,
- errors: [
- {
- message: `Missing enabling of secondary location support`,
- line: 2,
- endLine: 4,
- column: 9,
- endColumn: 36,
- },
- ],
- },
- {
- code: `
- import { toEncodedMessage } from './helpers';
- /* ... */
- toEncodedMessage(whatever);
- toEncodedMessage(whatever);`,
- errors: 1,
- },
- ],
-});
diff --git a/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.ts b/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.ts
deleted file mode 100644
index 73c56b76863..00000000000
--- a/eslint-bridge/tests/tools/sonar-runtime/rule/no-missing-sonar-runtime.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as estree from 'estree';
-import { Rule } from 'eslint';
-import {
- getFullyQualifiedName,
- getImportDeclarations,
- getObjectExpressionProperty,
- getUniqueWriteUsage,
- isIdentifier,
-} from 'linting/eslint/rules/helpers';
-
-/**
- *
- */
-export const ruleId = 'no-missing-sonar-runtime';
-
-/**
- * This rule is applied to our own code in the `src/rules` directory.
- * It checks whether the `sonar-runtime` is set for rules that obviously use the
- * `toEncodedMessage` method (which encodes secondary locations).
- */
-export const rule: Rule.RuleModule = {
- create(context: Rule.RuleContext) {
- let isSecondaryLocationUsed = false;
- let isSecondaryLocationEnabled = false;
- return {
- CallExpression: (node: estree.Node) => {
- if (isSecondaryLocationUsed) {
- return;
- }
- const { callee } = node as estree.CallExpression;
- if (callee.type === 'Identifier' && callee.name === 'toEncodedMessage') {
- isSecondaryLocationUsed =
- getModuleNameOfImportedIdentifier(context, callee) === './helpers';
- }
- },
- ObjectExpression: (node: estree.Node) => {
- if (isSecondaryLocationEnabled) {
- return;
- }
- const maybeMeta = getObjectExpressionProperty(node, 'meta');
- if (maybeMeta) {
- const maybeSchema = getObjectExpressionProperty(maybeMeta.value, 'schema');
- if (maybeSchema && maybeSchema.value.type === 'ArrayExpression') {
- const schema = maybeSchema.value;
- for (const element of schema.elements) {
- const maybeEnum = getObjectExpressionProperty(element, 'enum');
- if (maybeEnum) {
- isSecondaryLocationEnabled =
- maybeEnum.value.type === 'ArrayExpression' &&
- maybeEnum.value.elements.length === 1 &&
- maybeEnum.value.elements[0].type === 'Identifier' &&
- maybeEnum.value.elements[0].name === 'SONAR_RUNTIME';
- }
- }
- }
- }
- },
- 'Program:exit': (node: estree.Node) => {
- if (isSecondaryLocationUsed && !isSecondaryLocationEnabled) {
- context.report({
- message: `Missing enabling of secondary location support`,
- node,
- });
- }
- },
- };
- },
-};
-
-/**
- * Returns the module name, when an identifier represents a binding imported from another module.
- * Returns undefined otherwise.
- * example: Given `import { f } from 'module_name'`, `getModuleNameOfImportedIdentifier(f)` returns `module_name`
- */
-function getModuleNameOfImportedIdentifier(
- context: Rule.RuleContext,
- identifier: estree.Identifier,
-) {
- // check if importing using `import { f } from 'module_name'`
- const importedDeclaration = getImportDeclarations(context).find(({ specifiers }) =>
- specifiers.some(
- spec => spec.type === 'ImportSpecifier' && spec.imported.name === identifier.name,
- ),
- );
- if (importedDeclaration) {
- return importedDeclaration.source.value;
- }
- // check if importing using `const f = require('module_name').f` or `const { f } = require('module_name')`
- const writeExpression = getUniqueWriteUsage(context, identifier.name);
- if (writeExpression) {
- let maybeRequireCall: estree.Node;
- if (
- writeExpression.type === 'MemberExpression' &&
- isIdentifier(writeExpression.property, identifier.name)
- ) {
- maybeRequireCall = writeExpression.object;
- } else {
- maybeRequireCall = writeExpression;
- }
- const fqn = getFullyQualifiedName(context, maybeRequireCall);
- return fqn?.split('.')[0];
- }
-
- return undefined;
-}
diff --git a/eslint-bridge/tests/tools/sonar-runtime/sonar-runtime.test.ts b/eslint-bridge/tests/tools/sonar-runtime/sonar-runtime.test.ts
deleted file mode 100644
index d629ec74846..00000000000
--- a/eslint-bridge/tests/tools/sonar-runtime/sonar-runtime.test.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { rules } from 'linting/eslint';
-import { Linter, SourceCode } from 'eslint';
-import {
- rule as noMissingSonarRuntimeRule,
- ruleId as noMissingSonarRuntimeRuleId,
-} from './rule/no-missing-sonar-runtime';
-import { parseTypeScriptSourceFile } from '../helpers';
-import path from 'path';
-import { fileReadable } from '../helpers/files';
-
-/**
- * Detects missing secondary location support for rules using secondary locations.
- *
- * A rule is considered to be using secondary location if its implementation calls at
- * some point `toEncodedMessage` from `linting/eslint/rules/helpers/location.ts`.
- *
- * The idea is to parse and analyze the source code of all rules that are exposed in
- * the module `rules/main.ts`. The analysis relies on an internal rule that checks a
- * few conditions required for secondary locations to correctly be supported:
- *
- * - the rule calls `toEncodedMessage` from `./helpers`,
- * - the rule includes `meta: { schema: [{ enum: ['SONAR_RUNTIME'] }] }` metadata.
- * SONAR_RUNTIME is available in 'linting/eslint/linter/parameters'
- *
- * The source code of the exported rules violating these conditions will trigger an
- * issue during analysis.
- *
- * The detection is formalized in the form of a unit test. The rule implementations
- * missing something are collected. The presence of such rules eventually makes the
- * test fail, and the names of the problematical rules are reported.
- */
-describe('sonar-runtime', () => {
- it('should be enabled for rules using secondary locations', () => {
- const misconfiguredRules = [];
-
- const linter = new Linter();
- linter.defineRule(noMissingSonarRuntimeRuleId, noMissingSonarRuntimeRule);
-
- Object.keys(rules).forEach(async rule => {
- const ruleFilePath = path.join(
- __dirname,
- '/../../../src/linting/eslint/rules/',
- `${rule}.ts`,
- );
- if (!(await fileReadable(ruleFilePath))) {
- throw new Error(
- `The file '${ruleFilePath}' corresponding to rule name '${rule}' is missing. ` +
- 'A mismatch between the rule id and its corresponding file name?',
- );
- }
-
- const ruleSourceCode = (await parseTypeScriptSourceFile(ruleFilePath, [])) as SourceCode;
-
- const issues = linter.verify(ruleSourceCode, {
- rules: { [noMissingSonarRuntimeRuleId]: 'error' },
- });
- if (issues.length > 0) {
- misconfiguredRules.push(rule);
- }
- });
-
- expect(misconfiguredRules).toEqual([]);
- });
-});
diff --git a/eslint-bridge/tests/tools/testers/babel/index.ts b/eslint-bridge/tests/tools/testers/babel/index.ts
deleted file mode 100644
index c8d70dd55d2..00000000000
--- a/eslint-bridge/tests/tools/testers/babel/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './tester';
diff --git a/eslint-bridge/tests/tools/testers/babel/tester.ts b/eslint-bridge/tests/tools/testers/babel/tester.ts
deleted file mode 100644
index 90ff1a83e18..00000000000
--- a/eslint-bridge/tests/tools/testers/babel/tester.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RuleTester } from 'eslint';
-import { buildParserOptions } from 'parsing/jsts';
-
-export function BabelRuleTester() {
- const parserOptions = buildParserOptions(
- { filePath: 'some/filePath', tsConfigs: [], fileContent: '', fileType: 'MAIN' },
- true,
- );
- return new RuleTester({
- // we use babel to parse JSX syntax
- parser: require.resolve('@babel/eslint-parser'),
- parserOptions,
- });
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/adjustment.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/adjustment.js
deleted file mode 100644
index 88dc11a8f45..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/adjustment.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Noncompliant@+1
-alert(msg);
-
-alert(msg); // Noncompliant {{Expected error message}}
-// ^^^
-// ^^^^^@-1< {{Secondary location message1}}
-// ^@-2< {{Secondary location message2}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/conflict.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/conflict.js
deleted file mode 100644
index b98ead6f6c3..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/conflict.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg, msg); // Noncompliant {{Expected error message}}
-// ^^^ ^^^
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/count.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/count.js
deleted file mode 100644
index 8ff3622be50..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/count.js
+++ /dev/null
@@ -1 +0,0 @@
-alert(msg); // Noncompliant 2
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/ignored.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/ignored.js
deleted file mode 100644
index 4c32d23f037..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/ignored.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// ignored
-
-/* ignored */
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/merge.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/merge.js
deleted file mode 100644
index 8025be5c48b..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/merge.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Noncompliant@+2
-// Noncompliant@+1
-alert(msg);
-
-// Noncompliant@+2
-// Noncompliant@+1
-alert(msg);
-// ^^^
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/message.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/message.js
deleted file mode 100644
index a6665d7d8d2..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/message.js
+++ /dev/null
@@ -1 +0,0 @@
-alert(msg); // Noncompliant {{Expected error message}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/missing_secondary.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/missing_secondary.js
deleted file mode 100644
index 5d21b99a788..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/missing_secondary.js
+++ /dev/null
@@ -1,6 +0,0 @@
-alert(msg);
-// ^^^> {{Secondary location message}}
-alert(msg); // Noncompliant {{Rule message}}
-// ^^^
-
-console.log(msg); // Noncompliant {{Rule message}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/mix.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/mix.js
deleted file mode 100644
index b317df9a937..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/mix.js
+++ /dev/null
@@ -1 +0,0 @@
-alert(msg); // Noncompliant 2 {{Expected error message}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/multiple.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/multiple.js
deleted file mode 100644
index 96d16c14aae..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/multiple.js
+++ /dev/null
@@ -1 +0,0 @@
-alert(msg); // Noncompliant {{Expected error message 1}} {{Expected error message 2}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/non_compliant.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/non_compliant.js
deleted file mode 100644
index dbd2761bf7e..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/non_compliant.js
+++ /dev/null
@@ -1 +0,0 @@
-alert(msg); // Noncompliant
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan0.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan0.js
deleted file mode 100644
index e1c04b81f34..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan0.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg);
-// ^^^
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan1.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan1.js
deleted file mode 100644
index bd9e86db9f7..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan1.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg);
-// ^^^< {{Secondary location message}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan2.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan2.js
deleted file mode 100644
index 5f28439fe59..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/orphan2.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg);
-// ^^^> {{Secondary location message}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/parsing.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/parsing.js
deleted file mode 100644
index e1dc26375f1..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/parsing.js
+++ /dev/null
@@ -1,2 +0,0 @@
-console.log('https://hello.i.have.2.slashes.com/yo'); // Noncompliant
-
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/primary.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/primary.js
deleted file mode 100644
index 72b94f2b763..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/primary.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg); // Noncompliant {{Rule message}}
-// ^^^
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/secondary.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/secondary.js
deleted file mode 100644
index 3583428f419..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/secondary.js
+++ /dev/null
@@ -1,6 +0,0 @@
-alert(msg);
-// ^^^> {{Secondary location message1}}
-alert(msg); // Noncompliant {{Rule message}}
-// ^^^
-alert(msg);
-// ^^^< {{Secondary location message2}}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/fixtures/unexpected.js b/eslint-bridge/tests/tools/testers/comment-based/fixtures/unexpected.js
deleted file mode 100644
index 460dba9a584..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/fixtures/unexpected.js
+++ /dev/null
@@ -1,2 +0,0 @@
-alert(msg); // Noncompliant {{Rule message}}
-// ^^^ unexpected
diff --git a/eslint-bridge/tests/tools/testers/comment-based/framework.test.ts b/eslint-bridge/tests/tools/testers/comment-based/framework.test.ts
deleted file mode 100644
index 1f9644b3140..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/framework.test.ts
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as path from 'path';
-import { extractExpectations } from './framework';
-import { readFile } from 'helpers';
-
-describe('Comment-based Testing Framework', () => {
- const baseDir = path.resolve(`${__dirname}/fixtures`);
-
- async function assertions(filename: string, usesSecondaryLocations = false) {
- const filePath = path.join(baseDir, filename);
- const code = await readFile(filePath);
- return extractExpectations(code, filePath, usesSecondaryLocations);
- }
-
- it('non compliant', async () => {
- expect(await assertions('non_compliant.js')).toMatchObject({ errors: [{ line: 1 }] });
- });
-
- it('issue message', async () => {
- expect(await assertions('message.js')).toMatchObject({
- errors: [{ line: 1, message: 'Expected error message' }],
- });
- });
-
- it('multiple issue message', async () => {
- expect(await assertions('multiple.js')).toMatchObject({
- errors: [
- { line: 1, message: 'Expected error message 1' },
- { line: 1, message: 'Expected error message 2' },
- ],
- });
- });
-
- it('issue count', async () => {
- expect(await assertions('count.js')).toMatchObject({ errors: [{ line: 1 }, { line: 1 }] });
- });
-
- it('mixing message and count', async () => {
- const error = await assertions('mix.js').catch(err => err);
- expect(error.message).toEqual(
- 'Error, you can not specify issue count and messages at line 1, you have to choose either:' +
- '\n Noncompliant 2\nor\n Noncompliant {{Expected error message}}\n',
- );
- });
-
- it('primary', async () => {
- expect(await assertions('primary.js')).toMatchObject({
- errors: [
- {
- column: 7,
- endColumn: 10,
- endLine: 1,
- line: 1,
- message: 'Rule message',
- },
- ],
- });
- });
-
- it('secondary', async () => {
- expect(await assertions('secondary.js', true)).toMatchObject({
- errors: [
- {
- column: 7,
- line: 3,
- endColumn: 10,
- endLine: 3,
- message: JSON.stringify({
- message: 'Rule message',
- secondaryLocations: [
- {
- message: 'Secondary location message1',
- column: 6,
- line: 1,
- endColumn: 9,
- endLine: 1,
- },
- {
- message: 'Secondary location message2',
- column: 6,
- line: 5,
- endColumn: 9,
- endLine: 5,
- },
- ],
- }),
- },
- ],
- });
- });
-
- it('missing secondary', async () => {
- expect(await assertions('missing_secondary.js', true)).toMatchObject({
- errors: expect.arrayContaining([
- {
- line: 6,
- message: JSON.stringify({
- message: 'Rule message',
- secondaryLocations: [],
- }),
- },
- ]),
- });
- });
-
- it('line adjustment', async () => {
- expect(await assertions('adjustment.js', true)).toMatchObject({
- errors: [
- {
- line: 2,
- },
- {
- column: 7,
- endColumn: 10,
- endLine: 4,
- line: 4,
- message: JSON.stringify({
- message: 'Expected error message',
- secondaryLocations: [
- {
- message: 'Secondary location message1',
- column: 7,
- line: 4,
- endColumn: 12,
- endLine: 4,
- },
- {
- message: 'Secondary location message2',
- column: 12,
- line: 4,
- endColumn: 13,
- endLine: 4,
- },
- ],
- }),
- },
- ],
- });
- });
-
- it('issue merging', async () => {
- expect(await assertions('merge.js')).toMatchObject({
- errors: [
- { line: 3 },
- { line: 3 },
- {
- column: 7,
- endColumn: 10,
- endLine: 7,
- line: 7,
- },
- {
- column: 7,
- endColumn: 10,
- endLine: 7,
- line: 7,
- },
- ],
- });
- });
-
- it('ignoring comment', async () => {
- const result = await assertions('ignored.js').catch(err => err);
- expect(result).toMatchObject({ errors: [] });
- });
-
- it('unexpected character', async () => {
- const error = await assertions('unexpected.js').catch(err => err);
- expect(error.message).toEqual("Unexpected character 'u' found at 2:10");
- });
-
- it('conflictual primary', async () => {
- const error = await assertions('conflict.js').catch(err => err);
- expect(error.message).toEqual(
- 'Primary location conflicts with another primary location at (1:12,1:15)',
- );
- });
-
- it('orphan location', async () => {
- let error = await assertions('orphan0.js').catch(err => err);
- expect(error.message).toEqual('Primary location does not have a related issue at (1:7,1:10)');
- error = await assertions('orphan1.js').catch(err => err);
- expect(error.message).toEqual(
- "Secondary location '<' without previous primary location at (1:6,1:9)",
- );
- error = await assertions('orphan2.js').catch(err => err);
- expect(error.message).toEqual(
- "Secondary location '>' without next primary location at (1:6,1:9)",
- );
- });
-
- it('comments parsing ambiguity', async () => {
- const result = await assertions('parsing.js');
- expect(result).toMatchObject({ errors: [{ line: 1 }] });
- });
-
- it('quickfix', () => {
- const code = `
-wrong.code();// Noncompliant [[qf]]
-// fix@qf {{description}}
-// edit@qf {{fixed.code();}}`;
- expect(extractExpectations(code, '', false)).toMatchObject({
- errors: [
- {
- line: 2,
- suggestions: [
- {
- desc: 'description',
- output: `
-fixed.code();// Noncompliant [[qf]]
-// fix@qf {{description}}
-// edit@qf {{fixed.code();}}`,
- },
- ],
- },
- ],
- });
- });
-
- it('wrong quickfix id', () => {
- const code = `
-wrong.code();// Noncompliant [[qf]]
-// fix@qf1 {{description}}`;
- expect(() => extractExpectations(code, '', false)).toThrow(/Unexpected quickfix ID 'qf1'/);
- });
-
- it('quickfix id already declared', () => {
- const code = `wrong.code();// Noncompliant [[qf, qf]]`;
- expect(() => extractExpectations(code, '', false)).toThrow(
- 'QuickFix ID qf has already been declared',
- );
- });
-
- it('quickfix wrong end column', () => {
- const code = `
-wrong.code();// Noncompliant [[qf]]
-// edit@qf [[ec=20]] {{fixed.code();}}`;
- expect(() => extractExpectations(code, '', false)).toThrow(
- /End column cannot be in \/\/ Noncompliant comment/,
- );
- });
-
- it('quickfix end below start column', () => {
- const code = `
-wrong.code();// Noncompliant [[qf]]
-// edit@qf [[ec=2;sc=10]] {{fixed.code();}}`;
- expect(() => extractExpectations(code, '', false)).toThrow(
- /End column cannot be lower than start position/,
- );
- });
-
- it('quickfix with start and end column', () => {
- const code = `
-wrong.code();// Noncompliant [[qf]]
-// edit@qf [[ec=10;sc=6]] {{smelly.buggy.code}}`;
- expect(extractExpectations(code, '', false)).toMatchObject({
- errors: [
- {
- line: 2,
- suggestions: [
- {
- output: `
-wrong.smelly.buggy.code();// Noncompliant [[qf]]
-// edit@qf [[ec=10;sc=6]] {{smelly.buggy.code}}`,
- },
- ],
- },
- ],
- });
- });
-
- it('quickfix with 2 suggestions in same issue', () => {
- const code = `
-wrong.code();// Noncompliant [[qf1,qf2=0]]
-// edit@qf1 [[ec=5]] {{fixed}}
-// edit@qf2 [[ec=5]] {{repaired}}`;
- expect(extractExpectations(code, '', false)).toMatchObject({
- errors: [
- {
- line: 2,
- suggestions: [
- {
- output: `
-fixed.code();// Noncompliant [[qf1,qf2=0]]
-// edit@qf1 [[ec=5]] {{fixed}}
-// edit@qf2 [[ec=5]] {{repaired}}`,
- },
- {
- output: `
-repaired.code();// Noncompliant [[qf1,qf2=0]]
-// edit@qf1 [[ec=5]] {{fixed}}
-// edit@qf2 [[ec=5]] {{repaired}}`,
- },
- ],
- },
- ],
- });
- });
-
- it('autofix with multiple edits', () => {
- const code = `
-wrong.code();// Noncompliant [[qf!]]
-
-//comment to remove
-// edit@qf [[ec=5]] {{fixed}}
-// add@qf@+1 {{better.code();}}
-// del@qf@+2
-
-bad.code();// Noncompliant [[qf2!]]
-
-//another comment to remove
-// edit@qf2 [[ec=3]] {{good}}
-// add@qf2@+1 {{super.code();}}
-// del@qf2@+2
-`;
- expect(extractExpectations(code, '', false)).toMatchObject({
- output: `
-fixed.code();// Noncompliant [[qf!]]
-better.code();
-
-// edit@qf [[ec=5]] {{fixed}}
-// add@qf@+1 {{better.code();}}
-// del@qf@+2
-
-good.code();// Noncompliant [[qf2!]]
-super.code();
-
-// edit@qf2 [[ec=3]] {{good}}
-// add@qf2@+1 {{super.code();}}
-// del@qf2@+2
-`,
- });
- });
-});
diff --git a/eslint-bridge/tests/tools/testers/comment-based/framework.ts b/eslint-bridge/tests/tools/testers/comment-based/framework.ts
deleted file mode 100644
index 213fab9ba72..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/framework.ts
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Comment-based Testing Framework
- *
- * This utility is a TypeScript implementation of the commented-based testing framework of `sonar-analyzer-commons`,
- * which is implemented in Java. It supports most of the documented features except for the `effortToFix` feature.
- *
- * Basically, this testing framework extracts convential comments from a source file that denote expected occurences
- * of issues at well-located lines with expected messages and secondary locations, if any.
- *
- * As such, this testing framework cannot be used to test actual rule implementatons, as it only provides a helper
- * function to extract issue expectations. To use it, please refer to `launcher.test.ts`.
- *
- * @see https://github.com/SonarSource/sonar-analyzer-commons/tree/master/test-commons
- * @see https://github.com/SonarSource/sonar-analyzer-commons/tree/master/test-commons#noncompliant-format
- */
-
-import { RuleTester } from 'eslint';
-import { toEncodedMessage } from 'linting/eslint/rules/helpers';
-import { FileIssues, LineIssues } from './helpers';
-import { Change, QuickFix } from './helpers/quickfixes';
-
-interface ExpectationsResult {
- errors: RuleTester.TestCaseError[];
- output: string | null;
-}
-/**
- * Extracts issue expectations from a comment-based test file
- * @param fileContent the contents of the comment-based test file
- * @param filePath used to know if it's Vue or not
- * @param usesSecondaryLocations A flag that indicates if the tested rule uses sonar-runtime parameter
- * @returns an array of ESLint test case errors
- */
-export function extractExpectations(
- fileContent: string,
- filePath: string,
- usesSecondaryLocations: boolean,
-): ExpectationsResult {
- const expectedIssues = new FileIssues(fileContent, filePath).getExpectedIssues();
- const encodeMessageIfNeeded = usesSecondaryLocations ? toEncodedMessage : message => message;
- const result: ExpectationsResult = { errors: [], output: fileContent };
- expectedIssues.forEach(issue => {
- const line = issue.line;
- const primary = issue.primaryLocation;
- const messages = [...issue.messages.values()];
- const quickfixes = issue.quickfixes ? [...issue.quickfixes.values()] : [];
- messages.forEach((message, index) => {
- const suggestions = applyQuickFixes(
- quickfixes.filter(quickfix => quickfix.messageIndex === index),
- fileContent,
- result,
- expectedIssues,
- );
- const error: RuleTester.TestCaseError = { ...suggestions, ...(primary?.range || { line }) };
- if (primary !== null) {
- const secondary = primary.secondaryLocations;
- if (secondary.length) {
- error.message = encodeMessageIfNeeded(
- message,
- secondary.map(s => s.range.toLocationHolder()),
- secondary.map(s => s.message),
- );
- }
- }
- if (!error.message && message) {
- error.message = encodeMessageIfNeeded(message);
- }
-
- result.errors.push(error);
- });
- });
- if (result.output === fileContent) {
- result.output = null;
- }
- return result;
-}
-
-interface Suggestions {
- suggestions?: RuleTester.SuggestionOutput[];
-}
-
-/**
- * Applies quick fix operations to the source code line.
- *
- * @param quickfixes array of quick fixes to apply
- * @param fileContent the file contents
- * @param result The result object to have access to the output attribute
- * @param issues the array of issues, needed if a reindex needs to be done on all quickfixes
- */
-function applyQuickFixes(
- quickfixes: QuickFix[],
- fileContent: string,
- result: ExpectationsResult,
- issues: LineIssues[],
-): Suggestions {
- const suggestions: RuleTester.SuggestionOutput[] = [];
- for (const quickfix of quickfixes) {
- const lines = (quickfix.mandatory ? result.output : fileContent).split(/\n/);
- const { description: desc, changes } = quickfix;
- for (const change of changes) {
- switch (change.type) {
- case 'add':
- addLine(lines, change);
- if (quickfix.mandatory) {
- reIndexLines(issues, true, change.line);
- }
- break;
- case 'del':
- deleteLine(lines, change);
- if (quickfix.mandatory) {
- reIndexLines(issues, false, change.line);
- }
- break;
- case 'edit':
- editLine(lines, change);
- }
- }
-
- const output = lines.join('\n');
-
- if (output !== fileContent) {
- if (quickfix.mandatory) {
- result.output = output;
- } else {
- const suggestion: RuleTester.SuggestionOutput = { output };
- if (desc) {
- suggestion.desc = desc;
- }
- suggestions.push(suggestion);
- }
- }
- }
- return suggestions.length ? { suggestions } : {};
-}
-
-/**
- * After quickfixes add or delete a line, re-index the lines higher than
- * then given index, incrementing them by one when increment is true
- * or decrementing them otherwise
- * @param issues all issues from the file
- * @param increment where the lines need to be incremented or decremented
- * @param start starting line from which the change should be made
- */
-function reIndexLines(issues: LineIssues[], increment: boolean, start: number) {
- for (const issue of issues) {
- for (const quickfix of issue.quickfixes) {
- if (quickfix.mandatory) {
- for (const change of quickfix.changes) {
- if (change.line > start) {
- increment ? change.line++ : change.line--;
- }
- }
- }
- }
- }
-}
-
-/**
- * Applies quick fix edits to a source code line. The fixed line will be formed by a
- * concatenation of three strings:
- * - Original line from column 0 until start of fix column
- * - Contents of fix
- * - Original line from end of fix column until end of original line
- *
- * @param lines array of lines from file
- * @param change the change descriptor
- */
-function editLine(lines: string[], change: Change) {
- const { start, end, contents, line: issueLine } = change;
- if (contents !== undefined) {
- let appendAfterFix = '';
- const line = lines[issueLine - 1];
- const containsNC = line.search(/\s*\{?\s*(\/\*|\/\/)\s*Noncompliant/);
- if (end === undefined) {
- if (containsNC >= 0) {
- appendAfterFix = line.slice(containsNC);
- }
- } else {
- if (end < start) {
- throw new Error(`End column cannot be lower than start position ${end} < ${start}`);
- }
- if (containsNC >= 0 && end > containsNC) {
- throw new Error(`End column cannot be in // Noncompliant comment ${end} > ${containsNC}`);
- }
- appendAfterFix = line.slice(end);
- }
- lines[issueLine - 1] = line.slice(0, start || 0) + contents + appendAfterFix;
- }
-}
-
-/**
- * Adds a new line to the source code at the index and with the contents described
- * in the Change object
- *
- * @param lines array of lines from file
- * @param change the change descriptor
- */
-function addLine(lines: string[], change: Change) {
- const { contents, line } = change;
- if (contents !== undefined) {
- lines.splice(line - 1, 0, contents);
- }
-}
-
-/**
- * Removes the line from the source code.
- *
- * @param lines array of lines from file
- * @param change the change descriptor
- */
-function deleteLine(lines: string[], change: Change) {
- lines.splice(change.line - 1, 1);
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/comments.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/comments.ts
deleted file mode 100644
index 01b12a30190..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/comments.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { buildSourceCode } from 'parsing/jsts';
-import * as estree from 'estree';
-import { SourceCode } from 'eslint';
-
-export interface Comment {
- value: string;
- line: number;
- column: number;
- endLine: number;
- endColumn: number;
-}
-
-/**
- *
- * @param fileContent
- * @param filePath
- * @returns
- */
-export function extractComments(fileContent: string, filePath: string): Comment[] {
- const parsed = buildSourceCode({ fileContent, filePath, fileType: null, tsConfigs: [] }, null);
- let esTreeComments: estree.Comment[];
- if (parsed instanceof SourceCode) {
- esTreeComments = parsed.getAllComments();
- } else {
- throw Error(`File not parseable: ${fileContent}`);
- }
- return esTreeComments.map(c => {
- return {
- value: c.value,
- line: c.loc.start.line,
- column: c.loc.start.column + 2, // these offsets are everywhere down the road
- endLine: c.loc.end.line,
- endColumn: c.loc.end.column + 1, // same
- };
- });
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/file.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/file.ts
deleted file mode 100644
index 5ec72b2b8da..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/file.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { extractComments } from './comments';
-import {
- Location,
- extractLocations,
- PrimaryLocation,
- SecondaryLocation,
- isLocationLine,
-} from './locations';
-import { extractQuickFixes, isQuickfixLine, QuickFix } from './quickfixes';
-import { LineIssues, extractLineIssues, isNonCompliantLine } from './issues';
-
-export class FileIssues {
- public readonly expectedIssues = new Map();
- public readonly quickfixes = new Map();
- private orphanSecondaryLocations: SecondaryLocation[] = [];
- private currentPrimary: PrimaryLocation | null = null;
-
- /**
- * Parses the file into its expected errors. Throws if error flags are not well formatted.
- * @param fileContent
- * @param filePath
- */
- constructor(fileContent: string, filePath: string) {
- const comments = extractComments(fileContent, filePath);
- for (const comment of comments) {
- if (isNonCompliantLine(comment.value)) {
- extractLineIssues(this, comment);
- } else if (isLocationLine(comment.value)) {
- extractLocations(this, comment);
- } else if (isQuickfixLine(comment.value)) {
- extractQuickFixes(this.quickfixes, comment);
- }
- }
- }
-
- getExpectedIssues(): LineIssues[] {
- if (this.orphanSecondaryLocations.length !== 0) {
- throw new Error(
- this.orphanSecondaryLocations
- .map(
- secondary =>
- `Secondary location '>' without next primary location at ${secondary.range.toString()}`,
- )
- .join('\n\n'),
- );
- }
- return [...this.expectedIssues.values()];
- }
-
- public addLocation(location: Location) {
- if (location instanceof PrimaryLocation) {
- this.addPrimary(location);
- } else {
- this.addSecondary(location as SecondaryLocation);
- }
- }
-
- private addPrimary(primary: PrimaryLocation) {
- const lineIssues = this.expectedIssues.get(primary.range.line);
- if (lineIssues === undefined) {
- throw new Error(
- `Primary location does not have a related issue at ${primary.range.toString()}`,
- );
- }
- if (lineIssues.primaryLocation !== null) {
- throw new Error(
- `Primary location conflicts with another primary location at ${primary.range.toString()}`,
- );
- }
- this.orphanSecondaryLocations.forEach(secondary => primary.secondaryLocations.push(secondary));
- this.orphanSecondaryLocations = [];
- lineIssues.primaryLocation = primary;
- this.currentPrimary = primary;
- }
-
- private addSecondary(secondary: SecondaryLocation) {
- if (secondary.primaryIsBefore) {
- if (this.currentPrimary == null) {
- throw new Error(
- `Secondary location '<' without previous primary location at ${secondary.range.toString()}`,
- );
- }
- this.currentPrimary.secondaryLocations.push(secondary);
- } else {
- this.orphanSecondaryLocations.push(secondary);
- }
- }
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/index.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/index.ts
deleted file mode 100644
index fea04da153e..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export * from './comments';
-export * from './file';
-export * from './issues';
-export * from './locations';
-export * from './ranges';
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/issues.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/issues.ts
deleted file mode 100644
index 13eaa19f690..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/issues.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { extractEffectiveLine, LINE_ADJUSTMENT, PrimaryLocation } from './locations';
-import { QuickFix, QUICKFIX_ID, QUICKFIX_SEPARATOR } from './quickfixes';
-import { Comment } from './comments';
-import { FileIssues } from './file';
-
-const START_WITH_NON_COMPLIANT = /^ *Noncompliant/i;
-const NON_COMPLIANT_PATTERN = RegExp(
- ' *Noncompliant' +
- LINE_ADJUSTMENT +
- // issue count, ex: 2
- '(?: +(?\\d+))?' +
- // quickfixes, ex: [[qf1,qf2]]
- ' *(?:' +
- QUICKFIX_ID +
- ')?' +
- // messages, ex: {{msg1}} {{msg2}}
- ' *(?(\\{\\{.*?\\}\\} *)+)?',
- 'i',
-);
-
-export class LineIssues {
- public primaryLocation: PrimaryLocation | null;
- public quickfixes: QuickFix[] = [];
- constructor(
- readonly line: number,
- readonly messages: string[],
- quickfixes: string | undefined,
- quickFixesMap: Map,
- ) {
- this.primaryLocation = null;
- if (quickfixes?.length) {
- this.quickfixes = quickfixes
- .split(RegExp(QUICKFIX_SEPARATOR))
- .map((quickfixAndMessage, index) => {
- const [quickfixId, messageIndexStr] = quickfixAndMessage.split('=');
- const messageIndex = !messageIndexStr ? index : parseInt(messageIndexStr);
- if (quickFixesMap.has(quickfixId)) {
- throw new Error(`QuickFix ID ${quickfixId} has already been declared`);
- }
- if (messageIndex >= this.messages.length) {
- throw new Error(
- `QuickFix ID ${quickfixId} refers to message index ${messageIndex} but there are only ${this.messages.length} messages`,
- );
- }
- const [id, mandatory] = quickfixId.endsWith('!')
- ? [quickfixId.slice(0, -1), true]
- : [quickfixId, false];
- const qf = new QuickFix(id, mandatory, messageIndex, this);
- quickFixesMap.set(id, qf);
- return qf;
- });
- }
- }
-
- merge(other: LineIssues) {
- this.messages.push(...other.messages);
- if (this.primaryLocation === null) {
- this.primaryLocation = other.primaryLocation;
- }
- }
-}
-
-export function isNonCompliantLine(comment: string) {
- return START_WITH_NON_COMPLIANT.test(comment);
-}
-
-export function extractLineIssues(file: FileIssues, comment: Comment) {
- const matcher = comment.value.match(NON_COMPLIANT_PATTERN);
- if (matcher === null) {
- throw new Error(`Invalid comment format at line ${comment.line}: ${comment.value}`);
- }
- const effectiveLine = extractEffectiveLine(comment.line, matcher);
- const messages = extractIssueCountOrMessages(
- comment.line,
- matcher.groups?.issueCount,
- matcher.groups?.messages,
- );
- const lineIssues = new LineIssues(
- effectiveLine,
- messages,
- matcher.groups?.quickfixes,
- file.quickfixes,
- );
- const existingLineIssues = file.expectedIssues.get(lineIssues.line);
- if (existingLineIssues) {
- existingLineIssues.merge(lineIssues);
- } else {
- file.expectedIssues.set(lineIssues.line, lineIssues);
- }
-}
-
-function extractIssueCountOrMessages(
- line: number,
- issueCountGroup: string | undefined,
- messageGroup: string | undefined,
-) {
- if (messageGroup) {
- if (issueCountGroup) {
- throw new Error(
- `Error, you can not specify issue count and messages at line ${line}, you have to choose either:` +
- `\n Noncompliant ${issueCountGroup}\nor\n Noncompliant ${messageGroup}\n`,
- );
- }
- const messageContent = messageGroup.trim();
- return messageContent
- .substring('{{'.length, messageContent.length - '}}'.length)
- .split(/\}\} *\{\{/);
- }
- const issueCount = issueCountGroup ? parseInt(issueCountGroup) : 1;
- return new Array(issueCount);
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/locations.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/locations.ts
deleted file mode 100644
index 45c1d048378..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/locations.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { Range } from './ranges';
-import { FileIssues } from './file';
-import { Comment } from './comments';
-
-export const LINE_ADJUSTMENT = '(?:@(?(?[+-])?\\d+))?';
-
-const STARTS_WITH_LOCATION = /^ *\^/;
-const COUNT = '(?\\d+)';
-const DIRECTION = '(?[<>])';
-const MESSAGE = '(?.*?)';
-const LOCATION_PATTERN = RegExp(
- ' *' +
- // highlighted range, ex: ^^^^ |OR| ^^^@12 |OR| ^^^@-2
- '(?\\^(?:\\[(?[^\\]]+)\\]|\\^+)?)' +
- LINE_ADJUSTMENT +
- // count, ex: 3 |OR| direction
- ' *(?:' +
- COUNT +
- '|' +
- DIRECTION +
- ')?' +
- // message, ex: {{msg}}
- ' *(?:\\{\\{' +
- MESSAGE +
- '\\}\\})? *' +
- '(?:\r(\n?)|\n)?',
-);
-
-export abstract class Location {
- constructor(readonly range: Range) {}
-}
-
-export class PrimaryLocation extends Location {
- readonly secondaryLocations: SecondaryLocation[] = [];
-
- constructor(range: Range) {
- super(range);
- }
-}
-
-export class SecondaryLocation extends Location {
- index: number | undefined;
- message: string | undefined;
-
- constructor(range: Range, message: string | undefined, readonly primaryIsBefore: boolean) {
- // we need to extract 1 from columns as it's computed by us being sonar-friendly, while primary location is eslint-friendly
- super(new Range(range.line, range.column - 1, range.endLine, range.endColumn - 1));
- this.message = message;
- }
-}
-
-export function isLocationLine(comment: string) {
- return STARTS_WITH_LOCATION.test(comment);
-}
-
-export function extractLocations(file: FileIssues, comment: Comment) {
- const { line, column, value: commentContent } = comment;
- const locations: Location[] = [];
- let toBeMatched = commentContent;
- let offset = 0;
- let matcher: RegExpMatchArray | null;
- LOCATION_PATTERN.lastIndex = 0;
- while ((matcher = toBeMatched.match(LOCATION_PATTERN)) !== null) {
- locations.push(
- matcherToLocation(line, column, commentContent.indexOf(matcher[1], offset) + 1, matcher),
- );
- toBeMatched = toBeMatched.substring(matcher[0].length);
- offset += matcher[0].length;
- }
- if (offset !== commentContent.length) {
- throw new Error(
- `Unexpected character '${commentContent[offset]}' found at ${line}:${column + offset}`,
- );
- }
- if (locations.length) {
- for (const location of locations) {
- file.addLocation(location);
- }
- }
-}
-
-function matcherToLocation(
- line: number,
- column: number,
- offset: number,
- matcher: RegExpMatchArray,
-) {
- const effectiveLine = extractEffectiveLine(line - 1, matcher);
- const range = fileRange(effectiveLine, column, offset, matcher);
- const direction = matcher.groups?.direction;
- if (!direction) {
- return new PrimaryLocation(range);
- } else {
- return new SecondaryLocation(range, matcher.groups?.message, direction === '<');
- }
-}
-
-export function extractEffectiveLine(line: number, matcher: RegExpMatchArray) {
- const lineAdjustmentGroup = matcher.groups?.lineAdjustment;
- const relativeAdjustmentGroup = matcher.groups?.relativeAdjustment;
- const referenceLine = relativeAdjustmentGroup ? line : 0;
- return lineAdjustmentGroup ? referenceLine + parseInt(lineAdjustmentGroup) : line;
-}
-
-function fileRange(line: number, column: number, offset: number, matcher: RegExpMatchArray) {
- const rangeLine = line;
- const rangeColumn = column + offset;
- const rangeEndLine = line;
- const rangeEndColumn = rangeColumn + matcher[1].length;
- return new Range(rangeLine, rangeColumn, rangeEndLine, rangeEndColumn);
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/quickfixes.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/quickfixes.ts
deleted file mode 100644
index 2804c9fd320..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/quickfixes.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { LineIssues } from './issues';
-import { Comment } from './comments';
-import { extractEffectiveLine, LINE_ADJUSTMENT } from './locations';
-
-const STARTS_WITH_QUICKFIX = /^ *(edit|del|add|fix)@/;
-export const QUICKFIX_SEPARATOR = '[,\\s]+';
-export const QUICKFIX_ID =
- '\\[\\[(?\\w+(=\\d+)?!?(?:' + QUICKFIX_SEPARATOR + '(?:\\w+(=\\d+)?!?))*)\\]\\]';
-const QUICKFIX_DESCRIPTION_PATTERN = RegExp(
- ' *' +
- // quickfix description, ex: fix@qf1 {{Replace with foo}}
- 'fix@(?\\w+)' +
- // message, ex: {{msg}}
- ' *(?:\\{\\{(?.*?)\\}\\}(?!\\}))? *' +
- '(?:\r(\n?)|\n)?',
-);
-
-const QUICKFIX_CHANGE_PATTERN = RegExp(
- ' *' +
- // quickfix edit, ex: edit@qf1
- '(?edit|add|del)@(?\\w+)' +
- LINE_ADJUSTMENT +
- // start and end columns, ex: [[sc=1;ec=5]] both are optional
- ' *(?:\\[\\[' +
- '(?sc|ec)=(?\\d+)(?:;(?sc|ec)=(?\\d+))?' +
- '\\]\\])?' +
- // contents to be applied, ex: {{foo}}
- ' *(?:\\{\\{(?.*?)\\}\\}(?!\\}))?' +
- ' *(?:\r(\n?)|\n)?',
-);
-
-type ChangeType = 'add' | 'del' | 'edit';
-
-export type Change = {
- type: ChangeType;
- start: number | undefined;
- end: number | undefined;
- line: number;
- contents: string | undefined;
-};
-
-export class QuickFix {
- public changes: Change[] = [];
- public description: string | undefined = undefined;
- constructor(
- readonly id: string,
- readonly mandatory: boolean,
- readonly messageIndex: number,
- readonly lineIssues: LineIssues,
- ) {}
-}
-
-export function isQuickfixLine(comment: string) {
- return STARTS_WITH_QUICKFIX.test(comment);
-}
-
-export function extractQuickFixes(quickfixes: Map, comment: Comment) {
- if (QUICKFIX_DESCRIPTION_PATTERN.test(comment.value)) {
- const matches = comment.value.match(QUICKFIX_DESCRIPTION_PATTERN);
- const { quickfixId, message } = matches.groups;
- const quickfix = quickfixes.get(quickfixId);
- if (!quickfix) {
- throw new Error(
- `Unexpected quickfix ID '${quickfixId}' found at ${comment.line}:${comment.column}`,
- );
- } else if (quickfix.mandatory) {
- throw new Error(`ESLint fix '${quickfixId}' does not require description message`);
- }
- quickfix.description = message;
- } else if (QUICKFIX_CHANGE_PATTERN.test(comment.value)) {
- const matches = comment.value.match(QUICKFIX_CHANGE_PATTERN);
- const {
- quickfixId,
- type,
- firstColumnType,
- firstColumnValue,
- secondColumnType,
- secondColumnValue,
- contents,
- } = matches.groups;
- if (!quickfixes.has(quickfixId)) {
- throw new Error(
- `Unexpected quickfix ID '${matches.groups?.quickfixId}' found at ${comment.line}:${comment.column}`,
- );
- }
- const quickfix = quickfixes.get(quickfixId);
- const line = extractEffectiveLine(quickfix.lineIssues.line, matches);
- const edit: Change = {
- line,
- type: type as ChangeType,
- start:
- firstColumnType === 'sc'
- ? +firstColumnValue
- : secondColumnType === 'sc'
- ? +secondColumnValue
- : undefined,
- end:
- firstColumnType === 'ec'
- ? +firstColumnValue
- : secondColumnType === 'ec'
- ? +secondColumnValue
- : undefined,
- contents,
- };
- quickfix.changes.push(edit);
- }
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/helpers/ranges.ts b/eslint-bridge/tests/tools/testers/comment-based/helpers/ranges.ts
deleted file mode 100644
index 7e8c1556ac3..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/helpers/ranges.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-export class Range {
- constructor(
- readonly line: number,
- readonly column: number,
- readonly endLine: number,
- readonly endColumn: number,
- ) {}
-
- toLocationHolder() {
- return {
- loc: {
- start: { line: this.line, column: this.column },
- end: { line: this.endLine, column: this.endColumn },
- },
- };
- }
-
- toString() {
- return `(${this.line}:${this.column},${this.endLine}:${this.endColumn})`;
- }
-}
diff --git a/eslint-bridge/tests/tools/testers/comment-based/launcher.test.ts b/eslint-bridge/tests/tools/testers/comment-based/launcher.test.ts
deleted file mode 100644
index 8153994e536..00000000000
--- a/eslint-bridge/tests/tools/testers/comment-based/launcher.test.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2011-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Comment-based Testing Framework Launcher
- *
- * This file provides a launcher for the Comment-based Testing Framework, which relies
- * on Jest and ESLint's rule tester. Basically, it tests the rule implementation of each
- * test file in the `fixtures` of the current folder. To do so, it reads the file contents,
- * extracts from it the issue expectations, and use them as invalid test assertions with
- * ESLint's rule tester. To know which rule to test against a test file, the latter must
- * be named with the rule's name.
- *
- * @see package.json/ctest to test specific comment-based test files
- */
-
-import * as fs from 'fs';
-import * as path from 'path';
-import { Rule, RuleTester } from 'eslint';
-import { rules as reactESLintRules } from 'eslint-plugin-react';
-import { rules as typescriptESLintRules } from '@typescript-eslint/eslint-plugin';
-import { eslintRules } from 'linting/eslint/rules/core';
-import { rules as internalRules } from 'linting/eslint';
-import { hasSonarRuntimeOption } from 'linting/eslint/linter/parameters';
-import { buildSourceCode, Language } from 'parsing/jsts';
-import { FileType } from 'helpers';
-import { extractExpectations } from './framework';
-import { decorateExternalRules } from 'linting/eslint/linter/decoration';
-
-const fixtures = path.join(__dirname, '../../../linting/eslint/rules/comment-based');
-
-function extractRuleOptions(testFiles, rule) {
- if (testFiles.includes(`${rule}.json`)) {
- return JSON.parse(fs.readFileSync(path.join(fixtures, `${rule}.json`), { encoding: 'utf8' }));
- }
- return [];
-}
-
-function runRuleTests(rules: Record, ruleTester: RuleTester) {
- const testFiles = fs.readdirSync(fixtures);
- for (const testFile of testFiles) {
- const filename = path.join(fixtures, testFile);
- const { ext, name } = path.parse(filename);
- const rule = name.toLowerCase();
- if (
- ['.js', '.jsx', '.ts', '.tsx', '.vue'].includes(ext.toLowerCase()) &&
- rules.hasOwnProperty(rule)
- ) {
- describe(`Running comment-based tests for rule ${rule} ${ext}`, () => {
- const code = fs.readFileSync(filename, { encoding: 'utf8' }).replace(/\r?\n|\r/g, '\n');
- const { errors, output } = extractExpectations(
- code,
- filename,
- hasSonarRuntimeOption(rules[rule], rule),
- );
- const options = extractRuleOptions(testFiles, rule);
- const tests = {
- valid: [],
- invalid: [{ code, errors, filename, options, output }],
- };
- ruleTester.run(filename, rules[rule], tests);
- });
- }
- }
-}
-
-/**
- * This function is provided as 'parseForESLint' implementation which is used in RuleTester to invoke exactly same logic
- * as we use in our 'services/analysis/analyzer.ts' module
- */
-export function parseForESLint(
- fileContent: string,
- options: { filePath: string },
- fileType: FileType = 'MAIN',
-) {
- const { filePath } = options;
- const tsConfigs = [path.join(fixtures, 'tsconfig.json')];
- const sourceCode = buildSourceCode(
- { filePath, fileContent, fileType, tsConfigs },
- languageFromFile(fileContent, filePath),
- );
-
- /**
- * ESLint expects the parser services (including the type checker) to be available in a field
- * `services` after parsing while TypeScript ESLint returns it as `parserServices`. Therefore,
- * we need to extend the source code with this additional property so that the type checker
- * can be retrieved from type-aware rules.
- */
- return Object.create(sourceCode, {
- services: { value: sourceCode.parserServices },
- });
-}
-
-/**
- * Returns the source code's language based on the file content and path.
- */
-function languageFromFile(fileContent: string, filePath: string): Language {
- // Keep this regex aligned with the one in JavaScriptFilePredicate.java to have the same flow
- const hasScriptTagWithLangTs = /
-
diff --git a/its/plugin/projects/css-issues-project/src/file7.jsx b/its/plugin/projects/css-issues-project/src/file7.jsx
deleted file mode 100644
index 887ce8f3753..00000000000
--- a/its/plugin/projects/css-issues-project/src/file7.jsx
+++ /dev/null
@@ -1 +0,0 @@
-// file is not analyzed
diff --git a/its/plugin/projects/css-metrics-project/src/file1.css b/its/plugin/projects/css-metrics-project/src/file1.css
deleted file mode 100644
index fc4bf734a05..00000000000
--- a/its/plugin/projects/css-metrics-project/src/file1.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.class1 {
- background-color: #2d5e8b;
-}
-.class1 .class2 {
- color: #2d5e8b;
- foo: "some text";
-}
-
-/* some comment */
\ No newline at end of file
diff --git a/its/plugin/projects/css-metrics-project/src/file2.less b/its/plugin/projects/css-metrics-project/src/file2.less
deleted file mode 100644
index 691fd111bbf..00000000000
--- a/its/plugin/projects/css-metrics-project/src/file2.less
+++ /dev/null
@@ -1,11 +0,0 @@
-@color-base: #2d5e8b;
-.class1 {
- background-color: @color-base;
- .class2 {
- background-color: #fff;
- color: @color-base;
- foo: "some text";
- }
-}
-
-/* some comment */
\ No newline at end of file
diff --git a/its/plugin/projects/css-metrics-project/src/file3.scss b/its/plugin/projects/css-metrics-project/src/file3.scss
deleted file mode 100644
index fd624223ff9..00000000000
--- a/its/plugin/projects/css-metrics-project/src/file3.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-$firstValue: 62.5%;
-
-$firstValue: 24px !default;
-
-body {
- font-size: $firstValue;
- foo: "some text";
-}
-
-// body font size = 62.5%
-
-/* some comment */
\ No newline at end of file
diff --git a/its/plugin/projects/css-metrics-project/src/file4.html b/its/plugin/projects/css-metrics-project/src/file4.html
deleted file mode 100644
index 499a20b568b..00000000000
--- a/its/plugin/projects/css-metrics-project/src/file4.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-Example
-
-Hello World!
diff --git a/its/plugin/projects/css-minified-project/src/normal.css b/its/plugin/projects/css-minified-project/src/normal.css
deleted file mode 100644
index 60f1eab9713..00000000000
--- a/its/plugin/projects/css-minified-project/src/normal.css
+++ /dev/null
@@ -1,3 +0,0 @@
-body {
- color: red;
-}
diff --git a/its/plugin/projects/css-minified-project/src/normal.min.css b/its/plugin/projects/css-minified-project/src/normal.min.css
deleted file mode 100644
index d0e34073c1c..00000000000
--- a/its/plugin/projects/css-minified-project/src/normal.min.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/* content doesn't matter as file excluded based on filename */
-body {
- color: red;
-}
diff --git a/its/plugin/projects/css-minified-project/src/oneline.css b/its/plugin/projects/css-minified-project/src/oneline.css
deleted file mode 100644
index 072f35ffef8..00000000000
--- a/its/plugin/projects/css-minified-project/src/oneline.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Styles */ @import url(extra.css);ul li{list-style:square;margin:2em 20% 15px 0}#content{-webkit-font-smoothing:antialiased;background:url(img/gradient.png);background:linear-gradient(to bottom,red,rgba(255,0,0,0))}@media only screen and (min-width:35em){#content{width:50%}}.item+.item,.item~.item{margin-left:-15px}#buttons .lotsofcontent,#buttons>*,input[type=submit]{border-radius:.3rem}a:focus,a:hover{color:green}blockquote::after,blockquote::before{content:"\201d"}
diff --git a/its/plugin/projects/css-php-project/src/index.php b/its/plugin/projects/css-php-project/src/index.php
deleted file mode 100644
index 54d36eefa3c..00000000000
--- a/its/plugin/projects/css-php-project/src/index.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- Index
-
-
-
- = "Hello World!" ?>
-
-
diff --git a/its/plugin/projects/css-sonarlint-project/file.css b/its/plugin/projects/css-sonarlint-project/file.css
deleted file mode 100644
index 5acb8d64db6..00000000000
--- a/its/plugin/projects/css-sonarlint-project/file.css
+++ /dev/null
@@ -1,10 +0,0 @@
-@import "foo.css";
-@import "foo.css"; /* S1128 | no-duplicate-at-import-rules */
-
-a {
- color: pink;; /* S1116 | no-extra-semicolons */
-}
-
-a::pseudo { /* S4660 | selector-pseudo-element-no-unknown */
- color: red;
-}
diff --git a/its/plugin/projects/custom_rules/src/dir/Person.js b/its/plugin/projects/custom_rules/src/dir/Person.js
deleted file mode 100644
index 277c16d23e8..00000000000
--- a/its/plugin/projects/custom_rules/src/dir/Person.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/** BaseTreeVisitor **/
-var Person = function (first, last, middle) {
- this.first = first;
- this.middle = middle;
- this.last = last;
-};
-
-/** SubscriptionBaseVisitor **/
-var myArray = [1, 2, 3];
-
-for (props in myArray) {
- // do something;
-}
-
-/**
- * SubscriptionBaseVisitorCheck2
- */
-while (i > 10) {}
-
-// eslint based custom rule reports on CallExpression
-foo();
diff --git a/its/plugin/projects/custom_rules/src/dir/file.ts b/its/plugin/projects/custom_rules/src/dir/file.ts
deleted file mode 100644
index a9bba69aa6f..00000000000
--- a/its/plugin/projects/custom_rules/src/dir/file.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-// eslint based custom rule reports on CallExpression
-foo();
diff --git a/its/plugin/projects/custom_rules/src/dir/tsconfig.json b/its/plugin/projects/custom_rules/src/dir/tsconfig.json
deleted file mode 100644
index 0db3279e44b..00000000000
--- a/its/plugin/projects/custom_rules/src/dir/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-
-}
diff --git a/its/plugin/projects/eslint_based_rules/main.js b/its/plugin/projects/eslint_based_rules/main.js
deleted file mode 100644
index ccdcb880415..00000000000
--- a/its/plugin/projects/eslint_based_rules/main.js
+++ /dev/null
@@ -1,5 +0,0 @@
-if (cond) {
- foo();
-} else {
- foo();
-}
diff --git a/its/plugin/projects/eslint_based_rules_with_ts/main.js b/its/plugin/projects/eslint_based_rules_with_ts/main.js
deleted file mode 100644
index ccdcb880415..00000000000
--- a/its/plugin/projects/eslint_based_rules_with_ts/main.js
+++ /dev/null
@@ -1,5 +0,0 @@
-if (cond) {
- foo();
-} else {
- foo();
-}
diff --git a/its/plugin/projects/eslint_based_rules_with_ts/package-lock.json b/its/plugin/projects/eslint_based_rules_with_ts/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/eslint_based_rules_with_ts/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/eslint_based_rules_with_ts/package.json b/its/plugin/projects/eslint_based_rules_with_ts/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/eslint_based_rules_with_ts/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/eslint_report/.eslintrc.json b/its/plugin/projects/eslint_report/.eslintrc.json
deleted file mode 100644
index 3aa7df2fbd2..00000000000
--- a/its/plugin/projects/eslint_report/.eslintrc.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "env": {
- "browser": true,
- "es6": true
- },
- "extends": "eslint:recommended",
- "parserOptions": {
- "sourceType": "module"
- },
- "parser": "typescript-eslint-parser",
- "rules": {
- "linebreak-style": [
- "error",
- "unix"
- ],
- "quotes": [
- "error",
- "double"
- ],
- "semi": [
- "error",
- "always"
- ]
- }
-}
diff --git a/its/plugin/projects/eslint_report/package-lock.json b/its/plugin/projects/eslint_report/package-lock.json
deleted file mode 100644
index f6b23669928..00000000000
--- a/its/plugin/projects/eslint_report/package-lock.json
+++ /dev/null
@@ -1,1037 +0,0 @@
-{
- "name": "eslint",
- "version": "1.0.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "acorn": {
- "version": "5.5.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
- "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ=="
- },
- "acorn-jsx": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
- "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
- "requires": {
- "acorn": "3.3.0"
- },
- "dependencies": {
- "acorn": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
- "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
- }
- }
- },
- "ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
- "requires": {
- "co": "4.6.0",
- "fast-deep-equal": "1.1.0",
- "fast-json-stable-stringify": "2.0.0",
- "json-schema-traverse": "0.3.1"
- }
- },
- "ajv-keywords": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
- "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I="
- },
- "ansi-escapes": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
- "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "1.0.3"
- }
- },
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
- "requires": {
- "array-uniq": "1.0.3"
- }
- },
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
- },
- "babel-code-frame": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
- "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
- "requires": {
- "chalk": "1.1.3",
- "esutils": "2.0.2",
- "js-tokens": "3.0.2"
- },
- "dependencies": {
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- }
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "buffer-from": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
- "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
- },
- "caller-path": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
- "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
- "requires": {
- "callsites": "0.2.0"
- }
- },
- "callsites": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
- "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo="
- },
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "requires": {
- "ansi-styles": "3.2.1",
- "escape-string-regexp": "1.0.5",
- "supports-color": "5.4.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "1.9.1"
- }
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "requires": {
- "has-flag": "3.0.0"
- }
- }
- }
- },
- "chardet": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
- "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
- },
- "circular-json": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
- "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A=="
- },
- "cli-cursor": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
- "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
- "requires": {
- "restore-cursor": "2.0.0"
- }
- },
- "cli-width": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
- "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "requires": {
- "buffer-from": "1.0.0",
- "inherits": "2.0.3",
- "readable-stream": "2.3.6",
- "typedarray": "0.0.6"
- }
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
- "requires": {
- "lru-cache": "4.1.3",
- "shebang-command": "1.2.0",
- "which": "1.3.0"
- }
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "deep-is": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
- "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
- },
- "del": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
- "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
- "requires": {
- "globby": "5.0.0",
- "is-path-cwd": "1.0.0",
- "is-path-in-cwd": "1.0.1",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1",
- "rimraf": "2.6.2"
- }
- },
- "doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
- "requires": {
- "esutils": "2.0.2"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
- },
- "eslint": {
- "version": "4.19.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
- "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
- "requires": {
- "ajv": "5.5.2",
- "babel-code-frame": "6.26.0",
- "chalk": "2.4.1",
- "concat-stream": "1.6.2",
- "cross-spawn": "5.1.0",
- "debug": "3.1.0",
- "doctrine": "2.1.0",
- "eslint-scope": "3.7.1",
- "eslint-visitor-keys": "1.0.0",
- "espree": "3.5.4",
- "esquery": "1.0.1",
- "esutils": "2.0.2",
- "file-entry-cache": "2.0.0",
- "functional-red-black-tree": "1.0.1",
- "glob": "7.1.2",
- "globals": "11.5.0",
- "ignore": "3.3.8",
- "imurmurhash": "0.1.4",
- "inquirer": "3.3.0",
- "is-resolvable": "1.1.0",
- "js-yaml": "3.11.0",
- "json-stable-stringify-without-jsonify": "1.0.1",
- "levn": "0.3.0",
- "lodash": "4.17.10",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "natural-compare": "1.4.0",
- "optionator": "0.8.2",
- "path-is-inside": "1.0.2",
- "pluralize": "7.0.0",
- "progress": "2.0.0",
- "regexpp": "1.1.0",
- "require-uncached": "1.0.3",
- "semver": "5.5.0",
- "strip-ansi": "4.0.0",
- "strip-json-comments": "2.0.1",
- "table": "4.0.2",
- "text-table": "0.2.0"
- }
- },
- "eslint-scope": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
- "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
- "requires": {
- "esrecurse": "4.2.1",
- "estraverse": "4.2.0"
- }
- },
- "eslint-visitor-keys": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
- "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ=="
- },
- "espree": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
- "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
- "requires": {
- "acorn": "5.5.3",
- "acorn-jsx": "3.0.1"
- }
- },
- "esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
- },
- "esquery": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
- "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
- "requires": {
- "estraverse": "4.2.0"
- }
- },
- "esrecurse": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
- "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
- "requires": {
- "estraverse": "4.2.0"
- }
- },
- "estraverse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
- },
- "external-editor": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
- "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
- "requires": {
- "chardet": "0.4.2",
- "iconv-lite": "0.4.23",
- "tmp": "0.0.33"
- }
- },
- "fast-deep-equal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
- "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
- },
- "fast-json-stable-stringify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
- },
- "figures": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
- "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
- "requires": {
- "escape-string-regexp": "1.0.5"
- }
- },
- "file-entry-cache": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
- "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
- "requires": {
- "flat-cache": "1.3.0",
- "object-assign": "4.1.1"
- }
- },
- "flat-cache": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
- "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
- "requires": {
- "circular-json": "0.3.3",
- "del": "2.2.2",
- "graceful-fs": "4.1.11",
- "write": "0.2.1"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "functional-red-black-tree": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
- }
- },
- "globals": {
- "version": "11.5.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
- "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ=="
- },
- "globby": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
- "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
- "requires": {
- "array-union": "1.0.2",
- "arrify": "1.0.1",
- "glob": "7.1.2",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
- },
- "iconv-lite": {
- "version": "0.4.23",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
- "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
- "requires": {
- "safer-buffer": "2.1.2"
- }
- },
- "ignore": {
- "version": "3.3.8",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
- "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg=="
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "inquirer": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
- "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
- "requires": {
- "ansi-escapes": "3.1.0",
- "chalk": "2.4.1",
- "cli-cursor": "2.1.0",
- "cli-width": "2.2.0",
- "external-editor": "2.2.0",
- "figures": "2.0.0",
- "lodash": "4.17.10",
- "mute-stream": "0.0.7",
- "run-async": "2.3.0",
- "rx-lite": "4.0.8",
- "rx-lite-aggregates": "4.0.8",
- "string-width": "2.1.1",
- "strip-ansi": "4.0.0",
- "through": "2.3.8"
- }
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
- },
- "is-path-cwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
- "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0="
- },
- "is-path-in-cwd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
- "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
- "requires": {
- "is-path-inside": "1.0.1"
- }
- },
- "is-path-inside": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
- "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
- "requires": {
- "path-is-inside": "1.0.2"
- }
- },
- "is-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
- "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
- },
- "is-resolvable": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
- "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
- },
- "js-yaml": {
- "version": "3.11.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
- "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
- "requires": {
- "argparse": "1.0.10",
- "esprima": "4.0.0"
- }
- },
- "json-schema-traverse": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
- },
- "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
- "requires": {
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2"
- }
- },
- "lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
- },
- "lodash.unescape": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
- "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw="
- },
- "lru-cache": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
- "requires": {
- "pseudomap": "1.0.2",
- "yallist": "2.1.2"
- }
- },
- "mimic-fn": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "1.1.11"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "mute-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
- "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
- },
- "natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1.0.2"
- }
- },
- "onetime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
- "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
- "requires": {
- "mimic-fn": "1.2.0"
- }
- },
- "optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
- "requires": {
- "deep-is": "0.1.3",
- "fast-levenshtein": "2.0.6",
- "levn": "0.3.0",
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2",
- "wordwrap": "1.0.0"
- }
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "path-is-inside": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "requires": {
- "pinkie": "2.0.4"
- }
- },
- "pluralize": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
- "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow=="
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
- },
- "progress": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
- "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
- },
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
- },
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "2.0.0",
- "safe-buffer": "5.1.2",
- "string_decoder": "1.1.1",
- "util-deprecate": "1.0.2"
- }
- },
- "regexpp": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
- "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw=="
- },
- "require-uncached": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
- "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
- "requires": {
- "caller-path": "0.1.0",
- "resolve-from": "1.0.1"
- }
- },
- "resolve-from": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
- "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY="
- },
- "restore-cursor": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
- "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
- "requires": {
- "onetime": "2.0.1",
- "signal-exit": "3.0.2"
- }
- },
- "rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
- "requires": {
- "glob": "7.1.2"
- }
- },
- "run-async": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
- "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
- "requires": {
- "is-promise": "2.1.0"
- }
- },
- "rx-lite": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
- "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ="
- },
- "rx-lite-aggregates": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
- "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
- "requires": {
- "rx-lite": "4.0.8"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
- },
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
- "requires": {
- "shebang-regex": "1.0.0"
- }
- },
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
- },
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
- },
- "slice-ansi": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
- "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
- "requires": {
- "is-fullwidth-code-point": "2.0.0"
- }
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "5.1.2"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "3.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
- }
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- },
- "table": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
- "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
- "requires": {
- "ajv": "5.5.2",
- "ajv-keywords": "2.1.1",
- "chalk": "2.4.1",
- "lodash": "4.17.10",
- "slice-ansi": "1.0.0",
- "string-width": "2.1.1"
- }
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
- },
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
- },
- "tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "requires": {
- "os-tmpdir": "1.0.2"
- }
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "requires": {
- "prelude-ls": "1.1.2"
- }
- },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
- },
- "typescript": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz",
- "integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw=="
- },
- "typescript-eslint-parser": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-15.0.0.tgz",
- "integrity": "sha512-MMmSBcCaV5je+6DNinfnI2S6uwXSR6/TWR2phyzevqWDQKykobHc+f5eLDqK2sUpdg3T1Msd880o/xnRpAbG9Q==",
- "requires": {
- "lodash.unescape": "4.0.1",
- "semver": "5.5.0"
- }
- },
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "which": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
- "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
- "requires": {
- "isexe": "2.0.0"
- }
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "write": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
- "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
- "requires": {
- "mkdirp": "0.5.1"
- }
- },
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
- }
- }
-}
diff --git a/its/plugin/projects/eslint_report/package.json b/its/plugin/projects/eslint_report/package.json
deleted file mode 100644
index bfcd45de01c..00000000000
--- a/its/plugin/projects/eslint_report/package.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "eslint",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "",
- "license": "ISC",
- "dependencies": {
- "eslint": "^4.19.1",
- "typescript": "^2.8.3",
- "typescript-eslint-parser": "^15.0.0"
- }
-}
diff --git a/its/plugin/projects/eslint_report/readme b/its/plugin/projects/eslint_report/readme
deleted file mode 100644
index 6ed6ce7f01c..00000000000
--- a/its/plugin/projects/eslint_report/readme
+++ /dev/null
@@ -1,4 +0,0 @@
-The report was generated with
-npx eslint --ext ts,js -f json . > report.json
-
-Then path was manually changed to relative
diff --git a/its/plugin/projects/eslint_report/report.json b/its/plugin/projects/eslint_report/report.json
deleted file mode 100644
index 96a20d5b749..00000000000
--- a/its/plugin/projects/eslint_report/report.json
+++ /dev/null
@@ -1,168 +0,0 @@
-[
- {
- "filePath": "src/file.js",
- "messages": [
- {
- "ruleId": "no-unused-vars",
- "severity": 2,
- "message": "'addOne' is defined but never used.",
- "line": 1,
- "column": 10,
- "nodeType": "Identifier",
- "source": "function addOne(i) {",
- "endLine": 1,
- "endColumn": 16
- },
- {
- "ruleId": "use-isnan",
- "severity": 2,
- "message": "Use the isNaN function to compare with NaN.",
- "line": 2,
- "column": 7,
- "nodeType": "BinaryExpression",
- "source": " if (i != NaN) {",
- "endLine": 2,
- "endColumn": 15
- },
- {
- "ruleId": "semi",
- "severity": 2,
- "message": "Missing semicolon.",
- "line": 3,
- "column": 18,
- "nodeType": "ReturnStatement",
- "source": " return i ++",
- "fix": {
- "range": [
- 56,
- 56
- ],
- "text": ";"
- }
- },
- {
- "ruleId": "semi",
- "severity": 2,
- "message": "Missing semicolon.",
- "line": 5,
- "column": 11,
- "nodeType": "ReturnStatement",
- "source": " return",
- "fix": {
- "range": [
- 78,
- 78
- ],
- "text": ";"
- }
- },
- {
- "ruleId": "no-extra-semi",
- "severity": 2,
- "message": "Unnecessary semicolon.",
- "line": 7,
- "column": 2,
- "nodeType": "EmptyStatement",
- "source": "};",
- "messageId": "unexpected",
- "endLine": 7,
- "endColumn": 3,
- "fix": {
- "range": [
- 83,
- 85
- ],
- "text": "}"
- }
- }
- ],
- "errorCount": 5,
- "warningCount": 0,
- "fixableErrorCount": 3,
- "fixableWarningCount": 0,
- "source": "function addOne(i) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};\n"
- },
- {
- "filePath": "src/file.ts",
- "messages": [
- {
- "ruleId": "no-unused-vars",
- "severity": 2,
- "message": "'addOne' is defined but never used.",
- "line": 1,
- "column": 10,
- "nodeType": "Identifier",
- "source": "function addOne(i: number) {",
- "endLine": 1,
- "endColumn": 16
- },
- {
- "ruleId": "use-isnan",
- "severity": 2,
- "message": "Use the isNaN function to compare with NaN.",
- "line": 2,
- "column": 7,
- "nodeType": "BinaryExpression",
- "source": " if (i != NaN) {",
- "endLine": 2,
- "endColumn": 15
- },
- {
- "ruleId": "semi",
- "severity": 2,
- "message": "Missing semicolon.",
- "line": 3,
- "column": 18,
- "nodeType": "ReturnStatement",
- "source": " return i ++",
- "fix": {
- "range": [
- 64,
- 64
- ],
- "text": ";"
- }
- },
- {
- "ruleId": "semi",
- "severity": 2,
- "message": "Missing semicolon.",
- "line": 5,
- "column": 11,
- "nodeType": "ReturnStatement",
- "source": " return",
- "fix": {
- "range": [
- 86,
- 86
- ],
- "text": ";"
- }
- },
- {
- "ruleId": "no-extra-semi",
- "severity": 2,
- "message": "Unnecessary semicolon.",
- "line": 7,
- "column": 2,
- "nodeType": "EmptyStatement",
- "source": "};",
- "messageId": "unexpected",
- "endLine": 7,
- "endColumn": 3,
- "fix": {
- "range": [
- 91,
- 93
- ],
- "text": "}"
- }
- }
- ],
- "errorCount": 5,
- "warningCount": 0,
- "fixableErrorCount": 3,
- "fixableWarningCount": 0,
- "source": "function addOne(i: number) {\n if (i != NaN) {\n return i ++\n } else {\n return\n }\n};"
- }
-]
diff --git a/its/plugin/projects/eslint_report/src/file.js b/its/plugin/projects/eslint_report/src/file.js
deleted file mode 100644
index b94ead6ba00..00000000000
--- a/its/plugin/projects/eslint_report/src/file.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function addOne(i) {
- if (i != NaN) {
- return i ++
- } else {
- return
- }
-};
diff --git a/its/plugin/projects/eslint_report/src/file.ts b/its/plugin/projects/eslint_report/src/file.ts
deleted file mode 100644
index 803234e701d..00000000000
--- a/its/plugin/projects/eslint_report/src/file.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function addOne(i: number) {
- if (i != NaN) {
- return i ++
- } else {
- return
- }
-};
\ No newline at end of file
diff --git a/its/plugin/projects/esm-project/file.mjs b/its/plugin/projects/esm-project/file.mjs
deleted file mode 100644
index c9989695633..00000000000
--- a/its/plugin/projects/esm-project/file.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-import { foo, bar } from 'foobar';
-if (foo()) {
- bar();
-} else {
- bar();
-}
diff --git a/its/plugin/projects/external-tsconfig-dependency-project/package.json b/its/plugin/projects/external-tsconfig-dependency-project/package.json
deleted file mode 100644
index 94caea5dfc7..00000000000
--- a/its/plugin/projects/external-tsconfig-dependency-project/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "devDependencies": {
- "@tsconfig/node14": "1.0.3",
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/external-tsconfig-dependency-project/src/bar/main.ts b/its/plugin/projects/external-tsconfig-dependency-project/src/bar/main.ts
deleted file mode 100644
index 6585f9d1bcf..00000000000
--- a/its/plugin/projects/external-tsconfig-dependency-project/src/bar/main.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-function foo(b: number) {
- //
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/external-tsconfig-dependency-project/tsconfig.json b/its/plugin/projects/external-tsconfig-dependency-project/tsconfig.json
deleted file mode 100644
index 7e4626fa628..00000000000
--- a/its/plugin/projects/external-tsconfig-dependency-project/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "extends": "@tsconfig/node14/tsconfig.json",
- "include": ["src/bar"]
-}
diff --git a/its/plugin/projects/file-filter/excluded_dir/project/excluded_dir/main.js b/its/plugin/projects/file-filter/excluded_dir/project/excluded_dir/main.js
deleted file mode 100644
index bf0ae47aab8..00000000000
--- a/its/plugin/projects/file-filter/excluded_dir/project/excluded_dir/main.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// issues in this file are excluded by setting sonar.javascript.exclusions property
-if (cond) {
- foo();
-} else {
- foo();
-}
diff --git a/its/plugin/projects/file-filter/excluded_dir/project/main.js b/its/plugin/projects/file-filter/excluded_dir/project/main.js
deleted file mode 100644
index fbab0b15a3e..00000000000
--- a/its/plugin/projects/file-filter/excluded_dir/project/main.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// issues in this file are detected even if parent path contains directory excluded by sonar.javascript.exclusions
-// because property is applied on relative path from the base directory
-// project base dir is "project" directory
-if (cond) {
- foo();
-} else {
- foo();
-}
diff --git a/its/plugin/projects/js-sonarlint-project/file.js b/its/plugin/projects/js-sonarlint-project/file.js
deleted file mode 100644
index 12582f05517..00000000000
--- a/its/plugin/projects/js-sonarlint-project/file.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var xs = ["a", "b", "c", "d"];
-delete xs[2];
diff --git a/its/plugin/projects/js-sonarlint-project/file.vue b/its/plugin/projects/js-sonarlint-project/file.vue
deleted file mode 100644
index 392c28d9e53..00000000000
--- a/its/plugin/projects/js-sonarlint-project/file.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
diff --git a/its/plugin/projects/js-with-ts-eslint-project/file.js b/its/plugin/projects/js-with-ts-eslint-project/file.js
deleted file mode 100644
index 1596c04aabd..00000000000
--- a/its/plugin/projects/js-with-ts-eslint-project/file.js
+++ /dev/null
@@ -1,2 +0,0 @@
-const foo = (n) => n + 1;
-MyClass.prototype.property = foo;
diff --git a/its/plugin/projects/lcov-jsx/conditions-on-non-executable-lines.lcov b/its/plugin/projects/lcov-jsx/conditions-on-non-executable-lines.lcov
deleted file mode 100644
index 6475a5044f6..00000000000
--- a/its/plugin/projects/lcov-jsx/conditions-on-non-executable-lines.lcov
+++ /dev/null
@@ -1,15 +0,0 @@
-TN:
-SF:./file.jsx
-FN:3,(anonymous_0)
-FNF:1
-FNH:1
-FNDA:1,(anonymous_0)
-DA:3,1
-DA:4,1
-LF:2
-LH:2
-BRDA:5,0,0,1
-BRDA:5,0,1,0
-BRF:2
-BRH:1
-end_of_record
diff --git a/its/plugin/projects/lcov-jsx/file.jsx b/its/plugin/projects/lcov-jsx/file.jsx
deleted file mode 100644
index 2db1ef48e81..00000000000
--- a/its/plugin/projects/lcov-jsx/file.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-
-const Test = ({ condition }) => (
-
- {condition && Test1 }
-
- Test2
-
-)
-
-export default Test
diff --git a/its/plugin/projects/lcov-wildcard/bar/bar.js b/its/plugin/projects/lcov-wildcard/bar/bar.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov-wildcard/bar/bar.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/lcov-wildcard/bar/bar.lcov b/its/plugin/projects/lcov-wildcard/bar/bar.lcov
deleted file mode 100644
index 8d13373be45..00000000000
--- a/its/plugin/projects/lcov-wildcard/bar/bar.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./bar.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:6,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:6,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov-wildcard/baz/baz.js b/its/plugin/projects/lcov-wildcard/baz/baz.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov-wildcard/baz/baz.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/lcov-wildcard/baz/baz.lcov b/its/plugin/projects/lcov-wildcard/baz/baz.lcov
deleted file mode 100644
index 87bd27d861c..00000000000
--- a/its/plugin/projects/lcov-wildcard/baz/baz.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./baz.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:6,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:6,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov-wildcard/baz/qux/qux.js b/its/plugin/projects/lcov-wildcard/baz/qux/qux.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov-wildcard/baz/qux/qux.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/lcov-wildcard/baz/qux/qux.lcov b/its/plugin/projects/lcov-wildcard/baz/qux/qux.lcov
deleted file mode 100644
index 234a6029812..00000000000
--- a/its/plugin/projects/lcov-wildcard/baz/qux/qux.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./qux.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:6,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:6,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov-wildcard/foo.js b/its/plugin/projects/lcov-wildcard/foo.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov-wildcard/foo.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/lcov-wildcard/foo.lcov b/its/plugin/projects/lcov-wildcard/foo.lcov
deleted file mode 100644
index b362930e291..00000000000
--- a/its/plugin/projects/lcov-wildcard/foo.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./foo.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:6,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:6,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov/coverage-wrong-file-name.lcov b/its/plugin/projects/lcov/coverage-wrong-file-name.lcov
deleted file mode 100644
index 4fd40ee1e16..00000000000
--- a/its/plugin/projects/lcov/coverage-wrong-file-name.lcov
+++ /dev/null
@@ -1,10 +0,0 @@
-SF:./wrong/fileName.js
-BRDA:2,0,0,2
-BRDA:2,0,1,1
-BRDA:2,0,2,0
-BRDA:2,0,3,-
-DA:2,3
-DA:3,3
-DA:5,0
-DA:8,1
-end_of_record
diff --git a/its/plugin/projects/lcov/coverage-wrong-line.lcov b/its/plugin/projects/lcov/coverage-wrong-line.lcov
deleted file mode 100644
index 78622498e5f..00000000000
--- a/its/plugin/projects/lcov/coverage-wrong-line.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./file.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:999,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:0,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov/coverage.lcov b/its/plugin/projects/lcov/coverage.lcov
deleted file mode 100644
index 84cce46b85c..00000000000
--- a/its/plugin/projects/lcov/coverage.lcov
+++ /dev/null
@@ -1,24 +0,0 @@
-TN:
-SF:./file.js
-FN:1,isArrayLike
-FN:5,size
-FNF:2
-FNH:2
-FNDA:2,isArrayLike
-FNDA:2,size
-DA:1,1
-DA:2,2
-DA:5,1
-DA:6,2
-DA:7,0
-DA:9,2
-DA:12,1
-LF:7
-LH:6
-BRDA:6,1,0,0
-BRDA:6,1,1,2
-BRDA:9,2,0,1
-BRDA:9,2,1,1
-BRF:4
-BRH:3
-end_of_record
diff --git a/its/plugin/projects/lcov/dir/file.js b/its/plugin/projects/lcov/dir/file.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov/dir/file.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/lcov/file.js b/its/plugin/projects/lcov/file.js
deleted file mode 100644
index 4bad53da13b..00000000000
--- a/its/plugin/projects/lcov/file.js
+++ /dev/null
@@ -1,12 +0,0 @@
-function isArrayLike (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-function size (obj) {
- if (obj == null) {
- return 0;
- }
- return isArrayLike(obj) ? obj.length : Object.keys(obj).length;
-}
-
-module.exports = size;
diff --git a/its/plugin/projects/metrics/src/dir/Person.js b/its/plugin/projects/metrics/src/dir/Person.js
deleted file mode 100644
index 64ff637f045..00000000000
--- a/its/plugin/projects/metrics/src/dir/Person.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Header
- */
-
-var Person = function(first, last, middle) {
- this.first = first;
- this.middle = middle;
- this.last = last;
-};
-
-Person.prototype = {
-
- //
- // Just a comment
- //
-
- whoAreYou : function() {
- return this.first + (this.middle ? ' ' + this.middle: '') + ' ' + this.last;
- },
-
- set first(first) {
- this.first = first;
- },
-
- get first() {
- return this.first;
- }
-};
-
-class Utils {
- utils () {
- }
-}
diff --git a/its/plugin/projects/minified_files/src/file-min.js b/its/plugin/projects/minified_files/src/file-min.js
deleted file mode 100644
index 6d5dec610fe..00000000000
--- a/its/plugin/projects/minified_files/src/file-min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function a(n){return n.length}function o(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function s(n){return(n+="")===xa||n[0]===ba?ba+n:n}function f(n){return(n+="")[0]===ba?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=_a.length;r>e;++e){var u=_a[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],a=0,o=i.length;o>a;a++)(u=i[a])&&t(u,a,e);return n}function Z(n){return Sa(n,za),n}function V(n){var t,e;return function(r,u,i){var a,o=n[i].update,l=o.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(a=o[t])&&++t0&&(n=n.slice(0,o));var c=La.get(n);return c&&(n=c,l=B),o?t?u:r:t?b:i}function $(n,t){return function(e){var r=oa.event;oa.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{oa.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Ta,u="click"+r,i=oa.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==qa&&(qa="onselectstart"in e?!1:x(e.style,"userSelect")),qa){var a=n(e).style,o=a[qa];a[qa]="none"}return function(n){if(i.on(r,null),qa&&(a[qa]=o),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Ra){var i=t(n);if(i.scrollX||i.scrollY){r=oa.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var a=r[0][0].getScreenCTM();Ra=!(a.f||a.e),r.remove()}}return Ra?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var o=n.getBoundingClientRect();return[e.clientX-o.left-n.clientLeft,e.clientY-o.top-n.clientTop]}function G(){return oa.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?ja:Math.acos(n)}function tn(n){return n>1?Ha:-1>n?-Ha:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function an(n){return(n=Math.sin(n/2))*n}function on(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(a-i)*n/60:180>n?a:240>n?i+(a-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,a;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+t):e+t-e*t,i=2*e-a,new yn(u(n+120),u(n),u(n-120))}function sn(n,t,e){return this instanceof sn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof sn?new sn(n.h,n.c,n.l):n instanceof hn?pn(n.l,n.a,n.b):pn((n=Sn((n=oa.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new sn(n,t,e)}function fn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Oa)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof sn?fn(n.h,n.c,n.l):Sn((n=yn(n)).r,n.g,n.b):new hn(n,t,e)}function gn(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=vn(u)*Ka,r=vn(r)*Qa,i=vn(i)*no,new yn(mn(3.2404542*u-1.5371385*r-.4985314*i),mn(-.969266*u+1.8760108*r+.041556*i),mn(.0556434*u-.2040259*r+1.0572252*i))}function pn(n,t,e){return n>0?new sn(Math.atan2(e,t)*Ia,Math.sqrt(t*t+e*e),n):new sn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function mn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function yn(n,t,e){return this instanceof yn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof yn?new yn(n.r,n.g,n.b):_n(""+n,yn,cn):new yn(n,t,e)}function Mn(n){return new yn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,u,i,a=0,o=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(Nn(u[0]),Nn(u[1]),Nn(u[2]))}return(i=ro.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(a=(3840&i)>>4,a=a>>4|a,o=240&i,o=o>>4|o,l=15&i,l=l<<4|l):7===n.length&&(a=(16711680&i)>>16,o=(65280&i)>>8,l=255&i)),t(a,o,l))}function wn(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),a=Math.max(n,t,e),o=a-i,l=(a+i)/2;return o?(u=.5>l?o/(a+i):o/(2-a-i),r=n==a?(t-e)/o+(e>t?6:0):t==a?(e-n)/o+2:(n-t)/o+4,r*=60):(r=NaN,u=l>0&&1>l?0:r),new ln(r,u,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/Ka),u=dn((.2126729*n+.7151522*t+.072175*e)/Qa),i=dn((.0193339*n+.119192*t+.9503041*e)/no);return hn(116*u-16,500*(r-u),200*(u-i))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function u(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(i,l)}catch(r){return void a.error.call(i,r)}a.load.call(i,n)}else a.error.call(i,l)}var i={},a=oa.dispatch("beforesend","progress","load","error"),o={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=u:l.onreadystatechange=function(){l.readyState>3&&u()},l.onprogress=function(n){var t=oa.event;oa.event=n;try{a.progress.call(i,l)}finally{oa.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?o[n]:(null==t?delete o[n]:o[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(c=n,i):c},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ca(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),l.open(e,n,!0),null==t||"accept"in o||(o.accept=t+",*/*"),l.setRequestHeader)for(var s in o)l.setRequestHeader(s,o[s]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),a.beforesend.call(i,l),l.send(null==r?null:r),i},i.abort=function(){return l.abort(),i},oa.rebind(i,a,"on"),null==r?i:i.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,n:null};return io?io.n=i:uo=i,io=i,ao||(oo=clearTimeout(oo),ao=1,lo(Tn)),i}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(oo),oo=setTimeout(Tn,t)),ao=0):(ao=1,lo(Tn))}function Rn(){for(var n=Date.now(),t=uo;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=uo,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Un(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],a=0,o=r[0],l=0;u>0&&o>0&&(l+o+1>t&&(o=Math.max(1,t-l)),i.push(n.substring(u-=o,u+o)),!((l+=o+1)>t));)o=r[a=(a+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=so.exec(n),r=e[1]||" ",a=e[2]||">",o=e[3]||"-",l=e[4]||"",c=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===a)&&(c=r="0",a="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===l&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=fo.get(g)||Fn;var M=c&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===o?"":o;if(0>p){var l=oa.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===a?u+n+k:">"===a?k+u+n:"^"===a?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new go(e-1)),1),e}function i(n,e){return t(n=new go(+n),e),n}function a(n,r,i){var a=u(n),o=[];if(i>1)for(;r>a;)e(a)%i||o.push(new Date(+a)),t(a,1);else for(;r>a;)o.push(new Date(+a)),t(a,1);return o}function o(n,t,e){try{go=Hn;var r=new Hn;return r._=n,a(r,t,e)}finally{go=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=a;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(u),l.offset=In(i),l.range=o,n}function In(n){return function(t,e){try{go=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{go=Date}}}function Yn(n){function t(n){function t(t){for(var e,u,i,a=[],o=-1,l=0;++oo;){if(r>=c)return-1;if(u=t.charCodeAt(o++),37===u){if(a=t.charAt(o++),i=C[a in vo?t.charAt(o++):a],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{go=Hn;var t=new go;return t._=n,r(t)}finally{go=Date}}var r=t(n);return e.parse=function(n){try{go=Hn;var t=r.parse(n);return t&&t._}finally{go=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=oa.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(m),k=Xn(m),N=Vn(y),E=Xn(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ho.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ho.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ho.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:ot,"%":function(){return"%"}},C={a:r,A:u,b:i,B:a,c:o,d:tt,e:tt,H:rt,I:rt,j:et,L:at,m:nt,M:ut,p:s,S:it,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Vn(n){return new RegExp("^(?:"+n.map(oa.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ut(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function it(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function at(n,t,e){mo.lastIndex=0;var r=mo.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ot(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=Ma(t)/60|0,u=Ma(t)%60;return e+Zn(r,"0",2)+Zn(u,"0",2)}function lt(n,t,e){yo.lastIndex=0;var r=yo.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,o=a*e,l=Math.cos(t),c=Math.sin(t),s=i*c,f=u*l+s*Math.cos(o),h=s*a*Math.sin(o);So.add(Math.atan2(h,f)),r=n,u=l,i=c}var t,e,r,u,i;ko.point=function(a,o){ko.point=n,r=(t=a)*Oa,u=Math.cos(o=(e=o)*Oa/2+ja/4),i=Math.sin(o)},ko.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function mt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function yt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return Ma(n[0]-t[0])o;++o)u.point((e=n[o])[0],e[1]);return void u.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,i.push(l),a.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,i.push(l),a.push(c)}}),a.sort(t),qt(i),qt(a),i.length){for(var o=0,l=e,c=a.length;c>o;++o)a[o].e=l=!l;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var o=0,c=s.length;c>o;++o)u.point((f=s[o])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var o=s.length-1;o>=0;--o)u.point((f=s[o])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++a1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Dt))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:a,lineStart:l,lineEnd:c,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=a,y.lineStart=l,y.lineEnd=c,g=oa.merge(g);var n=Ot(m,p);g.length?(b||(i.polygonStart(),b=!0),Lt(g,jt,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Pt(),x=t(M),b=!1;return y}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function jt(n,t){return((n=n.x)[0]<0?n[1]-Ha-Da:Ha-n[1])-((t=t.x)[0]<0?t[1]-Ha-Da:Ha-t[1])}function Ut(n){var t,e=NaN,r=NaN,u=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(i,a){var o=i>0?ja:-ja,l=Ma(i-e);Ma(l-ja)0?Ha:-Ha),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(o,r),n.point(i,r),t=0):u!==o&&l>=ja&&(Ma(e-u)Da?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*a)):(t+r)/2}function Ht(n,t,e,r){var u;if(null==n)u=e*Ha,r.point(-ja,u),r.point(0,u),r.point(ja,u),r.point(ja,0),r.point(ja,-u),r.point(0,-u),r.point(-ja,-u),r.point(-ja,0),r.point(-ja,u);else if(Ma(n[0]-t[0])>Da){var i=n[0]o;++o){var c=t[o],s=c.length;if(s)for(var f=c[0],h=f[0],g=f[1]/2+ja/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=c[d];var m=n[0],y=n[1]/2+ja/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>ja,k=p*M;if(So.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Ua:b,S^h>=e^m>=e){var N=yt(dt(f),dt(n));bt(N);var E=yt(u,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(a+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Da>i||Da>i&&0>So)^1&a}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,l,c,s;return{lineStart:function(){c=l=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=a?v?0:u(f,h):v?u(f+(0>f?ja:-ja),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(g=r(e,p),(wt(e,g)||wt(p,g))&&(p[0]+=Da,p[1]+=Da,v=t(p[0],p[1]))),v!==l)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(o&&e&&a^v){var m;d&i||!(m=r(p,e,!0))||(s=0,a?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&wt(e,p)||n.point(p[0],p[1]),e=p,l=v,i=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return s|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),u=dt(t),a=[1,0,0],o=yt(r,u),l=mt(o,o),c=o[0],s=l-c*c;if(!s)return!e&&n;var f=i*l/s,h=-i*c/s,g=yt(a,o),p=xt(a,f),v=xt(o,h);Mt(p,v);var d=g,m=mt(p,d),y=mt(d,d),M=m*m-y*(mt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-m-x)/y);if(Mt(b,p),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=Ma(E-ja)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(Ma(b[0]-w)ja^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-m+x)/y);return Mt(z,p),[b,_t(z)]}}}function u(t,e){var r=a?n:ja-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),a=i>0,o=Ma(i)>Da,l=ve(n,6*Oa);return Rt(t,e,l,a?[0,-n]:[-ja,n-ja])}function Yt(n,t,e,r){return function(u){var i,a=u.a,o=u.b,l=a.x,c=a.y,s=o.x,f=o.y,h=0,g=1,p=s-l,v=f-c;if(i=n-l,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-l,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-c,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-c,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:l+h*p,y:c+h*v}),1>g&&(u.b={x:l+g*p,y:c+g*v}),u}}}}}}function Zt(n,t,e,r){function u(r,u){return Ma(r[0]-n)0?0:3:Ma(r[0]-e)0?2:1:Ma(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return a(n.x,t.x)}function a(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(o){function l(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,a=1,o=d[u],l=o.length,c=o[0];l>a;++a)i=o[a],c[1]<=r?i[1]>r&&Q(c,i,n)>0&&++t:i[1]<=r&&Q(c,i,n)<0&&--t,c=i;return 0!==t}function c(i,o,l,c){var s=0,f=0;if(null==i||(s=u(i,l))!==(f=u(o,l))||a(i,o)<0^l>0){do c.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+l+4)%4)!==f)}else c.point(o[0],o[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&o.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=NaN}function g(){v&&(p(y,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=f,w&&o.lineEnd()}function p(n,t){n=Math.max(-Fo,Math.min(Fo,n)),t=Math.max(-Fo,Math.min(Fo,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(o.lineStart(),o.point(n,t));else if(e&&w)o.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(o.lineStart(),o.point(r.a.x,r.a.y)),o.point(r.b.x,r.b.y),e||o.lineEnd(),k=!1):e&&(o.lineStart(),o.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,N=o,E=Pt(),A=Yt(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){o=E,v=[],d=[],k=!0},polygonEnd:function(){o=N,v=oa.merge(v);var t=l([n,r]),e=k&&t,u=v.length;(e||u)&&(o.polygonStart(),e&&(o.lineStart(),c(null,null,1,o),o.lineEnd()),u&&Lt(v,i,t,c,o),o.polygonEnd()),v=d=m=null}};return C}}function Vt(n){var t=0,e=ja/3,r=oe(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ja/180,e=n[1]*ja/180):[t/ja*180,e/ja*180]},u}function Xt(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),a-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),a=Math.sqrt(i)/u;return e.invert=function(n,t){var e=a-t;return[Math.atan2(n,e)/u,tn((i-(n*n+e*e)*u*u)/(2*u))]},e}function $t(){function n(n,t){Oo+=u*n-r*t,r=n,u=t}var t,e,r,u;Xo.point=function(i,a){Xo.point=n,t=r=i,e=u=a},Xo.lineEnd=function(){n(t,e)}}function Bt(n,t){Io>n&&(Io=n),n>Zo&&(Zo=n),Yo>t&&(Yo=t),t>Vo&&(Vo=t)}function Wt(){function n(n,t){a.push("M",n,",",t,i)}function t(n,t){a.push("M",n,",",t),o.point=e}function e(n,t){a.push("L",n,",",t)}function r(){o.point=n}function u(){a.push("Z")}var i=Jt(4.5),a=[],o={point:n,lineStart:function(){o.point=t},lineEnd:r,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=r,o.point=n},pointRadius:function(n){return i=Jt(n),o},result:function(){if(a.length){var n=a.join("");return a=[],n}}};return o}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ao+=n,Co+=t,++zo}function Kt(){function n(n,r){var u=n-t,i=r-e,a=Math.sqrt(u*u+i*i);Lo+=a*(t+n)/2,qo+=a*(e+r)/2,To+=a,Gt(t=n,e=r)}var t,e;Bo.point=function(r,u){Bo.point=n,Gt(t=r,e=u)}}function Qt(){Bo.point=Gt}function ne(){function n(n,t){var e=n-r,i=t-u,a=Math.sqrt(e*e+i*i);Lo+=a*(r+n)/2,qo+=a*(u+t)/2,To+=a,a=u*n-r*t,Ro+=a*(r+n),Do+=a*(u+t),Po+=3*a,Gt(r=n,u=t)}var t,e,r,u;Bo.point=function(i,a){Bo.point=n,Gt(t=r=i,e=u=a)},Bo.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+a,e),n.arc(t,e,a,0,Ua)}function e(t,e){n.moveTo(t,e),o.point=r}function r(t,e){n.lineTo(t,e)}function u(){o.point=t}function i(){n.closePath()}var a=4.5,o={point:t,lineStart:function(){o.point=e},lineEnd:u,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=u,o.point=t},pointRadius:function(n){return a=n,o},result:b};return o}function ee(n){function t(n){return(o?r:e)(n)}function e(t){return ie(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=i,t.lineStart()}function i(e,r){var i=dt([e,r]),a=n(e,r);u(M,x,y,b,_,w,M=a[0],x=a[1],y=e,b=i[0],_=i[1],w=i[2],o,t),t.point(M,x)}function a(){S.point=e,t.lineEnd()}function l(){r(),S.point=c,S.lineEnd=s}function c(n,t){
-i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,o,t),S.lineEnd=a,a()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:a,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,o,l,c,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=o+g,_=l+p,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=Ma(Ma(w)-1)i||Ma((y*z+M*L)/x-.5)>.3||a>o*g+l*p+c*v)&&(u(t,e,r,o,l,c,A,C,N,b/=S,_/=S,w,d,m),m.point(A,C),u(A,C,N,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,a=Math.cos(30*Oa),o=16;return t.precision=function(n){return arguments.length?(o=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function re(n){var t=ee(function(t,e){return n([t*Ia,e*Ia])});return function(n){return le(t(n))}}function ue(n){this.stream=n}function ie(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ae(n){return oe(function(){return n})()}function oe(n){function t(n){return n=o(n[0]*Oa,n[1]*Oa),[n[0]*h+l,c-n[1]*h]}function e(n){return n=o.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Ia,n[1]*Ia]}function r(){o=Ct(a=fe(m,M,x),i);var n=i(v,d);return l=g-n[0]*h,c=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,a,o,l,c,s,f=ee(function(n,t){return n=i(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Uo,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=le(b(a,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Uo):It((w=+n)*Oa),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Oa,d=n[1]%360*Oa,r()):[v*Ia,d*Ia]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Oa,M=n[1]%360*Oa,x=n.length>2?n[2]%360*Oa:0,r()):[m*Ia,M*Ia,x*Ia]},oa.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function le(n){return ie(n,function(t,e){n.point(t*Oa,e*Oa)})}function ce(n,t){return[n,t]}function se(n,t){return[n>ja?n-Ua:-ja>n?n+Ua:n,t]}function fe(n,t,e){return n?t||e?Ct(ge(n),pe(t,e)):ge(n):t||e?pe(t,e):se}function he(n){return function(t,e){return t+=n,[t>ja?t-Ua:-ja>t?t+Ua:t,e]}}function ge(n){var t=he(n);return t.invert=he(-n),t}function pe(n,t){function e(n,t){var e=Math.cos(t),o=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),s=c*r+o*u;return[Math.atan2(l*i-s*a,o*r-c*u),tn(s*i+l*a)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),a=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),o=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),s=c*i-l*a;return[Math.atan2(l*i+c*a,o*r+s*u),tn(s*r-o*u)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,a,o){var l=a*t;null!=u?(u=de(e,u),i=de(e,i),(a>0?i>u:u>i)&&(u+=a*Ua)):(u=n+a*Ua,i=n-.5*l);for(var c,s=u;a>0?s>i:i>s;s-=l)o.point((c=_t([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Da)%(2*Math.PI)}function me(n,t,e){var r=oa.range(n,t-Da,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function ye(n,t,e){var r=oa.range(n,t-Da,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),a=Math.cos(r),o=Math.sin(r),l=u*Math.cos(n),c=u*Math.sin(n),s=a*Math.cos(e),f=a*Math.sin(e),h=2*Math.asin(Math.sqrt(an(r-t)+u*a*an(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*l+t*s,u=e*c+t*f,a=e*i+t*o;return[Math.atan2(u,r)*Ia,Math.atan2(a,Math.sqrt(r*r+u*u))*Ia]}:function(){return[n*Ia,t*Ia]};return p.distance=h,p}function _e(){function n(n,u){var i=Math.sin(u*=Oa),a=Math.cos(u),o=Ma((n*=Oa)-t),l=Math.cos(o);Wo+=Math.atan2(Math.sqrt((o=a*Math.sin(o))*o+(o=r*i-e*a*l)*o),e*i+r*a*l),t=n,e=i,r=a}var t,e,r;Jo.point=function(u,i){t=u*Oa,e=Math.sin(i*=Oa),r=Math.cos(i),Jo.point=n},Jo.lineEnd=function(){Jo.point=Jo.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),a=Math.cos(u);return[Math.atan2(n*i,r*a),Math.asin(r&&e*i/r)]},e}function Se(n,t){function e(n,t){a>0?-Ha+Da>t&&(t=-Ha+Da):t>Ha-Da&&(t=Ha-Da);var e=a/Math.pow(u(t),i);return[e*Math.sin(i*n),a-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ja/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),a=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=a-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(a/r,1/i))-Ha]},e):Ne}function ke(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return Ma(u)u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var u=n[0],i=e[0],a=t[0]-u,o=r[0]-i,l=n[1],c=e[1],s=t[1]-l,f=r[1]-c,h=(o*(l-c)-f*(u-i))/(f*a-o*s);return[u+h*a,l+h*s]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function je(n){var t=ll.pop()||new Pe;return t.site=n,t}function Ue(n){Be(n),il.remove(n),ll.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,a=n.N,o=[n];Ue(n);for(var l=i;l.circle&&Ma(e-l.circle.x)s;++s)c=o[s],l=o[s-1],nr(c.edge,l.site,c.site,u);l=o[0],c=o[f-1],c.edge=Ke(l.site,c.site,null,u),$e(l),$e(c)}function He(n){for(var t,e,r,u,i=n.x,a=n.y,o=il._;o;)if(r=Oe(o,a)-i,r>Da)o=o.L;else{if(u=i-Ie(o,a),!(u>Da)){r>-Da?(t=o.P,e=o):u>-Da?(t=o,e=o.N):t=e=o;break}if(!o.R){t=o;break}o=o.R}var l=je(n);if(il.insert(t,l),t||e){if(t===e)return Be(t),e=je(t.site),il.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,s=c.x,f=c.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};nr(e.edge,c,p,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,p,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var a=n.P;if(!a)return-(1/0);e=a.site;var o=e.x,l=e.y,c=l-t;if(!c)return o;var s=o-r,f=1/i-1/c,h=s/c;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*c)-l+c/2+u-i/2)))/f+r:(r+o)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,u,i,a,o,l,c,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=ul,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(o=i.edges,l=o.length,a=0;l>a;)s=o[a].end(),r=s.x,u=s.y,c=o[++a%l].start(),t=c.x,e=c.y,(Ma(r-t)>Da||Ma(u-e)>Da)&&(o.splice(a,0,new tr(Qe(i.site,s,Ma(r-f)Da?{x:f,y:Ma(t-f)Da?{x:Ma(e-p)Da?{x:h,y:Ma(t-h)Da?{x:Ma(e-g)=-Pa)){var g=l*l+c*c,p=s*s+f*f,v=(f*g-c*p)/h,d=(l*p-s*g)/h,f=d+o,m=cl.pop()||new Xe;m.arc=n,m.site=u,m.x=v+a,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=ol._;M;)if(m.yd||d>=o)return;if(h>p){if(i){if(i.y>=c)return}else i={x:d,y:l};e={x:d,y:c}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else{if(i){if(i.yg){if(i){if(i.x>=o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}else{if(i){if(i.xi||f>a||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(l>m){var y=Math.sqrt(l=m);r=t-y,u=e-y,i=t+y,a=e+y,o=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,s,f,x,b);break;case 1:c(n,x,f,h,b);break;case 2:c(n,s,b,x,g);break;case 3:c(n,x,b,h,g)}}}(n,r,u,i,a),o}function vr(n,t){n=oa.rgb(n),t=oa.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,a=t.g-r,o=t.b-u;return function(n){return"#"+bn(Math.round(e+i*n))+bn(Math.round(r+a*n))+bn(Math.round(u+o*n))}}function dr(n,t){var e,r={},u={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function mr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function yr(n,t){var e,r,u,i=fl.lastIndex=hl.lastIndex=0,a=-1,o=[],l=[];for(n+="",t+="";(e=fl.exec(n))&&(r=hl.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),o[a]?o[a]+=u:o[++a]=u),(e=e[0])===(r=r[0])?o[a]?o[a]+=r:o[++a]=r:(o[++a]=null,l.push({i:a,x:mr(e,r)})),i=hl.lastIndex;return ir;++r)o[(e=l[r]).i]=e.x(n);return o.join("")})}function Mr(n,t){for(var e,r=oa.interpolators.length;--r>=0&&!(e=oa.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],u=[],i=n.length,a=t.length,o=Math.min(n.length,t.length);for(e=0;o>e;++e)r.push(Mr(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;a>e;++e)u[e]=t[e];return function(n){for(e=0;o>e;++e)u[e]=r[e](n);return u}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Ha)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ua*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ua/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=oa.hcl(n),t=oa.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,a=t.c-r,o=t.l-u;return isNaN(a)&&(a=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return fn(e+i*n,r+a*n,u+o*n)+""}}function Dr(n,t){n=oa.hsl(n),t=oa.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,a=t.s-r,o=t.l-u;return isNaN(a)&&(a=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return cn(e+i*n,r+a*n,u+o*n)+""}}function Pr(n,t){n=oa.lab(n),t=oa.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,a=t.a-r,o=t.b-u;return function(n){return gn(e+i*n,r+a*n,u+o*n)+""}}function jr(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Ur(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),u=Fr(t,e),i=Hr(Or(e,t,-u))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:mr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:mr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var u=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:u-4,x:mr(n[0],t[0])},{i:u-2,x:mr(n[1],t[1])})}else(1!==t[0]||1!==t[1])&&e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=oa.transform(n),t=oa.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,u=-1,i=r.length;++u=0;)e.push(u[r])}function au(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,a=-1;++ae;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function mu(n){return n.reduce(yu,0)}function yu(n,t){return n+t[1]}function Mu(n,t){return xu(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xu(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function bu(n){return[oa.min(n),oa.max(n)]}function _u(n,t){return n.value-t.value}function wu(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Su(n,t){n._pack_next=t,t._pack_prev=n}function ku(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Nu(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(c=e.length)){var e,r,u,i,a,o,l,c,s=1/0,f=-(1/0),h=1/0,g=-(1/0);if(e.forEach(Eu),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(u=e[1],u.x=u.r,u.y=0,t(u),c>2))for(i=e[2],zu(r,u,i),t(i),wu(r,i),r._pack_prev=i,wu(i,u),u=r._pack_next,a=3;c>a;a++){zu(r,u,i=e[a]);var p=0,v=1,d=1;for(o=u._pack_next;o!==u;o=o._pack_next,v++)if(ku(o,i)){p=1;break}if(1==p)for(l=r._pack_prev;l!==o._pack_prev&&!ku(l,i);l=l._pack_prev,d++);p?(d>v||v==d&&u.ra;a++)i=e[a],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(Au)}}function Eu(n){n._pack_next=n._pack_prev=n}function Au(n){delete n._pack_next,delete n._pack_prev}function Cu(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,a=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pu(n,t,e){return n.a.parent===t.parent?n.a:e}function ju(n){return 1+oa.max(n,function(n){return n.y})}function Uu(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fu(n){var t=n.children;return t&&t.length?Fu(t[0]):n}function Hu(n){var t,e=n.children;return e&&(t=e.length)?Hu(e[t-1]):n}function Ou(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Iu(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Yu(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zu(n){return n.rangeExtent?n.rangeExtent():Yu(n.range())}function Vu(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Xu(n,t){var e,r=0,u=n.length-1,i=n[r],a=n[u];return i>a&&(e=r,r=u,u=e,e=i,i=a,a=e),n[r]=t.floor(i),n[u]=t.ceil(a),n}function $u(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:wl}function Bu(n,t,e,r){var u=[],i=[],a=0,o=Math.min(n.length,t.length)-1;for(n[o]2?Bu:Vu,l=r?Wr:Br;return a=u(n,t,l,e),o=u(t,n,l,Mr),i}function i(n){return a(n)}var a,o;return i.invert=function(n){return o(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(jr)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Qu(n,t)},i.tickFormat=function(t,e){return ni(n,t,e)},i.nice=function(t){return Gu(n,t),u()},i.copy=function(){return Wu(n,t,e,r)},u()}function Ju(n,t){return oa.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gu(n,t){return Xu(n,$u(Ku(n,t)[2])),Xu(n,$u(Ku(n,t)[2])),n}function Ku(n,t){null==t&&(t=10);var e=Yu(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Qu(n,t){return oa.range.apply(oa,Ku(n,t))}function ni(n,t,e){var r=Ku(n,t);if(e){var u=so.exec(e);if(u.shift(),"s"===u[8]){var i=oa.formatPrefix(Math.max(Ma(r[0]),Ma(r[1])));return u[7]||(u[7]="."+ti(i.scale(r[2]))),u[8]="f",e=oa.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+ei(u[8],r)),e=u.join("")}else e=",."+ti(r[2])+"f";return oa.format(e)}function ti(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function ei(n,t){var e=ti(t[2]);return n in Sl?Math.abs(e-ti(Math.max(Ma(t[0]),Ma(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ri(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function a(t){return n(u(t))}return a.invert=function(t){return i(n.invert(t))},a.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),a):r},a.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),a):t},a.nice=function(){var t=Xu(r.map(u),e?Math:Nl);return n.domain(t),r=t.map(i),a},a.ticks=function(){var n=Yu(r),a=[],o=n[0],l=n[1],c=Math.floor(u(o)),s=Math.ceil(u(l)),f=t%1?2:t;if(isFinite(s-c)){if(e){for(;s>c;c++)for(var h=1;f>h;h++)a.push(i(c)*h);a.push(i(c))}else for(a.push(i(c));c++0;h--)a.push(i(c)*h);for(c=0;a[c]l;s--);a=a.slice(c,s)}return a},a.tickFormat=function(n,e){if(!arguments.length)return kl;arguments.length<2?e=kl:"function"!=typeof e&&(e=oa.format(e));var r=Math.max(1,t*n/a.ticks().length);return function(n){var a=n/i(Math.round(u(n)));return t-.5>a*t&&(a*=t),r>=a?e(n):""}},a.copy=function(){return ri(n.copy(),t,e,r)},Ju(a,n)}function ui(n,t,e){function r(t){return n(u(t))}var u=ii(t),i=ii(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Qu(e,n)},r.tickFormat=function(n,t){return ni(e,n,t)},r.nice=function(n){return r.domain(Gu(e,n))},r.exponent=function(a){return arguments.length?(u=ii(t=a),i=ii(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return ui(n.copy(),t,e)},Ju(r,n)}function ii(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ai(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):NaN))-1)%i.length]}function r(t,e){return oa.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new c;for(var i,a=-1,o=r.length;++ae?[NaN,NaN]:[e>0?o[e-1]:n[0],et?NaN:t/i+n,[t,t+1/i]},r.copy=function(){return li(n,t,e)},u()}function ci(n,t){function e(e){return e>=e?t[oa.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return ci(n,t)},e}function si(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qu(n,t)},t.tickFormat=function(t,e){return ni(n,t,e)},t.copy=function(){return si(n)},t}function fi(){return 0}function hi(n){return n.innerRadius}function gi(n){return n.outerRadius}function pi(n){return n.startAngle}function vi(n){return n.endAngle}function di(n){return n&&n.padAngle}function mi(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function yi(n,t,e,r,u){var i=n[0]-t[0],a=n[1]-t[1],o=(u?r:-r)/Math.sqrt(i*i+a*a),l=o*a,c=-o*i,s=n[0]+l,f=n[1]+c,h=t[0]+l,g=t[1]+c,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(Math.max(0,M*M*y-x*x)),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,N=_-p,E=w-v,A=S-p,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mi(n){function t(t){function a(){c.push("M",i(n(s),o))}for(var l,c=[],s=[],f=-1,h=t.length,g=En(e),p=En(r);++f1?n.join("L"):n+"Z"}function bi(n){return n.join("L")+"Z"}function _i(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1&&u.push("H",r[0]),u.join("")}function wi(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){o=t[1],i=n[l],l++,r+="C"+(u[0]+a[0])+","+(u[1]+a[1])+","+(i[0]-o[0])+","+(i[1]-o[1])+","+i[0]+","+i[1];for(var c=2;c9&&(u=3*t/Math.sqrt(u),a[o]=u*e,a[o+1]=u*r));for(o=-1;++o<=l;)u=(n[Math.min(l,o+1)][0]-n[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),i.push([u||0,a[o]*u||0]);return i}function Fi(n){return n.length<3?xi(n):n[0]+Ai(n,Ui(n))}function Hi(n){for(var t,e,r,u=-1,i=n.length;++u=t?a(n-t):void(s.c=a)}function a(e){var u=p.active,i=p[u];i&&(i.timer.c=null,i.timer.t=NaN,--p.count,delete p[u],i.event&&i.event.interrupt.call(n,n.__data__,i.index));for(var a in p)if(r>+a){var c=p[a];c.timer.c=null,c.timer.t=NaN,--p.count,delete p[a]}s.c=o,qn(function(){return s.c&&o(e||1)&&(s.c=null,s.t=NaN),1},0,l),p.active=r,v.event&&v.event.start.call(n,n.__data__,t),g=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&g.push(r)}),h=v.ease,f=v.duration}function o(u){for(var i=u/f,a=h(i),o=g.length;o>0;)g[--o].call(n,a);return i>=1?(v.event&&v.event.end.call(n,n.__data__,t),--p.count?delete p[r]:delete n[e],1):void 0}var l,s,f,h,g,p=n[e]||(n[e]={active:0,count:0}),v=p[r];v||(l=u.time,s=qn(i,0,l),v=p[r]={tween:new c,time:l,timer:s,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++p.count)}function na(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function ta(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function ea(n){return n.toISOString()}function ra(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=oa.bisect(Gl,u);return i==Gl.length?[t.year,Ku(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Gl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=ua(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=ua(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yu(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],ua(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ra(n.copy(),t,e)},Ju(r,n)}function ua(n){return new Date(n)}function ia(n){return JSON.parse(n.responseText)}function aa(n){var t=sa.createRange();return t.selectNode(sa.body),t.createContextualFragment(n.responseText)}var oa={version:"3.5.12"},la=[].slice,ca=function(n){return la.call(n)},sa=this.document;if(sa)try{ca(sa.documentElement.childNodes)[0].nodeType}catch(fa){ca=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),sa)try{sa.createElement("DIV").style.setProperty("opacity",0,"")}catch(ha){var ga=this.Element.prototype,pa=ga.setAttribute,va=ga.setAttributeNS,da=this.CSSStyleDeclaration.prototype,ma=da.setProperty;ga.setAttribute=function(n,t){pa.call(this,n,t+"")},ga.setAttributeNS=function(n,t,e){va.call(this,n,t,e+"")},da.setProperty=function(n,t,e){ma.call(this,n,t+"",e)}}oa.ascending=e,oa.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},oa.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},oa.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},oa.extent=function(n,t){var e,r,u,i=-1,a=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++i r&&(e=r),r>u&&(u=r))}else{for(;++i =r){e=u=r;break}for(;++i r&&(e=r),r>u&&(u=r))}return[e,u]},oa.sum=function(n,t){var e,r=0,i=n.length,a=-1;if(1===arguments.length)for(;++a1?l/(s-1):void 0},oa.deviation=function(){var n=oa.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ya=i(e);oa.bisectLeft=ya.left,oa.bisect=oa.bisectRight=ya.right,oa.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},oa.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},oa.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},oa.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},oa.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=oa.min(arguments,a),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--a]=r[t];return e};var Ma=Math.abs;oa.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=o(Ma(e)),a=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++a)>t;)u.push(r/i);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var l,s,f,h,g=-1,p=a.length,v=i[o++],d=new c;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(oa.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},oa.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),oa.behavior={},oa.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},oa.event=null,oa.requote=function(n){return n.replace(wa,"\\$&")};var wa=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,Sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ka=function(n,t){return t.querySelector(n)},Na=function(n,t){return t.querySelectorAll(n)},Ea=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ea=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(ka=function(n,t){return Sizzle(n,t)[0]||null},Na=Sizzle,Ea=Sizzle.matchesSelector),oa.selection=function(){return oa.select(sa.documentElement)};var Aa=oa.selection.prototype=[];Aa.select=function(n){var t,e,r,u,i=[];n=A(n);for(var a=-1,o=this.length;++a=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Ca.hasOwnProperty(e)?{space:Ca[e],local:n}:n}},Aa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=oa.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Aa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++uu){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Aa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(j(t,n[t]));return this}return this.each(j(n,t))},Aa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Aa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Aa.append=function(n){return n=U(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Aa.insert=function(n,t){return n=U(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Aa.remove=function(){return this.each(F)},Aa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new c,y=new Array(a);for(r=-1;++rr;++r)p[r]=H(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,o.push(p),l.push(g),s.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var o=0,l=e.length;l>o;o++)(r=e[o])&&n.call(r,r.__data__,o,i)&&t.push(r)}return E(u)},Aa.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},Aa.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},Aa.size=function(){var n=0;return Y(this,function(){++n}),n};var za=[];oa.selection.enter=Z,oa.selection.enter.prototype=za,za.append=Aa.append,za.empty=Aa.empty,za.node=Aa.node,za.call=Aa.call,za.size=Aa.size,za.select=function(n){for(var t,e,r,u,i,a=[],o=-1,l=this.length;++or){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var La=oa.map({mouseenter:"mouseover",mouseleave:"mouseout"});sa&&La.forEach(function(n){"on"+n in sa&&La.remove(n)});var qa,Ta=0;oa.mouse=function(n){return J(n,k())};var Ra=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;oa.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},oa.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",a)}function e(n,t,e,i,a){return function(){function o(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(m.on(i+d,null).on(a+d,null),y(p),g({type:"dragend"}))}var c,s=this,f=oa.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=oa.select(e(f)).on(i+d,o).on(a+d,l),y=W(f),M=t(h,v);u?(c=u.apply(s,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],g({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),u=null,i=e(b,oa.mouse,t,"mousemove","mouseup"),a=e(G,oa.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},oa.rebind(n,r,"on")},oa.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ca(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Da=1e-6,Pa=Da*Da,ja=Math.PI,Ua=2*ja,Fa=Ua-Da,Ha=ja/2,Oa=ja/180,Ia=180/ja,Ya=Math.SQRT2,Za=2,Va=4;oa.interpolateZoom=function(n,t){var e,r,u=n[0],i=n[1],a=n[2],o=t[0],l=t[1],c=t[2],s=o-u,f=l-i,h=s*s+f*f;if(Pa>h)r=Math.log(c/a)/Ya,e=function(n){return[u+n*s,i+n*f,a*Math.exp(Ya*n*r)]};else{var g=Math.sqrt(h),p=(c*c-a*a+Va*h)/(2*a*Za*g),v=(c*c-a*a-Va*h)/(2*c*Za*g),d=Math.log(Math.sqrt(p*p+1)-p),m=Math.log(Math.sqrt(v*v+1)-v);r=(m-d)/Ya,e=function(n){var t=n*r,e=rn(d),o=a/(Za*g)*(e*un(Ya*t+d)-en(d));return[u+o*s,i+o*f,a*e/rn(Ya*t+d)]}}return e.duration=1e3*r,e},oa.behavior.zoom=function(){function n(n){n.on(L,f).on($a+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(A[0],Math.min(A[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function a(t,e,r,a){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,a)),i(d=e,r),t=oa.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function o(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){o=1,i(oa.mouse(u),h),c(a)}function r(){f.on(q,null).on(T,null),g(o),s(a)}var u=this,a=D.of(u,arguments),o=0,f=oa.select(t(u)).on(q,n).on(T,r),h=e(oa.mouse(u)),g=W(u);Ol.call(u),l(a)}function h(){function n(){var n=oa.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=oa.event.target;oa.select(t).on(x,r).on(b,o),_.push(t);for(var e=oa.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var s=l[0];a(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var s=l[0],f=l[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,a=oa.touches(p);Ol.call(p);for(var o=0,l=a.length;l>o;++o,r=null)if(e=a[o],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),c(v)}function o(){if(oa.event.touches.length){for(var t=oa.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}oa.selectAll(_).on(y,null),w.on(L,f).on(R,h),N(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+oa.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=oa.select(p),N=W(p);t(),l(v),w.on(L,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Ol.call(this),v=e(d=m||oa.mouse(this)),l(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Xa())*k.k),i(d,v),c(n)}function p(){var n=oa.mouse(this),t=Math.log(k.k)/Math.LN2;a(this,n,e(n),oa.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Ba,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return $a||($a="onwheel"in sa?(Xa=function(){return-oa.event.deltaY*(oa.event.deltaMode?120:1)},"wheel"):"onmousewheel"in sa?(Xa=function(){return oa.event.wheelDelta},"mousewheel"):(Xa=function(){return-oa.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Fl?oa.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=d?d[0]:e/2,i=d?d[1]:r/2,a=oa.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=a(t),o=e/r[2];this.__chart__=k={x:u-r[0]*o,y:i-r[1]*o,k:o},c(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,l(n),c(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},u(+t),o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Ba:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},oa.rebind(n,D,"on")};var Xa,$a,Ba=[0,1/0];oa.color=on,on.prototype.toString=function(){return this.rgb()+""},oa.hsl=ln;var Wa=ln.prototype=new on;Wa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Wa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Wa.rgb=function(){return cn(this.h,this.s,this.l)},oa.hcl=sn;var Ja=sn.prototype=new on;Ja.brighter=function(n){return new sn(this.h,this.c,Math.min(100,this.l+Ga*(arguments.length?n:1)))},Ja.darker=function(n){return new sn(this.h,this.c,Math.max(0,this.l-Ga*(arguments.length?n:1)))},Ja.rgb=function(){return fn(this.h,this.c,this.l).rgb()},oa.lab=hn;var Ga=18,Ka=.95047,Qa=1,no=1.08883,to=hn.prototype=new on;to.brighter=function(n){return new hn(Math.min(100,this.l+Ga*(arguments.length?n:1)),this.a,this.b)},to.darker=function(n){return new hn(Math.max(0,this.l-Ga*(arguments.length?n:1)),this.a,this.b)},to.rgb=function(){return gn(this.l,this.a,this.b)},oa.rgb=yn;var eo=yn.prototype=new on;eo.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new yn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new yn(u,u,u)},eo.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new yn(n*this.r,n*this.g,n*this.b)},eo.hsl=function(){return wn(this.r,this.g,this.b)},eo.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ro=oa.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ro.forEach(function(n,t){ro.set(n,Mn(t))}),oa.functor=En,oa.xhr=An(y),oa.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var a=Cn(n,t,null==e?r:u(e),i);return a.row=function(n){return arguments.length?a.response(null==(e=n)?r:u(n)):e},a}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(a).join(n)}function a(n){return o.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var o=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=c)return a;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),o=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++o);else if(r!==l)continue;return n.slice(t,s-o)}return n.slice(t)}for(var r,u,i={},a={},o=[],c=n.length,s=0,f=0;(r=e())!==a;){for(var h=[];r!==i&&r!==a;)h.push(r),r=e();t&&null==(h=t(h,f++))||o.push(h)}return o},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(a).join(n)].concat(t.map(function(t){return u.map(function(n){return a(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},oa.csv=oa.dsv(",","text/csv"),oa.tsv=oa.dsv(" ","text/tab-separated-values");var uo,io,ao,oo,lo=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};oa.timer=function(){qn.apply(this,arguments)},oa.timer.flush=function(){Rn(),Dn()},oa.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var co=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(jn);oa.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=oa.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),co[8+e/3]};var so=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,fo=oa.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=oa.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ho=oa.time={},go=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){po.setUTCDate.apply(this._,arguments)},setDay:function(){po.setUTCDay.apply(this._,arguments)},setFullYear:function(){po.setUTCFullYear.apply(this._,arguments)},setHours:function(){po.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){po.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){po.setUTCMinutes.apply(this._,arguments)},setMonth:function(){po.setUTCMonth.apply(this._,arguments)},setSeconds:function(){po.setUTCSeconds.apply(this._,arguments)},setTime:function(){po.setTime.apply(this._,arguments)}};var po=Date.prototype;ho.year=On(function(n){return n=ho.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ho.years=ho.year.range,ho.years.utc=ho.year.utc.range,ho.day=On(function(n){var t=new go(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ho.days=ho.day.range,ho.days.utc=ho.day.utc.range,ho.dayOfYear=function(n){var t=ho.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ho[n]=On(function(n){return(n=ho.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ho.year(n).getDay();return Math.floor((ho.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ho[n+"s"]=e.range,ho[n+"s"].utc=e.utc.range,ho[n+"OfYear"]=function(n){var e=ho.year(n).getDay();return Math.floor((ho.dayOfYear(n)+(e+t)%7)/7)}}),ho.week=ho.sunday,ho.weeks=ho.sunday.range,ho.weeks.utc=ho.sunday.utc.range,ho.weekOfYear=ho.sundayOfYear;var vo={"-":"",_:" ",0:"0"},mo=/^\s*\d+/,yo=/^%/;oa.locale=function(n){return{numberFormat:Un(n),timeFormat:Yn(n)}};var Mo=oa.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
-shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});oa.format=Mo.numberFormat,oa.geo={},st.prototype={s:0,t:0,add:function(n){ft(n,this.t,xo),ft(xo.s,this.s,this),this.s?this.t+=xo.t:this.s=xo.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var xo=new st;oa.geo.stream=function(n,t){n&&bo.hasOwnProperty(n.type)?bo[n.type](n,t):ht(n,t)};var bo={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*ja+n:n,ko.lineStart=ko.lineEnd=ko.point=b}};oa.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=dt([t*Oa,e*Oa]);if(m){var u=yt(m,r),i=[u[1],-u[0],0],a=yt(i,u);bt(a),a=_t(a);var l=t-p,c=l>0?1:-1,v=a[0]*Ia*c,d=Ma(l)>180;if(d^(v>c*p&&c*t>v)){var y=a[1]*Ia;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>c*p&&c*t>v)){var y=-a[1]*Ia;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?o(s,t)>o(s,h)&&(h=t):o(t,h)>o(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=Ma(r)>180?r+(r>0?360:-360):r}else v=n,d=e;ko.point(n,e),t(n,e)}function i(){ko.lineStart()}function a(){u(v,d),ko.lineEnd(),Ma(y)>Da&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function o(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nSo?(s=-(h=180),f=-(g=90)):y>Da?g=90:-Da>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],oa.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],c(e[0],u)||c(e[1],u)?(o(u[0],e[1])>o(u[0],u[1])&&(u[1]=e[1]),o(e[0],u[1])>o(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var a,e,p=-(1/0),t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(a=o(u[1],e[0]))>p&&(p=a,s=e[0],h=u[1])}return M=x=null,s===1/0||f===1/0?[[NaN,NaN],[NaN,NaN]]:[[s,f],[h,g]]}}(),oa.geo.centroid=function(n){No=Eo=Ao=Co=zo=Lo=qo=To=Ro=Do=Po=0,oa.geo.stream(n,jo);var t=Ro,e=Do,r=Po,u=t*t+e*e+r*r;return Pa>u&&(t=Lo,e=qo,r=To,Da>Eo&&(t=Ao,e=Co,r=zo),u=t*t+e*e+r*r,Pa>u)?[NaN,NaN]:[Math.atan2(e,t)*Ia,tn(r/Math.sqrt(u))*Ia]};var No,Eo,Ao,Co,zo,Lo,qo,To,Ro,Do,Po,jo={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){jo.lineStart=At},polygonEnd:function(){jo.lineStart=Nt}},Uo=Rt(zt,Ut,Ht,[-ja,-ja/2]),Fo=1e9;oa.geo.clipExtent=function(){var n,t,e,r,u,i,a={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(o){return arguments.length?(i=Zt(n=+o[0][0],t=+o[0][1],e=+o[1][0],r=+o[1][1]),u&&(u.valid=!1,u=null),a):[[n,t],[e,r]]}};return a.extent([[0,0],[960,500]])},(oa.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,oa.geo.albers=function(){return oa.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},oa.geo.albersUsa=function(){function n(n){var i=n[0],a=n[1];return t=null,e(i,a),t||(r(i,a),t)||u(i,a),t}var t,e,r,u,i=oa.geo.albers(),a=oa.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),o=oa.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?a:u>=.166&&.234>u&&r>=-.214&&-.115>r?o:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=a.stream(n),r=o.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),a.precision(t),o.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),a.scale(.35*t),o.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var c=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*c,f-.238*c],[s+.455*c,f+.238*c]]).stream(l).point,r=a.translate([s-.307*c,f+.201*c]).clipExtent([[s-.425*c+Da,f+.12*c+Da],[s-.214*c-Da,f+.234*c-Da]]).stream(l).point,u=o.translate([s-.205*c,f+.212*c]).clipExtent([[s-.214*c+Da,f+.166*c+Da],[s-.115*c-Da,f+.234*c-Da]]).stream(l).point,n},n.scale(1070)};var Ho,Oo,Io,Yo,Zo,Vo,Xo={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Oo=0,Xo.lineStart=$t},polygonEnd:function(){Xo.lineStart=Xo.lineEnd=Xo.point=b,Ho+=Ma(Oo/2)}},$o={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Bo={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Bo.lineStart=ne},polygonEnd:function(){Bo.point=Gt,Bo.lineStart=Kt,Bo.lineEnd=Qt}};oa.geo.path=function(){function n(n){return n&&("function"==typeof o&&i.pointRadius(+o.apply(this,arguments)),a&&a.valid||(a=u(i)),oa.geo.stream(n,a)),i.result()}function t(){return a=null,n}var e,r,u,i,a,o=4.5;return n.area=function(n){return Ho=0,oa.geo.stream(n,u(Xo)),Ho},n.centroid=function(n){return Ao=Co=zo=Lo=qo=To=Ro=Do=Po=0,oa.geo.stream(n,u(Bo)),Po?[Ro/Po,Do/Po]:To?[Lo/To,qo/To]:zo?[Ao/zo,Co/zo]:[NaN,NaN]},n.bounds=function(n){return Zo=Vo=-(Io=Yo=1/0),oa.geo.stream(n,u($o)),[[Io,Yo],[Zo,Vo]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||re(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Wt:new te(n),"function"!=typeof o&&i.pointRadius(o),t()):r},n.pointRadius=function(t){return arguments.length?(o="function"==typeof t?t:(i.pointRadius(+t),+t),n):o},n.projection(oa.geo.albersUsa()).context(null)},oa.geo.transform=function(n){return{stream:function(t){var e=new ue(t);for(var r in n)e[r]=n[r];return e}}},ue.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},oa.geo.projection=ae,oa.geo.projectionMutator=oe,(oa.geo.equirectangular=function(){return ae(ce)}).raw=ce.invert=ce,oa.geo.rotation=function(n){function t(t){return t=n(t[0]*Oa,t[1]*Oa),t[0]*=Ia,t[1]*=Ia,t}return n=fe(n[0]%360*Oa,n[1]*Oa,n.length>2?n[2]*Oa:0),t.invert=function(t){return t=n.invert(t[0]*Oa,t[1]*Oa),t[0]*=Ia,t[1]*=Ia,t},t},se.invert=ce,oa.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=fe(-n[0]*Oa,-n[1]*Oa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ia,n[1]*=Ia}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Oa,u*Oa),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Oa,(u=+r)*Oa),n):u},n.angle(90)},oa.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Oa,u=n[1]*Oa,i=t[1]*Oa,a=Math.sin(r),o=Math.cos(r),l=Math.sin(u),c=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*a)*e+(e=c*s-l*f*o)*e),l*s+c*f*o)},oa.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return oa.range(Math.ceil(i/d)*d,u,d).map(h).concat(oa.range(Math.ceil(c/m)*m,l,m).map(g)).concat(oa.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Ma(n%d)>Da}).map(s)).concat(oa.range(Math.ceil(o/v)*v,a,v).filter(function(n){return Ma(n%m)>Da}).map(f))}var e,r,u,i,a,o,l,c,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(l).slice(1),h(u).reverse().slice(1),g(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],c=+t[0][1],l=+t[1][1],i>u&&(t=i,i=u,u=t),c>l&&(t=c,c=l,l=t),n.precision(y)):[[i,c],[u,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],o=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),o>a&&(t=o,o=a,a=t),n.precision(y)):[[r,o],[e,a]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=me(o,a,90),f=ye(r,e,y),h=me(c,l,90),g=ye(i,u,y),n):y},n.majorExtent([[-180,-90+Da],[180,90-Da]]).minorExtent([[-180,-80-Da],[180,80+Da]])},oa.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=Me,u=xe;return n.distance=function(){return oa.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},oa.geo.interpolate=function(n,t){return be(n[0]*Oa,n[1]*Oa,t[0]*Oa,t[1]*Oa)},oa.geo.length=function(n){return Wo=0,oa.geo.stream(n,Jo),Wo};var Wo,Jo={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Go=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(oa.geo.azimuthalEqualArea=function(){return ae(Go)}).raw=Go;var Ko=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(oa.geo.azimuthalEquidistant=function(){return ae(Ko)}).raw=Ko,(oa.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(oa.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var Qo=we(function(n){return 1/n},Math.atan);(oa.geo.gnomonic=function(){return ae(Qo)}).raw=Qo,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ha]},(oa.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var nl=we(function(){return 1},Math.asin);(oa.geo.orthographic=function(){return ae(nl)}).raw=nl;var tl=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(oa.geo.stereographic=function(){return ae(tl)}).raw=tl,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ha]},(oa.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,oa.geom={},oa.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=En(e),i=En(r),a=n.length,o=[],l=[];for(t=0;a>t;t++)o.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(o.sort(qe),t=0;a>t;t++)l.push([o[t][0],-o[t][1]]);var c=Le(o),s=Le(l),f=s[0]===c[0],h=s[s.length-1]===c[c.length-1],g=[];for(t=c.length-1;t>=0;--t)g.push(n[o[c[t]][2]]);for(t=+f;t=r&&c.x<=i&&c.y>=u&&c.y<=a?[[r,a],[i,a],[i,u],[r,u]]:[];s.point=n[o]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Da)*Da,y:Math.round(a(n,t)/Da)*Da,i:t}})}var r=Ce,u=ze,i=r,a=u,o=sl;return n?t(n):(t.links=function(n){return or(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return or(e(n)).cells.forEach(function(e,r){for(var u,i,a=e.site,o=e.edges.sort(Ve),l=-1,c=o.length,s=o[c-1].edge,f=s.l===a?s.r:s.l;++l=c,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=hr()),f?u=c:o=c,h?a=s:l=s,i(n,t,e,r,u,a,o,l)}var s,f,h,g,p,v,d,m,y,M=En(o),x=En(l);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,a)for(g=0;p>g;++g)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=hr();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){gr(n,k,v,d,m,y)},k.find=function(n){return pr(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=pl.get(e)||gl,r=vl.get(r)||y,br(r(e.apply(null,la.call(arguments,1))))},oa.interpolateHcl=Rr,oa.interpolateHsl=Dr,oa.interpolateLab=Pr,oa.interpolateRound=jr,oa.transform=function(n){var t=sa.createElementNS(oa.ns.prefix.svg,"g");return(oa.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Ur(e?e.matrix:dl)})(n)},Ur.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var dl={a:1,b:0,c:0,d:1,e:0,f:0};oa.interpolateTransform=$r,oa.layout={},oa.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++eo*o/m){if(v>l){var c=t.charge/l;n.px-=i*c,n.py-=a*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=i*c,n.py-=a*c}}return!t.charge}}function t(n){n.px=oa.event.x,n.py=oa.event.y,l.resume()}var e,r,u,i,a,o,l={},c=oa.dispatch("start","tick","end"),s=[1,1],f=.9,h=ml,g=yl,p=-30,v=Ml,d=.1,m=.64,M=[],x=[];return l.tick=function(){if((u*=.99)<.005)return e=null,c.end({type:"end",alpha:u=0}),!0;var t,r,l,h,g,v,m,y,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,g=l.target,y=g.x-h.x,b=g.y-h.y,(v=y*y+b*b)&&(v=u*a[r]*((v=Math.sqrt(v))-i[r])/v,y*=v,b*=v,g.x-=y*(m=h.weight+g.weight?h.weight/(h.weight+g.weight):.5),g.y-=b*m,h.x+=y*(m=1-m),h.y+=b*m);if((m=u*d)&&(y=s[0]/2,b=s[1]/2,r=-1,m))for(;++r<_;)l=M[r],l.x+=(y-l.x)*m,l.y+=(b-l.y)*m;if(p)for(ru(t=oa.geom.quadtree(M),u,o),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*f,l.y-=(l.py-(l.py=l.y))*f);c.tick({type:"tick",alpha:u})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(s=n,l):s},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.friction=function(n){return arguments.length?(f=+n,l):f},l.charge=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(m=n*n,l):Math.sqrt(m)},l.alpha=function(n){return arguments.length?(n=+n,u?n>0?u=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:u=0})):n>0&&(c.start({type:"start",alpha:u=n}),e=qn(l.tick)),l):u},l.start=function(){function n(n,r){if(!e){for(e=new Array(u),l=0;u>l;++l)e[l]=[];for(l=0;c>l;++l){var i=x[l];e[i.source.index].push(i.target),e[i.target.index].push(i.source)}}for(var a,o=e[t],l=-1,s=o.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;u>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",f)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(i=[],"function"==typeof h)for(t=0;c>t;++t)i[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)i[t]=h;if(a=[],"function"==typeof g)for(t=0;c>t;++t)a[t]=+g.call(this,x[t],t);else for(t=0;c>t;++t)a[t]=g;if(o=[],"function"==typeof p)for(t=0;u>t;++t)o[t]=+p.call(this,M[t],t);else for(t=0;u>t;++t)o[t]=p;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=oa.behavior.drag().origin(y).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",nu)),arguments.length?void this.on("mouseover.force",tu).on("mouseout.force",eu).call(r):r},oa.rebind(l,c,"on")};var ml=20,yl=1,Ml=1/0;oa.layout.hierarchy=function(){function n(u){var i,a=[u],o=[];for(u.depth=0;null!=(i=a.pop());)if(o.push(i),(c=e.call(n,i,i.depth))&&(l=c.length)){for(var l,c,s;--l>=0;)a.push(s=c[l]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=c}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return au(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),o}var t=cu,e=ou,r=lu;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(iu(t,function(n){n.children&&(n.value=0)}),au(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},oa.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(a=i.length)){var a,o,l,c=-1;for(r=t.value?r/t.value:0;++cf?-1:1),p=oa.sum(c),v=p?(f-l*g)/p:0,d=oa.range(l),m=[];return null!=e&&d.sort(e===xl?function(n,t){return c[t]-c[n]}:function(n,t){return e(a[n],a[t])}),d.forEach(function(n){m[n]={data:a[n],value:o=c[n],startAngle:s,endAngle:s+=o*v+g,padAngle:h}}),m}var t=Number,e=xl,r=0,u=Ua,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var xl={};oa.layout.stack=function(){function n(o,l){if(!(h=o.length))return o;var c=o.map(function(e,r){return t.call(n,e,r)}),s=c.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),a.call(n,t,e)]})}),f=e.call(n,s,l);c=oa.permute(c,f),s=oa.permute(s,f);var h,g,p,v,d=r.call(n,s,l),m=c[0].length;for(p=0;m>p;++p)for(u.call(n,c[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,c[g][p],v+=s[g-1][p][1],s[g][p][1]);return o}var t=y,e=pu,r=vu,u=gu,i=fu,a=hu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:bl.get(t)||pu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:_l.get(t)||vu,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(a=t,n):a},n.out=function(t){return arguments.length?(u=t,n):u},n};var bl=oa.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(du),i=n.map(mu),a=oa.range(r).sort(function(n,t){return u[n]-u[t]}),o=0,l=0,c=[],s=[];for(t=0;r>t;++t)e=a[t],l>o?(o+=i[e],c.push(e)):(l+=i[e],s.push(e));return s.reverse().concat(c)},reverse:function(n){return oa.range(n.length).reverse()},"default":pu}),_l=oa.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,a=[],o=0,l=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>o&&(o=r),a.push(r)}for(e=0;i>e;++e)l[e]=(o-a[e])/2;return l},wiggle:function(n){var t,e,r,u,i,a,o,l,c,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=l=c=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,o=f[e][0]-f[e-1][0];s>t;++t){for(r=0,a=(n[t][e][1]-n[t][e-1][1])/(2*o);t>r;++r)a+=(n[r][e][1]-n[r][e-1][1])/o;i+=a*n[t][e][1]}g[e]=l-=u?i/u*o:0,c>l&&(c=l)}for(e=0;h>e;++e)g[e]-=c;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,a=1/u,o=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=a}for(e=0;i>e;++e)o[e]=0;return o},zero:vu});oa.layout.histogram=function(){function n(n,i){for(var a,o,l=[],c=n.map(e,this),s=r.call(this,c,i),f=u.call(this,s,c,i),i=-1,h=c.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&o<=s[1]&&(a=l[oa.bisect(f,o,1,g)-1],a.y+=p,a.push(n[i]));return l}var t=!0,e=Number,r=bu,u=Mu;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return xu(n,t)}:En(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},oa.layout.pack=function(){function n(n,i){var a=e.call(this,n,i),o=a[0],l=u[0],c=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(o.x=o.y=0,au(o,function(n){n.r=+s(n.value)}),au(o,Nu),r){var f=r*(t?1:Math.max(2*o.r/l,2*o.r/c))/2;au(o,function(n){n.r+=f}),au(o,Nu),au(o,function(n){n.r-=f})}return Cu(o,l/2,c/2,t?1:1/Math.max(2*o.r/l,2*o.r/c)),a}var t,e=oa.layout.hierarchy().sort(_u),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},uu(n,e)},oa.layout.tree=function(){function n(n,u){var s=a.call(this,n,u),f=s[0],h=t(f);if(au(h,e),h.parent.m=-h.z,iu(h,r),c)iu(f,i);else{var g=f,p=f,v=f;iu(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=o(g,p)/2-g.x,m=l[0]/(p.x+o(p,g)/2+d),y=l[1]/(v.depth||1);iu(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,a=0,o=i.length;o>a;++a)r.push((i[a]=u={_:i[a],parent:t,children:(u=i[a].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:a}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Du(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+o(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+o(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,a=t,l=u.parent.children[0],c=u.m,s=i.m,f=a.m,h=l.m;a=Tu(a),u=qu(u),a&&u;)l=qu(l),i=Tu(i),i.a=n,r=a.z+f-u.z-c+o(a._,u._),r>0&&(Ru(Pu(a,n,e),n,r),c+=r,s+=r),f+=a.m,c+=u.m,h+=l.m,s+=i.m;a&&!Tu(i)&&(i.t=a,i.m+=f-s),u&&!qu(l)&&(l.t=u,l.m+=c-h,e=n)}return e}function i(n){n.x*=l[0],n.y=n.depth*l[1]}var a=oa.layout.hierarchy().sort(null).value(null),o=Lu,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(o=t,n):o},n.size=function(t){return arguments.length?(c=null==(l=t)?i:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:i,n):c?l:null},uu(n,a)},oa.layout.cluster=function(){function n(n,i){var a,o=t.call(this,n,i),l=o[0],c=0;au(l,function(n){var t=n.children;t&&t.length?(n.x=Uu(t),n.y=ju(t)):(n.x=a?c+=e(n,a):0,n.y=0,a=n)});var s=Fu(l),f=Hu(l),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return au(l,u?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),o}var t=oa.layout.hierarchy().sort(null).value(null),e=Lu,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},uu(n,t)},oa.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var a,o,l,c=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?c.dx:"dice"===g?c.dy:"slice-dice"===g?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),s.area=0;(l=h.length)>0;)s.push(a=h[l-1]),s.area+=a.area,"squarify"!==g||(o=r(s,v))<=p?(h.pop(),p=o):(s.area-=s.pop().area,u(s,v,c,!1),v=Math.min(c.dx,c.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,c,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,a=f(t),o=r.slice(),l=[];for(n(o,a.dx*a.dy/t.value),l.area=0;i=o.pop();)l.push(i),l.area+=i.area,null!=i.z&&(u(l,i.z?a.dx:a.dy,a,!o.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,a=-1,o=n.length;++ae&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,a=n.length,o=e.x,c=e.y,s=t?l(n.area/t):0;
\ No newline at end of file
diff --git a/its/plugin/projects/minified_files/src/file.js b/its/plugin/projects/minified_files/src/file.js
deleted file mode 100644
index 72326958950..00000000000
--- a/its/plugin/projects/minified_files/src/file.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function fun1() {
-}
-
-function fun2() {
-}
-
-if (true) {}
diff --git a/its/plugin/projects/minified_files/src/file.min.js b/its/plugin/projects/minified_files/src/file.min.js
deleted file mode 100644
index c525ef521bc..00000000000
--- a/its/plugin/projects/minified_files/src/file.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=" ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
diff --git a/its/plugin/projects/missing-tsconfig-vue/package-lock.json b/its/plugin/projects/missing-tsconfig-vue/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/missing-tsconfig-vue/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/missing-tsconfig-vue/package.json b/its/plugin/projects/missing-tsconfig-vue/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/missing-tsconfig-vue/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/missing-tsconfig-vue/src/file.vue b/its/plugin/projects/missing-tsconfig-vue/src/file.vue
deleted file mode 100644
index c5c4c9d74c5..00000000000
--- a/its/plugin/projects/missing-tsconfig-vue/src/file.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
diff --git a/its/plugin/projects/missing-tsconfig-vue/src/main.ts b/its/plugin/projects/missing-tsconfig-vue/src/main.ts
deleted file mode 100644
index 22e51ccf192..00000000000
--- a/its/plugin/projects/missing-tsconfig-vue/src/main.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-function x(x: number) {
- let y = x as number;
-}
diff --git a/its/plugin/projects/missing-tsconfig/package-lock.json b/its/plugin/projects/missing-tsconfig/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/missing-tsconfig/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/missing-tsconfig/package.json b/its/plugin/projects/missing-tsconfig/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/missing-tsconfig/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/missing-tsconfig/src/main.ts b/its/plugin/projects/missing-tsconfig/src/main.ts
deleted file mode 100644
index 22e51ccf192..00000000000
--- a/its/plugin/projects/missing-tsconfig/src/main.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-function x(x: number) {
- let y = x as number;
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/package-lock.json b/its/plugin/projects/multi-tsconfig-test-project/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/package.json b/its/plugin/projects/multi-tsconfig-test-project/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/bar/excluded/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/bar/excluded/main.ts
deleted file mode 100644
index 6585f9d1bcf..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/bar/excluded/main.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-function foo(b: number) {
- //
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/bar/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/bar/main.ts
deleted file mode 100644
index 6585f9d1bcf..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/bar/main.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-function foo(b: number) {
- //
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/dir1/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/dir1/main.ts
deleted file mode 100644
index c4e75978fb3..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/dir1/main.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-function foo(b: number) {
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/dir1/tsconfig.json b/its/plugin/projects/multi-tsconfig-test-project/src/dir1/tsconfig.json
deleted file mode 100644
index 198c6536f3a..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/dir1/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "lib": [
- "esnext", // to test trailing comma
- ]
- },
- "include": ["main.ts"], // to test trailing comma
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/dir2/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/dir2/main.ts
deleted file mode 100644
index c4e75978fb3..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/dir2/main.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-function foo(b: number) {
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/dir2/tsconfig.json b/its/plugin/projects/multi-tsconfig-test-project/src/dir2/tsconfig.json
deleted file mode 100644
index 4e70e3994d4..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/dir2/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "lib": [
- "esnext"
- ]
- },
- "files": ["main.ts"]
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/excluded/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/excluded/main.ts
deleted file mode 100644
index 6585f9d1bcf..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/excluded/main.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-function foo(b: number) {
- //
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/foo/main.ts b/its/plugin/projects/multi-tsconfig-test-project/src/foo/main.ts
deleted file mode 100644
index c4e75978fb3..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/foo/main.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-function foo(b: number) {
- //
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/src/foo/tsconfig.json b/its/plugin/projects/multi-tsconfig-test-project/src/foo/tsconfig.json
deleted file mode 100644
index 4e70e3994d4..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/src/foo/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "lib": [
- "esnext"
- ]
- },
- "files": ["main.ts"]
-}
diff --git a/its/plugin/projects/multi-tsconfig-test-project/tsconfig.json b/its/plugin/projects/multi-tsconfig-test-project/tsconfig.json
deleted file mode 100644
index 8164eea289a..00000000000
--- a/its/plugin/projects/multi-tsconfig-test-project/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "include": ["src/bar"],
- "exclude": ["src/bar/excluded"]
-}
diff --git a/its/plugin/projects/nosonar/main.js b/its/plugin/projects/nosonar/main.js
deleted file mode 100644
index 4c95c079b26..00000000000
--- a/its/plugin/projects/nosonar/main.js
+++ /dev/null
@@ -1,4 +0,0 @@
-foo();
-; /* NOSONAR */
-; // NOSONAR
-;
diff --git a/its/plugin/projects/pr-analysis-cpd-js-branch/file1.js b/its/plugin/projects/pr-analysis-cpd-js-branch/file1.js
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-js-branch/file1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-js-branch/file2.js b/its/plugin/projects/pr-analysis-cpd-js-branch/file2.js
deleted file mode 100644
index c207cd4c46b..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-js-branch/file2.js
+++ /dev/null
@@ -1,33 +0,0 @@
-class A {
- meth(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
- }
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-js-branch/file3.js b/its/plugin/projects/pr-analysis-cpd-js-branch/file3.js
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-js-branch/file3.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-js-main/file1.js b/its/plugin/projects/pr-analysis-cpd-js-main/file1.js
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-js-main/file1.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-js-main/file2.js b/its/plugin/projects/pr-analysis-cpd-js-main/file2.js
deleted file mode 100644
index c207cd4c46b..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-js-main/file2.js
+++ /dev/null
@@ -1,33 +0,0 @@
-class A {
- meth(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
- }
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-branch/file1.ts b/its/plugin/projects/pr-analysis-cpd-ts-branch/file1.ts
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-branch/file1.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-branch/file2.ts b/its/plugin/projects/pr-analysis-cpd-ts-branch/file2.ts
deleted file mode 100644
index c207cd4c46b..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-branch/file2.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-class A {
- meth(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
- }
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-branch/file3.ts b/its/plugin/projects/pr-analysis-cpd-ts-branch/file3.ts
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-branch/file3.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-branch/tsconfig.json b/its/plugin/projects/pr-analysis-cpd-ts-branch/tsconfig.json
deleted file mode 100644
index 22f6236e23d..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-branch/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["file1.ts", "file2.ts", "file3.ts"]
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-main/file1.ts b/its/plugin/projects/pr-analysis-cpd-ts-main/file1.ts
deleted file mode 100644
index 1728c7717bd..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-main/file1.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-function func(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-main/file2.ts b/its/plugin/projects/pr-analysis-cpd-ts-main/file2.ts
deleted file mode 100644
index c207cd4c46b..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-main/file2.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-class A {
- meth(results) {
- console.log("a");
- console.log("b");
- console.log("c");
- console.log("d");
- console.log("e");
- if (results.length > 10) {
- console.log("f");
- console.log("g");
- console.log("h");
- console.log("i");
- console.log("j");
- for (const result of results) {
- console.log(result);
- console.log("k");
- console.log("l");
- console.log("m");
- console.log("n");
- }
- console.log("o");
- console.log("p");
- console.log("q");
- console.log("r");
- console.log("s");
- console.log("t");
- }
- console.log("u");
- console.log("v");
- console.log("w");
- console.log("x");
- }
-}
diff --git a/its/plugin/projects/pr-analysis-cpd-ts-main/tsconfig.json b/its/plugin/projects/pr-analysis-cpd-ts-main/tsconfig.json
deleted file mode 100644
index ea9d1faee68..00000000000
--- a/its/plugin/projects/pr-analysis-cpd-ts-main/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["file1.ts", "file2.ts"]
-}
diff --git a/its/plugin/projects/pr-analysis-js-branch/hello.js b/its/plugin/projects/pr-analysis-js-branch/hello.js
deleted file mode 100644
index a49f2ed48d7..00000000000
--- a/its/plugin/projects/pr-analysis-js-branch/hello.js
+++ /dev/null
@@ -1,7 +0,0 @@
-exports.hello = function(name) {
- console.log('Starting...');;
- setTimeout(() => {
- console.log(`Hello, ${name.toUpperCase()}!`);
- setTimeout(() => console.log('Stopped!'), 100);
- }, sleep);
-}
diff --git a/its/plugin/projects/pr-analysis-js-branch/index.js b/its/plugin/projects/pr-analysis-js-branch/index.js
deleted file mode 100644
index a2061a89934..00000000000
--- a/its/plugin/projects/pr-analysis-js-branch/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-const { hello } = require('./hello');
-hello('World');;
diff --git a/its/plugin/projects/pr-analysis-js-branch/package.json b/its/plugin/projects/pr-analysis-js-branch/package.json
deleted file mode 100644
index b2092a1c99a..00000000000
--- a/its/plugin/projects/pr-analysis-js-branch/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"pr-analysis-js","version":"1.0.0","main":"index.js"}
diff --git a/its/plugin/projects/pr-analysis-js-main/hello.js b/its/plugin/projects/pr-analysis-js-main/hello.js
deleted file mode 100644
index 890a24112ab..00000000000
--- a/its/plugin/projects/pr-analysis-js-main/hello.js
+++ /dev/null
@@ -1,3 +0,0 @@
-exports.hello = function(name) {
- console.log(`Hello, ${name}!`);
-};
diff --git a/its/plugin/projects/pr-analysis-js-main/index.js b/its/plugin/projects/pr-analysis-js-main/index.js
deleted file mode 100644
index a2061a89934..00000000000
--- a/its/plugin/projects/pr-analysis-js-main/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-const { hello } = require('./hello');
-hello('World');;
diff --git a/its/plugin/projects/pr-analysis-js-main/package.json b/its/plugin/projects/pr-analysis-js-main/package.json
deleted file mode 100644
index b2092a1c99a..00000000000
--- a/its/plugin/projects/pr-analysis-js-main/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"pr-analysis-js","version":"1.0.0","main":"index.js"}
diff --git a/its/plugin/projects/pr-analysis-ts-branch/hello.ts b/its/plugin/projects/pr-analysis-ts-branch/hello.ts
deleted file mode 100644
index a49f2ed48d7..00000000000
--- a/its/plugin/projects/pr-analysis-ts-branch/hello.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-exports.hello = function(name) {
- console.log('Starting...');;
- setTimeout(() => {
- console.log(`Hello, ${name.toUpperCase()}!`);
- setTimeout(() => console.log('Stopped!'), 100);
- }, sleep);
-}
diff --git a/its/plugin/projects/pr-analysis-ts-branch/index.ts b/its/plugin/projects/pr-analysis-ts-branch/index.ts
deleted file mode 100644
index a2061a89934..00000000000
--- a/its/plugin/projects/pr-analysis-ts-branch/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const { hello } = require('./hello');
-hello('World');;
diff --git a/its/plugin/projects/pr-analysis-ts-branch/package.json b/its/plugin/projects/pr-analysis-ts-branch/package.json
deleted file mode 100644
index af48dd1ce89..00000000000
--- a/its/plugin/projects/pr-analysis-ts-branch/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-"name":"pr-analysis-ts",
-"version":"1.0.0",
-"main":"index.ts",
-"devDependencies":{"@types/node":"^18.7.13"}
-}
diff --git a/its/plugin/projects/pr-analysis-ts-branch/tsconfig.json b/its/plugin/projects/pr-analysis-ts-branch/tsconfig.json
deleted file mode 100644
index 38e963f8e23..00000000000
--- a/its/plugin/projects/pr-analysis-ts-branch/tsconfig.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":["index.ts","hello.ts"]}
diff --git a/its/plugin/projects/pr-analysis-ts-main/hello.ts b/its/plugin/projects/pr-analysis-ts-main/hello.ts
deleted file mode 100644
index 890a24112ab..00000000000
--- a/its/plugin/projects/pr-analysis-ts-main/hello.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-exports.hello = function(name) {
- console.log(`Hello, ${name}!`);
-};
diff --git a/its/plugin/projects/pr-analysis-ts-main/index.ts b/its/plugin/projects/pr-analysis-ts-main/index.ts
deleted file mode 100644
index a2061a89934..00000000000
--- a/its/plugin/projects/pr-analysis-ts-main/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const { hello } = require('./hello');
-hello('World');;
diff --git a/its/plugin/projects/pr-analysis-ts-main/package.json b/its/plugin/projects/pr-analysis-ts-main/package.json
deleted file mode 100644
index af48dd1ce89..00000000000
--- a/its/plugin/projects/pr-analysis-ts-main/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-"name":"pr-analysis-ts",
-"version":"1.0.0",
-"main":"index.ts",
-"devDependencies":{"@types/node":"^18.7.13"}
-}
diff --git a/its/plugin/projects/pr-analysis-ts-main/tsconfig.json b/its/plugin/projects/pr-analysis-ts-main/tsconfig.json
deleted file mode 100644
index 38e963f8e23..00000000000
--- a/its/plugin/projects/pr-analysis-ts-main/tsconfig.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":["index.ts","hello.ts"]}
diff --git a/its/plugin/projects/pr-analysis-yaml-branch/file1.yaml b/its/plugin/projects/pr-analysis-yaml-branch/file1.yaml
deleted file mode 100644
index 554e4dd7f57..00000000000
--- a/its/plugin/projects/pr-analysis-yaml-branch/file1.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09 # This file is the same between the 2 branches.
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLogGroup:
- Type: AWS::Logs::LogGroup #Noncompliant (S6295)
- Properties:
- LogGroupName: !Join ['/', ['/aws/lambda', !Ref MyLambdaFunction]]
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- console.log('Hello, World');
diff --git a/its/plugin/projects/pr-analysis-yaml-branch/file2.yaml b/its/plugin/projects/pr-analysis-yaml-branch/file2.yaml
deleted file mode 100644
index fa63c8366b9..00000000000
--- a/its/plugin/projects/pr-analysis-yaml-branch/file2.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- console.log('Hello, World');; // Noncompliant (javascript:S1116)
diff --git a/its/plugin/projects/pr-analysis-yaml-main/file1.yaml b/its/plugin/projects/pr-analysis-yaml-main/file1.yaml
deleted file mode 100644
index 554e4dd7f57..00000000000
--- a/its/plugin/projects/pr-analysis-yaml-main/file1.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09 # This file is the same between the 2 branches.
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLogGroup:
- Type: AWS::Logs::LogGroup #Noncompliant (S6295)
- Properties:
- LogGroupName: !Join ['/', ['/aws/lambda', !Ref MyLambdaFunction]]
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- console.log('Hello, World');
diff --git a/its/plugin/projects/pr-analysis-yaml-main/file2.yaml b/its/plugin/projects/pr-analysis-yaml-main/file2.yaml
deleted file mode 100644
index 8c8f733daf8..00000000000
--- a/its/plugin/projects/pr-analysis-yaml-main/file2.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Serverless::Function"
- Properties:
- Runtime: "nodejs16.0"
- InlineCode: >
- console.log('Hello, World');
diff --git a/its/plugin/projects/project-with-bom/fileWithBom.js b/its/plugin/projects/project-with-bom/fileWithBom.js
deleted file mode 100644
index afc3be4313d..00000000000
--- a/its/plugin/projects/project-with-bom/fileWithBom.js
+++ /dev/null
@@ -1,6 +0,0 @@
-if (cond) {
- foo();
- } else {
- foo();
- }
-
\ No newline at end of file
diff --git a/its/plugin/projects/project-with-different-encoding/fileWithUtf16.js b/its/plugin/projects/project-with-different-encoding/fileWithUtf16.js
deleted file mode 100644
index f3da652e072..00000000000
Binary files a/its/plugin/projects/project-with-different-encoding/fileWithUtf16.js and /dev/null differ
diff --git a/its/plugin/projects/quickfix/main.js b/its/plugin/projects/quickfix/main.js
deleted file mode 100644
index 039d2f32e10..00000000000
--- a/its/plugin/projects/quickfix/main.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-var x = 5;;
diff --git a/its/plugin/projects/referenced-tsconfigs/dir/file.ts b/its/plugin/projects/referenced-tsconfigs/dir/file.ts
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/its/plugin/projects/referenced-tsconfigs/dir/tsconfig.json b/its/plugin/projects/referenced-tsconfigs/dir/tsconfig.json
deleted file mode 100644
index 28c206890cd..00000000000
--- a/its/plugin/projects/referenced-tsconfigs/dir/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "files": ["file.ts"],
- "references": [
- {
- "path": "..\\tsconfig.json"
- }
- ]
-}
diff --git a/its/plugin/projects/referenced-tsconfigs/file.ts b/its/plugin/projects/referenced-tsconfigs/file.ts
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/its/plugin/projects/referenced-tsconfigs/tsconfig.json b/its/plugin/projects/referenced-tsconfigs/tsconfig.json
deleted file mode 100644
index 91aa8811e19..00000000000
--- a/its/plugin/projects/referenced-tsconfigs/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "files": ["file.ts"],
- "references": [
- {
- "path": "dir/tsconfig.json"
- }
- ]
-}
diff --git a/its/plugin/projects/same-filename/file.js b/its/plugin/projects/same-filename/file.js
deleted file mode 100644
index 1c257bb2abc..00000000000
--- a/its/plugin/projects/same-filename/file.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function foo() {
- let str = 'str', num = 5;
-
- if (str === num) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/same-filename/file.ts b/its/plugin/projects/same-filename/file.ts
deleted file mode 100644
index f610f1f8515..00000000000
--- a/its/plugin/projects/same-filename/file.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-function bar(b: number, c: number) {
- if (b == 0) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/same-filename/tsconfig.json b/its/plugin/projects/same-filename/tsconfig.json
deleted file mode 100644
index 0967ef424bc..00000000000
--- a/its/plugin/projects/same-filename/tsconfig.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/its/plugin/projects/solution-tsconfig-custom/package-lock.json b/its/plugin/projects/solution-tsconfig-custom/package-lock.json
deleted file mode 100644
index 642ef30d501..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.9.7",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
- "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
- }
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig-custom/package.json b/its/plugin/projects/solution-tsconfig-custom/package.json
deleted file mode 100644
index d2f6110ef3e..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "solution-tsconfig",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "dependencies": {
- "typescript": "^3.9.7"
- },
- "devDependencies": {},
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "",
- "license": "ISC"
-}
diff --git a/its/plugin/projects/solution-tsconfig-custom/src/file.ts b/its/plugin/projects/solution-tsconfig-custom/src/file.ts
deleted file mode 100644
index a7112e7c7ca..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/src/file.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { doOneMoreThing } from "./unlisted";
-
-function foo(b: number, c: number) {
- if (b == 0) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig-custom/src/tsconfig.json b/its/plugin/projects/solution-tsconfig-custom/src/tsconfig.json
deleted file mode 100644
index ad6a43ea096..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/src/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["file.ts"]
-}
diff --git a/its/plugin/projects/solution-tsconfig-custom/src/unlisted.ts b/its/plugin/projects/solution-tsconfig-custom/src/unlisted.ts
deleted file mode 100644
index 448751baf00..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/src/unlisted.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// this file is not listed in tsconfig.json, but it's referenced from file.ts
-
-export function doOneMoreThing() {
- if (condition) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig-custom/tsconfig.json b/its/plugin/projects/solution-tsconfig-custom/tsconfig.json
deleted file mode 100644
index 7c4a09f8d60..00000000000
--- a/its/plugin/projects/solution-tsconfig-custom/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "files": [],
- "references": [
- {
- "path": "src"
- }
- ]
-}
diff --git a/its/plugin/projects/solution-tsconfig/package-lock.json b/its/plugin/projects/solution-tsconfig/package-lock.json
deleted file mode 100644
index de041ae8ded..00000000000
--- a/its/plugin/projects/solution-tsconfig/package-lock.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.9.7",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
- "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw=="
- }
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig/package.json b/its/plugin/projects/solution-tsconfig/package.json
deleted file mode 100644
index d2f6110ef3e..00000000000
--- a/its/plugin/projects/solution-tsconfig/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "solution-tsconfig",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "dependencies": {
- "typescript": "^3.9.7"
- },
- "devDependencies": {},
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "",
- "license": "ISC"
-}
diff --git a/its/plugin/projects/solution-tsconfig/src/file.ts b/its/plugin/projects/solution-tsconfig/src/file.ts
deleted file mode 100644
index a7112e7c7ca..00000000000
--- a/its/plugin/projects/solution-tsconfig/src/file.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { doOneMoreThing } from "./unlisted";
-
-function foo(b: number, c: number) {
- if (b == 0) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig/src/unlisted.ts b/its/plugin/projects/solution-tsconfig/src/unlisted.ts
deleted file mode 100644
index 448751baf00..00000000000
--- a/its/plugin/projects/solution-tsconfig/src/unlisted.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// this file is not listed in tsconfig.json, but it's referenced from file.ts
-
-export function doOneMoreThing() {
- if (condition) {
- // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/solution-tsconfig/tsconfig.app.json b/its/plugin/projects/solution-tsconfig/tsconfig.app.json
deleted file mode 100644
index 1c52fa51895..00000000000
--- a/its/plugin/projects/solution-tsconfig/tsconfig.app.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["src/file.ts"]
-}
diff --git a/its/plugin/projects/solution-tsconfig/tsconfig.json b/its/plugin/projects/solution-tsconfig/tsconfig.json
deleted file mode 100644
index b8d93e89ac0..00000000000
--- a/its/plugin/projects/solution-tsconfig/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "files": [],
- "references": [
- {
- "path": "tsconfig.app.json"
- }
- ]
-}
diff --git a/its/plugin/projects/test-code-project/src/file.js b/its/plugin/projects/test-code-project/src/file.js
deleted file mode 100644
index c86234ffafc..00000000000
--- a/its/plugin/projects/test-code-project/src/file.js
+++ /dev/null
@@ -1 +0,0 @@
-new MyConstructor();
\ No newline at end of file
diff --git a/its/plugin/projects/test-code-project/test/file.test.js b/its/plugin/projects/test-code-project/test/file.test.js
deleted file mode 100644
index c86234ffafc..00000000000
--- a/its/plugin/projects/test-code-project/test/file.test.js
+++ /dev/null
@@ -1 +0,0 @@
-new MyConstructor();
\ No newline at end of file
diff --git a/its/plugin/projects/ts-rule-project/S1219.ts b/its/plugin/projects/ts-rule-project/S1219.ts
deleted file mode 100644
index 0c1406091c4..00000000000
--- a/its/plugin/projects/ts-rule-project/S1219.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-switch (foo()) {
- case 0:
- bar();
- break;
- case 1:
- l: while (true) bar(); // Noncompliant
- break;
-}
diff --git a/its/plugin/projects/ts-rule-project/S1439.ts b/its/plugin/projects/ts-rule-project/S1439.ts
deleted file mode 100644
index 5bd745e489d..00000000000
--- a/its/plugin/projects/ts-rule-project/S1439.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-
-function compliant(x: number) {
- label0:
- while (x < 0) {
- x++;
- break label0;
- }
-
- label1: do {
- label2: for (let i = 0; i < 3; i++) {
- if (x % i == 1) {
- break label1;
- } else {
- break label2;
- }
- return 3;
- }
- } while (true);
-}
-
-function nonCompliant(x: number) {
- label0: // Noncompliant
- if (x > 0) {
- return 0;
- }
-
- label1: const val = 1; // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S1472.ts b/its/plugin/projects/ts-rule-project/S1472.ts
deleted file mode 100644
index bae5f7283b3..00000000000
--- a/its/plugin/projects/ts-rule-project/S1472.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-function foo(k: number) {
- return k + 1;
-}
-
-const n = 5;
-
-foo(n);
-
-foo(
- n
-);
-
-foo
-(n); // Noncompliant
diff --git a/its/plugin/projects/ts-rule-project/S1529.ts b/its/plugin/projects/ts-rule-project/S1529.ts
deleted file mode 100644
index 115907b11ba..00000000000
--- a/its/plugin/projects/ts-rule-project/S1529.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-function f(a: any, b: any) {
- if (a | b) { // Noncompliant
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S2077.ts b/its/plugin/projects/ts-rule-project/S2077.ts
deleted file mode 100644
index 1d4b7209b69..00000000000
--- a/its/plugin/projects/ts-rule-project/S2077.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import * as mysql from 'mysql';
-
-const mycon = mysql.createConnection({ host, user, password, database });
-mycon.connect(function(error) {
- mycon.query('SELECT * FROM users WHERE id = ' + userinput, (err, res) => {}); // Noncompliant
-});
diff --git a/its/plugin/projects/ts-rule-project/S2123.ts b/its/plugin/projects/ts-rule-project/S2123.ts
deleted file mode 100644
index bc45d8d70ab..00000000000
--- a/its/plugin/projects/ts-rule-project/S2123.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-function f1() {
- let i = 1;
- i = i++; // Noncompliant
- i = j++;
- i = ++i;
- i++;
- i = i--; // Noncompliant
-
- return i++; // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S2234.ts b/its/plugin/projects/ts-rule-project/S2234.ts
deleted file mode 100644
index a677900a1d2..00000000000
--- a/its/plugin/projects/ts-rule-project/S2234.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-function standardMethod() {
- const length = 1;
- const from = 0;
- return "abcdef".substr(length, from); // Noncompliant
-}
-
-class A {
- method(a: string, b: number, c: string, d: string) {}
-}
-
-let a = 4;
-let b = "";
-let c = "";
-let d = "";
-
-new A().method(b, a, c, d);
-new A().method(b, a, d, c); // Noncompliant
-
-function myFunction(a, b, c, d) {}
-
-function testWithoutTypes(a, b, c, d) {
- myFunction(b, a, c, d); // Noncompliant
- myFunction(b, a, d, c); // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S2757.ts b/its/plugin/projects/ts-rule-project/S2757.ts
deleted file mode 100644
index 9d0ab4e2d76..00000000000
--- a/its/plugin/projects/ts-rule-project/S2757.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-
-function compliant() {
- let x = +1;
- x = -1;
- let y = !1;
- y =
- ! 1;
- y=!1;
-}
-
-function nonCompliant() {
- let x = 0;
- x =+ 1; // Noncompliant
- x =- 1; // Noncompliant
- let y =! true; // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S2871.ts b/its/plugin/projects/ts-rule-project/S2871.ts
deleted file mode 100644
index e6224581ae7..00000000000
--- a/its/plugin/projects/ts-rule-project/S2871.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-var arrayOfNumbers = [80, 3, 9, 34, 23, 5, 1];
-arrayOfNumbers.sort(); // Noncompliant
-
-arrayOfNumbers.sort((n, m) => n - m);
-
-sort();
-
-function getArrayOfNumbers(): number[] {}
-getArrayOfNumbers().sort(); // Noncompliant
-
-var arrayOfStrings = ["foo", "bar"];
-arrayOfStrings.sort();
-
-var arrayOfObjects = [{a: 2}, {a: 4}];
-arrayOfObjects.sort();
-
-unknownArrayType.sort();
-
-interface MyCustomNumber extends Number {}
-const arrayOfCustomNumbers: MyCustomNumber[];
-arrayOfCustomNumbers.sort();
diff --git a/its/plugin/projects/ts-rule-project/S3616.ts b/its/plugin/projects/ts-rule-project/S3616.ts
deleted file mode 100644
index e0379145c53..00000000000
--- a/its/plugin/projects/ts-rule-project/S3616.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-function commaOperator() {
- switch (a) {
- case 0: // OK
- case 1: // OK
- foo1();
- break;
- case 2,3: // Noncompliant
- foo2();
- break;
- case "a","b","c","d": // Noncompliant
- foo3();
- break;
- case bar(), baz() : // Noncompliant
- foo();
- break;
- default:
- foo4();
- }
-}
-
-function orOperator() {
- switch (a) {
- case 0: // OK
- case 1 && 2: // OK
- foo1();
- break;
- case 2 || 3: // Noncompliant
- foo2();
- break;
- case "a" || "b" || "c" || "d": // Noncompliant
- foo3();
- break;
- case bar() || baz() : // Noncompliant
- foo();
- break;
- default:
- foo4();
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S3854.ts b/its/plugin/projects/ts-rule-project/S3854.ts
deleted file mode 100644
index aef7a320e03..00000000000
--- a/its/plugin/projects/ts-rule-project/S3854.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-class Dog extends Animal {
- constructor(name) {
- super();
- this.name = name;
- super(); // Noncompliant
- super.doSomething();
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S3973.ts b/its/plugin/projects/ts-rule-project/S3973.ts
deleted file mode 100644
index 2aad7fdeae1..00000000000
--- a/its/plugin/projects/ts-rule-project/S3973.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-x = 7;
-
-function doTheThing() { }
-function doTheOtherThing() { }
-
-if (x == 5) // Noncompliant
-doTheThing();
-else if (x == 6) // Noncompliant
-doTheThing();
-else // Noncompliant
-doTheThing();
diff --git a/its/plugin/projects/ts-rule-project/S3984.ts b/its/plugin/projects/ts-rule-project/S3984.ts
deleted file mode 100644
index ecc20af2aa4..00000000000
--- a/its/plugin/projects/ts-rule-project/S3984.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// OK
-foo(new Error());
-foo(TypeError);
-throw new Error();
-new LooksLikeAnError().doSomething();
-
-// NOK
- new Error(); // Noncompliant
-//^^^^^^^^^^^
-new TypeError(); // Noncompliant
-new MyError(); // Noncompliant
-new A.MyError(); // Noncompliant
-
-
-new A(function () {
- new SomeError(); // Noncompliant
-});
-
-new MyException(); // Noncompliant
diff --git a/its/plugin/projects/ts-rule-project/S4124.ts b/its/plugin/projects/ts-rule-project/S4124.ts
deleted file mode 100644
index 3c983219365..00000000000
--- a/its/plugin/projects/ts-rule-project/S4124.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface TypeDeclaredElsewhere {
- someMethod(): number;
- new(b: boolean): TypeDeclaredElsewhere; // Noncompliant
- constructor(b: boolean): void; // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S4157.ts b/its/plugin/projects/ts-rule-project/S4157.ts
deleted file mode 100644
index aab5648ee55..00000000000
--- a/its/plugin/projects/ts-rule-project/S4157.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-function f() {}
-f();
-f();
-f(); // Noncompliant
-
-function g() {}
-g();
-g(); // Noncompliant
-g();
-g();
-g(); // Noncompliant
-
-class C {}
-new C();
-new C(); // Noncompliant
-new C();
diff --git a/its/plugin/projects/ts-rule-project/S4158.ts b/its/plugin/projects/ts-rule-project/S4158.ts
deleted file mode 100644
index 2345b382dd7..00000000000
--- a/its/plugin/projects/ts-rule-project/S4158.ts
+++ /dev/null
@@ -1,185 +0,0 @@
-export function toCreateModule() {}
-
-const array : number[] = [];
-
-export function testElementAccessRead() {
- console.log(array[2]); // Noncompliant
-}
-
-function testLoopRead() {
- for (const _ of array) { // Noncompliant
- }
-
- for (const _ in array) { // Noncompliant
- }
-}
-
-function testIterationMethodsRead() {
- array.forEach(item => console.log()); // Noncompliant
- array[Symbol.iterator](); // Noncompliant
-}
-
-function testAccessorMethodsRead(otherArray: number[]) {
- const initialArray: number[] = [];
- return initialArray.concat(otherArray); // Noncompliant
-}
-
-function okForNotEmptyInit() {
- const nonEmptyArray = [1, 2, 3];
- foo(nonEmptyArray[2]); // OK
- nonEmptyArray.forEach(item => console.log()); // OK
- for (const _ of nonEmptyArray) { console.log(); } // OK
-}
-
-function okLatelyWritten() {
- const okLatelyWritten: number[] = [];
- okLatelyWritten.push(1);
- okLatelyWritten.forEach(item => console.log()); // OK
-}
-
-
-function okLatelyInitialized() {
- let arrayLatelyInitialized: number[];
- arrayLatelyInitialized = [];
- arrayLatelyInitialized.forEach(item => console.log()); // Noncompliant
-}
-
-function testCollectionContructors(){
- const arrayConstructor = new Array();
- arrayConstructor.forEach(item => console.log()); // Noncompliant
-
- const notEmptyarrayConstructor = new Array(1, 2, 3);
- notEmptyarrayConstructor.forEach(item => console.log()); // Ok
-
- const arrayWithoutNew = Array();
- arrayWithoutNew.forEach(item => console.log()); // Noncompliant
-
- const myMap = new Map();
- myMap.get(1); // Noncompliant
-
- const mySet = new Set();
- mySet.has(1); // Noncompliant
-}
-
-export let exportedArray: number[] = [];
-foo(exportedArray[1]); // Noncompliant
-
-import { IMPORTED_ARRAY } from "./dep";
-foo(IMPORTED_ARRAY[1]); // OK
-
-function parametersAreIgnore(parameterArray: number[]) {
- foo(parameterArray[1]);
- parameterArray = [];
- foo(parameterArray[1]); // FN
-}
-
-class MyClass {
- myArray: string [] = [];
- propertiesAreIgnored() {
- foo(this.myArray[1]); // OK
- }
-}
-
-function arrayUsedAsArgument() {
- const array: number[] = [];
- foo(array);
- const copy = new Array(...array);
- copy.push(42);
- foo(array[1]); // OK
-
- return copy;
-}
-
-function reassignment() {
- let overwrittenArray = [];
- const otherArray = [1,2,3,4];
- overwrittenArray = otherArray;
- foo(overwrittenArray[1]); // OK
-
- const arrayWrittenInsideArrow: number[] = [];
- foo((n: number) => arrayWrittenInsideArrow.push(n));
- foo(arrayWrittenInsideArrow[1]); // OK
-
- let arrayWrittenInsideArrow2: number[] = [];
- foo((n: number) => arrayWrittenInsideArrow2 = otherArray);
- foo(arrayWrittenInsideArrow2[1]); // OK
-}
-
-// Interface Declaration
-interface Array {
- equals(array: Array): boolean // OK, symbol Array is an interface declaration
-}
-
-// Type Alias Declaration
-type MyArrayTypeAlias = T[];
-// OK, symbol MyArrayTypeAlias is a TypeAliasDeclaration
-function isMyArrayTypeAlias(value: MyArrayTypeAlias | number): value is MyArrayTypeAlias {
- return !!(value as any).length;
-}
-
-function arrayUsedInORExpression(otherArray: number[]) {
- const emptyArray: number[] = [];
- console.log(otherArray || emptyArray); // OK used in OR expression
-}
-
-function arrayUsedInPropertyDeclaration() {
- const emptyArray: number[] = [];
- return {
- a: emptyArray // OK, emptyArray is used in a property declaration
- };
-}
-
-function arrayUsedInReturnStatement() {
- const emptyArray: number[] = [];
- return emptyArray; // OK, emptyArray is used in a return statement
-}
-
-
-function writeWithTernaryOperator(flag: boolean) {
- const potentiallyNonEmptyArray1 : number [] = [];
- const potentiallyNonEmptyArray2: number[] = [];
- (flag ? potentiallyNonEmptyArray1 : potentiallyNonEmptyArray2).push(1);
-
- foo(potentiallyNonEmptyArray1[0]); // OK
- foo(potentiallyNonEmptyArray2[0]); // OK
-}
-
-function writeOnAliasVariable() {
- const reassignedArray: number[] = [];
- const aliasArray = reassignedArray;
- aliasArray.push(1);
-
- foo(aliasArray[0]); // OK
- foo(reassignedArray[0]); // OK
-}
-
-function arrayInitializedByFunctionCall(init: () => number[]) {
- const externalInitializedArray: number[] = init();
- foo(externalInitializedArray[0]); // OK
-}
-
-function arrayNotInitialized() {
- let notInitializedArray!: number[];
- foo(notInitializedArray[0]); // Not reported
-}
-
-function compoundAssignmentEmptyArray() {
- const compoundAssignmentEmptyArray: number[] = [];
- compoundAssignmentEmptyArray[1] += 42; // Noncompliant
-}
-
-function assignmentEmptyArray() {
- const assignmentEmptyArray: number[] = [];
- assignmentEmptyArray[1] = 42; // ok
-}
-
-function destructuringAssignmentEmptyArray() {
- const destructuringAssignmentEmptyArray: number[] = [];
- [ , destructuringAssignmentEmptyArray[1]] = [42, 42]; // ok
- foo(destructuringAssignmentEmptyArray[1]);
-}
-
-function elementAccessWithoutAssignment() {
- const elementAccessWithoutAssignment: number[] = [];
- foo(elementAccessWithoutAssignment[1]); // Noncompliant
-}
diff --git a/its/plugin/projects/ts-rule-project/S4275.ts b/its/plugin/projects/ts-rule-project/S4275.ts
deleted file mode 100644
index e669b169dbd..00000000000
--- a/its/plugin/projects/ts-rule-project/S4275.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-class MyClass {
- private x: string;
- private _y = "hello";
- private z = 0;
-
- constructor(private w: number, readonly ro: number) {
-
- }
-
- public setX(x: number) { // Noncompliant
- }
-
- public GetX(): string { // Noncompliant
- return this._y;
- }
-
- public get y(): number { // Noncompliant
- return this.z;
- }
-
- public set y(y: number) { // Noncompliant
- }
-
- public getY(): string { // OK
- return this._y;
- }
-
- public SetZ(z: number) { // OK
- this.z = z;
- }
-
- public setW(x: string) { // Noncompliant
- this.x = x;
- }
-
- public setRO(ro: number) { // OK
- const twoStatementBody = 1;
- this.z = ro;
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S4335.ts b/its/plugin/projects/ts-rule-project/S4335.ts
deleted file mode 100644
index 8696e2fc61c..00000000000
--- a/its/plugin/projects/ts-rule-project/S4335.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-function withNull(x: number & null) {} // Noncompliant
-
-function withUndefined(x: { a: string } & undefined) {} // Noncompliant
-
-function withVoid(x: string & void) {} // Noncompliant
-
-function triple(
- x: null // Noncompliant
- & string
- & undefined) {} // Noncompliant
-
-function declarations() {
- let x: string & null; // Noncompliant
-}
-
-function withEmptyObjectLiteral(x: { a: string } & {}) {} // Noncompliant
-
-interface Empty {}
-function withEmptyInterface(x: { a: string } & Empty) {} // Noncompliant
-
-function withAny(x: any & { a: string }) {} // Noncompliant
-
-function withNever(x: boolean & never) {} // Noncompliant
-
-// OK
-function twoPrimitives(x: string & number) {}
-
-// OK
-function twoInterfaces(x: { a: string } & { b: number }) {}
-
-// OK, extended interface
-interface WithString {
- a: string;
-}
-interface NotEmpty extends WithString {}
-function withNotEmptyInterface(x: { a: string } & NotEmpty) {}
diff --git a/its/plugin/projects/ts-rule-project/S4524.ts b/its/plugin/projects/ts-rule-project/S4524.ts
deleted file mode 100644
index d10aa3732eb..00000000000
--- a/its/plugin/projects/ts-rule-project/S4524.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-export function toCreateModule() {}
-
-function fooDefault(x: number) {
- switch (x) {
- case 1:
- return 1;
- default: // Noncompliant
- return 0;
- case 2:
- return 2;
- }
-}
-
-function barDefault(y: any) {
- switch (y) {
- default: // Noncompliant
- console.log("Default message");
- break;
- case "foo":
- console.log("Hello World")
- break;
- case "bar":
- console.log("42");
- break;
- }
-}
-
-function compliantDefault(z: any) {
- switch (z) {
- case "foo":
- console.log("Hello World")
- break;
- case "bar":
- console.log("42");
- break;
- default:
- console.log("Default message");
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S4619.ts b/its/plugin/projects/ts-rule-project/S4619.ts
deleted file mode 100644
index ef91caea3ee..00000000000
--- a/its/plugin/projects/ts-rule-project/S4619.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-let arr = ["a", "b", "c"];
-
- "1" in arr; // Noncompliant
- 1 in arr;
- "b" in arr; // Noncompliant
-
-
-// in different contexts
-const result = "car" in arr ? "something" : "someething else"; // Noncompliant
-foo("car" in arr); // Noncompliant
-if ("car" in arr) {} // Noncompliant
-
-
-// to check the property of an object do this
-"car" in { "car" : 1};
-// and not this
- "car" in Object.keys({ "car": 1 }); // Noncompliant
-
-function erroneousIncludesES2016(array: any[], elem: any) {
- return elem in array; // Noncompliant
-}
-
-
-const dict = {a: 1, b: 2, c: 3};
-"a" in dict; // OK on objects
-
-function okOnArrayLikeObjects(a: any, b: any) {
- let key = "1";
- if (key in arguments) {
- return "Something";
- }
- return "Something else";
-}
diff --git a/its/plugin/projects/ts-rule-project/S4787.ts b/its/plugin/projects/ts-rule-project/S4787.ts
deleted file mode 100644
index 50ed5978446..00000000000
--- a/its/plugin/projects/ts-rule-project/S4787.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import * as crypto from 'crypto';
-
-const cipher = crypto.createCipher(algo, key); // Noncompliant
-const cipheriv = crypto.createCipheriv(algo, key, iv); // Noncompliant
-const decipher = crypto.createDecipher(algo, key); // Noncompliant
-const decipheriv = crypto.createDecipheriv(algo, key, iv); // Noncompliant
-const pubEnc = crypto.publicEncrypt(key, buf); // Noncompliant
-const pubDec = crypto.publicDecrypt(key, privEnc); // Noncompliant
diff --git a/its/plugin/projects/ts-rule-project/S4817.ts b/its/plugin/projects/ts-rule-project/S4817.ts
deleted file mode 100644
index 87fc0bfbec4..00000000000
--- a/its/plugin/projects/ts-rule-project/S4817.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// Two fist issues are due to S3533
-import * as xpath from 'xpath';
-import * as xmldom from 'xmldom';
-
-const doc = new xmldom.DOMParser().parseFromString(xml);
-const nodes = xpath.select(userinput, doc); // Noncompliant
-const node = xpath.select1(userinput, doc); // Noncompliant
diff --git a/its/plugin/projects/ts-rule-project/S4822.ts b/its/plugin/projects/ts-rule-project/S4822.ts
deleted file mode 100644
index f574f8f9595..00000000000
--- a/its/plugin/projects/ts-rule-project/S4822.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-function returningPromise() {
- return Promise.reject();
-}
-
-function singlePromise() {
- try { // Noncompliant
- returningPromise();
- } catch (e) {
- console.log(e);
- }
-}
-
-async function okWithAwait() {
- try {
- await returningPromise();
- } catch (e) {
- console.log(e);
- }
-}
-
-function uselessTry() {
- try { // Noncompliant
- returningPromise().catch();
- } catch (e) {
- console.log(e);
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/S888.ts b/its/plugin/projects/ts-rule-project/S888.ts
deleted file mode 100644
index 27bbb4e07d0..00000000000
--- a/its/plugin/projects/ts-rule-project/S888.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-for (var i=0; i>10; i+=1){ } // Compliant, not an equality in condition
-for (var i=0; i!=10; i*=1){ } // Compliant, not an inc/dec update
-
-for (i=10; i==0; i--){ } // Noncompliant
-for(i=from, j=0; i!=to; i+=dir, j++){} // Noncompliant
diff --git a/its/plugin/projects/ts-rule-project/package-lock.json b/its/plugin/projects/ts-rule-project/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/ts-rule-project/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/package.json b/its/plugin/projects/ts-rule-project/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/ts-rule-project/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/ts-rule-project/tsconfig.json b/its/plugin/projects/ts-rule-project/tsconfig.json
deleted file mode 100644
index 8785876def9..00000000000
--- a/its/plugin/projects/ts-rule-project/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- },
- "include": [
- "./**/*"
- ]
-}
diff --git a/its/plugin/projects/ts-sonarlint-project/file.ts b/its/plugin/projects/ts-sonarlint-project/file.ts
deleted file mode 100644
index f9898390c3a..00000000000
--- a/its/plugin/projects/ts-sonarlint-project/file.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-var xs: string[] = ["a", "b", "c", "d"];
-delete xs[2];
diff --git a/its/plugin/projects/ts-sonarlint-project/file.vue b/its/plugin/projects/ts-sonarlint-project/file.vue
deleted file mode 100644
index 012ace12705..00000000000
--- a/its/plugin/projects/ts-sonarlint-project/file.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
diff --git a/its/plugin/projects/tslint-report-project/package-lock.json b/its/plugin/projects/tslint-report-project/package-lock.json
deleted file mode 100644
index 42dca233c46..00000000000
--- a/its/plugin/projects/tslint-report-project/package-lock.json
+++ /dev/null
@@ -1,298 +0,0 @@
-{
- "name": "tslint-report-project",
- "version": "1.0.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "1.0.3"
- }
- },
- "babel-code-frame": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
- "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
- "requires": {
- "chalk": "1.1.3",
- "esutils": "2.0.2",
- "js-tokens": "3.0.2"
- },
- "dependencies": {
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- }
- }
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
- },
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "requires": {
- "ansi-styles": "3.2.1",
- "escape-string-regexp": "1.0.5",
- "supports-color": "5.4.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "1.9.1"
- }
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "requires": {
- "has-flag": "3.0.0"
- }
- }
- }
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
- },
- "commander": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
- "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "diff": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
- "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
- },
- "esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
- }
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
- },
- "js-yaml": {
- "version": "3.11.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
- "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
- "requires": {
- "argparse": "1.0.10",
- "esprima": "4.0.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "1.1.11"
- }
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1.0.2"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "path-parse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
- },
- "resolve": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
- "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
- "requires": {
- "path-parse": "1.0.5"
- }
- },
- "semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- },
- "tslib": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
- "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
- },
- "tslint": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz",
- "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=",
- "requires": {
- "babel-code-frame": "6.26.0",
- "builtin-modules": "1.1.1",
- "chalk": "2.4.1",
- "commander": "2.15.1",
- "diff": "3.5.0",
- "glob": "7.1.2",
- "js-yaml": "3.11.0",
- "minimatch": "3.0.4",
- "resolve": "1.7.1",
- "semver": "5.5.0",
- "tslib": "1.9.0",
- "tsutils": "2.26.2"
- }
- },
- "tsutils": {
- "version": "2.26.2",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.26.2.tgz",
- "integrity": "sha512-uzwnhmrSbyinPCiwfzGsOY3IulBTwoky7r83HmZdz9QNCjhSCzavkh47KLWuU0zF2F2WbpmmzoJUIEiYyd+jEQ==",
- "requires": {
- "tslib": "1.9.0"
- }
- },
- "typescript": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz",
- "integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw=="
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- }
- }
-}
diff --git a/its/plugin/projects/tslint-report-project/package.json b/its/plugin/projects/tslint-report-project/package.json
deleted file mode 100644
index b6765eb65c9..00000000000
--- a/its/plugin/projects/tslint-report-project/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "tslint-report-project",
- "version": "1.0.0",
- "description": "",
- "main": "index.ts",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "author": "",
- "license": "ISC",
- "dependencies": {
- "tslint": "^5.9.1",
- "typescript": "^2.8.3"
- }
-}
diff --git a/its/plugin/projects/tslint-report-project/report.json b/its/plugin/projects/tslint-report-project/report.json
deleted file mode 100644
index 2366be81d0a..00000000000
--- a/its/plugin/projects/tslint-report-project/report.json
+++ /dev/null
@@ -1,88 +0,0 @@
-[
- {
- "endPosition": {
- "character": 13,
- "line": 7,
- "position": 213
- },
- "failure": "else statements must be braced",
- "fix": [
- {
- "innerStart": 174,
- "innerLength": 0,
- "innerText": " {"
- },
- {
- "innerStart": 213,
- "innerLength": 0,
- "innerText": "\n }"
- }
- ],
- "name": "src/index.ts",
- "ruleName": "curly",
- "ruleSeverity": "ERROR",
- "startPosition": {
- "character": 4,
- "line": 6,
- "position": 170
- }
- },
- {
- "endPosition": {
- "character": 10,
- "line": 2,
- "position": 61
- },
- "failure": "unused expression, expected an assignment or function call",
- "name": "src/index.ts",
- "ruleName": "no-unused-expression",
- "ruleSeverity": "ERROR",
- "startPosition": {
- "character": 9,
- "line": 2,
- "position": 60
- }
- },
- {
- "endPosition": {
- "character": 9,
- "line": 4,
- "position": 87
- },
- "failure": "Identifier 'y' is never reassigned; use 'const' instead of 'let'.",
- "fix": {
- "innerStart": 82,
- "innerLength": 3,
- "innerText": "const"
- },
- "name": "src/index.ts",
- "ruleName": "prefer-const",
- "ruleSeverity": "ERROR",
- "startPosition": {
- "character": 8,
- "line": 4,
- "position": 86
- }
- },
- {
- "endPosition": {
- "character": 14,
- "line": 4,
- "position": 92
- },
- "failure": "Missing semicolon",
- "fix": {
- "innerStart": 92,
- "innerLength": 0,
- "innerText": ";"
- },
- "name": "src/index.ts",
- "ruleName": "semicolon",
- "ruleSeverity": "ERROR",
- "startPosition": {
- "character": 14,
- "line": 4,
- "position": 92
- }
- }
-]
diff --git a/its/plugin/projects/tslint-report-project/src/index.ts b/its/plugin/projects/tslint-report-project/src/index.ts
deleted file mode 100644
index c2ef650ac4a..00000000000
--- a/its/plugin/projects/tslint-report-project/src/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-function foo() {
- let x = 42;
- x = 0, 5; // external_tslint:no-unused-expression
- if (x > 0) {
- let y = 42 // external_tslint:prefer-const, external_tslint:semicolon
- return y;
- } else // external_tslint:curly
- return x;
-}
diff --git a/its/plugin/projects/tslint-report-project/tsconfig.json b/its/plugin/projects/tslint-report-project/tsconfig.json
deleted file mode 100644
index 58ecccce6b2..00000000000
--- a/its/plugin/projects/tslint-report-project/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "compilerOptions": {
- /* Basic Options */
- "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
- "strict": true, /* Enable all strict type-checking options. */
- "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
- }
-}
diff --git a/its/plugin/projects/tslint-report-project/tslint.json b/its/plugin/projects/tslint-report-project/tslint.json
deleted file mode 100644
index ee0b0ca32ee..00000000000
--- a/its/plugin/projects/tslint-report-project/tslint.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "defaultSeverity": "error",
- "extends": [
- "tslint:recommended"
- ],
- "jsRules": {},
- "rules": { },
- "rulesDirectory": []
-}
diff --git a/its/plugin/projects/tsproject-extended/dir/file.excluded.ts b/its/plugin/projects/tsproject-extended/dir/file.excluded.ts
deleted file mode 100644
index 6b96bb831ad..00000000000
--- a/its/plugin/projects/tsproject-extended/dir/file.excluded.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function foo(b: number, c: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/tsproject-extended/dir/file.ts b/its/plugin/projects/tsproject-extended/dir/file.ts
deleted file mode 100644
index 6b96bb831ad..00000000000
--- a/its/plugin/projects/tsproject-extended/dir/file.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function foo(b: number, c: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/tsproject-extended/dir/tsconfig.json b/its/plugin/projects/tsproject-extended/dir/tsconfig.json
deleted file mode 100644
index 3c43903cfdd..00000000000
--- a/its/plugin/projects/tsproject-extended/dir/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "../tsconfig.json"
-}
diff --git a/its/plugin/projects/tsproject-extended/package-lock.json b/its/plugin/projects/tsproject-extended/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/tsproject-extended/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/tsproject-extended/package.json b/its/plugin/projects/tsproject-extended/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/tsproject-extended/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/tsproject-extended/tsconfig.json b/its/plugin/projects/tsproject-extended/tsconfig.json
deleted file mode 100644
index 9fb9102a57e..00000000000
--- a/its/plugin/projects/tsproject-extended/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "exclude": [ "**/*.excluded.ts" ]
-}
diff --git a/its/plugin/projects/tsproject-no-typescript/file.ts b/its/plugin/projects/tsproject-no-typescript/file.ts
deleted file mode 100644
index 629a61984a5..00000000000
--- a/its/plugin/projects/tsproject-no-typescript/file.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const x: number = 42;
-export const y = x as number;
diff --git a/its/plugin/projects/tsproject-no-typescript/file2.ts b/its/plugin/projects/tsproject-no-typescript/file2.ts
deleted file mode 100644
index 629a61984a5..00000000000
--- a/its/plugin/projects/tsproject-no-typescript/file2.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-const x: number = 42;
-export const y = x as number;
diff --git a/its/plugin/projects/tsproject-no-typescript/package.json b/its/plugin/projects/tsproject-no-typescript/package.json
deleted file mode 100644
index 2c63c085104..00000000000
--- a/its/plugin/projects/tsproject-no-typescript/package.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/its/plugin/projects/tsproject-no-typescript/tsconfig.json b/its/plugin/projects/tsproject-no-typescript/tsconfig.json
deleted file mode 100644
index 2c63c085104..00000000000
--- a/its/plugin/projects/tsproject-no-typescript/tsconfig.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/its/plugin/projects/tsproject/custom.tsconfig.json b/its/plugin/projects/tsproject/custom.tsconfig.json
deleted file mode 100644
index 17f5bcf5801..00000000000
--- a/its/plugin/projects/tsproject/custom.tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "allowJs": true
- },
- "files": ["fileUsedInCustomTsConfig.ts"]
-}
diff --git a/its/plugin/projects/tsproject/duplication.lint.ts b/its/plugin/projects/tsproject/duplication.lint.ts
deleted file mode 100644
index eaf79060cc3..00000000000
--- a/its/plugin/projects/tsproject/duplication.lint.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
-
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/tsproject/fileUsedInCustomTsConfig.ts b/its/plugin/projects/tsproject/fileUsedInCustomTsConfig.ts
deleted file mode 100644
index aa9604d83da..00000000000
--- a/its/plugin/projects/tsproject/fileUsedInCustomTsConfig.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function foo(b: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/tsproject/nosonar.lint.ts b/its/plugin/projects/tsproject/nosonar.lint.ts
deleted file mode 100644
index 95ed6d9c092..00000000000
--- a/its/plugin/projects/tsproject/nosonar.lint.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-function foo(b: number) {
- if (b == 0) { doOneMoreThing(); } else { doOneMoreThing(); } // NOSONAR
- if (b == 0) { doOneMoreThing(); } else { doOneMoreThing(); }
-}
diff --git a/its/plugin/projects/tsproject/package-lock.json b/its/plugin/projects/tsproject/package-lock.json
deleted file mode 100644
index 58e5df3dd37..00000000000
--- a/its/plugin/projects/tsproject/package-lock.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
- "dev": true
- }
- }
-}
diff --git a/its/plugin/projects/tsproject/package.json b/its/plugin/projects/tsproject/package.json
deleted file mode 100644
index cce1382fc69..00000000000
--- a/its/plugin/projects/tsproject/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "typescript": "3.5.3"
- }
-}
diff --git a/its/plugin/projects/tsproject/sample.lint.ts b/its/plugin/projects/tsproject/sample.lint.ts
deleted file mode 100644
index 859e73ea477..00000000000
--- a/its/plugin/projects/tsproject/sample.lint.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/*eslint max-params: ["error", 1]*/
-
-function foo(b: number, c: number) {
- if (b == 0) { // Noncompliant
- doOneMoreThing();
- } else {
- doOneMoreThing();
- }
-}
diff --git a/its/plugin/projects/tsproject/tsconfig.json b/its/plugin/projects/tsproject/tsconfig.json
deleted file mode 100644
index cdfcaa789eb..00000000000
--- a/its/plugin/projects/tsproject/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "compilerOptions": {
- "module": "es2020",
- "target": "es6",
- "allowJs": true
- },
- "files": ["sample.lint.ts", "duplication.lint.ts", "nosonar.lint.ts"]
-}
diff --git a/its/plugin/projects/tsprojects/dir/custom.tsconfig.json b/its/plugin/projects/tsprojects/dir/custom.tsconfig.json
deleted file mode 100644
index 05d9d821dc1..00000000000
--- a/its/plugin/projects/tsprojects/dir/custom.tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "allowJs": true
- },
- "files": ["file.ts"]
-}
diff --git a/its/plugin/projects/tsprojects/dir/file.ts b/its/plugin/projects/tsprojects/dir/file.ts
deleted file mode 100644
index 381ea5aeada..00000000000
--- a/its/plugin/projects/tsprojects/dir/file.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function f(x: number) {
- if (x === 0) { // Noncompliant
- g();
- } else {
- g();
- }
-}
diff --git a/its/plugin/projects/tsprojects/file.ts b/its/plugin/projects/tsprojects/file.ts
deleted file mode 100644
index b7525eda260..00000000000
--- a/its/plugin/projects/tsprojects/file.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-function f(x: number) {
- if (x === 0) { // Noncompliant
- g();
- } else {
- g();
- }
-}
diff --git a/its/plugin/projects/tsprojects/tsconfig.json b/its/plugin/projects/tsprojects/tsconfig.json
deleted file mode 100644
index 203ac24fd8b..00000000000
--- a/its/plugin/projects/tsprojects/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "allowJs": true
- },
- "files": ["file.ts"]
-}
diff --git a/its/plugin/projects/vue-js-project-with-lang-js/file.vue b/its/plugin/projects/vue-js-project-with-lang-js/file.vue
deleted file mode 100644
index 0f0bb62d57d..00000000000
--- a/its/plugin/projects/vue-js-project-with-lang-js/file.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
diff --git a/its/plugin/projects/vue-js-project-with-lang-ts/file.vue b/its/plugin/projects/vue-js-project-with-lang-ts/file.vue
deleted file mode 100644
index 1ab6988e8dc..00000000000
--- a/its/plugin/projects/vue-js-project-with-lang-ts/file.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
diff --git a/its/plugin/projects/vue-js-project-with-lang-ts/main.ts b/its/plugin/projects/vue-js-project-with-lang-ts/main.ts
deleted file mode 100644
index ccdcb880415..00000000000
--- a/its/plugin/projects/vue-js-project-with-lang-ts/main.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-if (cond) {
- foo();
-} else {
- foo();
-}
diff --git a/its/plugin/projects/vue-js-project-with-lang-ts/tsconfig.json b/its/plugin/projects/vue-js-project-with-lang-ts/tsconfig.json
deleted file mode 100644
index 020435b76c2..00000000000
--- a/its/plugin/projects/vue-js-project-with-lang-ts/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "include": [
- "**/*.ts",
- "**/*.vue"
- ]
-}
diff --git a/its/plugin/projects/vue-js-project/file.vue b/its/plugin/projects/vue-js-project/file.vue
deleted file mode 100644
index 057efbe0ff0..00000000000
--- a/its/plugin/projects/vue-js-project/file.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
- {{greeting}}
-
-
-
-
-
\ No newline at end of file
diff --git a/its/plugin/projects/yaml-aws-lambda-analyzed/file.yaml b/its/plugin/projects/yaml-aws-lambda-analyzed/file.yaml
deleted file mode 100644
index 8fa467a16c2..00000000000
--- a/its/plugin/projects/yaml-aws-lambda-analyzed/file.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLogGroup:
- Type: AWS::Logs::LogGroup #Noncompliant (S6295)
- Properties:
- LogGroupName: !Join ['/', ['/aws/lambda', !Ref MyLambdaFunction]]
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Code:
- ZipFile: function handler(event, context) { if (foo()) bar(); else bar(); /* Noncompliant (S3923) */ }
- Description: "The branch duplication should be reported at 14:53"
- Runtime: "nodejs16.0"
diff --git a/its/plugin/projects/yaml-aws-lambda-skipped/file.yaml b/its/plugin/projects/yaml-aws-lambda-skipped/file.yaml
deleted file mode 100644
index 89d14dc8a39..00000000000
--- a/its/plugin/projects/yaml-aws-lambda-skipped/file.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-AWSTemplateFormatVersion: 2010-09-09
-Transform: AWS::Serverless-2016-10-31
-Resources:
- SomeLambdaFunction:
- Type: "AWS::Lambda::Function"
- Properties:
- Code:
- ZipFile: print("hello")
- Runtime: "python2.7"
diff --git a/its/plugin/tests/pom.xml b/its/plugin/tests/pom.xml
deleted file mode 100644
index f22d787c87c..00000000000
--- a/its/plugin/tests/pom.xml
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
- 4.0.0
-
-
- org.sonarsource.javascript
- javascript-it-plugin
- 10.0.0-SNAPSHOT
-
-
- javascript-it-plugin-tests
- JavaScript :: IT :: Plugin :: Tests
-
-
- -server
-
-
-
-
- com.google.code.gson
- gson
- test
-
-
- org.sonarsource.analyzer-commons
- sonar-analyzer-commons
- test
-
-
- org.sonarsource.orchestrator
- sonar-orchestrator
-
-
- org.sonarsource.sonarlint.core
- sonarlint-core
-
-
-
- org.sonarsource.sonarqube
- sonar-ws
-
-
- org.sonarsource.sonarqube
- sonar-plugin-api-impl
- test
-
-
- org.junit.jupiter
- junit-jupiter
- test
-
-
- org.eclipse.jgit
- org.eclipse.jgit
-
-
- org.assertj
- assertj-core
-
-
- com.google.code.findbugs
- jsr305
- provided
-
-
- org.apache.commons
- commons-compress
-
-
- org.awaitility
- awaitility
-
-
-
-
-
-
- maven-surefire-plugin
-
-
- **/*Test.java
-
-
-
-
-
-
-
-
-
- qa
-
-
- env.SONARSOURCE_QA
- true
-
-
-
-
-
- maven-dependency-plugin
-
-
- copy-plugin
- generate-test-resources
-
- copy
-
-
-
-
- ${project.groupId}
- sonar-javascript-plugin
- sonar-plugin
- true
-
-
- ../../../sonar-javascript-plugin/target
- true
- true
-
-
-
-
-
-
-
-
-
-
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CoverageTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CoverageTest.java
deleted file mode 100644
index 2aaa239d8af..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CoverageTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.util.regex.Pattern;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasureAsInt;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class CoverageTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @Test
- void LCOV_path_can_be_relative() {
- final String projectKey = "LcovPathCanBeRelative";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.exclusions", "dir/**")
- .setProperty("sonar.javascript.lcov.reportPaths", "coverage.lcov");
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(4);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(1);
- }
-
- @Test
- void LCOV_path_can_be_absolute() {
- final String projectKey = "LcovPathCanBeAbsolute";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.exclusions", "dir/**")
- .setProperty("sonar.javascript.lcov.reportPaths", TestUtils.file("projects/lcov/coverage.lcov").getAbsolutePath());
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(4);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(1);
- }
-
- @Test
- void LCOV_report_paths() {
- final String projectKey = "LcovReportPaths";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.exclusions", "dir/**")
- .setProperty("sonar.javascript.lcov.reportPaths", TestUtils.file("projects/lcov/coverage.lcov").getAbsolutePath());
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(4);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(1);
- }
-
- @Test
- void LCOV_report_paths_alias() {
- final String projectKey = "LcovReportPathsAlias";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.exclusions", "dir/**")
- .setProperty("sonar.typescript.lcov.reportPaths", TestUtils.file("projects/lcov/coverage.lcov").getAbsolutePath());
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- }
-
- @Test
- void zero_coverage() {
- final String projectKey = "ZeroCoverage";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setProperty("sonar.exclusions", "dir/**")
- .setSourceDirs(".");
-
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(5);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(5);
-
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isNull();
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isNull();
- }
-
- @Test
- // SONARJS-301
- public void print_log_for_not_found_resource() {
- final String projectKey = "PrintLogForNotFoundResource";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.javascript.lcov.reportPaths", TestUtils.file("projects/lcov/coverage-wrong-file-name.lcov").getAbsolutePath())
- .setDebugLogs(true);
- OrchestratorStarter.setEmptyProfile(projectKey);
- BuildResult result = orchestrator.executeBuild(build);
-
- // Check that a log is printed
- assertThat(result.getLogs())
- .containsPattern(Pattern.compile("Analysing .*coverage-wrong-file-name\\.lcov"))
- .containsPattern(Pattern.compile("WARN.*Could not resolve 1 file paths in \\[.*coverage-wrong-file-name\\.lcov\\]"))
- .containsPattern(Pattern.compile("DEBUG: Unresolved paths:\n\\./wrong/fileName\\.js"));
- }
-
- @Test
- // SONARJS-547
- void wrong_line_in_report() {
- final String projectKey = "WrongLineInReport";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setDebugLogs(true)
- .setProperty("sonar.exclusions", "dir/**")
- .setProperty("sonar.javascript.lcov.reportPaths", TestUtils.file("projects/lcov/coverage-wrong-line.lcov").getAbsolutePath());
- OrchestratorStarter.setEmptyProfile(projectKey);
- BuildResult result = orchestrator.executeBuild(build);
-
- // Check that a log is printed
- assertThat(result.getLogs())
- .contains("DEBUG: Problem during processing LCOV report: can't save DA data for line 12 of coverage report file")
- .contains("DEBUG: Problem during processing LCOV report: can't save BRDA data for line 18 of coverage report file");
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(3);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(0);
- }
-
- @Test
- void conditions_on_non_executable_lines() {
- final String projectKey = "ConditionsOnNonExecutableLines";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov-jsx"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setDebugLogs(true)
- .setProperty("sonar.javascript.lcov.reportPaths", TestUtils.file("projects/lcov-jsx/conditions-on-non-executable-lines.lcov").getAbsolutePath());
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(3);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(0);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(2);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(1);
- }
-
- @Test
- void wildcard_LCOV_report_paths() {
- final String projectKey = "LcovWildcardReportPaths";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov-wildcard"))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.javascript.lcov.reportPaths", "foo.lcov,bar/*.lcov,**/qux/*.lcov");
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey + ":foo.js", "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey + ":bar/bar.js", "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey + ":baz/baz.js", "uncovered_lines")).isEqualTo(5);
- assertThat(getMeasureAsInt(projectKey + ":baz/qux/qux.js", "uncovered_lines")).isEqualTo(1);
- }
-
- @Test
- void LCOV_report_outside_module() {
- final String projectKey = "LcovReportOutsideModule";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("lcov"))
- .setProperty("sonar.modules", "dir")
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs(".")
- .setProperty("sonar.exclusions", "**")
- .setProperty("dir.sonar.exclusions", "")
- .setProperty("dir.sonar.projectBaseDir", "dir")
- .setProperty("dir.sonar.javascript.lcov.reportPaths", "../coverage.lcov");
- OrchestratorStarter.setEmptyProfile(projectKey);
- orchestrator.executeBuild(build);
-
- assertThat(getMeasureAsInt(projectKey, "lines_to_cover")).isEqualTo(7);
- assertThat(getMeasureAsInt(projectKey, "uncovered_lines")).isEqualTo(1);
- assertThat(getMeasureAsInt(projectKey, "conditions_to_cover")).isEqualTo(4);
- assertThat(getMeasureAsInt(projectKey, "uncovered_conditions")).isEqualTo(1);
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssIssuesTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssIssuesTest.java
deleted file mode 100644
index 401ed1b359d..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssIssuesTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static java.util.Collections.emptySet;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssIssuesTest {
-
- private static final String PROJECT_KEY = "css-issues-project";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static BuildResult buildResult;
-
- @BeforeAll
- public static void prepare() {
- ProfileGenerator.RulesConfiguration rulesConfiguration = new ProfileGenerator.RulesConfiguration();
- rulesConfiguration.add("S4660", "ignorePseudoElements", "ng-deep, /^custom-/");
- var profile = ProfileGenerator.generateProfile(orchestrator, "css", "css", rulesConfiguration, emptySet());
- orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
- orchestrator.getServer().associateProjectToQualityProfile(PROJECT_KEY, "css", profile);
-
- SonarScanner scanner = CssTestsUtils.createScanner(PROJECT_KEY);
- scanner.setProperty("sonar.exclusions", "**/file-with-parsing-error-excluded.css");
- scanner.setProperty("sonar.html.file.suffixes", ".htm");
- buildResult = orchestrator.executeBuild(scanner);
- }
-
- @Test
- void parsing_error_not_on_excluded_files() {
- assertThat(buildResult.getLogs())
- .doesNotMatch("(?s).*ERROR: Failed to parse file:\\S*file-with-parsing-error-excluded\\.css.*")
- .matches("(?s).*ERROR: Failed to parse file:\\S*file-with-parsing-error\\.css, line 1, Unclosed block.*");
- }
-
- @Test
- void issue_list() {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
- List issuesList = newWsClient(orchestrator).issues().search(request).getIssuesList().stream()
- .filter(i -> i.getRule().startsWith("css:"))
- .collect(Collectors.toList());
-
- assertThat(issuesList).extracting(Issue::getRule, Issue::getComponent).containsExactlyInAnyOrder(
- tuple("css:S4662", "css-issues-project:src/cssModules.css"),
- tuple("css:S4667", "css-issues-project:src/empty1.css"),
- tuple("css:S4667", "css-issues-project:src/empty2.less"),
- tuple("css:S4667", "css-issues-project:src/empty3.scss"),
- tuple("css:S1128", "css-issues-project:src/file1.css"),
- tuple("css:S1116", "css-issues-project:src/file1.css"),
- tuple("css:S4664", "css-issues-project:src/file1.css"),
- tuple("css:S4660", "css-issues-project:src/file1.css"),
- tuple("css:S4659", "css-issues-project:src/file1.css"),
- tuple("css:S4647", "css-issues-project:src/file1.css"),
- tuple("css:S4663", "css-issues-project:src/file1.css"),
- tuple("css:S4652", "css-issues-project:src/file1.css"),
- tuple("css:S4656", "css-issues-project:src/file1.css"),
- tuple("css:S4649", "css-issues-project:src/file1.css"),
- tuple("css:S4648", "css-issues-project:src/file1.css"),
- tuple("css:S4654", "css-issues-project:src/file1.css"),
- tuple("css:S4657", "css-issues-project:src/file1.css"),
- tuple("css:S4650", "css-issues-project:src/file1.css"),
- tuple("css:S4650", "css-issues-project:src/file1.css"),
- tuple("css:S4653", "css-issues-project:src/file1.css"),
- tuple("css:S4668", "css-issues-project:src/file1.css"),
- tuple("css:S4654", "css-issues-project:src/file1.css"),
- tuple("css:S4651", "css-issues-project:src/file1.css"),
- tuple("css:S4666", "css-issues-project:src/file1.css"),
- tuple("css:S4670", "css-issues-project:src/file1.css"),
- tuple("css:S4662", "css-issues-project:src/file1.css"),
- tuple("css:S4655", "css-issues-project:src/file1.css"),
- tuple("css:S4658", "css-issues-project:src/file1.css"),
- tuple("css:S4661", "css-issues-project:src/file1.css"),
- tuple("css:S1128", "css-issues-project:src/file2.less"),
- tuple("css:S1116", "css-issues-project:src/file2.less"),
- tuple("css:S4664", "css-issues-project:src/file2.less"),
- tuple("css:S4660", "css-issues-project:src/file2.less"),
- tuple("css:S4659", "css-issues-project:src/file2.less"),
- tuple("css:S4647", "css-issues-project:src/file2.less"),
- tuple("css:S4663", "css-issues-project:src/file2.less"),
- tuple("css:S4652", "css-issues-project:src/file2.less"),
- tuple("css:S4656", "css-issues-project:src/file2.less"),
- tuple("css:S4649", "css-issues-project:src/file2.less"),
- tuple("css:S4648", "css-issues-project:src/file2.less"),
- tuple("css:S4654", "css-issues-project:src/file2.less"),
- tuple("css:S4657", "css-issues-project:src/file2.less"),
- tuple("css:S4650", "css-issues-project:src/file2.less"),
- tuple("css:S4650", "css-issues-project:src/file2.less"),
- tuple("css:S4653", "css-issues-project:src/file2.less"),
- tuple("css:S4651", "css-issues-project:src/file2.less"),
- tuple("css:S4666", "css-issues-project:src/file2.less"),
- tuple("css:S4670", "css-issues-project:src/file2.less"),
- tuple("css:S4662", "css-issues-project:src/file2.less"),
- tuple("css:S4655", "css-issues-project:src/file2.less"),
- tuple("css:S4658", "css-issues-project:src/file2.less"),
- tuple("css:S4661", "css-issues-project:src/file2.less"),
- tuple("css:S1128", "css-issues-project:src/file3.scss"),
- tuple("css:S1116", "css-issues-project:src/file3.scss"),
- tuple("css:S4664", "css-issues-project:src/file3.scss"),
- tuple("css:S4660", "css-issues-project:src/file3.scss"),
- tuple("css:S4659", "css-issues-project:src/file3.scss"),
- tuple("css:S4647", "css-issues-project:src/file3.scss"),
- tuple("css:S4663", "css-issues-project:src/file3.scss"),
- tuple("css:S4652", "css-issues-project:src/file3.scss"),
- tuple("css:S4656", "css-issues-project:src/file3.scss"),
- tuple("css:S4649", "css-issues-project:src/file3.scss"),
- tuple("css:S4648", "css-issues-project:src/file3.scss"),
- tuple("css:S4654", "css-issues-project:src/file3.scss"),
- tuple("css:S4657", "css-issues-project:src/file3.scss"),
- tuple("css:S4650", "css-issues-project:src/file3.scss"),
- tuple("css:S4650", "css-issues-project:src/file3.scss"),
- tuple("css:S4653", "css-issues-project:src/file3.scss"),
- tuple("css:S4651", "css-issues-project:src/file3.scss"),
- tuple("css:S4666", "css-issues-project:src/file3.scss"),
- tuple("css:S4670", "css-issues-project:src/file3.scss"),
- tuple("css:S4662", "css-issues-project:src/file3.scss"),
- tuple("css:S4655", "css-issues-project:src/file3.scss"),
- tuple("css:S4658", "css-issues-project:src/file3.scss"),
- tuple("css:S4661", "css-issues-project:src/file3.scss"),
- tuple("css:S1116", "css-issues-project:src/file5.htm"),
- tuple("css:S1116", "css-issues-project:src/file6.vue"),
- tuple("css:S5362", "css-issues-project:src/file1.css"),
- tuple("css:S5362", "css-issues-project:src/file2.less"),
- tuple("css:S5362", "css-issues-project:src/file3.scss")
- );
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMetricsTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMetricsTest.java
deleted file mode 100644
index 82b28099a9e..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMetricsTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasure;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasureAsDouble;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssMetricsTest {
-
- private static final String PROJECT_KEY = "css-metrics-project";
-
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- orchestrator.executeBuild(CssTestsUtils.createScanner(PROJECT_KEY));
- }
-
- @Test
- void test() {
- assertThat(getMeasureAsDouble(PROJECT_KEY, "lines")).isEqualTo(43);
- assertThat(getMeasureAsDouble(PROJECT_KEY, "ncloc")).isEqualTo(32);
- assertThat(getMeasure(PROJECT_KEY, "ncloc_language_distribution").getValue()).isEqualTo("css=22;web=10");
- assertThat(getMeasureAsDouble(PROJECT_KEY, "comment_lines")).isEqualTo(4);
-
- assertThat(getMeasure(PROJECT_KEY + ":src/file1.css", "ncloc_data").getValue())
- .contains("1=1;", "2=1;", "3=1;", "4=1;", "5=1;", "6=1;", "7=1");
-
- assertThat(getMeasure(PROJECT_KEY + ":src/file2.less", "ncloc_data").getValue())
- .contains("1=1;", "2=1;", "3=1;", "4=1;", "5=1;", "6=1;", "7=1;", "8=1;", "9=1");
-
- assertThat(getMeasure(PROJECT_KEY + ":src/file3.scss", "ncloc_data").getValue())
- .contains("1=1;", "3=1;", "5=1;", "6=1;", "7=1;", "8=1");
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMinifiedTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMinifiedTest.java
deleted file mode 100644
index ac04e2ed5ab..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssMinifiedTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasureAsDouble;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssMinifiedTest {
-
- private static final String PROJECT_KEY = "css-minified-project";
-
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- orchestrator.executeBuild(CssTestsUtils.createScanner(PROJECT_KEY));
- }
-
- @Test
- void test() {
- assertThat(getMeasureAsDouble(PROJECT_KEY, "files")).isEqualTo(1);
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNoCssFileProjectTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNoCssFileProjectTest.java
deleted file mode 100644
index ebefc09205b..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNoCssFileProjectTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssNoCssFileProjectTest {
-
- private static final String PROJECT_KEY = "css-php-project";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
- SonarScanner scanner = CssTestsUtils.createScanner(PROJECT_KEY);
- orchestrator.executeBuild(scanner);
- }
-
- @Test
- void test() {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
- List issuesList = newWsClient(orchestrator).issues().search(request).getIssuesList().stream()
- .filter(i -> i.getRule().startsWith("css:"))
- .collect(Collectors.toList());
-
- assertThat(issuesList).extracting(Issues.Issue::getRule, Issues.Issue::getLine, Issues.Issue::getComponent).containsExactlyInAnyOrder(
- tuple("css:S4658", 7, "css-php-project:src/index.php"));
-
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNonStandardPathTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNonStandardPathTest.java
deleted file mode 100644
index 469bdf021fe..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssNonStandardPathTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static java.util.Collections.emptySet;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssNonStandardPathTest {
-
- private static final String PROJECT_KEY = "css-dir-with-paren";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- var rulesConfiguration = new ProfileGenerator.RulesConfiguration();
- var profile = ProfileGenerator.generateProfile(orchestrator, "css", "css", rulesConfiguration, emptySet());
- orchestrator.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
- orchestrator.getServer().associateProjectToQualityProfile(PROJECT_KEY, "css", profile);
-
- SonarScanner scanner = getSonarScanner()
- .setSourceEncoding("UTF-8")
- .setProjectDir(TestUtils.projectDir("css-(dir with paren)"))
- .setProjectKey(PROJECT_KEY)
- .setProjectName(PROJECT_KEY)
- .setSourceDirs("src");
- orchestrator.executeBuild(scanner);
- }
-
- @Test
- void test() {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
- List issuesList = newWsClient(orchestrator).issues().search(request).getIssuesList().stream()
- .filter(i -> i.getRule().startsWith("css:"))
- .collect(Collectors.toList());
-
- assertThat(issuesList).extracting(Issue::getRule, Issue::getComponent).containsExactly(
- tuple("css:S1128", "css-dir-with-paren:src/file1.css")
- );
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssStylelintReportTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssStylelintReportTest.java
deleted file mode 100644
index 6a148ed9a64..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssStylelintReportTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import java.util.Collections;
-import java.util.List;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class CssStylelintReportTest {
-
- private static final String PROJECT_KEY = "css-external-report-project";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- orchestrator.executeBuild(CssTestsUtils.createScanner(PROJECT_KEY).setProperty("sonar.css.stylelint.reportPaths", "report.json"));
- }
-
- @Test
- void test() {
- if (orchestrator.getServer().version().isGreaterThanOrEquals(7, 2)) {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(Collections.singletonList(PROJECT_KEY));
- List issuesList = newWsClient(orchestrator).issues().search(request).getIssuesList();
-
- assertThat(issuesList).extracting("line").containsExactlyInAnyOrder(111, 81, 55, 58, 114);
- assertThat(issuesList).extracting("rule").containsExactlyInAnyOrder(
- "external_stylelint:no-missing-end-of-source-newline",
- "external_stylelint:no-missing-end-of-source-newline",
- "external_stylelint:rule-empty-line-before",
- "external_stylelint:selector-pseudo-element-colon-notation",
- "css:S4658");
- }
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssTestsUtils.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssTestsUtils.java
deleted file mode 100644
index b8e9543675f..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/CssTestsUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.build.SonarScanner;
-
-
-class CssTestsUtils {
-
- static SonarScanner createScanner(String projectKey) {
- return OrchestratorStarter.getSonarScanner()
- .setSourceEncoding("UTF-8")
- .setProjectDir(TestUtils.projectDir(projectKey))
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setDebugLogs(true)
- .setSourceDirs("src");
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ECMAScriptModulesTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ECMAScriptModulesTest.java
deleted file mode 100644
index aaa22c19215..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ECMAScriptModulesTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
-import java.util.List;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class ECMAScriptModulesTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static final File PROJECT_DIR = TestUtils.projectDir("esm-project");
-
- @Test
- void test() {
- String projectKey = "esm-project";
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(PROJECT_DIR);
-
- OrchestratorStarter.setProfile(projectKey, "eslint-based-rules-profile", "js");
- orchestrator.executeBuild(build);
-
- List issuesList = getIssues(projectKey);
- assertThat(issuesList).hasSize(1);
- assertThat(issuesList.get(0).getLine()).isEqualTo(2);
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBasedRulesTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBasedRulesTest.java
deleted file mode 100644
index 816f3e0c3e5..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBasedRulesTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.List;
-import org.jetbrains.annotations.NotNull;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static com.sonar.javascript.it.plugin.ProfileGenerator.generateProfile;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class EslintBasedRulesTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static String jsProfile;
-
- @BeforeAll
- static void setup() {
- jsProfile = generateProfile(orchestrator, "js", "javascript", new ProfileGenerator.RulesConfiguration(),
- emptySet());
- }
-
- @Test
- void test_without_ts() {
- testProject(TestUtils.projectDir("eslint_based_rules"), "eslint-based-rules-project");
- }
-
- @Test
- void test_with_ts() throws IOException, InterruptedException {
- // When project contains both JS and TS, ts dependency will be available, therefore @typescript-eslint/eslint-plugin
- // rules will also be available, causing potential conflicts.
- File projectDir = TestUtils.projectDir("eslint_based_rules_with_ts");
- testProject(projectDir, "eslint-based-rules-project-with-ts");
- }
-
- public void testProject(File projectDir, String projectKey) {
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(projectDir);
-
- OrchestratorStarter.setProfile(projectKey, jsProfile, "js");
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.getLogsLines(l -> l.startsWith("ERROR"))).isEmpty();
-
- List issuesList = getIssueList(projectKey, "javascript:S3923");
- assertThat(issuesList).hasSize(1);
- assertThat(issuesList.get(0).getLine()).isEqualTo(1);
- }
-
- @Test
- void test_directory_with_special_chars() {
- String projectKey = "special-chars";
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(TestUtils.projectDir("(dir with paren)/eslint_based_rules"));
-
- OrchestratorStarter.setProfile(projectKey, "eslint-based-rules-profile", "js");
-
- orchestrator.executeBuild(build);
-
- List issuesList = getIssueList(projectKey, "javascript:S3923");
- assertThat(issuesList).hasSize(1);
- assertThat(issuesList.get(0).getLine()).isEqualTo(5);
- }
-
- @Test
- void test_js_with_ts_eslint_parser() {
- String projectKey = "js-with-ts-eslint-key";
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(TestUtils.projectDir("js-with-ts-eslint-project"));
-
- OrchestratorStarter.setProfile(projectKey, "js-with-ts-eslint-profile", "js");
-
- orchestrator.executeBuild(build);
-
- List issuesList = getIssueList(projectKey, "javascript:S3525");
- assertThat(issuesList).hasSize(1);
- assertThat(issuesList.get(0).getLine()).isEqualTo(2);
- }
-
- @Test
- void test_exclusion_filter() throws Exception {
- String projectKey = "file-filter-project";
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(TestUtils.projectDir("file-filter/excluded_dir/project"))
- .setProperty("sonar.javascript.exclusions", "excluded_dir/**");
-
- OrchestratorStarter.setProfile(projectKey, jsProfile, "js");
-
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.getLogsLines(l -> l.startsWith("ERROR"))).isEmpty();
- List issuesList = getIssueList(projectKey, "javascript:S3923");
- assertThat(issuesList).hasSize(1)
- .extracting(Issue::getComponent)
- .containsExactly("file-filter-project:main.js");
- }
-
- @Test
- // cwd - current working directory
- void should_not_use_node_in_cwd() throws Exception {
- if (!System.getProperty("os.name").startsWith("Windows")) {
- // this test only makes sense on Windows
- return;
- }
- String projectKey = "eslint_based_rules";
- File projectDir = TestUtils.projectDir(projectKey);
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setDebugLogs(true)
- .setProjectDir(projectDir);
-
- // copy ping.exe to node.exe and place it in the project directory
- Path ping = Paths.get("C:\\Windows\\System32\\PING.EXE");
- Path fakeNodePath = projectDir.toPath().resolve("node.exe");
- Files.copy(ping, fakeNodePath, StandardCopyOption.REPLACE_EXISTING);
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.isSuccess()).isTrue();
- assertThat(buildResult.getLogs()).contains("Looking for Node.js in the PATH using where.exe (Windows)");
-
- // compare that the node which we used is not "ping.exe"
- String log = buildResult.getLogsLines(s -> s.contains("Found node.exe at")).get(0);
- Path nodePath = Paths.get(log.substring(log.indexOf("at") + 3));
- assertThat(nodePath).isNotEqualTo(fakeNodePath);
- byte[] nodeBytes = Files.readAllBytes(nodePath);
- byte[] pingBytes = Files.readAllBytes(ping);
- assertThat(pingBytes).isNotEqualTo(nodeBytes);
- }
-
- @Test
- void should_record_perf_metrics() throws Exception {
- String projectKey = "eslint_based_rules";
- File projectDir = TestUtils.projectDir(projectKey);
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProperty("sonar.javascript.monitoring", "true")
- .setProperty("sonar.javascript.monitoring.path", projectDir.toPath().resolve(".scannerwork").toString())
- .setProjectDir(projectDir);
-
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.isSuccess()).isTrue();
- assertThat(projectDir.toPath().resolve(".scannerwork/metrics.json")).exists();
- }
-
- @Test
- void quickfix() throws Exception {
- var projectKey = "quickfix";
- var projectDir = TestUtils.projectDir(projectKey);
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(projectDir);
- OrchestratorStarter.setProfile(projectKey, jsProfile, "js");
-
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.getLogsLines(l -> l.startsWith("ERROR"))).isEmpty();
-
- var issuesList = getIssueList(projectKey, "javascript:S1116");
- assertThat(issuesList).hasSize(1);
- var issue = issuesList.get(0);
- assertThat(issue.getLine()).isEqualTo(2);
- assertThat(issue.getQuickFixAvailable()).isTrue();
- }
-
- @Test
- void jsFileNamedAsTsFile() {
- var projectKey = "same-filename";
- var projectDir = TestUtils.projectDir(projectKey);
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setDebugLogs(true)
- .setProjectDir(projectDir);
- OrchestratorStarter.setProfile(projectKey, "eslint-based-rules-profile", "js");
-
- BuildResult buildResult = orchestrator.executeBuild(build);
- assertThat(buildResult.getLogsLines(l -> l.contains("Failed to parse") && l.contains("with TypeScript parser"))).isEmpty();
-
- var issuesList = getIssues(projectKey);
- assertThat(issuesList).extracting(Issue::getRule, Issue::getComponent).containsExactlyInAnyOrder(
- tuple("javascript:S3403", projectKey + ":file.js"), // rule requires type information
- tuple("javascript:S3923", projectKey + ":file.js"), // rule does not require type information
- tuple("typescript:S3923", projectKey + ":file.ts")
- );
- }
-
- @NotNull
- private static List getIssueList(String projectKey, String ruleKey) {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(singletonList(projectKey)).setRules(singletonList(ruleKey));
- return newWsClient(orchestrator).issues().search(request).getIssuesList();
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBridgeIntegrationTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBridgeIntegrationTest.java
deleted file mode 100644
index 2b1145c5721..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintBridgeIntegrationTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.zip.GZIPInputStream;
-import org.apache.commons.compress.archivers.ArchiveEntry;
-import org.apache.commons.compress.archivers.ArchiveInputStream;
-import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-import org.apache.commons.compress.utils.IOUtils;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-
-/**
- * This test extracts eslint-bridge archive into tmp directory and starts eslint-bridge using node, then tries to analyze
- * small JS snippet.
- * The goal is to assert http API of eslint-bridge the way it is used by SonarLint in Visual Studio (i.e. without
- * Java plugin).
- * One optimization for SonarLint is, that we don't compute metrics when running under SonarLint.
- */
-class EslintBridgeIntegrationTest {
-
- @TempDir
- Path temp;
-
- static Path pluginJar = OrchestratorStarter.JAVASCRIPT_PLUGIN_LOCATION.getFile().toPath();
- static final Gson gson = new Gson();
-
- @Test
- void test() throws Exception {
-
- String filename = "eslint-bridge-1.0.0.tgz";
- EslintBridge eslintBridge = new EslintBridge();
- try (FileSystem fileSystem = FileSystems.newFileSystem(pluginJar, null)) {
- Path fileToExtract = fileSystem.getPath(filename);
- extractArchive(fileToExtract, temp);
- eslintBridge.start(temp);
- assertStatus(eslintBridge);
- eslintBridge.request(gson.toJson(InitLinter.build("sonar-no-unused-vars")), "init-linter");
- assertAnalyzeJs(eslintBridge);
- } finally {
- eslintBridge.stop();
- }
- }
-
- private void assertAnalyzeJs(EslintBridge eslintBridge) throws IOException, InterruptedException {
- AnalysisRequest r = new AnalysisRequest();
- r.fileContent = "function foo() { \n"
- + " var a; \n"
- + " var c; // NOSONAR\n"
- + " var b = 42; \n"
- + "} \n";
- r.filePath = temp.resolve("file.js").toAbsolutePath().toString();
- String response = eslintBridge.request(gson.toJson(r), "analyze-js");
- JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
- JsonArray issues = jsonObject.getAsJsonArray("issues");
- assertThat(issues).hasSize(3);
- assertThat(issues).extracting(i -> i.getAsJsonObject().get("line").getAsInt()).containsExactlyInAnyOrder(2, 3, 4);
- // this assert makes sure that we don't compute metrics except nosonar lines
- JsonObject metrics = jsonObject.getAsJsonObject("metrics");
- assertThat(metrics.entrySet()).hasSize(1);
- assertThat(metrics.get("nosonarLines").getAsJsonArray()).containsExactly(new JsonPrimitive(3));
- }
-
- private void assertStatus(EslintBridge eslintBridge) {
- String[] response = new String[1];
- await().atMost(30, SECONDS).until(() -> {
- try {
- response[0] = eslintBridge.status();
- return response[0].equals("OK!");
- } catch (IOException e) {
- Thread.sleep(100);
- return false;
- }
- });
- assertThat(response[0]).isEqualTo("OK!");
- }
-
- static void extractArchive(Path tgz, Path targetPath) throws IOException {
- try (InputStream stream = new GZIPInputStream(Files.newInputStream(tgz));
- ArchiveInputStream archive = new TarArchiveInputStream(stream)) {
- ArchiveEntry entry;
- while ((entry = archive.getNextEntry()) != null) {
- if (!archive.canReadEntryData(entry)) {
- throw new IllegalStateException("Failed to extract bundle");
- }
- Path entryFile = entryPath(targetPath, entry);
- if (entry.isDirectory()) {
- Files.createDirectories(entryFile);
- } else {
- Path parent = entryFile.getParent();
- Files.createDirectories(parent);
- try (OutputStream os = Files.newOutputStream(entryFile)) {
- IOUtils.copy(archive, os);
- }
- }
- }
- }
- }
-
- private static Path entryPath(Path targetPath, ArchiveEntry entry) {
- Path entryPath = targetPath.resolve(entry.getName()).normalize();
- if (!entryPath.startsWith(targetPath)) {
- throw new IllegalStateException("Archive entry " + entry.getName() + " is not within " + targetPath);
- }
- return entryPath;
- }
-
-
- class EslintBridge {
- int port;
- final HttpClient client;
- private Process process;
-
- EslintBridge() {
- this.client = HttpClient.newHttpClient();
- }
-
- void start(Path dest) throws IOException {
- port = findOpenPort();
- String[] cmd = {"node", dest.resolve("package/bin/server").toString(), String.valueOf(port), "127.0.0.1",
- temp.toString(), "true", "true"};
- ProcessBuilder pb = new ProcessBuilder(cmd);
- pb.inheritIO();
- process = pb.start();
- }
-
- String request(String json, String endpoint) throws IOException, InterruptedException {
- var request = HttpRequest.newBuilder(url(endpoint))
- .header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(json))
- .build();
-
- var response = client.send(request, HttpResponse.BodyHandlers.ofString());
- return response.body();
- }
-
- String status() throws IOException, InterruptedException {
- var request = HttpRequest.newBuilder(url("status")).GET().build();
- return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
- }
-
- private URI url(String endpoint) {
- try {
- return new URI("http", null, "127.0.0.1", port, "/" + endpoint, null, null);
- } catch (URISyntaxException e) {
- throw new IllegalStateException(e);
- }
- }
-
- int findOpenPort() throws IOException {
- try (ServerSocket socket = new ServerSocket(0)) {
- return socket.getLocalPort();
- }
- }
-
- void stop() {
- process.destroyForcibly();
- }
- }
-
- static class AnalysisRequest {
- String filePath;
- String fileContent;
- String fileType = "MAIN";
- }
-
- static class InitLinter {
- List rules = new ArrayList<>();
- List environments = new ArrayList<>();
- List globals = new ArrayList<>();
-
- static InitLinter build(String rule) {
- InitLinter initLinter = new InitLinter();
- Rule rule1 = new Rule();
- rule1.key = rule;
- initLinter.rules.add(rule1);
- return initLinter;
- }
- }
-
- static class Rule {
- String key;
- List configurations = Collections.emptyList();
- String fileTypeTarget = "MAIN";
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintCustomRulesTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintCustomRulesTest.java
deleted file mode 100644
index de9d6ab3968..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintCustomRulesTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import com.sonar.orchestrator.locator.FileLocation;
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import org.assertj.core.groups.Tuple;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.sonarqube.ws.Common;
-import org.sonarqube.ws.Issues;
-import org.sonarqube.ws.Issues.Issue;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.JAVASCRIPT_PLUGIN_LOCATION;
-import static org.assertj.core.api.Assertions.assertThat;
-
-class EslintCustomRulesTest {
- private static final String PLUGIN_ARTIFACT_ID = "eslint-custom-rules-plugin";
-
- private static Orchestrator orchestrator;
-
- @BeforeAll
- public static void before() {
- orchestrator = initOrchestrator(PLUGIN_ARTIFACT_ID);
- }
-
-
- @AfterAll
- public static void after() {
- orchestrator.stop();
- }
-
- static Orchestrator initOrchestrator(String customRulesArtifactId) {
- Orchestrator orchestrator = Orchestrator.builderEnv()
- .useDefaultAdminCredentialsForBuilds(true)
- .setSonarVersion(System.getProperty("sonar.runtimeVersion", "LATEST_RELEASE"))
- .addPlugin(JAVASCRIPT_PLUGIN_LOCATION)
- .restoreProfileAtStartup(FileLocation.ofClasspath("/empty-js-profile.xml"))
- .addPlugin(FileLocation.byWildcardMavenFilename(
- new File("../plugins/" + customRulesArtifactId + "/target"), customRulesArtifactId + "-*.jar"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/profile-javascript-custom-rules.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/profile-typescript-custom-rules.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/nosonar.xml"))
- .build();
- // Installation of SQ server in orchestrator is not thread-safe, so we need to synchronize
- synchronized (OrchestratorStarter.class) {
- orchestrator.start();
- }
- return orchestrator;
- }
-
- static List findIssues(String ruleKey, Orchestrator orchestrator) {
- org.sonarqube.ws.client.issues.SearchRequest searchRequest = new org.sonarqube.ws.client.issues.SearchRequest();
- searchRequest.setRules(Collections.singletonList(ruleKey));
- Issues.SearchWsResponse response = OrchestratorStarter.newWsClient(orchestrator).issues().search(searchRequest);
- return response.getIssuesList();
- }
-
- static BuildResult runBuild(Orchestrator orchestrator) {
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("custom_rules"))
- .setProjectKey("custom-rules")
- .setProjectName("Custom Rules")
- .setProjectVersion("1.0")
- .setDebugLogs(true)
- .setSourceDirs("src");
- orchestrator.getServer().provisionProject("custom-rules", "Custom Rules");
- orchestrator.getServer().associateProjectToQualityProfile("custom-rules", "js", "javascript-custom-rules-profile");
- orchestrator.getServer().associateProjectToQualityProfile("custom-rules", "ts", "ts-custom-rules-profile");
- return orchestrator.executeBuild(build);
- }
-
- @Test
- void test() {
- BuildResult buildResult = runBuild(orchestrator);
- assertThat(buildResult.getLogsLines(l -> l.matches(".*DEBUG: Deploying custom rules bundle jar:file:.*/custom-eslint-based-rules-1\\.0\\.0\\.tgz to .*"))).hasSize(1);
- assertThat(buildResult.getLogsLines(l -> l.contains("Custom JavaScript rules are deprecated and API will be removed in future version."))).isEmpty();
- assertThat(buildResult.getLogsLines(l -> l.contains("TS API in custom rule: TS version 4.9.4"))).hasSize(2);
- List issues = findIssues("eslint-custom-rules:sqKey", orchestrator);
- assertThat(issues).hasSize(2);
- assertThat(issues).extracting(Issue::getRule, Issue::getComponent, Issue::getLine, Issue::getMessage)
- .containsExactlyInAnyOrder(
- new Tuple("eslint-custom-rules:sqKey", "custom-rules:src/dir/Person.js", 21, "call"),
- new Tuple("eslint-custom-rules:sqKey", "custom-rules:src/dir/file.ts", 4, "call")
- );
- Common.Location secondaryLocation = issues.get(0).getFlows(0).getLocations(0);
- assertThat(secondaryLocation.getMsg()).isEqualTo(new File(TestUtils.projectDir("custom_rules"), ".scannerwork").getAbsolutePath());
-
- issues = findIssues("ts-custom-rules:tsRuleKey", orchestrator);
- assertThat(issues).extracting(Issue::getRule, Issue::getComponent, Issue::getLine, Issue::getMessage)
- .containsExactlyInAnyOrder(
- new Tuple("ts-custom-rules:tsRuleKey", "custom-rules:src/dir/file.ts", 4, "tsrule call")
- );
-
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintReportTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintReportTest.java
deleted file mode 100644
index a779526d6cf..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/EslintReportTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.setEmptyProfile;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class EslintReportTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static final String PROJECT_KEY_PREFIX = "SonarJS-eslint-report-test";
- private static final File PROJECT_DIR = TestUtils.projectDir("eslint_report");
-
- @Test
- void should_save_issues_from_external_report_with_relative_paths() {
- String projectKey = PROJECT_KEY_PREFIX + "-relative";
-
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(PROJECT_DIR)
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs("src");
-
- setEmptyProfile(projectKey);
- build.setProperty("sonar.eslint.reportPaths", "report.json");
- orchestrator.executeBuild(build);
-
- assertIssues(projectKey);
- }
-
- @Test
- void should_save_issues_from_external_report_with_absolute_paths() throws IOException {
- String projectKey = PROJECT_KEY_PREFIX + "-absolute";
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(PROJECT_DIR)
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1.0")
- .setSourceDirs("src");
-
- setEmptyProfile(projectKey);
-
- File reportWithRelativePaths = new File(PROJECT_DIR, "report.json");
- File reportWithAbsolutePaths = new File(PROJECT_DIR, "report_absolute_paths.json");
- createReportWithAbsolutePaths(reportWithRelativePaths, reportWithAbsolutePaths);
-
- build.setProperty("sonar.eslint.reportPaths", reportWithAbsolutePaths.getAbsolutePath());
- orchestrator.executeBuild(build);
-
- assertIssues(projectKey);
-
- Files.delete(reportWithAbsolutePaths.toPath());
- }
-
- private void assertIssues(String projectKey) {
- List jsIssuesList = getIssues(projectKey + ":src/file.js");
- List tsIssuesList = getIssues(projectKey + ":src/file.ts");
-
- assertThat(jsIssuesList).extracting(Issue::getLine, Issue::getRule).containsExactlyInAnyOrder(
- tuple(1, "external_eslint_repo:no-unused-vars"),
- tuple(2, "external_eslint_repo:use-isnan"),
- tuple(3, "external_eslint_repo:semi"),
- tuple(5, "external_eslint_repo:semi"),
- tuple(7, "external_eslint_repo:no-extra-semi")
- );
-
- assertThat(tsIssuesList).extracting(Issue::getLine, Issue::getRule).containsExactlyInAnyOrder(
- tuple(1, "external_eslint_repo:no-unused-vars"),
- tuple(2, "external_eslint_repo:use-isnan"),
- tuple(3, "external_eslint_repo:semi"),
- tuple(5, "external_eslint_repo:semi"),
- tuple(7, "external_eslint_repo:no-extra-semi")
- );
- }
-
- private void createReportWithAbsolutePaths(File reportWithRelativePaths, File reportWithAbsolutePaths) throws IOException {
- List reportContent = Files.readAllLines(reportWithRelativePaths.toPath());
- String prefix = "\"filePath\": \"";
- List transformed = reportContent.stream().map(s -> {
- if (s.contains(prefix)) {
- File file = new File(PROJECT_DIR, "src/file." + (s.contains(".js") ? "js" : "ts"));
- String absolutePath = file.getAbsolutePath();
- if (System.getProperty("os.name").startsWith("Windows")) {
- // try to "break" file resolution (see https://github.com/SonarSource/SonarJS/issues/1985) by low-casing drive letter
- absolutePath = absolutePath.substring(0, 1).toLowerCase() + absolutePath.substring(1);
- absolutePath = absolutePath.replace("\\", "\\\\");
- }
- return prefix + absolutePath + "\",";
- } else {
- return s;
- }
- }).collect(Collectors.toList());
- Files.write(reportWithAbsolutePaths.toPath(), transformed);
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExpectedIssues.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExpectedIssues.java
deleted file mode 100644
index 1191f3cc7f7..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExpectedIssues.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-
-public class ExpectedIssues {
-
- private Map> expectedLinesPerFile = new TreeMap<>();
-
- private static final Pattern NON_COMPLIANT_PATTERN = Pattern.compile("//\\s*Noncompliant", Pattern.CASE_INSENSITIVE);
- private static final String GENERATED_EXPECTATIONS_DIR = "target/expected/ts";
-
- public static void parseForExpectedIssues(String projectKey, Path projectDir) throws IOException {
- Map expectedIssuesByRule = new HashMap<>();
-
- Arrays.stream(projectDir.toFile().listFiles())
- .filter(file -> file.toString().endsWith(".ts") || file.toString().endsWith(".tsx"))
- .forEach(file -> parseFile(projectKey, projectDir, expectedIssuesByRule, file.toPath()));
-
- Gson gson = new GsonBuilder().setPrettyPrinting().create();
- Path expectationsDirectory = prepareExpectationsDir(projectKey);
- expectedIssuesByRule.forEach((rule, expectedIssues) -> {
- try {
- Path expectationsFile = expectationsDirectory.resolve("typescript" + "-" + rule + ".json");
- String asJson = gson.toJson(expectedIssues.expectedLinesPerFile);
- Files.createFile(expectationsFile);
- Files.write(expectationsFile, asJson.getBytes());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- });
- }
-
- private static void parseFile(String projectKey, Path projectDirPath, Map expectedIssuesByRule, Path file) {
- String ruleKey = file.toFile().getName().split("\\.")[0];
- String fileKey = projectKey + ":" + projectDirPath.relativize(file).toString().replaceAll(Pattern.quote(File.separator), "/");
- List lines = getLines(file);
- for (int lineNumber = 1; lineNumber <= lines.size(); lineNumber++) {
- String currentLine = lines.get(lineNumber - 1);
-
- if (NON_COMPLIANT_PATTERN.matcher(currentLine).find() && !currentLine.trim().startsWith("//")) {
- addLineWithIssue(expectedIssuesByRule, ruleKey, fileKey, lineNumber);
- }
- // continue if no "// Noncompliant" in the line or the entire line is commented (to not consider commented out code)
- }
- }
-
- private static List getLines(Path file) {
- try {
- return Files.readAllLines(file);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static Path prepareExpectationsDir(String projectKey) throws IOException {
- Path topExpectationsDir = Paths.get(GENERATED_EXPECTATIONS_DIR);
- if (!topExpectationsDir.toFile().exists()) {
- Files.createDirectories(topExpectationsDir);
- }
- Path projectExpectationsDir = Paths.get(GENERATED_EXPECTATIONS_DIR, projectKey);
- File[] files = projectExpectationsDir.toFile().listFiles();
- if (files != null) {
- Arrays.stream(files).forEach(File::delete);
- }
- Files.deleteIfExists(projectExpectationsDir);
- return Files.createDirectory(projectExpectationsDir);
- }
-
- private static void addLineWithIssue(Map expectedIssuesByRule, String currentRuleKey, String fileKey, int lineNumber) {
- expectedIssuesByRule.computeIfAbsent(currentRuleKey, key -> new ExpectedIssues())
- .expectedLinesPerFile.computeIfAbsent(fileKey, key -> new ArrayList<>())
- .add(lineNumber);
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExternalTSConfigDependencyTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExternalTSConfigDependencyTest.java
deleted file mode 100644
index c884f3820c9..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ExternalTSConfigDependencyTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-
-import java.io.File;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class ExternalTSConfigDependencyTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static final String PROJECT = "external-tsconfig-dependency-project";
- private static final File PROJECT_DIR = TestUtils.projectDir(PROJECT);
-
- @Test
- void test() throws Exception {
- SonarScanner build = getSonarScanner()
- .setProjectKey(PROJECT)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(PROJECT_DIR);
-
- orchestrator.getServer().provisionProject(PROJECT, PROJECT);
- orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "ts", "eslint-based-rules-profile");
-
- BuildResult buildResult = orchestrator.executeBuild(build);
-
- assertThat(getIssues(PROJECT)).extracting(Issue::getLine, Issue::getComponent).containsExactlyInAnyOrder(
- tuple(4, "external-tsconfig-dependency-project:src/bar/main.ts")
- );
- assertThat(buildResult.getLogsLines(l -> l.equals("WARN: At least one tsconfig.json was not found in the project. Please run 'npm install' for a more complete analysis. Check analysis logs for more details."))).hasSize(1);
-
- File rootDrive = PROJECT_DIR;
- while (rootDrive.getParentFile() != null) {
- rootDrive = rootDrive.getParentFile();
- }
-
- File lastTsConfigPath = new File(rootDrive, "node_modules" + File.separator + "@tsconfig" + File.separator + "node14" + File.separator + "tsconfig.json");
-
- assertThat(buildResult.getLogsLines(l -> l.equals("WARN: Could not find tsconfig.json: " + lastTsConfigPath.getAbsolutePath().replace('\\', '/') + "; falling back to an empty configuration."))).hasSize(1);
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MetricsTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MetricsTest.java
deleted file mode 100644
index fc21338de7e..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MetricsTest.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Measures.Measure;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasure;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasureAsDouble;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class MetricsTest {
-
- private static final String PROJECT_KEY = "MetricsTest";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("metrics"))
- .setProjectKey(PROJECT_KEY)
- .setProjectName(PROJECT_KEY)
- .setProjectVersion("1.0")
- .setSourceDirs("src");
- OrchestratorStarter.setEmptyProfile(PROJECT_KEY);
- orchestrator.executeBuild(build);
- }
-
- @Test
- void project_level() {
- // Size
- assertThat(getProjectMeasureAsDouble("ncloc")).isEqualTo(20);
- assertThat(getProjectMeasureAsDouble("classes")).isEqualTo(1);
- assertThat(getProjectMeasureAsDouble("functions")).isEqualTo(5);
- assertThat(getProjectMeasureAsDouble("statements")).isEqualTo(8);
-
- // Documentation
- assertThat(getProjectMeasureAsDouble("comment_lines")).isEqualTo(1);
- assertThat(getProjectMeasureAsDouble("comment_lines_density")).isEqualTo(4.8);
-
- // Complexity
- assertThat(getProjectMeasureAsDouble("complexity")).isEqualTo(6.0);
-
- // Duplication
- assertThat(getProjectMeasureAsDouble("duplicated_lines")).isEqualTo(0.0);
- assertThat(getProjectMeasureAsDouble("duplicated_blocks")).isEqualTo(0.0);
- assertThat(getProjectMeasureAsDouble("duplicated_files")).isEqualTo(0.0);
- assertThat(getProjectMeasureAsDouble("duplicated_lines_density")).isEqualTo(0.0);
- // Rules
- assertThat(getProjectMeasureAsDouble("violations")).isEqualTo(0.0);
- // Tests
- assertThat(getProjectMeasureAsDouble("tests")).isNull();
-
- assertThat(getProjectMeasureAsDouble("coverage")).isEqualTo(0.0);
- }
-
- @Test
- void directory_level() {
- // Size
- assertThat(getDirectoryMeasureAsDouble("ncloc")).isEqualTo(20);
- assertThat(getDirectoryMeasureAsDouble("classes")).isEqualTo(1);
- assertThat(getDirectoryMeasureAsDouble("functions")).isEqualTo(5);
- assertThat(getDirectoryMeasureAsDouble("statements")).isEqualTo(8);
- // Documentation
- assertThat(getDirectoryMeasureAsDouble("comment_lines")).isEqualTo(1);
- assertThat(getDirectoryMeasureAsDouble("comment_lines_density")).isEqualTo(4.8);
- // Duplication
- assertThat(getDirectoryMeasureAsDouble("duplicated_lines")).isEqualTo(0.0);
- assertThat(getDirectoryMeasureAsDouble("duplicated_blocks")).isEqualTo(0.0);
- assertThat(getDirectoryMeasureAsDouble("duplicated_files")).isEqualTo(0.0);
- assertThat(getDirectoryMeasureAsDouble("duplicated_lines_density")).isEqualTo(0.0);
- // Rules
- assertThat(getDirectoryMeasureAsDouble("violations")).isEqualTo(0.0);
- }
-
- @Test
- void file_level() {
- // Size
- assertThat(getFileMeasureAsDouble("functions")).isEqualTo(5);
- // Documentation
- assertThat(getFileMeasureAsDouble("comment_lines")).isEqualTo(1);
- assertThat(getFileMeasureAsDouble("comment_lines_density")).isEqualTo(4.8);
- // Duplication
- assertThat(getFileMeasureAsDouble("duplicated_lines")).isZero();
- assertThat(getFileMeasureAsDouble("duplicated_blocks")).isZero();
- assertThat(getFileMeasureAsDouble("duplicated_files")).isZero();
- assertThat(getFileMeasureAsDouble("duplicated_lines_density")).isZero();
- // Rules
- assertThat(getFileMeasureAsDouble("violations")).isZero();
- }
-
- /**
- * SONARPLUGINS-2183
- */
- @Test
- void should_be_compatible_with_DevCockpit() {
- // 2 header comment line
- // 4 empty line
- // 5 code line
- // 14 comment line
- // 15 empty comment line
-
- assertThat(getFileMeasure("ncloc_data").getValue())
- .doesNotContain(";2=1;")
- .doesNotContain(";4=1;")
- .contains("5=1;")
- .doesNotContain(";14=1;")
- .doesNotContain(";15=1;");
- }
-
- /* Helper methods */
-
- private Double getProjectMeasureAsDouble(String metricKey) {
- return getMeasureAsDouble(PROJECT_KEY, metricKey);
- }
-
- private Double getDirectoryMeasureAsDouble(String metricKey) {
- return getMeasureAsDouble(keyFor("dir"), metricKey);
- }
-
- private Measure getFileMeasure(String metricKey) {
- return getMeasure(keyFor("dir/Person.js"), metricKey);
- }
-
- private Double getFileMeasureAsDouble(String metricKey) {
- return getMeasureAsDouble(keyFor("dir/Person.js"), metricKey);
- }
-
- private static String keyFor(String s) {
- return PROJECT_KEY + ":src/" + s;
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MinifiedFilesTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MinifiedFilesTest.java
deleted file mode 100644
index dc9d8c8d766..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MinifiedFilesTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getMeasureAsInt;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class MinifiedFilesTest {
-
- private static final String PROJECT_KEY = "minifiedFilesTest";
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- @BeforeAll
- public static void prepare() {
- SonarScanner build = OrchestratorStarter.createScanner()
- .setProjectDir(TestUtils.projectDir("minified_files"))
- .setProjectKey(PROJECT_KEY)
- .setProjectName(PROJECT_KEY)
- .setProjectVersion("1.0")
- .setSourceDirs("src");
- OrchestratorStarter.setEmptyProfile(PROJECT_KEY);
- orchestrator.executeBuild(build);
- }
-
- @Test
- void test() {
- assertThat(getMeasureAsInt(PROJECT_KEY, "functions")).isEqualTo(2);
- assertThat(getMeasureAsInt(PROJECT_KEY, "statements")).isEqualTo(1);
- }
-
- /* Helper methods */
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MultiTsconfigTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MultiTsconfigTest.java
deleted file mode 100644
index 94dcedca8db..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/MultiTsconfigTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.Issues.Issue;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-@ExtendWith(OrchestratorStarter.class)
-class MultiTsconfigTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static final String PROJECT = "multi-tsconfig-test-project";
- private static final File PROJECT_DIR = TestUtils.projectDir(PROJECT);
-
- @Test
- void test() throws Exception {
- SonarScanner build = getSonarScanner()
- .setProjectKey(PROJECT)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(PROJECT_DIR)
- // setting inclusions like this will exclude tsconfig.json files, which is what we want to test
- .setProperty("sonar.inclusions", "**/*.ts");
-
- orchestrator.getServer().provisionProject(PROJECT, PROJECT);
- orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "ts", "eslint-based-rules-profile");
-
- orchestrator.executeBuild(build);
-
- assertThat(getIssues(PROJECT)).extracting(Issue::getLine, Issue::getComponent).containsExactlyInAnyOrder(
- tuple(4, "multi-tsconfig-test-project:src/bar/main.ts"),
- tuple(3, "multi-tsconfig-test-project:src/dir1/main.ts"),
- tuple(3, "multi-tsconfig-test-project:src/dir2/main.ts"),
- tuple(3, "multi-tsconfig-test-project:src/foo/main.ts")
- );
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/NoSonarTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/NoSonarTest.java
deleted file mode 100644
index f34b22acbf9..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/NoSonarTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import java.io.File;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.sonarqube.ws.client.issues.SearchRequest;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.newWsClient;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-@ExtendWith(OrchestratorStarter.class)
-class NoSonarTest {
-
- private static final Orchestrator orchestrator = OrchestratorStarter.ORCHESTRATOR;
-
- private static final File PROJECT_DIR = TestUtils.projectDir("nosonar");
-
- @BeforeAll
- public static void startServer() {
- String projectKey = "nosonar-project";
- SonarScanner build = getSonarScanner()
- .setProjectKey(projectKey)
- .setProjectName(projectKey)
- .setProjectVersion("1")
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(PROJECT_DIR);
-
- OrchestratorStarter.setProfile(projectKey, "nosonar-profile", "js");
-
- orchestrator.executeBuild(build);
- }
-
- @Test
- void test() {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(singletonList("nosonar-project")).setSeverities(singletonList("INFO")).setRules(singletonList("javascript:S1116"));
- assertThat(newWsClient(orchestrator).issues().search(request).getIssuesList()).hasSize(1);
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/OrchestratorStarter.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/OrchestratorStarter.java
deleted file mode 100644
index af4c600703b..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/OrchestratorStarter.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import com.sonar.orchestrator.locator.FileLocation;
-import com.sonar.orchestrator.locator.MavenLocation;
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-import org.junit.jupiter.api.extension.BeforeAllCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.Measures.Measure;
-import org.sonarqube.ws.client.HttpConnector;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.WsClientFactories;
-import org.sonarqube.ws.client.issues.SearchRequest;
-import org.sonarqube.ws.client.measures.ComponentRequest;
-
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;
-
-public final class OrchestratorStarter implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
-
- static final String SCANNER_VERSION = "4.7.0.2747";
- static final FileLocation JAVASCRIPT_PLUGIN_LOCATION = FileLocation.byWildcardMavenFilename(
- new File("../../../sonar-javascript-plugin/target"), "sonar-javascript-plugin-*.jar");
-
- public static final Orchestrator ORCHESTRATOR = Orchestrator.builderEnv()
- .useDefaultAdminCredentialsForBuilds(true)
- .setSonarVersion(System.getProperty("sonar.runtimeVersion", "LATEST_RELEASE"))
- .addPlugin(MavenLocation.of("org.sonarsource.php", "sonar-php-plugin", "LATEST_RELEASE"))
- .addPlugin(MavenLocation.of("org.sonarsource.html", "sonar-html-plugin", "LATEST_RELEASE"))
- // required to load YAML files
- .addPlugin(MavenLocation.of("org.sonarsource.config", "sonar-config-plugin", "LATEST_RELEASE"))
- .addPlugin(JAVASCRIPT_PLUGIN_LOCATION)
- .restoreProfileAtStartup(FileLocation.ofClasspath("/empty-js-profile.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/empty-ts-profile.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/profile-javascript-custom-rules.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/nosonar.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/eslint-based-rules.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/ts-eslint-based-rules.xml"))
- .restoreProfileAtStartup(FileLocation.ofClasspath("/js-with-ts-eslint-profile.xml"))
- .build();
-
- private static volatile boolean started;
-
- private OrchestratorStarter() {
- }
-
- /**
- * make sure that whole test suite uses the same version of the scanner
- */
- static SonarScanner getSonarScanner() {
- return SonarScanner.create()
- .setScannerVersion(SCANNER_VERSION);
- }
-
- @Override
- public void beforeAll(ExtensionContext context) {
- synchronized (OrchestratorStarter.class) {
- if (!started) {
- started = true;
- // this will register "this.close()" method to be called when GLOBAL context is shutdown
- context.getRoot().getStore(GLOBAL).put(OrchestratorStarter.class, this);
- ORCHESTRATOR.start();
-
- // to avoid a race condition in scanner file cache mechanism we analyze single project before any test to populate the cache
- testProject();
- }
- }
- }
-
-
- @Override
- public void close() {
- // this is executed once all tests are finished
- ORCHESTRATOR.stop();
- }
-
- public static SonarScanner createScanner() {
- SonarScanner scanner = getSonarScanner();
- scanner.setProperty("sonar.exclusions", "**/ecmascript6/**, **/file-for-rules/**, **/frameworks/**, **/jest/**/*, **/babylon/**/*");
- scanner.setSourceEncoding("UTF-8");
- return scanner;
- }
-
- public static void setEmptyProfile(String projectKey) {
- ORCHESTRATOR.getServer().provisionProject(projectKey, projectKey);
- ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, "ts", "empty-profile");
- ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, "js", "empty-profile");
- }
-
- public static void setProfile(String projectKey, String profileName, String language) {
- ORCHESTRATOR.getServer().provisionProject(projectKey, projectKey);
- ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKey, language, profileName);
- }
-
- public static void setProfiles(String projectKey, Map profiles) {
- setProfiles(ORCHESTRATOR, projectKey, profiles);
- }
-
- static void setProfiles(Orchestrator orchestrator, String projectKey, Map profiles) {
- orchestrator.getServer().provisionProject(projectKey, projectKey);
- profiles.forEach((profileName, language) -> orchestrator.getServer().associateProjectToQualityProfile(projectKey, language, profileName));
- }
-
- @CheckForNull
- static Measure getMeasure(String componentKey, String metricKey) {
- return getMeasure(ORCHESTRATOR, componentKey, metricKey, null, null);
- }
-
- @CheckForNull
- private static Measure getMeasure(Orchestrator orchestrator, String componentKey, String metricKey, String branch, String pullRequest) {
- var request = new ComponentRequest()
- .setComponent(componentKey)
- .setMetricKeys(singletonList(metricKey));
- if (branch != null) {
- request.setBranch(branch);
- }
- if (pullRequest != null) {
- request.setPullRequest(pullRequest);
- }
- var response = newWsClient(orchestrator).measures().component(request);
- var measures = response.getComponent().getMeasuresList();
- return measures.size() == 1 ? measures.get(0) : null;
- }
-
- @CheckForNull
- static Integer getMeasureAsInt(String componentKey, String metricKey) {
- Measure measure = getMeasure(componentKey, metricKey);
- return (measure == null) ? null : Integer.parseInt(measure.getValue());
- }
-
- @CheckForNull
- static Double getMeasureAsDouble(String componentKey, String metricKey) {
- return getMeasureAsDouble(ORCHESTRATOR, componentKey, metricKey, null, null);
- }
-
- @CheckForNull
- public static Double getMeasureAsDouble(Orchestrator orchestrator, String componentKey, String metricKey, String branch, String pullRequest) {
- var measure = getMeasure(orchestrator, componentKey, metricKey, branch, pullRequest);
- return (measure == null) ? null : Double.parseDouble(measure.getValue());
- }
-
- static WsClient newWsClient(Orchestrator orchestrator) {
- return WsClientFactories.getDefault().newClient(HttpConnector.newBuilder()
- .url(orchestrator.getServer().getUrl())
- .build());
- }
-
- static List getIssues(String componentKey) {
- return getIssues(ORCHESTRATOR, componentKey, null, null);
- }
-
- static List getIssues(Orchestrator orchestrator, String componentKey, String branch, String pullRequest) {
- SearchRequest request = new SearchRequest();
- request.setComponentKeys(singletonList(componentKey));
- if (branch != null) {
- request.setBranch(branch);
- }
- if (pullRequest != null) {
- request.setPullRequest(pullRequest);
- }
- return newWsClient(orchestrator).issues().search(request).getIssuesList();
- }
-
- private static void testProject() {
- var projectKey = "eslint_based_rules";
- var projectDir = TestUtils.projectDir(projectKey);
- var build = getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setSourceDirs(".")
- .setProjectDir(projectDir);
- OrchestratorStarter.setProfile(projectKey, "empty-profile", "js");
-
- var buildResult = ORCHESTRATOR.executeBuild(build);
- assertThat(buildResult.isSuccess()).isTrue();
- assertThat(buildResult.getLogsLines(l -> l.startsWith("ERROR"))).isEmpty();
- }
-
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/PRAnalysisTest.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/PRAnalysisTest.java
deleted file mode 100644
index 0793ab26805..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/PRAnalysisTest.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.sonar.javascript.it.plugin.assertj.BuildResultAssert;
-import com.sonar.javascript.it.plugin.assertj.Measures;
-import com.sonar.javascript.it.plugin.assertj.MeasuresAssert;
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildResult;
-import com.sonar.orchestrator.build.SonarScanner;
-import com.sonar.orchestrator.container.Edition;
-import com.sonar.orchestrator.locator.FileLocation;
-import com.sonar.orchestrator.locator.MavenLocation;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.concurrent.Callable;
-import java.util.function.Function;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-import org.sonarqube.ws.Issues;
-
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.JAVASCRIPT_PLUGIN_LOCATION;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getIssues;
-import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
-import static java.lang.String.format;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-
-class PRAnalysisTest {
-
- private static Orchestrator orchestrator;
-
- @TempDir
- private Path gitBaseDir;
-
- @ParameterizedTest
- @ValueSource(strings = {"js", "ts"})
- void should_analyse_js_ts_pull_requests(String language) {
- var testProject = TestProject.fromName(language);
- var projectKey = testProject.getProjectKey();
- var projectPath = gitBaseDir.resolve(projectKey).toAbsolutePath();
-
- OrchestratorStarter.setProfiles(orchestrator, projectKey, Map.of(testProject.getProfileName(), testProject.getLanguage()));
-
- try (var gitExecutor = testProject.createIn(projectPath)) {
- var indexFile = "index." + language;
- var helloFile = "hello." + language;
-
- gitExecutor.execute(git -> git.checkout().setName(Main.BRANCH));
- var buildResult = scanWith(getMasterScannerIn(projectPath, projectKey));
- BuildResultAssert.assertThat(buildResult)
- .withProjectKey(projectKey)
- .logsAtLeastOnce("DEBUG: Analysis of unchanged files will not be skipped (current analysis requires all files to be analyzed)")
- .logsOnce("DEBUG: Initializing linter \"default\"")
- .doesNotLog("DEBUG: Initializing linter \"unchanged\"")
- .cacheFileStrategy("WRITE_ONLY")
- .withReason("current analysis requires all files to be analyzed")
- .forFiles(indexFile, helloFile)
- .withCachedFilesCounts(1, 1)
- .isUsed()
- .logsOnce(format("%s\" with linterId \"default\"", indexFile))
- .logsTimes(Main.ANALYZER_REPORTED_ISSUES, "DEBUG: Saving issue for rule no-extra-semi")
- .logsOnce(format("%s\" with linterId \"default\"", helloFile))
- .logsOnce("INFO: Hit the cache for 0 out of 2", "Miss the cache for 2 out of 2: ANALYSIS_MODE_INELIGIBLE [2/2]")
- .generatesUcfgFilesForAll(projectPath, indexFile, helloFile);
- assertThat(getIssues(orchestrator, projectKey, Main.BRANCH, null))
- .hasSize(1)
- .extracting(Issues.Issue::getComponent)
- .contains(projectKey + ":" + indexFile);
-
- gitExecutor.execute(git -> git.checkout().setName(PR.BRANCH));
- BuildResultAssert.assertThat(scanWith(getBranchScannerIn(projectPath, projectKey)))
- .withProjectKey(projectKey)
- .logsAtLeastOnce("DEBUG: Files which didn't change will be part of UCFG generation only, other rules will not be executed")
- .logsOnce("DEBUG: Initializing linter \"default\"")
- .logsOnce("DEBUG: Initializing linter \"unchanged\"")
- .cacheFileStrategy("READ_AND_WRITE").forFiles(indexFile).withCachedFilesCounts(1).isUsed()
- .doesNotLog(format("%s\" with linterId \"unchanged\"", indexFile))
- .cacheFileStrategy("WRITE_ONLY")
- .withReason("the current file is changed")
- .forFiles(helloFile)
- .withCachedFilesCounts(1)
- .isUsed()
- .logsOnce(format("%s\" with linterId \"default\"", helloFile))
- .logsTimes(PR.ANALYZER_REPORTED_ISSUES, "DEBUG: Saving issue for rule no-extra-semi")
- .logsOnce("INFO: Hit the cache for 1 out of 2", "INFO: Miss the cache for 1 out of 2: FILE_CHANGED [1/2]")
- .generatesUcfgFilesForAll(projectPath, indexFile, helloFile);
- assertThat(getIssues(orchestrator, projectKey, null, PR.BRANCH))
- .hasSize(1)
- .extracting(Issues.Issue::getComponent)
- .contains(projectKey + ":" + helloFile);
- }
- }
-
- @Test
- void should_analyse_yaml_pull_requests() {
- var cloudformation = TestProject.YAML;
- var projectKey = cloudformation.getProjectKey();
- var projectPath = gitBaseDir.resolve(projectKey).toAbsolutePath();
-
- OrchestratorStarter.setProfiles(orchestrator, projectKey, Map.of(
- TestProject.JS.getProfileName(), TestProject.JS.getLanguage()
- ));
-
- try (var gitExecutor = cloudformation.createIn(projectPath)) {
- gitExecutor.execute(git -> git.checkout().setName(Main.BRANCH));
- BuildResultAssert.assertThat(scanWith(getMasterScannerIn(projectPath, projectKey)))
- .withProjectKey(projectKey)
- .logsAtLeastOnce("DEBUG: Analysis of unchanged files will not be skipped (current analysis requires all files to be analyzed)")
- .logsOnce("DEBUG: Initializing linter \"default\"")
- .doesNotLog("DEBUG: Initializing linter \"unchanged\"")
- .cacheFileStrategy("WRITE_ONLY")
- .withReason("current analysis requires all files to be analyzed")
- .forFiles("file1.yaml", "file2.yaml")
- .withCachedFilesCounts(1, 1)
- .isUsed()
- .logsOnce("file1.yaml\" with linterId \"default\"")
- .logsOnce("file2.yaml\" with linterId \"default\"")
- .logsOnce("INFO: Hit the cache for 0 out of 2", "Miss the cache for 2 out of 2: ANALYSIS_MODE_INELIGIBLE [2/2]")
- .generatesUcfgFilesForAll(projectPath, "file2_SomeLambdaFunction_yaml", "file1_SomeLambdaFunction_yaml");
- assertThat(getIssues(orchestrator, projectKey, Main.BRANCH, null))
- .isEmpty();
-
- gitExecutor.execute(git -> git.checkout().setName(PR.BRANCH));
- BuildResultAssert.assertThat(scanWith(getBranchScannerIn(projectPath, projectKey)))
- .withProjectKey(projectKey)
- .logsAtLeastOnce("DEBUG: Files which didn't change will be part of UCFG generation only, other rules will not be executed")
- .logsOnce("DEBUG: Initializing linter \"default\"")
- .logsOnce("DEBUG: Initializing linter \"unchanged\"")
- .cacheFileStrategy("READ_AND_WRITE").forFiles("file1.yaml").withCachedFilesCounts(1).isUsed()
- .doesNotLog("file1.yaml\" with linterId \"unchanged\"")
- .cacheFileStrategy("WRITE_ONLY")
- .withReason("the current file is changed")
- .forFiles("file2.yaml")
- .withCachedFilesCounts(1)
- .isUsed()
- .logsOnce("file2.yaml\" with linterId \"default\"")
- .logsTimes(PR.ANALYZER_REPORTED_ISSUES, "DEBUG: Saving issue for rule no-extra-semi")
- .logsOnce("INFO: Hit the cache for 1 out of 2", "INFO: Miss the cache for 1 out of 2: FILE_CHANGED [1/2]")
- .generatesUcfgFilesForAll(projectPath, "file2_SomeLambdaFunction_yaml", "file1_SomeLambdaFunction_yaml");
- assertThat(getIssues(orchestrator, projectKey, null, PR.BRANCH))
- .hasSize(1)
- .extracting(issue -> tuple(issue.getComponent(), issue.getRule()))
- .contains(tuple(projectKey + ":file2.yaml", "javascript:S1116"));
- }
- }
-
- @ParameterizedTest
- @ValueSource(strings = {"cpd-js", "cpd-ts"})
- void should_generate_cpds(String name) {
- var testProject = TestProject.fromName(name);
- var language = testProject.getLanguage();
- var projectKey = testProject.getProjectKey();
- var projectPath = gitBaseDir.resolve(projectKey).toAbsolutePath();
-
- OrchestratorStarter.setProfiles(orchestrator, projectKey, Map.of(testProject.getProfileName(), language));
-
- try (var gitExecutor = testProject.createIn(projectPath)) {
- gitExecutor.execute(git -> git.checkout().setName(Main.BRANCH));
- scanWith(getMasterScannerIn(projectPath, projectKey));
-
- MeasuresAssert.assertThat(getMeasures(projectKey + ":file1." + language, Main.BRANCH, null))
- .has("duplicated_lines", 30.0d)
- .has("duplicated_blocks", 1.0d)
- .has("duplicated_files", 1.0d)
- .has("duplicated_lines_density", 93.8d);
-
- MeasuresAssert.assertThat(getMeasures(projectKey + ":file2." + language, Main.BRANCH, null))
- .has("duplicated_lines", 30.0d)
- .has("duplicated_blocks", 1.0d)
- .has("duplicated_files", 1.0d)
- .has("duplicated_lines_density", 88.2d);
-
- MeasuresAssert.assertThat(getMeasures(projectKey, Main.BRANCH, null))
- .has("duplicated_lines", 60.0d)
- .has("duplicated_blocks", 2.0d)
- .has("duplicated_files", 2.0d)
- .has("duplicated_lines_density", 90.9d);
-
- gitExecutor.execute(git -> git.checkout().setName(PR.BRANCH));
- BuildResultAssert.assertThat(scanWith(getBranchScannerIn(projectPath, projectKey)))
- .logsTimes(2, "DEBUG: Processing cache analysis of file");
-
- MeasuresAssert.assertThat(getMeasures(projectKey + ":file3." + language, null, PR.BRANCH))
- .has("duplicated_lines", 31.0d)
- .has("duplicated_blocks", 2.0d)
- .has("duplicated_files", 1.0d)
- .has("duplicated_lines_density", 96.9d);
-
- MeasuresAssert.assertThat(getMeasures(projectKey, null, PR.BRANCH))
- .has("duplicated_lines", 92.0d)
- .has("duplicated_blocks", 5.0d)
- .has("duplicated_files", 3.0d)
- .has("duplicated_lines_density", 93.9d);
- }
- }
-
- private static Measures getMeasures(String componentKey, String branch, String pullRequest) {
- return new Measures(orchestrator, componentKey, branch, pullRequest);
- }
-
- @BeforeAll
- public static void startOrchestrator() {
- var builder = Orchestrator.builderEnv()
- .useDefaultAdminCredentialsForBuilds(true)
- .setSonarVersion(System.getProperty("sonar.runtimeVersion", "LATEST_RELEASE"))
- .addPlugin(JAVASCRIPT_PLUGIN_LOCATION)
- .setEdition(Edition.DEVELOPER).activateLicense()
- .addPlugin(MavenLocation.of("com.sonarsource.security", "sonar-security-plugin", "DEV"))
- .addPlugin(MavenLocation.of("com.sonarsource.security", "sonar-security-js-frontend-plugin", "DEV"))
- .addPlugin(MavenLocation.of("org.sonarsource.config", "sonar-config-plugin", "LATEST_RELEASE"));
-
- for (var projectTestCase : TestProject.values()) {
- builder.restoreProfileAtStartup(FileLocation.ofClasspath(projectTestCase.getProfileFile()));
- }
-
- orchestrator = builder.build();
- // Installation of SQ server in orchestrator is not thread-safe, so we need to synchronize
- synchronized (OrchestratorStarter.class) {
- orchestrator.start();
- }
- }
-
- @AfterAll
- public static void stopOrchestrator() {
- orchestrator.stop();
- }
-
- private static SonarScanner getMasterScannerIn(Path projectDir, String projectKey) {
- return getScanner(projectDir, projectKey).setProperty("sonar.branch.name", Main.BRANCH);
- }
-
- private static SonarScanner getBranchScannerIn(Path projectDir, String projectKey) {
- return getScanner(projectDir, projectKey)
- .setProperty("sonar.pullrequest.key", PR.BRANCH)
- .setProperty("sonar.pullrequest.branch", PR.BRANCH)
- .setProperty("sonar.pullrequest.base", Main.BRANCH);
- }
-
- private static SonarScanner getScanner(Path projectDir, String projectKey) {
- return getSonarScanner()
- .setProjectKey(projectKey)
- .setSourceEncoding("UTF-8")
- .setDebugLogs(true)
- .setSourceDirs(".")
- .setProjectDir(projectDir.toFile())
- .setProperty("sonar.scm.provider", "git")
- .setProperty("sonar.scm.disabled", "false")
- .setProperty("sonar.internal.analysis.failFast", "true");
- }
-
- private static BuildResult scanWith(SonarScanner scanner) {
- var result = orchestrator.executeBuild(scanner);
- assertThat(result.isSuccess()).isTrue();
- return result;
- }
-
- enum TestProject {
-
- JS("js", "js"),
- TS("ts", "ts"),
- YAML("yaml", "js"),
- CPD_JS("cpd-js", "js"),
- CPD_TS("cpd-ts", "ts");
-
- private final String name;
- private final String language;
-
- TestProject(String name, String language) {
- this.name = name;
- this.language = language;
- }
-
- static TestProject fromName(String name) {
- for (var value : values()) {
- if (value.name.equals(name)) {
- return value;
- }
- }
- throw new NoSuchElementException();
- }
-
- String getLanguage() {
- return language;
- }
-
- String getProjectKey() {
- return "pr-analysis-" + name;
- }
-
- String getProfileName() {
- return getProjectKey() + "-profile";
- }
-
- String getProfileFile() {
- return "/" + getProjectKey() + ".xml";
- }
-
- GitExecutor createIn(Path projectDir) {
- var mainProjectDir = TestUtils.projectDir(getProjectKey() + "-main");
- var branchProjectDir = TestUtils.projectDir(getProjectKey() + "-branch");
- var executor = new GitExecutor(projectDir);
-
- TestUtils.copyFiles(projectDir, mainProjectDir.toPath());
- executor.execute(git -> git.add().addFilepattern("."));
- executor.execute(git -> git.commit().setMessage("Create project"));
-
- executor.execute(git -> git.checkout().setCreateBranch(true).setName(PR.BRANCH));
- TestUtils.copyFiles(projectDir, branchProjectDir.toPath());
- executor.execute(git -> git.add().addFilepattern("."));
- executor.execute(git -> git.commit().setMessage("Refactor"));
- executor.execute(git -> git.checkout().setName(Main.BRANCH));
-
- return executor;
- }
-
- }
-
- static class GitExecutor implements AutoCloseable {
-
- private final Git git;
-
- GitExecutor(Path root) {
- try {
- git = Git.init()
- .setDirectory(Files.createDirectories(root).toFile())
- .setInitialBranch(Main.BRANCH)
- .call();
- } catch (IOException | GitAPIException e) {
- throw new RuntimeException(e);
- }
- }
-
- void execute(Function> f) {
- try {
- f.apply(git).call();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public void close() {
- git.close();
- }
-
- }
-
- static class Main {
- static final String BRANCH = "main";
- static final int ANALYZER_REPORTED_ISSUES = 1;
- }
-
- static class PR {
- static final String BRANCH = "pr";
- static final int ANALYZER_REPORTED_ISSUES = 1;
- }
-}
diff --git a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ProfileGenerator.java b/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ProfileGenerator.java
deleted file mode 100644
index fc01accf487..00000000000
--- a/its/plugin/tests/src/test/java/com/sonar/javascript/it/plugin/ProfileGenerator.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * SonarQube JavaScript Plugin
- * Copyright (C) 2012-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package com.sonar.javascript.it.plugin;
-
-import com.google.gson.Gson;
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.locator.FileLocation;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-/**
- * This class is a copy of ProfileGenerator from sonar-analyzer-commons, but it uses Gson parser which is thread-safe
- * @see https://github.com/SonarSource/sonar-analyzer-commons/blob/master/commons/src/main/java/org/sonarsource/analyzer/commons/ProfileGenerator.java
- */
-public class ProfileGenerator {
-
- private static final Gson gson = new Gson();
- private static final int QUERY_PAGE_SIZE = 500;
-
- private ProfileGenerator() {
- }
-
- public static String generateProfile(Orchestrator orchestrator, String language, String repository, RulesConfiguration rulesConfiguration, Set excludedRules) {
- try {
- Set ruleKeys = getRuleKeys(orchestrator.getServer().getUrl(), language, repository);
- ruleKeys.removeAll(excludedRules);
- var name = "rules-" + UUID.randomUUID();
- var profileFile = generateProfile(name, language, repository, rulesConfiguration, ruleKeys);
- orchestrator.getServer().restoreProfile(FileLocation.of(profileFile));
- return name;
- } catch (IOException | XMLStreamException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static File generateProfile(String name, String language, String repository, RulesConfiguration rulesConfiguration, Set ruleKeys) throws XMLStreamException, IOException {
- XMLOutputFactory output = XMLOutputFactory.newInstance();
- StringWriter stringWriter = new StringWriter();
- XMLStreamWriter xml = output.createXMLStreamWriter(stringWriter);
-
- xml.writeStartDocument("UTF-8", "1.0");
- xml.writeStartElement("profile");
- el(xml, "name", name);
- el(xml, "language", language);
-
- xml.writeStartElement("rules");
- for (String key : ruleKeys) {
- xml.writeStartElement("rule");
- el(xml, "repositoryKey", repository);
- el(xml, "key", key);
- el(xml, "priority", "INFO");
- Collection parameters = rulesConfiguration.config.getOrDefault(key, Collections.emptyList());
- if (!parameters.isEmpty()) {
- xml.writeStartElement("parameters");
- for (Parameter parameter : parameters) {
- xml.writeStartElement("parameter");
- el(xml, "key", parameter.parameterKey);
- el(xml, "value", parameter.parameterValue);
- xml.writeEndElement();
- }
- xml.writeEndElement();
- }
- xml.writeEndElement();
- }
- xml.writeEndElement();
- xml.writeEndElement();
- xml.writeEndDocument();
-
- File file = File.createTempFile("profile", ".xml");
- Files.write(file.toPath(), stringWriter.toString().getBytes(StandardCharsets.UTF_8));
- file.deleteOnExit();
- return file;
-
- }
-
- private static void el(XMLStreamWriter xml, String name, String text) throws XMLStreamException {
- xml.writeStartElement(name);
- xml.writeCharacters(text);
- xml.writeEndElement();
- }
-
- private static Set getRuleKeys(String serverUrl, String language, String repository) throws IOException {
- Set ruleKeys = new HashSet<>();
- long total;
- int processed = 0;
- int page = 1;
- do {
- Map response = queryRules(serverUrl, language, repository, page);
- total = ((Double) response.get("total")).longValue();
- @SuppressWarnings("unchecked")
- List> jsonRules = (List>) response.get("rules");
- for (Map