diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 35ef0867f..000000000 --- a/.eslintignore +++ /dev/null @@ -1,22 +0,0 @@ -# .gitignore -out -server -node_modules -*.vsix -.DS_Store -.vscode-test -undefined -target -dist -jre -lombok -bin/ -.settings -.classpath -.project -test/resources/projects/**/.vscode -test/resources/projects/maven/salut/testGradle -test-temp - -# specific to eslint -vscode*.d.ts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index fa1f61863..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "env": { - "es6": true, - "node": true - }, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "project": [ - "tsconfig.webview.json", - "tsconfig.json" - ] - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/member-delimiter-style": [ - "error", - { - "multiline": { - "delimiter": "semi", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/naming-convention": "error", - "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", - "@typescript-eslint/prefer-for-of": "error", - "@typescript-eslint/semi": [ - "error", - "always" - ], - "@typescript-eslint/type-annotation-spacing": "error", - "curly": [ - "error", - "multi-line" - ], - "eqeqeq": [ - "error", - "always" - ], - "id-denylist": [ - "error", - "any", - "Number", - "number", - "String", - "string", - "Boolean", - "boolean", - "Undefined", - "undefined" - ], - "id-match": "error", - "no-debugger": "error", - "no-multiple-empty-lines": "error", - "no-trailing-spaces": "error", - "no-underscore-dangle": "error", - "no-var": "error", - "prefer-arrow-callback": [ - "error", - { - "allowNamedFunctions": true - } - ], - "prefer-const": "error", - "prefer-template": "error", - "quote-props": [ - "error", - "as-needed" - ], - "semi": "error", - "spaced-comment": [ - "error", - "always", - { - "markers": [ - "/" - ] - } - ] - }, - "overrides": [ - { - "files": [ - "**/*.js" - ], - "rules": { - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/semi": "off", - "prefer-arrow/prefer-arrow-functions": "off", - "prefer-arrow-callback": "off", - "no-useless-escape": "off", - "spaced-comment": "off", - "semi": "off", - "prefer-template": "off", - "prefer-const": "off" - } - }, - { - "files": [ - "**/*.test.ts" - ], - "rules": { - "prefer-arrow-callback": "off" - } - } - ] -} \ No newline at end of file diff --git a/.github/workflows/conflictDetector.yaml b/.github/workflows/conflictDetector.yaml index 15a95fd88..afa7436c8 100644 --- a/.github/workflows/conflictDetector.yaml +++ b/.github/workflows/conflictDetector.yaml @@ -6,7 +6,7 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: mschilde/auto-label-merge-conflicts@8c6faa8a252e35ba5e15703b3d747bf726cdb95c + - uses: mschilde/auto-label-merge-conflicts@cd484bbf0476fbe79474a937681a253e094cac3d with: CONFLICT_LABEL_NAME: "has conflicts" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.vscode/settings.json b/.vscode/settings.json index 4012de914..528142020 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ "search.exclude": { "out": true // set this to false to include "out" folder in search results }, - "typescript.tsdk": "./node_modules/typescript/lib", + "js/ts.tsdk.path": "./node_modules/typescript/lib", "git.alwaysSignOff": true, "vsicons.presets.angular": false // we want to use the TS server from our node_modules folder to control its version } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d653ec0f..d08992ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,43 @@ # Change Log +## 1.55.0 (June 24, 2026) + * enhancement - Use standard `decorator` instead of `annotation` token type for highlighting Java annotation. See [#4421](https://github.com/redhat-developer/vscode-java/pull/4421). + * enhancement - Add right click menu item to copy the fully qualified name of the identifier under the cursor. See [#374](https://github.com/redhat-developer/vscode-java/issues/374). + * enhancement - Add regenerate hashCode()/equals() method quick-fix. See [JLS#3764](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3764). + * enhancement - Add type annotation quick-fixes. See [JLS#3759](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3759). + * enhancement - Add Java 26 to Gradle/Java Compatibility Matrix. See [JLS#3757](https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3757). + * enhancement - Add new quick-fixes (type argument and modifier related). See [JLS#3756](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3756). + * enhancement - Add varargs-related quick-fixes. See [JLS#3754](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3754). + * enhancement - Add new null annotation quick-fixes from upstream JDT. See [JLS#3752](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3752). + * enhancement - Add support for vscode path variables for settings url settings. See [JLS#2529](https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/2529). + * bug fix - Sanitize existing command links from hover Javadocs. See [#4429](https://github.com/redhat-developer/vscode-java/pull/4429). + * bug fix - Maven projects 5 folders deep were not loaded as Java projects. See [#4364](https://github.com/redhat-developer/vscode-java/issues/4364). + * bug fix - Prevent Javadoc entries with tables from being truncated in the hover documentation. See [#4219](https://github.com/redhat-developer/vscode-java/issues/4219). + * bug fix - Keep LSP initialize() resilient when m2e is not yet available. See [#3469](https://github.com/redhat-developer/vscode-java/issues/3469). + * bug fix - If the specified type comment template is empty, use the default. See [JLS#3816](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3816). + * bug fix - Prevent setter generation for record components. See [#JLS3812](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3812). + * bug fix - JDTLS batch file fails when located in a folder path with spaces. See [JLS#3783](https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3783). + * bug fix - Completion of annotation properties proposes invalid choices. See [JLS#3604](https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3604). + * bug fix - Do not offer override/implement actions for annotation types. See [JLS#3814](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3814). + +## 1.54.0 (April 15th, 2026) + * enhancement - Add `serverRunning()` API (v0.14) for progressive loading. See [#4372](https://github.com/redhat-developer/vscode-java/pull/4372). + * enhancement - Add JDK 26. See [#4367](https://github.com/redhat-developer/vscode-java/pull/4367). + * enhancement - Add inlay hints for format parameters. See [#4350](https://github.com/redhat-developer/vscode-java/issues/4350). + * enhancement - Support Scala in Gradle projects. See [#4358](https://github.com/redhat-developer/vscode-java/issues/4358). + * enhancement - Progressive project import notifications for tree view. See [JLS#3744](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3744). + * enhancement - Add Null Annotation quick-fixes from JDT to jdt.ls. See [JLS#3727](https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/3727). + * enhancement - Remove the first blank line from generated classes created in the default package. See [JLS#3725](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3725). + * enhancement - Add quick-assist to convert a class to a record. See [JLS#3723](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3723). + * enhancement - Enable change compiler compliance quick-fixes. See [JLS#3743](https://github.com/eclipse-jdtls/eclipse.jdt.ls/pull/3743). + * bug fix - Regression in 1.53.0: Gradle import stuck at 70% with Groovy support enabled in custom multi-project settings plugin layout. See [#4360](https://github.com/redhat-developer/vscode-java/issues/4360). + * bug fix - Navigating to a Kotlin class now opens the sources instead of the decompiled code. See [#4345](https://github.com/redhat-developer/vscode-java/issues/4345). + * bug fix - Quick fix "Add throws declaration" removes backslashes and qute fragments. See [#4314](https://github.com/redhat-developer/vscode-java/issues/4314). + * bug fix - Constructor code completion is broken in certain situations. See [#2336](https://github.com/redhat-developer/vscode-java/issues/2336). + * dependencies - bump brace-expansion from 1.1.12 to 1.1.13. See [#4373](https://github.com/redhat-developer/vscode-java/pull/4373). + * dependencies - bump picomatch. See [#4370](https://github.com/redhat-developer/vscode-java/pull/4370). + * dependencies - bump @tootallnate/once and @vscode/test-electron. See [#4355](https://github.com/redhat-developer/vscode-java/pull/4355). + ## 1.53.0 (February 26th, 2026) * enhancement - Kotlin imports into Java file are unresolved. See [#531](https://github.com/redhat-developer/vscode-java/issues/531). * enhancement - After opening the Kotlin class of a downloaded Maven dependency source, show `.kt` file instead of `.class`. See [#4297](https://github.com/redhat-developer/vscode-java/issues/4297). diff --git a/README.md b/README.md index 425edf87e..488ac8885 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ The following settings are supported: * `java.configuration.maven.userSettings` : Path to Maven's user settings.xml. * `java.configuration.checkProjectSettingsExclusions`: **Deprecated, please use 'java.import.generatesMetadataFilesAtProjectRoot' to control whether to generate the project metadata files at the project root. And use 'files.exclude' to control whether to hide the project metadata files from the file explorer.** Controls whether to exclude extension-generated project settings files (`.project`, `.classpath`, `.factorypath`, `.settings/`) from the file explorer. Defaults to `false`. * `java.referencesCodeLens.enabled` : Enable/disable the references code lenses. +* `java.referencesCodeLens.includeFields` : Enable/disable the references code lens for fields. * `java.implementationCodeLens` : Enable/disable the implementations code lens for the provided categories. * `java.signatureHelp.enabled` : Enable/disable signature help support (triggered on `(`). * `java.signatureHelp.description.enabled` : Enable/disable to show the description in signature help. Defaults to `false`. @@ -168,6 +169,7 @@ The following settings are supported: * `java.codeGeneration.hashCodeEquals.useJava7Objects`: Use Objects.hash and Objects.equals when generating the hashCode and equals methods. This setting only applies to Java 7 and higher. Defaults to `false`. * `java.codeGeneration.useBlocks`: Use blocks in 'if' statements when generating the methods. Defaults to `false`. * `java.codeGeneration.generateComments`: Generate method comments when generating the methods. Defaults to `false`. +* `java.codeGeneration.generateCommentsInMarkdown`: Generate Javadoc comments in Markdown style when generating methods, constructors, and types. Requires source compliance >= 23. Defaults to false. * `java.codeGeneration.toString.template`: The template for generating the toString method. Defaults to `${object.className} [${member.name()}=${member.value}, ${otherMembers}]`. * `java.codeGeneration.toString.codeStyle`: The code style for generating the toString method. Defaults to `STRING_CONCATENATION`. * `java.codeGeneration.toString.skipNullValues`: Skip null values when generating the toString method. Defaults to `false`. @@ -198,6 +200,10 @@ The following settings are supported: * `java.import.gradle.java.home`: Specifies the location to the JVM used to run the Gradle daemon. * `java.project.resourceFilters`: Excludes files and folders from being refreshed by the Java Language Server, which can improve the overall performance. For example, ["node_modules","\.git"] will exclude all files and folders named 'node_modules' or '.git'. Pattern expressions must be compatible with `java.util.regex.Pattern`. Defaults to ["node_modules","\.git"]. * `java.templates.fileHeader`: Specifies the file header comment for new Java file. Supports configuring multi-line comments with an array of strings, and using ${variable} to reference the [predefined variables](https://github.com/redhat-developer/vscode-java/wiki/Predefined-Variables-for-Java-Template-Snippets). +* `java.templates.methodBody`: Specifies the method body snippet for unimplemented methods (e.g. generated by "Add unimplemented methods"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](https://github.com/redhat-developer/vscode-java/wiki/Predefined-Variables-for-Java-Template-Snippets). +* `java.templates.preferPackagePrivateVisibility`: Specifies whether newly created top-level types (class/interface/enum/record) should be package-private instead of public. Defaults to `false`. +* `java.templates.methodBodySuper`: Specifies the method body snippet for overridden methods that call `super` (e.g. generated by "Override/Implement Methods"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](https://github.com/redhat-developer/vscode-java/wiki/Predefined-Variables-for-Java-Template-Snippets). +* `java.templates.catchBody`: Specifies the catch block body snippet (e.g. generated by "Surround with try/catch"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](https://github.com/redhat-developer/vscode-java/wiki/Predefined-Variables-for-Java-Template-Snippets). * `java.templates.typeComment`: Specifies the type comment for new Java type. Supports configuring multi-line comments with an array of strings, and using ${variable} to reference the [predefined variables](https://github.com/redhat-developer/vscode-java/wiki/Predefined-Variables-for-Java-Template-Snippets). * `java.templates.newFile.enabled` : Enable/disable automatic generation of class body and package declaration when creating a new Java file. Set to `false` to create empty Java files. Defaults to `true`. * `java.references.includeAccessors`: Include getter, setter and builder/constructor when finding references. Default to true. @@ -234,6 +240,7 @@ The following settings are supported: * `java.jdt.ls.androidSupport.enabled`: [Experimental] Specify whether to enable Android project importing. When set to `auto`, the Android support will be enabled in Visual Studio Code - Insiders. **Note:** Only works for Android Gradle Plugin `3.2.0` or higher. Defaults to `auto`. * `java.jdt.ls.kotlinSupport.enabled`: [Experimental] Specify whether to enable `org.jetbrains.kotlin.jvm` plugin in Gradle projects. Defaults to `true`. * `java.jdt.ls.groovySupport.enabled`: [Experimental] Specify whether to enable `groovy` plugin in Gradle projects. Defaults to `true`. +* `java.jdt.ls.scalaSupport.enabled`: [Experimental] Specify whether to enable `scala` plugin in Gradle projects. Defaults to `true`. * `java.completion.postfix.enabled`: Enable/disable postfix completion support. Defaults to `true`. * `java.completion.chain.enabled`: Enable/disable chain completion support. Defaults to `false`. * `java.completion.matchCase`: Specify whether to match case for code completion. Defaults to `firstLetter`. diff --git a/changes b/changes new file mode 100644 index 000000000..92b7e65b1 --- /dev/null +++ b/changes @@ -0,0 +1,7 @@ +Fetching issues from https://api.github.com/repos/redhat-developer/vscode-java/issues?state=closed&milestone=154&page=1 + * enhancement - Fix #3210: map decorator token to annotation scope. See [#4421](https://github.com/redhat-developer/vscode-java/pull/4421). + * enhancement - Add feature: copy fully qualified name . See [#374](https://github.com/redhat-developer/vscode-java/issues/374). + * bug fix - Sanitize existing command links from hover Javadocs. See [#4429](https://github.com/redhat-developer/vscode-java/pull/4429). + * bug fix - Maven project 5 folders deap are not loaded as java projects. See [#4364](https://github.com/redhat-developer/vscode-java/issues/4364). + * bug fix - Very long Javadoc is truncated on hover. See [#4219](https://github.com/redhat-developer/vscode-java/issues/4219). + * bug fix - Failed to initialize language server due to "Internal error. Caused by: NPE: Cannot invoke 'o.e.m.c.e.IMaven.getSettings()' because the return value of 'o.e.m.c.MavenPlugin.getMaven()' is null". See [#3469](https://github.com/redhat-developer/vscode-java/issues/3469). diff --git a/document/_java.templateVariables.md b/document/_java.templateVariables.md index f3f78c5d0..2b4f0fcec 100644 --- a/document/_java.templateVariables.md +++ b/document/_java.templateVariables.md @@ -13,3 +13,7 @@ Below are the predefined variables you could use in the template settings such a - `${day}` - current day of the month - `${hour}` - current hour - `${minute}` - current minute +- `${todo}` - the configured task tag (e.g. "TODO") +- `${enclosing_method}` - name of the method being implemented or overridden +- `${body_statement}` - the generated body statement (e.g. a call to the overridden `super` method) +- `${exception_var}` - name of the caught exception variable diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..7eaef9353 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,146 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import tseslint from "typescript-eslint"; +import globals from "globals"; +import stylistic from "@stylistic/eslint-plugin"; + +export default defineConfig([globalIgnores([ + "out", + "server", + "node_modules", + "*.vsix", + ".DS_Store", + ".vscode-test", + "undefined", + "target", + "dist", + "jre", + "lombok", + "bin/", + ".settings", + ".classpath", + ".project", + "test/resources/projects/**/.vscode", + "test/resources/projects/maven/salut/testGradle", + "test-temp", + "vscode*.d.ts", +]), { + files: ["src/**"], + + plugins: { + "@typescript-eslint": tseslint.plugin, + "stylistic": stylistic, + }, + + languageOptions: { + globals: { + ...globals.node, + }, + + parser: tseslint.parser, + ecmaVersion: "latest", + sourceType: "commonjs", + + parserOptions: { + project: ["tsconfig.webview.json", "tsconfig.json"], + }, + }, + + rules: { + "stylistic/member-delimiter-style": ["error", { + multiline: { + delimiter: "semi", + requireLast: true, + }, + + singleline: { + delimiter: "semi", + requireLast: false, + }, + }], + + "@typescript-eslint/naming-convention": "error", + "@typescript-eslint/prefer-for-of": "error", + "stylistic/semi": ["error", "always"], + "stylistic/type-annotation-spacing": "error", + curly: ["error", "multi-line"], + eqeqeq: ["error", "always"], + + "id-denylist": [ + "error", + "any", + "Number", + "number", + "String", + "string", + "Boolean", + "boolean", + "Undefined", + "undefined", + ], + + "id-match": "error", + "no-debugger": "error", + "no-multiple-empty-lines": "error", + "no-trailing-spaces": "error", + "no-underscore-dangle": "error", + "no-var": "error", + + "prefer-arrow-callback": ["error", { + allowNamedFunctions: true, + }], + + "prefer-const": "error", + "prefer-template": "error", + "quote-props": ["error", "as-needed"], + semi: "error", + + "spaced-comment": ["error", "always", { + markers: ["/"], + }], + }, +}, { + files: ["**/*.js", "**/*.mjs"], + + plugins: { + "@typescript-eslint": tseslint.plugin, + }, + + languageOptions: { + globals: { + ...globals.node, + }, + + parser: tseslint.parser, + ecmaVersion: "latest", + sourceType: "commonjs", + }, + + rules: { + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/naming-convention": "off", + "stylistic/semi": "off", + "prefer-arrow/prefer-arrow-functions": "off", + "prefer-arrow-callback": "off", + "no-useless-escape": "off", + "spaced-comment": "off", + semi: "off", + "prefer-template": "off", + "prefer-const": "off", + }, +}, { + files: ["**/*.test.ts"], + + languageOptions: { + globals: { + ...globals.node, + }, + + parser: tseslint.parser, + ecmaVersion: "latest", + sourceType: "commonjs", + }, + + rules: { + "prefer-arrow-callback": "off", + }, +}]); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0c70622fb..44a307b19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,17 @@ { "name": "java", - "version": "1.54.0", + "version": "1.56.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "java", - "version": "1.54.0", + "version": "1.56.0", "license": "EPL-2.0", "dependencies": { "@redhat-developer/vscode-extension-proposals": "0.0.23", "@redhat-developer/vscode-redhat-telemetry": "0.10.2", "@vscode/codicons": "^0.0.32", - "@vscode/webview-ui-toolkit": "1.2.2", "chokidar": "^3.5.3", "expand-home-dir": "^0.0.3", "fmtr": "^1.1.2", @@ -30,6 +29,7 @@ "winston-daily-rotate-file": "^4.7.1" }, "devDependencies": { + "@stylistic/eslint-plugin": "^5.10.0", "@types/fs-extra": "^8.0.0", "@types/glob": "5.0.30", "@types/lodash.findindex": "^4.6.6", @@ -43,12 +43,11 @@ "@types/vscode-webview": "^1.57.0", "@types/winreg": "^1.2.30", "@types/winston": "^2.4.4", - "@typescript-eslint/eslint-plugin": "^5.18.0", - "@typescript-eslint/parser": "^5.18.0", - "@vscode/test-electron": "^2.5.2", + "@vscode/test-electron": "^3.1.0", "css-loader": "^6.7.3", - "eslint": "^8.13.0", - "eslint-webpack-plugin": "^3.2.0", + "eslint": "^10.7.0", + "eslint-webpack-plugin": "^6.0.0", + "globals": "^17.7.0", "lodash.findindex": "^4.6.0", "mini-css-extract-plugin": "^2.9.4", "minimist": ">=1.2.6", @@ -57,8 +56,9 @@ "tar": "^7.5.11", "ts-loader": "^9.4.2", "typescript": "^4.6.4", + "typescript-eslint": "^8.65.0", "webpack": "^5.105.0", - "webpack-cli": "^4.6.0" + "webpack-cli": "^7.2.1" }, "engines": { "vscode": "^1.77.0" @@ -73,53 +73,174 @@ } }, "node_modules/@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.1.0.tgz", + "integrity": "sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=14.17.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", - "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@eslint/core": "^1.2.1" }, "engines": { - "node": ">=10.10.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@humanwhocodes/object-schema": { + "node_modules/@eslint/core": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -274,82 +395,6 @@ "node": ">=8" } }, - "node_modules/@microsoft/fast-element": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.11.0.tgz", - "integrity": "sha512-VKJYMkS5zgzHHb66sY7AFpYv6IfFhXrjQcAyNgi2ivD65My1XOhtjfKez5ELcLFRJfgZNAxvI8kE69apXERTkw==" - }, - "node_modules/@microsoft/fast-foundation": { - "version": "2.47.0", - "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.47.0.tgz", - "integrity": "sha512-EyFuioaZQ9ngjUNRQi8R3dIPPsaNQdUOS+tP0G7b1MJRhXmQWIitBM6IeveQA6ZvXG6H21dqgrfEWlsYrUZ2sw==", - "dependencies": { - "@microsoft/fast-element": "^1.11.0", - "@microsoft/fast-web-utilities": "^5.4.1", - "tabbable": "^5.2.0", - "tslib": "^1.13.0" - } - }, - "node_modules/@microsoft/fast-foundation/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@microsoft/fast-react-wrapper": { - "version": "0.1.48", - "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.1.48.tgz", - "integrity": "sha512-9NvEjru9Kn5ZKjomAMX6v+eF0DR+eDkxKDwDfi+Wb73kTbrNzcnmlwd4diN15ygH97kldgj2+lpvI4CKLQQWLg==", - "dependencies": { - "@microsoft/fast-element": "^1.9.0", - "@microsoft/fast-foundation": "^2.41.1" - }, - "peerDependencies": { - "react": ">=16.9.0" - } - }, - "node_modules/@microsoft/fast-web-utilities": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@microsoft/fast-web-utilities/-/fast-web-utilities-5.4.1.tgz", - "integrity": "sha512-ReWYncndjV3c8D8iq9tp7NcFNc1vbVHvcBFPME2nNFKNbS1XCesYZGlIlf3ot5EmuOXPlrzUHOWzQ2vFpIkqDg==", - "dependencies": { - "exenv-es6": "^1.1.1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -541,6 +586,81 @@ "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "dev": true }, + "node_modules/@stylistic/eslint-plugin": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@stylistic/eslint-plugin/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -563,6 +683,13 @@ "@types/estree": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -717,292 +844,103 @@ "winston": "*" } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.18.0.tgz", - "integrity": "sha512-tzrmdGMJI/uii9/V6lurMo4/o+dMTKDH82LkNjhJ3adCW22YQydoRs5MwTiqxGF9CSYxPxQ7EYb4jLNlIs+E+A==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.18.0", - "@typescript-eslint/type-utils": "5.18.0", - "@typescript-eslint/utils": "5.18.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", + "debug": "^4.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@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/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": 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" + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.18.0.tgz", - "integrity": "sha512-+08nYfurBzSSPndngnHvFw/fniWYJ5ymOrn/63oMIbgomVQOvIDhBoJmYZ9lwQOCnQV9xHGvf88ze3jFGUYooQ==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.18.0", - "@typescript-eslint/types": "5.18.0", - "@typescript-eslint/typescript-estree": "5.18.0", - "debug": "^4.3.2" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.18.0.tgz", - "integrity": "sha512-C0CZML6NyRDj+ZbMqh9FnPscg2PrzSaVQg3IpTmpe0NURMVBXlghGZgMYqBw07YW73i0MCqSDqv2SbywnCS8jQ==", + "node_modules/@typescript-eslint/types": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.18.0", - "@typescript-eslint/visitor-keys": "5.18.0" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.18.0.tgz", - "integrity": "sha512-vcn9/6J5D6jtHxpEJrgK8FhaM8r6J1/ZiNu70ZUJN554Y3D9t3iovi6u7JF8l/e7FcBIxeuTEidZDR70UuCIfA==", + "node_modules/@vscode/codicons": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.32.tgz", + "integrity": "sha512-3lgSTWhAzzWN/EPURoY4ZDBEA80OPmnaknNujA3qnI4Iu7AONWd9xF3iE4L+4prIe8E3TUnLQ4pxoaFTEEZNwg==" + }, + "node_modules/@vscode/test-electron": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-3.1.0.tgz", + "integrity": "sha512-CRqv5u+YYoseuNVJ6Tyo4k0sF0mx4qnKMihRB0PjsUF8Dc0WKtCXo6CNL6nWWm5esfFQsQA/pejMj4ZbpJVLTw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.18.0", - "debug": "^4.3.2", - "tsutils": "^3.21.0" + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "jszip": "^3.10.1", + "ora": "^8.1.0", + "semver": "^7.6.2" }, "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": ">=22" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "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" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.18.0.tgz", - "integrity": "sha512-bhV1+XjM+9bHMTmXi46p1Led5NP6iqQcsOxgx7fvk6gGiV48c6IynY0apQb7693twJDsXiVzNXTflhplmaiJaw==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.18.0.tgz", - "integrity": "sha512-wa+2VAhOPpZs1bVij9e5gyVu60ReMi/KuOx4LKjGx2Y3XTNUDJgQ+5f77D49pHtqef/klglf+mibuHs9TrPxdQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.18.0", - "@typescript-eslint/visitor-keys": "5.18.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "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/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": 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/@typescript-eslint/utils": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.18.0.tgz", - "integrity": "sha512-+hFGWUMMri7OFY26TsOlGa+zgjEy1ssEipxpLjtl4wSll8zy85x0GrUSju/FHdKfVorZPYJLkF3I4XPtnCTewA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.18.0", - "@typescript-eslint/types": "5.18.0", - "@typescript-eslint/typescript-estree": "5.18.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "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/visitor-keys": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.18.0.tgz", - "integrity": "sha512-Hf+t+dJsjAKpKSkg3EHvbtEpFFb/1CiOHnvI8bjHgOD4/wAw3gKrA0i94LrbekypiZVanJu3McWJg7rWDMzRTg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.18.0", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vscode/codicons": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.32.tgz", - "integrity": "sha512-3lgSTWhAzzWN/EPURoY4ZDBEA80OPmnaknNujA3qnI4Iu7AONWd9xF3iE4L+4prIe8E3TUnLQ4pxoaFTEEZNwg==" - }, - "node_modules/@vscode/test-electron": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz", - "integrity": "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "jszip": "^3.10.1", - "ora": "^8.1.0", - "semver": "^7.6.2" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@vscode/webview-ui-toolkit": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.2.2.tgz", - "integrity": "sha512-xIQoF4FC3Xh6d7KNKIoIezSiFWYFuf6gQMdDyKueKBFGeKwaHWEn+dY2g3makvvEsNMEDji/woEwvg9QSbuUsw==", - "dependencies": { - "@microsoft/fast-element": "^1.6.2", - "@microsoft/fast-foundation": "^2.38.0", - "@microsoft/fast-react-wrapper": "^0.1.18" - }, - "peerDependencies": { - "react": ">=16.9.0" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, "license": "MIT" }, @@ -1142,42 +1080,6 @@ "@xtuc/long": "4.2.2" } }, - "node_modules/@webpack-cli/configtest": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", - "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==", - "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", - "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", - "dev": true, - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", - "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==", - "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -1193,9 +1095,9 @@ "license": "Apache-2.0" }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", "bin": { @@ -1223,6 +1125,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1238,10 +1141,11 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1322,15 +1226,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -1368,14 +1263,24 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "dev": true, + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -1436,15 +1341,6 @@ "dev": true, "license": "MIT" }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001769", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", @@ -1569,6 +1465,7 @@ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -1609,12 +1506,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "node_modules/colornames": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", @@ -1644,12 +1535,6 @@ "dev": true, "license": "MIT" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1732,9 +1617,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -1753,7 +1638,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/diagnostics": { "version": "1.1.1", @@ -1775,39 +1661,6 @@ "node": ">=0.3.1" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dir-glob/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==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -1916,27 +1769,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/enquirer/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", @@ -1951,10 +1783,11 @@ "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" }, "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", "dev": true, + "license": "MIT", "bin": { "envinfo": "dist/cli.js" }, @@ -1962,6 +1795,16 @@ "node": ">=4" } }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -1980,55 +1823,62 @@ } }, "node_modules/eslint": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz", - "integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.7.0.tgz", + "integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==", "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", "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.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^10.2.4", "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", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-scope": { @@ -2044,148 +1894,43 @@ "node": ">=8.0.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==", - "dev": 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-utils/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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "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==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-6.0.0.tgz", + "integrity": "sha512-x9m9cH0Rw0RNJB/utP9AMGzmuXg/yLP/FCHSVSfsyjQUyetXN4g1BaIqxkj1i3mVX48aOys0bsVt63LLfh6oYg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", + "@types/eslint": "^9.6.1", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" + "schema-utils": "^4.3.3" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 20.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", + "eslint": "^9.0.0 || ^10.0.0", "webpack": "^5.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/@types/eslint": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz", - "integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/eslint-webpack-plugin/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/eslint/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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": 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==", - "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/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==", - "dev": 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==", - "dev": 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", @@ -2199,16 +1944,35 @@ } }, "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==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -2216,53 +1980,48 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, - "node_modules/eslint/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==", + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "ansi-regex": "^5.0.1" + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" }, "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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.3.0" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2275,6 +2034,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2310,10 +2070,11 @@ } }, "node_modules/esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2327,55 +2088,6 @@ "node": ">=0.8.x" } }, - "node_modules/execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "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/execa/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/execa/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/exenv-es6": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exenv-es6/-/exenv-es6-1.1.1.tgz", - "integrity": "sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==" - }, "node_modules/expand-home-dir": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/expand-home-dir/-/expand-home-dir-0.0.3.tgz", @@ -2387,39 +2099,19 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "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==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } + "license": "MIT" }, - "node_modules/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=", - "dev": 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==", + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.0.6", @@ -2427,9 +2119,9 @@ "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "dev": true, "funding": [ { @@ -2443,36 +2135,22 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fecha": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-stream-rotator": { @@ -2494,6 +2172,23 @@ "node": ">=8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -2504,60 +2199,25 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "license": "ISC", + "license": "MIT", "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" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.3.tgz", + "integrity": "sha512-/zipXxyO6rGvuNGDiULY9MvEGSkb2gaG4GGH4ygMi0ZZzyMHdUZBmntJmx5x1G2VuPytCwGN4xsJP6cw+sK+vQ==", + "dev": true, + "license": "ISC" }, "node_modules/fmtr": { "version": "1.1.2", @@ -2608,13 +2268,6 @@ "node": ">=6 <7 || >=8" } }, - "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==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -2633,16 +2286,11 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "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": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2722,27 +2370,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/glob/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/glob/node_modules/jackspeak": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", @@ -2767,21 +2394,6 @@ "node": "20 || >=22" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob/node_modules/path-scurry": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", @@ -2799,35 +2411,13 @@ } }, "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", + "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", "dev": 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" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2848,10 +2438,11 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -2914,15 +2505,6 @@ "node": ">= 14" } }, - "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/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -2969,36 +2551,12 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "dev": true }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -3008,6 +2566,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -3019,23 +2580,21 @@ "node": ">=0.8.19" } }, - "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==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "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==" }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/invert-kv": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-3.0.1.tgz", @@ -3060,12 +2619,13 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -3134,8 +2694,9 @@ "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -3176,8 +2737,9 @@ "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3249,6 +2811,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "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", @@ -3259,7 +2828,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3293,11 +2863,22 @@ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "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==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3327,6 +2908,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3392,12 +2974,6 @@ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "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==", - "dev": true - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -3529,15 +3105,6 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -3615,16 +3182,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "license": "ISC", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.5" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -3712,9 +3281,9 @@ } }, "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -3748,22 +3317,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -4021,28 +3574,23 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/optionator/node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "node_modules/ora": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", @@ -4260,10 +3808,11 @@ } }, "node_modules/p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4280,18 +3829,6 @@ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4301,16 +3838,6 @@ "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==", - "dev": true, - "license": "MIT", - "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", @@ -4323,7 +3850,8 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", @@ -4378,6 +3906,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -4390,6 +3919,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -4403,6 +3933,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4415,6 +3946,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -4430,6 +3962,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -4548,6 +4081,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -4576,26 +4110,6 @@ "node": ">=6" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4655,16 +4169,17 @@ "node": ">=8.10.0" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "engines": { + "node": ">= 10.13.0" } }, "node_modules/require-directory": { @@ -4686,18 +4201,23 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4707,6 +4227,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -4719,6 +4240,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4769,39 +4291,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4914,6 +4403,7 @@ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -4989,15 +4479,6 @@ "node": ">=8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5203,6 +4684,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5210,11 +4692,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tabbable": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz", - "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==" - }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -5315,11 +4792,53 @@ "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -5343,6 +4862,19 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-loader": { "version": "9.4.2", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", @@ -5423,17 +4955,12 @@ "node": ">=8" } }, - "node_modules/tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -5450,29 +4977,232 @@ "node": ">=4" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">=10" + "node": ">=4.2.0" + } + }, + "node_modules/typescript-eslint": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">=4.2.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.65.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.65.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/typescript-eslint/node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/ua-parser-js": { @@ -5560,12 +5290,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "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==", - "dev": true - }, "node_modules/vscode-jsonrpc": { "version": "8.2.1-next.1", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1-next.1.tgz", @@ -5588,9 +5312,9 @@ } }, "node_modules/vscode-languageclient/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -5697,40 +5421,47 @@ } }, "node_modules/webpack-cli": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", - "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.2", - "@webpack-cli/info": "^1.2.3", - "@webpack-cli/serve": "^1.3.1", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.2.1.tgz", + "integrity": "sha512-YwSGbcZdfz12DM8JIseVPr3oBb09IgVCVc4vY3oDvZnI/mALTGPAP1QiqOi4/bBLSJrRHaqDIXeHcNA0+G38aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^1.1.0", + "commander": "^14.0.3", + "cross-spawn": "^7.0.6", + "envinfo": "^7.21.0", + "import-local": "^3.2.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^6.0.1" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "js-yaml": "^4.0.0 || ^5.0.0", + "json5": "^2.2.3", + "toml": "^3.0.0 || ^4.0.0", + "webpack": "^5.101.0", + "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0", + "webpack-dev-server": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { - "@webpack-cli/generators": { + "js-yaml": { + "optional": true + }, + "json5": { "optional": true }, - "@webpack-cli/migrate": { + "toml": { "optional": true }, "webpack-bundle-analyzer": { @@ -5742,46 +5473,28 @@ } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-cli/node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, + "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=20" } }, "node_modules/webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" + "flat": "^5.0.2", + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-sources": { @@ -5819,10 +5532,11 @@ } }, "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" }, "node_modules/winreg-utf8": { "version": "0.1.1", @@ -5935,10 +5649,11 @@ } }, "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index ff146e413..fff1f8de0 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "author": "Red Hat", "icon": "icons/icon128.png", "license": "EPL-2.0", - "version": "1.54.0", + "version": "1.56.0", "publisher": "redhat", "bugs": "https://github.com/redhat-developer/vscode-java/issues", "preview": false, @@ -182,6 +182,9 @@ "annotation": [ "storage.type.annotation.java" ], + "decorator": [ + "storage.type.annotation.java" + ], "annotationMember": [ "entity.name.annotationMember.java", "constant.other.key.java" @@ -413,6 +416,13 @@ "scope": "window", "order": 80 }, + "java.jdt.ls.scalaSupport.enabled": { + "type": "boolean", + "default": true, + "markdownDescription": "[Experimental] Specify whether to enable `scala` plugin in Gradle projects. Defaults to `true`.", + "scope": "window", + "order": 80 + }, "java.jdt.ls.groovySupport.enabled": { "type": "boolean", "default": true, @@ -1227,6 +1237,43 @@ "default": [], "order": 20 }, + "java.templates.methodBody": { + "type": "array", + "markdownDescription": "Specifies the method body snippet for unimplemented methods (e.g. generated by \"Add unimplemented methods\"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](command:_java.templateVariables).", + "scope": "window", + "default": [ + "// ${todo} Auto-generated method stub", + "throw new UnsupportedOperationException(\"Unimplemented method '${enclosing_method}'\");" + ], + "order": 30 + }, + "java.templates.preferPackagePrivateVisibility": { + "type": "boolean", + "markdownDescription": "Specifies whether newly created top-level types (class/interface/record) should be package-private instead of public.", + "scope": "window", + "default": false, + "order": 40 + }, + "java.templates.methodBodySuper": { + "type": "array", + "markdownDescription": "Specifies the method body snippet for overridden methods that call `super` (e.g. generated by \"Override/Implement Methods\"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](command:_java.templateVariables).", + "scope": "window", + "default": [ + "// ${todo} Auto-generated method stub", + "${body_statement}" + ], + "order": 31 + }, + "java.templates.catchBody": { + "type": "array", + "markdownDescription": "Specifies the catch block body snippet (e.g. generated by \"Surround with try/catch\"). Supports configuring multi-line content with an array of strings, and using ${variable} to reference the [predefined variables](command:_java.templateVariables).", + "scope": "window", + "default": [ + "// ${todo} Auto-generated catch block", + "${exception_var}.printStackTrace();" + ], + "order": 32 + }, "java.codeGeneration.insertionLocation": { "type": "string", "enum": [ @@ -1286,6 +1333,11 @@ "default": false, "scope": "window" }, + "java.codeGeneration.generateCommentsInMarkdown": { + "type": "boolean", + "description": "Generate Javadoc comments in Markdown style (requires source compliance >= 23).", + "default": false + }, "java.codeGeneration.toString.template": { "type": "string", "description": "The template for generating the toString method.", @@ -1475,6 +1527,13 @@ "scope": "window", "order": 10 }, + "java.referencesCodeLens.includeFields": { + "type": "boolean", + "default": false, + "description": "Enable/disable the references code lens for fields.", + "scope": "window", + "order": 15 + }, "java.implementationCodeLens": { "type": "string", "enum": [ @@ -1592,11 +1651,13 @@ "type": "string", "enum": [ "all", - "main" + "main", + "projectOnly" ], "enumDescriptions": [ "Search on all classpath entries including reference libraries and projects.", - "All classpath entries excluding test classpath entries." + "All classpath entries excluding test classpath entries.", + "Only search sources, tests, and referenced projects, excluding the JDK and referenced libraries from the search." ], "default": "all", "markdownDescription": "Specifies the scope which must be used for search operation like \n - Find Reference\n - Call Hierarchy\n - Workspace Symbols", @@ -1856,6 +1917,11 @@ "command": "java.runtimes.add", "title": "%java.runtimes.add%", "category": "Java" + }, + { + "command": "java.action.copyFullyQualifiedName", + "title": "%java.action.copyFullyQualifiedName%", + "category": "Java" } ], "keybindings": [ @@ -1899,12 +1965,12 @@ "group": "1_javaactions" }, { - "when": "explorerResourceIsFolder&&javaLSReady", + "when": "explorerResourceIsFolder&&javaLSReady&&resourceDirname in java.projects", "command": "java.project.addToSourcePath.command", "group": "1_javaactions@1" }, { - "when": "explorerResourceIsFolder&&javaLSReady", + "when": "explorerResourceIsFolder&&javaLSReady&&resourceDirname in java.projects", "command": "java.project.removeFromSourcePath.command", "group": "1_javaactions@2" } @@ -1941,6 +2007,11 @@ "command": "java.action.showTypeHierarchy", "when": "javaLSReady && editorTextFocus && editorLangId == java", "group": "0_navigation@3" + }, + { + "command": "java.action.copyFullyQualifiedName", + "when": "javaLSReady && editorTextFocus && editorLangId == java", + "group": "1_javaactions" } ], "commandPalette": [ @@ -2065,7 +2136,7 @@ "build": "node scripts/index.mjs build-or-download", "fast-build-server": "node scripts/index.mjs dev-server", "watch-server": "node scripts/index.mjs watch-server", - "eslint": "eslint --ignore-path .eslintignore --ext .js,.ts,.tsx .", + "eslint": "eslint .", "repo:check": "node scripts/index.mjs repo-check", "repo:fix": "node scripts/index.mjs repo-fix", "clean-jre": "node scripts/index.mjs clean-jre", @@ -2078,6 +2149,7 @@ "prepare-pre-release": "node scripts/index.mjs prepare-pre-release" }, "devDependencies": { + "@stylistic/eslint-plugin": "^5.10.0", "@types/fs-extra": "^8.0.0", "@types/glob": "5.0.30", "@types/lodash.findindex": "^4.6.6", @@ -2091,12 +2163,11 @@ "@types/vscode-webview": "^1.57.0", "@types/winreg": "^1.2.30", "@types/winston": "^2.4.4", - "@typescript-eslint/eslint-plugin": "^5.18.0", - "@typescript-eslint/parser": "^5.18.0", - "@vscode/test-electron": "^2.5.2", + "@vscode/test-electron": "^3.1.0", "css-loader": "^6.7.3", - "eslint": "^8.13.0", - "eslint-webpack-plugin": "^3.2.0", + "eslint": "^10.7.0", + "eslint-webpack-plugin": "^6.0.0", + "globals": "^17.7.0", "lodash.findindex": "^4.6.0", "mini-css-extract-plugin": "^2.9.4", "minimist": ">=1.2.6", @@ -2105,14 +2176,14 @@ "tar": "^7.5.11", "ts-loader": "^9.4.2", "typescript": "^4.6.4", + "typescript-eslint": "^8.65.0", "webpack": "^5.105.0", - "webpack-cli": "^4.6.0" + "webpack-cli": "^7.2.1" }, "dependencies": { "@redhat-developer/vscode-extension-proposals": "0.0.23", "@redhat-developer/vscode-redhat-telemetry": "0.10.2", "@vscode/codicons": "^0.0.32", - "@vscode/webview-ui-toolkit": "1.2.2", "chokidar": "^3.5.3", "expand-home-dir": "^0.0.3", "fmtr": "^1.1.2", @@ -2134,4 +2205,4 @@ }, "segmentWriteKey": "Y7Y5Xk8dKEhVZHTmAkFZkqgdN4d7c4lt", "segmentWriteKeyDebug": "BflPll7uuKOCm3y0g7JpfXLVBVFBivDE" -} \ No newline at end of file +} diff --git a/package.nls.json b/package.nls.json index 2ac32d40a..c695cfe3e 100644 --- a/package.nls.json +++ b/package.nls.json @@ -30,5 +30,6 @@ "java.action.doCleanup": "Performs Cleanup Actions", "java.change.searchScope": "Change Search Scope", "java.action.showExtendedOutline": "Open Extended Outline", - "java.runtimes.add": "Add Java Runtime" + "java.runtimes.add": "Add Java Runtime", + "java.action.copyFullyQualifiedName": "Copy Fully Qualified Name" } diff --git a/scripts/jre.mjs b/scripts/jre.mjs index 0485afda7..f66f8062f 100644 --- a/scripts/jre.mjs +++ b/scripts/jre.mjs @@ -1,5 +1,4 @@ #!/usr/bin/env node -/* eslint-disable @typescript-eslint/naming-convention */ import fs from 'fs-extra'; import path from 'path'; diff --git a/scripts/server.mjs b/scripts/server.mjs index 2037d99c9..b2592250f 100644 --- a/scripts/server.mjs +++ b/scripts/server.mjs @@ -1,7 +1,5 @@ #!/usr/bin/env node -/* eslint-disable no-underscore-dangle */ - import fs from 'fs-extra'; import path from 'path'; import { execSync } from 'child_process'; diff --git a/scripts/test.mjs b/scripts/test.mjs index 3886c5c19..b3c6489ff 100644 --- a/scripts/test.mjs +++ b/scripts/test.mjs @@ -1,5 +1,4 @@ #!/usr/bin/env node -/* eslint-disable @typescript-eslint/naming-convention */ import fs from 'fs-extra'; import path from 'path'; diff --git a/src/commands.ts b/src/commands.ts index be87ca431..ab5aa0543 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -385,6 +385,12 @@ export namespace Commands { * Add Java Runtime */ export const ADD_JAVA_RUNTIME = 'java.runtimes.add'; + + /** + * Copy fully qualified name. + */ + export const COPY_FULLY_QUALIFIED_NAME = 'java.action.copyFullyQualifiedName'; + export const GET_FULLY_QUALIFIED_NAME = 'java.getFullyQualifiedName'; } /** diff --git a/src/extension.ts b/src/extension.ts index b7c221562..b7bec291a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -52,6 +52,7 @@ const jdtEventEmitter = new EventEmitter(); const extensionName = 'Language Support for Java'; let storagePath: string; let clientLogFile: string; +let standardServerStart: Promise | undefined; const excutable= new Deferred(); @@ -110,6 +111,7 @@ function getHeapDumpFolderFromSettings(): string { } const REPLACE_JDT_LINKS_PATTERN: RegExp = /(\[(?:[^\]])+\]\()(jdt:\/\/(?:(?:(?:\\\))|([^)]))+))\)/g; +const EXISTING_COMMAND_PATTERN: RegExp = /\[([^\]]+)\]\(command:[^)]+\)/g; /** * Replace `jdt://` links in the documentation with links that execute the VS Code command required to open the referenced file. @@ -120,7 +122,11 @@ const REPLACE_JDT_LINKS_PATTERN: RegExp = /(\[(?:[^\]])+\]\()(jdt:\/\/(?:(?:(?:\ * @returns the documentation with fixed links */ export function fixJdtLinksInDocumentation(oldDocumentation: MarkdownString): MarkdownString { - const newContent: string = oldDocumentation.value.replace(REPLACE_JDT_LINKS_PATTERN, (_substring, group1, group2) => { + // sanitize existing command: links + const sanitizedContent = oldDocumentation.value.replace(EXISTING_COMMAND_PATTERN, (_substring, group1: string, group2) => { + return group1; + }); + const newContent: string = sanitizedContent.replace(REPLACE_JDT_LINKS_PATTERN, (_substring, group1, group2) => { const uri = `command:${Commands.OPEN_FILE}?${encodeURI(JSON.stringify([encodeURIComponent(group2)]))}`; return `${group1}${uri})`; }); @@ -190,7 +196,11 @@ export async function activate(context: ExtensionContext): Promise } } - return requirements.resolveRequirements(context).catch(error => { + let requirementsData: requirements.RequirementsData; + + try { + requirementsData = await requirements.resolveRequirements(context); + } catch (error) { // show error window.showErrorMessage(error.message, error.label).then((selection) => { if (error.label && error.label === selection && error.command) { @@ -199,489 +209,567 @@ export async function activate(context: ExtensionContext): Promise }); // rethrow to disrupt the chain. throw error; - }).then(async (requirements) => { - const triggerFiles = await getTriggerFiles(); - return new Promise(async (resolve) => { - const syntaxServerWorkspacePath = path.resolve(`${storagePath}/ss_ws`); - - let serverMode = getJavaServerMode(); - const isWorkspaceTrusted = (workspace as any).isTrusted; // TODO: use workspace.isTrusted directly when other clients catch up to adopt 1.56.0 - if (isWorkspaceTrusted !== undefined && !isWorkspaceTrusted) { // keep compatibility for old engines < 1.56.0 - serverMode = ServerMode.lightWeight; - } - commands.executeCommand('setContext', 'java:serverMode', serverMode); - const isDebugModeByClientPort = !!process.env['SYNTAXLS_CLIENT_PORT'] || !!process.env['JDTLS_CLIENT_PORT']; - const requireSyntaxServer = (serverMode !== ServerMode.standard) && (!isDebugModeByClientPort || !!process.env['SYNTAXLS_CLIENT_PORT']); - let requireStandardServer = (serverMode !== ServerMode.lightWeight) && (!isDebugModeByClientPort || !!process.env['JDTLS_CLIENT_PORT']); - let initFailureReported: boolean = false; - - const javaConfig = await getJavaConfig(requirements.java_home); - javaConfigDeferred.resolve(javaConfig); - - // Options to control the language client - const clientOptions: LanguageClientOptions = { - // Register the server for java - documentSelector: [ - { scheme: 'file', language: 'java' }, - { scheme: 'jdt', language: 'java' }, - { scheme: 'untitled', language: 'java' }, - { scheme: 'vscode-notebook-cell', language: 'java' } - ], - synchronize: { - configurationSection: ['java', 'editor.insertSpaces', 'editor.tabSize', "files.associations"], - }, - initializationOptions: { - bundles: collectJavaExtensions(extensions.all), - workspaceFolders: workspace.workspaceFolders ? workspace.workspaceFolders.map(f => f.uri.toString()) : null, - settings: { java: javaConfig }, - extendedClientCapabilities: { - classFileContentsSupport: true, - overrideMethodsPromptSupport: true, - hashCodeEqualsPromptSupport: true, - advancedOrganizeImportsSupport: true, - generateToStringPromptSupport: true, - advancedGenerateAccessorsSupport: true, - generateConstructorsPromptSupport: true, - generateDelegateMethodsPromptSupport: true, - advancedExtractRefactoringSupport: true, - inferSelectionSupport: ["extractMethod", "extractVariable", "extractField"], - moveRefactoringSupport: true, - clientHoverProvider: true, - clientDocumentSymbolProvider: true, - gradleChecksumWrapperPromptSupport: true, - advancedIntroduceParameterRefactoringSupport: true, - actionableRuntimeNotificationSupport: true, - onCompletionItemSelectedCommand: "editor.action.triggerParameterHints", - extractInterfaceSupport: true, - advancedUpgradeGradleSupport: true, - executeClientCommandSupport: true, - snippetEditSupport: true, - nonStandardJavaFormatting : { - schemes: ["vscode-notebook-cell"], - extensions: ["jsh", "jshell", "ipynb"], - getContentCallback: Commands.GET_VISIBLE_EDITOR_CONTENT, + } + const triggerFiles = await getTriggerFiles(); + const syntaxServerWorkspacePath = path.resolve(`${storagePath}/ss_ws`); + + let serverMode = getJavaServerMode(); + const isWorkspaceTrusted = (workspace as any).isTrusted; // TODO: use workspace.isTrusted directly when other clients catch up to adopt 1.56.0 + if (isWorkspaceTrusted !== undefined && !isWorkspaceTrusted) { // keep compatibility for old engines < 1.56.0 + serverMode = ServerMode.lightWeight; + } + commands.executeCommand('setContext', 'java:serverMode', serverMode); + const isDebugModeByClientPort = !!process.env['SYNTAXLS_CLIENT_PORT'] || !!process.env['JDTLS_CLIENT_PORT']; + const requireSyntaxServer = (serverMode !== ServerMode.standard) && (!isDebugModeByClientPort || !!process.env['SYNTAXLS_CLIENT_PORT']); + const requireStandardServer = (serverMode !== ServerMode.lightWeight) && (!isDebugModeByClientPort || !!process.env['JDTLS_CLIENT_PORT']); + let initFailureReported: boolean = false; + + const javaConfig = await getJavaConfig(requirementsData.java_home); + javaConfigDeferred.resolve(javaConfig); + + // Options to control the language client + const clientOptions: LanguageClientOptions = { + // Register the server for java + documentSelector: [ + { scheme: 'file', language: 'java' }, + { scheme: 'jdt', language: 'java' }, + { scheme: 'untitled', language: 'java' }, + { scheme: 'vscode-notebook-cell', language: 'java' } + ], + synchronize: { + configurationSection: ['java', 'editor.insertSpaces', 'editor.tabSize', "files.associations"], + }, + initializationOptions: { + bundles: collectJavaExtensions(extensions.all), + workspaceFolders: workspace.workspaceFolders ? workspace.workspaceFolders.map(f => f.uri.toString()) : null, + settings: { java: javaConfig }, + extendedClientCapabilities: { + classFileContentsSupport: true, + overrideMethodsPromptSupport: true, + hashCodeEqualsPromptSupport: true, + advancedOrganizeImportsSupport: true, + generateToStringPromptSupport: true, + advancedGenerateAccessorsSupport: true, + generateConstructorsPromptSupport: true, + generateDelegateMethodsPromptSupport: true, + advancedExtractRefactoringSupport: true, + inferSelectionSupport: ["extractMethod", "extractVariable", "extractField"], + moveRefactoringSupport: true, + moveRefactoringConfirmationSupport: true, + clientHoverProvider: true, + clientDocumentSymbolProvider: true, + gradleChecksumWrapperPromptSupport: true, + advancedIntroduceParameterRefactoringSupport: true, + actionableRuntimeNotificationSupport: true, + onCompletionItemSelectedCommand: "editor.action.triggerParameterHints", + extractInterfaceSupport: true, + advancedUpgradeGradleSupport: true, + executeClientCommandSupport: true, + snippetEditSupport: true, + nonStandardJavaFormatting: { + schemes: ["vscode-notebook-cell"], + extensions: ["jsh", "jshell", "ipynb"], + getContentCallback: Commands.GET_VISIBLE_EDITOR_CONTENT, + } + }, + triggerFiles, + }, + middleware: { + workspace: { + didChangeConfiguration: async () => { + await standardClient.getClient().sendNotification(DidChangeConfigurationNotification.type, { + settings: { + java: await getJavaConfig(requirementsData.java_home), } - }, - triggerFiles, - }, - middleware: { - workspace: { - didChangeConfiguration: async () => { - await standardClient.getClient().sendNotification(DidChangeConfigurationNotification.type, { - settings: { - java: await getJavaConfig(requirements.java_home), + }); + } + }, + resolveCompletionItem: async (item, token, next): Promise => { + const completionItem = await next(item, token); + if (completionItem?.documentation instanceof MarkdownString) { + completionItem.documentation = fixJdtLinksInDocumentation(completionItem.documentation); + } + return completionItem; + }, + // https://github.com/redhat-developer/vscode-java/issues/2130 + // include all diagnostics for the current line in the CodeActionContext params for the performance reason + provideCodeActions: async (document, range, context, token, next) => { + const client: LanguageClient = standardClient.getClient(); + const params: CodeActionParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + context: await client.code2ProtocolConverter.asCodeActionContext(context) + }; + const showAt = getJavaConfiguration().get("quickfix.showAt"); + if (showAt === 'line' && range.start.line === range.end.line && range.start.character === range.end.character) { + const textLine = document.lineAt(params.range.start.line); + if (textLine !== null) { + const diagnostics = client.diagnostics.get(document.uri); + const allDiagnostics: Diagnostic[] = []; + for (const diagnostic of diagnostics) { + if (textLine.range.intersection(diagnostic.range)) { + const newLen = allDiagnostics.push(diagnostic); + if (newLen > 1000) { + break; } - }); - } - }, - resolveCompletionItem: async (item, token, next): Promise => { - const completionItem = await next(item, token); - if (completionItem?.documentation instanceof MarkdownString) { - completionItem.documentation = fixJdtLinksInDocumentation(completionItem.documentation); + } } - return completionItem; - }, - // https://github.com/redhat-developer/vscode-java/issues/2130 - // include all diagnostics for the current line in the CodeActionContext params for the performance reason - provideCodeActions: async (document, range, context, token, next) => { - const client: LanguageClient = standardClient.getClient(); - const params: CodeActionParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), - range: client.code2ProtocolConverter.asRange(range), - context: await client.code2ProtocolConverter.asCodeActionContext(context) + const codeActionContext: CodeActionContext = { + diagnostics: allDiagnostics, + only: context.only, + triggerKind: context.triggerKind, }; - const showAt = getJavaConfiguration().get("quickfix.showAt"); - if (showAt === 'line' && range.start.line === range.end.line && range.start.character === range.end.character) { - const textLine = document.lineAt(params.range.start.line); - if (textLine !== null) { - const diagnostics = client.diagnostics.get(document.uri); - const allDiagnostics: Diagnostic[] = []; - for (const diagnostic of diagnostics) { - if (textLine.range.intersection(diagnostic.range)) { - const newLen = allDiagnostics.push(diagnostic); - if (newLen > 1000) { - break; + params.context = await client.code2ProtocolConverter.asCodeActionContext(codeActionContext); + } + } + return client.sendRequest(CodeActionRequest.type, params, token).then(async (values) => { + if (values === null) { + return undefined; + } + const result = []; + for (const item of values) { + if (Command.is(item)) { + result.push(client.protocol2CodeConverter.asCommand(item)); + } + else { + result.push(await client.protocol2CodeConverter.asCodeAction(item)); + } + } + return result; + }, (error) => { + return client.handleFailedRequest(CodeActionRequest.type, token, error, []); + }); + }, + + resolveCodeAction: async (item, token, next) => { + const client: LanguageClient = standardClient.getClient(); + const documentUris = []; + const snippetEdits = []; + return client.sendRequest(CodeActionResolveRequest.type, client.code2ProtocolConverter.asCodeActionSync(item), token).then(async (result) => { + if (token.isCancellationRequested) { + return item; + } + const docChanges = result.edit !== undefined ? result.edit.documentChanges : undefined; + if (docChanges !== undefined) { + for (const docChange of docChanges) { + if ("textDocument" in docChange) { + for (const edit of docChange.edits) { + if ("snippet" in edit) { + documentUris.push(Uri.parse(docChange.textDocument.uri).toString()); + const snippetValue = (edit as any).snippet.value; + const snippet = new SnippetTextEdit( + client.protocol2CodeConverter.asRange((edit as any).range), + new SnippetString(escapeSnippetLiterals(snippetValue)) + ); + if (semver.gte(version, '1.98.0')) { + snippet["keepWhitespace"] = true; } + snippetEdits.push(snippet); } } - const codeActionContext: CodeActionContext = { - diagnostics: allDiagnostics, - only: context.only, - triggerKind: context.triggerKind, - }; - params.context = await client.code2ProtocolConverter.asCodeActionContext(codeActionContext); } } - return client.sendRequest(CodeActionRequest.type, params, token).then(async (values) => { - if (values === null) { - return undefined; - } - const result = []; - for (const item of values) { - if (Command.is(item)) { - result.push(client.protocol2CodeConverter.asCommand(item)); - } - else { - result.push(await client.protocol2CodeConverter.asCodeAction(item)); - } - } - return result; - }, (error) => { - return client.handleFailedRequest(CodeActionRequest.type, token, error, []); - }); - }, - - resolveCodeAction: async (item, token, next) => { - const client: LanguageClient = standardClient.getClient(); - const documentUris = []; - const snippetEdits = []; - return client.sendRequest(CodeActionResolveRequest.type, client.code2ProtocolConverter.asCodeActionSync(item), token).then(async (result) => { - if (token.isCancellationRequested) { - return item; - } - const docChanges = result.edit !== undefined ? result.edit.documentChanges : undefined; - if (docChanges !== undefined) { - for (const docChange of docChanges) { - if ("textDocument" in docChange) { - for (const edit of docChange.edits) { - if ("snippet" in edit) { - documentUris.push(Uri.parse(docChange.textDocument.uri).toString()); - const snippetValue = (edit as any).snippet.value; - const snippet = new SnippetTextEdit( - client.protocol2CodeConverter.asRange((edit as any).range), - new SnippetString(escapeSnippetLiterals(snippetValue)) - ); - if (semver.gte(version, '1.98.0')) { - snippet["keepWhitespace"] = true; - } - snippetEdits.push(snippet); - } + const codeAction = await client.protocol2CodeConverter.asCodeAction(result, token); + const docEdits = codeAction.edit !== undefined ? codeAction.edit.entries() : []; + for (const docEdit of docEdits) { + const uri = docEdit[0]; + if (documentUris.includes(uri.toString())) { + const editList = []; + for (const edit of docEdit[1]) { + let isSnippet = false; + snippetEdits.forEach((snippet, index) => { + if (edit.range.isEqual(snippet.range) && documentUris[index] === uri.toString()) { + editList.push(snippet); + isSnippet = true; } + }); + if (!isSnippet) { + editList.push(edit); } } - const codeAction = await client.protocol2CodeConverter.asCodeAction(result, token); - const docEdits = codeAction.edit !== undefined? codeAction.edit.entries() : []; - for (const docEdit of docEdits) { - const uri = docEdit[0]; - if (documentUris.includes(uri.toString())) { - const editList = []; - for (const edit of docEdit[1]) { - let isSnippet = false; - snippetEdits.forEach((snippet, index) => { - if (edit.range.isEqual(snippet.range) && documentUris[index] === uri.toString()) { - editList.push(snippet); - isSnippet = true; - } - }); - if (!isSnippet) { - editList.push(edit); - } - } - codeAction.edit.set(uri, null); - codeAction.edit.set(uri, editList); - } - } - return codeAction; + codeAction.edit.set(uri, null); + codeAction.edit.set(uri, editList); } - return await client.protocol2CodeConverter.asCodeAction(result, token); - }, (error) => { - return client.handleFailedRequest(CodeActionResolveRequest.type, token, error, item); - }); - }, - - provideReferences: async(document, position, options, token, next): Promise => { - // Override includeDeclaration from VS Code by allowing it to be configured - options.includeDeclaration = getJavaConfiguration().get('references.includeDeclarations'); - return await next(document, position, options, token); - } - }, - revealOutputChannelOn: RevealOutputChannelOn.Never, - errorHandler: new ClientErrorHandler(extensionName), - initializationFailedHandler: error => { - logger.error(`Failed to initialize ${extensionName} due to ${error && error.toString()}`); - if ((error.toString().includes('Connection') && error.toString().includes('disposed')) || error.toString().includes('Internal error')) { - if (!initFailureReported) { - apiManager.fireTraceEvent({ - name: "java.client.error.initialization", - properties: { - message: error && error.toString(), - data: resolveActualCause(error?.data), - }, - }); } - initFailureReported = true; - return false; - } else { - return true; + return codeAction; } - }, - outputChannel: requireStandardServer ? new OutputInfoCollector(extensionName) : undefined, - outputChannelName: extensionName - }; - - apiManager.initialize(requirements, serverMode); - registerCodeCompletionTelemetryListener(); - resolve(apiManager.getApiInstance()); - // the promise is resolved - // no need to pass `resolve` into any code past this point, - // since `resolve` is a no-op from now on - if (requireSyntaxServer) { - const serverOptions = prepareExecutable(requirements, syntaxServerWorkspacePath, context, true); - excutable.resolve(serverOptions); - if (process.env['SYNTAXLS_CLIENT_PORT']) { - syntaxClient.initialize(requirements, clientOptions); - } else { - syntaxClient.initialize(requirements, clientOptions, serverOptions); - } - syntaxClient.start().then(() => { - syntaxClient.registerSyntaxClientActions(serverOptions); + return await client.protocol2CodeConverter.asCodeAction(result, token); + }, (error) => { + return client.handleFailedRequest(CodeActionResolveRequest.type, token, error, item); }); - serverStatusBarProvider.showLightWeightStatus(); - } + }, - context.subscriptions.push(commands.registerCommand(Commands.EXECUTE_WORKSPACE_COMMAND, (command, ...rest) => { - const api: ExtensionAPI = apiManager.getApiInstance(); - if (api.serverMode === ServerMode.lightWeight) { - console.warn(`The command: ${command} is not supported in LightWeight mode. See: https://github.com/redhat-developer/vscode-java/issues/1480`); - return; - } - let token: CancellationToken; - let commandArgs: any[] = rest; - if (rest && rest.length && CancellationToken.is(rest[rest.length - 1])) { - token = rest[rest.length - 1]; - commandArgs = rest.slice(0, rest.length - 1); - } - const params: ExecuteCommandParams = { - command, - arguments: commandArgs - }; - if (token) { - return standardClient.getClient().sendRequest(ExecuteCommandRequest.type, params, token); - } else { - return standardClient.getClient().sendRequest(ExecuteCommandRequest.type, params); - } - })); - - if (cleanWorkspaceExists) { - const data = {}; - try { - cleanupLombokCache(context); - cleanupWorkspaceState(context); - deleteDirectory(workspacePath); - deleteDirectory(syntaxServerWorkspacePath); - cleanJavaLSConfiguration(context); - } catch (error) { - data['error'] = getMessage(error); - window.showErrorMessage(`Failed to delete ${workspacePath}: ${error}`); + provideReferences: async (document, position, options, token, next): Promise => { + // Override includeDeclaration from VS Code by allowing it to be configured + options.includeDeclaration = getJavaConfiguration().get('references.includeDeclarations'); + return await next(document, position, options, token); + } + }, + revealOutputChannelOn: RevealOutputChannelOn.Never, + errorHandler: new ClientErrorHandler(extensionName), + initializationFailedHandler: error => { + logger.error(`Failed to initialize ${extensionName} due to ${error && error.toString()}`); + if ((error.toString().includes('Connection') && error.toString().includes('disposed')) || error.toString().includes('Internal error')) { + if (!initFailureReported) { + apiManager.fireTraceEvent({ + name: "java.client.error.initialization", + properties: { + message: error && error.toString(), + data: resolveActualCause(error?.data), + }, + }); } - await Telemetry.sendTelemetry(Commands.CLEAN_WORKSPACE, data); + initFailureReported = true; + return false; + } else { + return true; } + }, + outputChannel: requireStandardServer ? new OutputInfoCollector(extensionName) : undefined, + outputChannelName: extensionName + }; - // Register commands here to make it available even when the language client fails - context.subscriptions.push(commands.registerCommand(Commands.OPEN_STATUS_SHORTCUT, async (status: string) => { - const items: ShortcutQuickPickItem[] = []; - if (status === ServerStatusKind.error || status === ServerStatusKind.warning) { - commands.executeCommand("workbench.panel.markers.view.focus"); - } else { - commands.executeCommand(Commands.SHOW_SERVER_TASK_STATUS, true); - } + apiManager.initialize(requirementsData, serverMode); + registerCodeCompletionTelemetryListener(); + void postExtensionStartInit( + context, + requirementsData, + clientOptions, + workspacePath, + syntaxServerWorkspacePath, + serverMode, + requireSyntaxServer, + requireStandardServer, + cleanWorkspaceExists + ); + + return apiManager.getApiInstance(); +} - items.push(...getShortcuts().map((shortcut: IJavaShortcut) => { - return { - label: shortcut.title, - command: shortcut.command, - args: shortcut.arguments, - }; - })); - - const choice = await window.showQuickPick(items); - if (!choice) { - return; - } +async function getStandardLanguageClient(): Promise { + try { + if (standardServerStart) { + return await standardServerStart; + } + } catch (error) { + logger.error(`Failed to initialize the Java language client: ${getMessage(error)}`); + } + return standardClient.getClient(); +} - apiManager.fireTraceEvent({ - name: "triggerShortcutCommand", - properties: { - message: choice.command, - }, - }); +async function postExtensionStartInit( + context: ExtensionContext, + requirements: requirements.RequirementsData, + clientOptions: LanguageClientOptions, + workspacePath: string, + syntaxServerWorkspacePath: string, + serverMode: ServerMode, + requireSyntaxServer: boolean, + requireStandardServer: boolean, + cleanWorkspaceExists: boolean +): Promise { + if (requireSyntaxServer) { + const serverOptions = prepareExecutable(requirements, syntaxServerWorkspacePath, context, true); + excutable.resolve(serverOptions); + if (process.env['SYNTAXLS_CLIENT_PORT']) { + syntaxClient.initialize(requirements, clientOptions); + } else { + syntaxClient.initialize(requirements, clientOptions, serverOptions); + } + syntaxClient.start().then(() => { + syntaxClient.registerSyntaxClientActions(serverOptions); + }); + serverStatusBarProvider.showLightWeightStatus(); + } - if (choice.command) { - commands.executeCommand(choice.command, ...(choice.args || [])); - } - })); - context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_LOG, (column: ViewColumn) => openServerLogFile(storagePath, column))); - context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_STDOUT_LOG, (column: ViewColumn) => openRollingServerLogFile(storagePath, '.out-jdt.ls', column))); - context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_STDERR_LOG, (column: ViewColumn) => openRollingServerLogFile(storagePath, '.error-jdt.ls', column))); - - context.subscriptions.push(commands.registerCommand(Commands.OPEN_CLIENT_LOG, (column: ViewColumn) => openClientLogFile(clientLogFile, column))); - - context.subscriptions.push(commands.registerCommand(Commands.OPEN_LOGS, () => openLogs())); - - context.subscriptions.push(commands.registerCommand(Commands.OPEN_FORMATTER, async () => openFormatter(context.extensionPath))); - context.subscriptions.push(commands.registerCommand(Commands.OPEN_FILE, async (uri: string) => { - const parsedUri = Uri.parse(uri); - const editor = await window.showTextDocument(parsedUri); - // Reveal the document at the specified line, if possible (e.g. jumping to a specific javadoc method). - if (editor && parsedUri.scheme === 'jdt' && parsedUri.fragment) { - const line = parseInt(parsedUri.fragment); - if (isNaN(line) || line < 1 || line > editor.document.lineCount) { - return; - } - const range = editor.document.lineAt(line -1).range; - editor.revealRange(range, TextEditorRevealType.AtTop); - } - })); + apiManager.getApiInstance().onDidServerModeChange((event: ServerMode) => { + if (event === ServerMode.standard) { + syntaxClient.stop(); + fileEventHandler.setServerStatus(true); + languageStatusBarProvider.initialize(context); + } + commands.executeCommand('setContext', 'java:serverMode', event); + }); - context.subscriptions.push(commands.registerCommand(Commands.CLEAN_WORKSPACE, (force?: boolean) => cleanWorkspace(workspacePath, force))); - context.subscriptions.push(commands.registerCommand(Commands.CLEAN_SHARED_INDEXES, () => cleanSharedIndexes(context))); + if (cleanWorkspaceExists) { + const data = {}; + try { + cleanupLombokCache(context); + cleanupWorkspaceState(context); + deleteDirectory(workspacePath); + deleteDirectory(syntaxServerWorkspacePath); + cleanJavaLSConfiguration(context); + } catch (error) { + data['error'] = getMessage(error); + window.showErrorMessage(`Failed to delete ${workspacePath}: ${error}`); + } + await Telemetry.sendTelemetry(Commands.CLEAN_WORKSPACE, data); + } - context.subscriptions.push(commands.registerCommand(Commands.GET_WORKSPACE_PATH, () => workspacePath)); + if (serverMode === ServerMode.hybrid && !await fse.pathExists(path.join(workspacePath, ".metadata", ".plugins"))) { + const config = getJavaConfiguration(); + const importOnStartupSection: string = "project.importOnFirstTimeStartup"; + const importOnStartup = config.get(importOnStartupSection); + if (importOnStartup === "disabled" || + env.uiKind === UIKind.Web && env.appName.includes("Visual Studio Code")) { + apiManager.getApiInstance().serverMode = ServerMode.lightWeight; + apiManager.fireDidServerModeChange(ServerMode.lightWeight); + requireStandardServer = false; + } else if (importOnStartup === "interactive" && await workspaceContainsBuildFiles()) { + apiManager.getApiInstance().serverMode = ServerMode.lightWeight; + apiManager.fireDidServerModeChange(ServerMode.lightWeight); + requireStandardServer = await promptUserForStandardServer(config); + } else { + requireStandardServer = true; + } + } - context.subscriptions.push(commands.registerCommand(Commands.REFRESH_BUNDLES_COMMAND, () => { - return getBundlesToReload(); - })); + if (requireStandardServer) { + void startStandardServer(context, requirements, clientOptions, workspacePath); + } - context.subscriptions.push(onConfigurationChange(workspacePath, context)); + context.subscriptions.push(commands.registerCommand(Commands.EXECUTE_WORKSPACE_COMMAND, async (command, ...rest) => { + const api: ExtensionAPI = apiManager.getApiInstance(); + if (api.serverMode === ServerMode.lightWeight) { + console.warn(`The command: ${command} is not supported in LightWeight mode. See: https://github.com/redhat-developer/vscode-java/issues/1480`); + return; + } + let token: CancellationToken; + let commandArgs: any[] = rest; + if (rest && rest.length && CancellationToken.is(rest[rest.length - 1])) { + token = rest[rest.length - 1]; + commandArgs = rest.slice(0, rest.length - 1); + } + const params: ExecuteCommandParams = { + command, + arguments: commandArgs + }; + const client: LanguageClient | undefined = await getStandardLanguageClient(); + if (!client) { + console.warn(`Cannot execute Java workspace command '${command}' because the Java language client is not initialized`); + return; + } + if (token) { + return client.sendRequest(ExecuteCommandRequest.type, params, token); + } else { + return client.sendRequest(ExecuteCommandRequest.type, params); + } + })); - context.subscriptions.push(commands.registerCommand(Commands.GET_VISIBLE_EDITOR_CONTENT, (uri: string) => { - for (const editor of window.visibleTextEditors) { - if (editor.document.uri.toString() === uri) { - return editor.document.getText(); - } - } - const editor = window.activeTextEditor; - if (editor) { - return editor.document.getText(); - } else { - return null; - } - })); - - registerRestartJavaLanguageServerCommand(context); - - /** - * Command to switch the server mode. Currently it only supports switch from lightweight to standard. - * @param force force to switch server mode without asking - */ - commands.registerCommand(Commands.SWITCH_SERVER_MODE, async (switchTo: ServerMode, force: boolean = false) => { - const isWorkspaceTrusted = (workspace as any).isTrusted; - if (isWorkspaceTrusted !== undefined && !isWorkspaceTrusted) { // keep compatibility for old engines < 1.56.0 - const button = "Manage Workspace Trust"; - const choice = await window.showInformationMessage("For security concern, Java language server cannot be switched to Standard mode in untrusted workspaces.", button); - if (choice === button) { - commands.executeCommand("workbench.trust.manage"); - } - return; - } + context.subscriptions.push(commands.registerCommand(Commands.OPEN_STATUS_SHORTCUT, async (status: string) => { + const items: ShortcutQuickPickItem[] = []; + if (status === ServerStatusKind.error || status === ServerStatusKind.warning) { + commands.executeCommand("workbench.panel.markers.view.focus"); + } else { + commands.executeCommand(Commands.SHOW_SERVER_TASK_STATUS, true); + } - const clientStatus: ClientStatus = standardClient.getClientStatus(); - if (clientStatus === ClientStatus.starting || clientStatus === ClientStatus.started) { - return; - } + items.push(...getShortcuts().map((shortcut: IJavaShortcut) => { + return { + label: shortcut.title, + command: shortcut.command, + args: shortcut.arguments, + }; + })); - const api: ExtensionAPI = apiManager.getApiInstance(); - if (!force && (api.serverMode === switchTo || api.serverMode === ServerMode.standard)) { - return; - } + const choice = await window.showQuickPick(items); + if (!choice) { + return; + } - let choice: string; - if (force) { - choice = "Yes"; - } else { - choice = await window.showInformationMessage("Are you sure you want to switch the Java language server to Standard mode?", "Yes", "No"); - } + apiManager.fireTraceEvent({ + name: "triggerShortcutCommand", + properties: { + message: choice.command, + }, + }); - if (choice === "Yes") { - await startStandardServer(context, requirements, clientOptions, workspacePath, true /* triggeredByCommand */); - } - }); + if (choice.command) { + commands.executeCommand(choice.command, ...(choice.args || [])); + } + })); + context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_LOG, (column: ViewColumn) => openServerLogFile(storagePath, column))); + context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_STDOUT_LOG, (column: ViewColumn) => openRollingServerLogFile(storagePath, '.out-jdt.ls', column))); + context.subscriptions.push(commands.registerCommand(Commands.OPEN_SERVER_STDERR_LOG, (column: ViewColumn) => openRollingServerLogFile(storagePath, '.error-jdt.ls', column))); + + context.subscriptions.push(commands.registerCommand(Commands.OPEN_CLIENT_LOG, (column: ViewColumn) => openClientLogFile(clientLogFile, column))); + + context.subscriptions.push(commands.registerCommand(Commands.OPEN_LOGS, () => openLogs())); + + context.subscriptions.push(commands.registerCommand(Commands.OPEN_FORMATTER, async () => openFormatter(context.extensionPath))); + context.subscriptions.push(commands.registerCommand(Commands.OPEN_FILE, async (uri: string) => { + const parsedUri = Uri.parse(uri); + const editor = await window.showTextDocument(parsedUri); + // Reveal the document at the specified line, if possible (e.g. jumping to a specific javadoc method). + if (editor && parsedUri.scheme === 'jdt' && parsedUri.fragment) { + const line = parseInt(parsedUri.fragment); + if (isNaN(line) || line < 1 || line > editor.document.lineCount) { + return; + } + const range = editor.document.lineAt(line - 1).range; + editor.revealRange(range, TextEditorRevealType.AtTop); + } + })); - context.subscriptions.push(commands.registerCommand(Commands.CHANGE_JAVA_SEARCH_SCOPE, async () => { - const selection = await window.showQuickPick(["all", "main"], { - canPickMany: false, - placeHolder: `Current: ${workspace.getConfiguration().get("java.search.scope")}`, - }); - if(selection) { - workspace.getConfiguration().update("java.search.scope", selection, false); - } - })); + context.subscriptions.push(commands.registerCommand(Commands.CLEAN_WORKSPACE, (force?: boolean) => cleanWorkspace(workspacePath, force))); + context.subscriptions.push(commands.registerCommand(Commands.CLEAN_SHARED_INDEXES, () => cleanSharedIndexes(context))); - context.subscriptions.push(snippetCompletionProvider.initialize()); - context.subscriptions.push(serverStatusBarProvider); - context.subscriptions.push(languageStatusBarProvider); + context.subscriptions.push(commands.registerCommand(Commands.GET_WORKSPACE_PATH, () => workspacePath)); - const classEditorProviderRegistration = window.registerCustomEditorProvider(JavaClassEditorProvider.viewType, new JavaClassEditorProvider(context)); - context.subscriptions.push(classEditorProviderRegistration); + context.subscriptions.push(commands.registerCommand(Commands.REFRESH_BUNDLES_COMMAND, () => { + return getBundlesToReload(); + })); - registerClientProviders(context, { contentProviderEvent: jdtEventEmitter.event }); + context.subscriptions.push(onConfigurationChange(workspacePath, context)); - apiManager.getApiInstance().onDidServerModeChange((event: ServerMode) => { - if (event === ServerMode.standard) { - syntaxClient.stop(); - fileEventHandler.setServerStatus(true); - languageStatusBarProvider.initialize(context); - } - commands.executeCommand('setContext', 'java:serverMode', event); - }); + context.subscriptions.push(commands.registerCommand(Commands.GET_VISIBLE_EDITOR_CONTENT, (uri: string) => { + for (const editor of window.visibleTextEditors) { + if (editor.document.uri.toString() === uri) { + return editor.document.getText(); + } + } + const editor = window.activeTextEditor; + if (editor) { + return editor.document.getText(); + } else { + return null; + } + })); - if (serverMode === ServerMode.hybrid && !await fse.pathExists(path.join(workspacePath, ".metadata", ".plugins"))) { - const config = getJavaConfiguration(); - const importOnStartupSection: string = "project.importOnFirstTimeStartup"; - const importOnStartup = config.get(importOnStartupSection); - if (importOnStartup === "disabled" || - env.uiKind === UIKind.Web && env.appName.includes("Visual Studio Code")) { - apiManager.getApiInstance().serverMode = ServerMode.lightWeight; - apiManager.fireDidServerModeChange(ServerMode.lightWeight); - requireStandardServer = false; - } else if (importOnStartup === "interactive" && await workspaceContainsBuildFiles()) { - apiManager.getApiInstance().serverMode = ServerMode.lightWeight; - apiManager.fireDidServerModeChange(ServerMode.lightWeight); - requireStandardServer = await promptUserForStandardServer(config); - } else { - requireStandardServer = true; - } + context.subscriptions.push(commands.registerCommand(Commands.COPY_FULLY_QUALIFIED_NAME, async () => { + const editor = window.activeTextEditor; + if (!editor || editor.document.languageId !== 'java') { + return; + } + + const params = { + textDocument: { + uri: editor.document.uri.toString() + }, + position: { + line: editor.selection.active.line, + character: editor.selection.active.character } + }; - if (requireStandardServer) { - await startStandardServer(context, requirements, clientOptions, workspacePath); + const fullyQualifiedName = await commands.executeCommand( + Commands.EXECUTE_WORKSPACE_COMMAND, + Commands.GET_FULLY_QUALIFIED_NAME, + JSON.stringify(params) + ); + + if (fullyQualifiedName) { + await env.clipboard.writeText(fullyQualifiedName); + } + })); + registerRestartJavaLanguageServerCommand(context); + + /** + * Command to switch the server mode. Currently it only supports switch from lightweight to standard. + * @param force force to switch server mode without asking + */ + commands.registerCommand(Commands.SWITCH_SERVER_MODE, async (switchTo: ServerMode, force: boolean = false) => { + const isWorkspaceTrusted = (workspace as any).isTrusted; + if (isWorkspaceTrusted !== undefined && !isWorkspaceTrusted) { // keep compatibility for old engines < 1.56.0 + const button = "Manage Workspace Trust"; + const choice = await window.showInformationMessage("For security concern, Java language server cannot be switched to Standard mode in untrusted workspaces.", button); + if (choice === button) { + commands.executeCommand("workbench.trust.manage"); } + return; + } - const onDidGrantWorkspaceTrust = (workspace as any).onDidGrantWorkspaceTrust; - if (onDidGrantWorkspaceTrust !== undefined) { // keep compatibility for old engines < 1.56.0 - context.subscriptions.push(onDidGrantWorkspaceTrust(() => { - if (getJavaServerMode() !== ServerMode.lightWeight) { - // See the issue https://github.com/redhat-developer/vscode-java/issues/1994 - // Need to recollect the Java bundles before starting standard mode. - let pollingCount: number = 0; - // Poll every ~100ms (timeout after 1s) and check whether contributing javaExtensions have changed. - const intervalId = setInterval(() => { - const existingJavaExtensions = clientOptions.initializationOptions.bundles; - clientOptions.initializationOptions.bundles = collectJavaExtensions(extensions.all); - if (++pollingCount >= 10 || isContributedPartUpdated(existingJavaExtensions, clientOptions.initializationOptions.bundles)) { - clearInterval(intervalId); - commands.executeCommand(Commands.SWITCH_SERVER_MODE, ServerMode.standard, true); - return; - } - }, 100); + const clientStatus: ClientStatus = standardClient.getClientStatus(); + if (clientStatus === ClientStatus.starting || clientStatus === ClientStatus.started) { + return; + } + + const api: ExtensionAPI = apiManager.getApiInstance(); + if (!force && (api.serverMode === switchTo || api.serverMode === ServerMode.standard)) { + return; + } + + let choice: string; + if (force) { + choice = "Yes"; + } else { + choice = await window.showInformationMessage("Are you sure you want to switch the Java language server to Standard mode?", "Yes", "No"); + } + + if (choice === "Yes") { + await startStandardServer(context, requirements, clientOptions, workspacePath, true /* triggeredByCommand */); + } + }); + + context.subscriptions.push(commands.registerCommand(Commands.CHANGE_JAVA_SEARCH_SCOPE, async () => { + const selection = await window.showQuickPick(["all", "main", "projectOnly"], { + canPickMany: false, + placeHolder: `Current: ${workspace.getConfiguration().get("java.search.scope")}`, + }); + if (selection) { + workspace.getConfiguration().update("java.search.scope", selection, false); + } + })); + + context.subscriptions.push(snippetCompletionProvider.initialize()); + context.subscriptions.push(serverStatusBarProvider); + context.subscriptions.push(languageStatusBarProvider); + + const classEditorProviderRegistration = window.registerCustomEditorProvider(JavaClassEditorProvider.viewType, new JavaClassEditorProvider(context)); + context.subscriptions.push(classEditorProviderRegistration); + + registerClientProviders(context, { contentProviderEvent: jdtEventEmitter.event }); + + const onDidGrantWorkspaceTrust = (workspace as any).onDidGrantWorkspaceTrust; + if (onDidGrantWorkspaceTrust !== undefined) { // keep compatibility for old engines < 1.56.0 + context.subscriptions.push(onDidGrantWorkspaceTrust(() => { + if (getJavaServerMode() !== ServerMode.lightWeight) { + // See the issue https://github.com/redhat-developer/vscode-java/issues/1994 + // Need to recollect the Java bundles before starting standard mode. + let pollingCount: number = 0; + // Poll every ~100ms (timeout after 1s) and check whether contributing javaExtensions have changed. + const intervalId = setInterval(() => { + const existingJavaExtensions = clientOptions.initializationOptions.bundles; + clientOptions.initializationOptions.bundles = collectJavaExtensions(extensions.all); + if (++pollingCount >= 10 || isContributedPartUpdated(existingJavaExtensions, clientOptions.initializationOptions.bundles)) { + clearInterval(intervalId); + commands.executeCommand(Commands.SWITCH_SERVER_MODE, ServerMode.standard, true); + return; } - })); + }, 100); } - context.subscriptions.push(workspace.onDidChangeTextDocument(event => handleTextDocumentChanges(event.document, event.contentChanges))); - }); - }); + })); + } + context.subscriptions.push(workspace.onDidChangeTextDocument(event => handleTextDocumentChanges(event.document, event.contentChanges))); } - -async function startStandardServer(context: ExtensionContext, requirements: requirements.RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, triggeredByCommand: boolean = false) { +async function startStandardServer( + context: ExtensionContext, + requirements: requirements.RequirementsData, + clientOptions: LanguageClientOptions, + workspacePath: string, + triggeredByCommand: boolean = false +): Promise { + if (standardServerStart) { + const client = await standardServerStart; + if (client || !triggeredByCommand) { + return client; + } + } if (standardClient.getClientStatus() !== ClientStatus.uninitialized) { - return; + return standardClient.getClient(); } + standardServerStart = doStartStandardServer(context, requirements, clientOptions, workspacePath, triggeredByCommand).finally(() => { + standardServerStart = undefined; + }); + return standardServerStart; +} +async function doStartStandardServer(context: ExtensionContext, requirements: requirements.RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, triggeredByCommand: boolean = false): Promise { const selector: BuildFileSelector = new BuildFileSelector(context, []); const importMode: ImportMode = await getImportMode(context, selector); if (importMode === ImportMode.automatic) { if (!await ensureNoBuildToolConflicts(context, clientOptions)) { - return; + return undefined; } } else { const buildFiles: string[] = []; @@ -696,7 +784,7 @@ async function startStandardServer(context: ExtensionContext, requirements: requ if (buildFiles.length === 0) { commands.executeCommand('setContext', 'java:serverMode', ServerMode.lightWeight); serverStatusBarProvider.showNotImportedStatus(); - return; + return undefined; } clientOptions.initializationOptions.projectConfigurations = buildFiles; } @@ -711,6 +799,7 @@ async function startStandardServer(context: ExtensionContext, requirements: requ standardClient.registerLanguageClientActions(context, await fse.pathExists(path.join(workspacePath, ".metadata", ".plugins")), jdtEventEmitter); }); serverStatusBarProvider.setBusy("Activating..."); + return standardClient.getClient(); } async function workspaceContainsBuildFiles(): Promise { @@ -1272,8 +1361,8 @@ function registerRestartJavaLanguageServerCommand(context: ExtensionContext) { })); } -function escapeSnippetLiterals(value: string): string { +export function escapeSnippetLiterals(value: string): string { return value - .replace(/\\/g, '\\\\') // Escape backslashes + .replace(/\\(?!,)/g, '\\\\') // Escape backslashes, but preserve escaped commas .replace(/\$(?!\{)/g, '\\$'); // Escape $ only if NOT followed by { } diff --git a/src/fileEventHandler.ts b/src/fileEventHandler.ts index 03e950b5a..2fa9a35cf 100644 --- a/src/fileEventHandler.ts +++ b/src/fileEventHandler.ts @@ -13,6 +13,7 @@ import * as stringInterpolate from 'fmtr'; import { apiManager } from './apiManager'; let serverReady: boolean = false; +type LanguageClientProvider = LanguageClient | (() => LanguageClient); const BRACE_POSITION_KEY = "org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"; const END_OF_LINE = "end_of_line"; @@ -24,7 +25,7 @@ export function setServerStatus(ready: boolean) { serverReady = ready; } -export function registerFileEventHandlers(client: LanguageClient, context: ExtensionContext) { +export function registerFileEventHandlers(client: LanguageClientProvider, context: ExtensionContext) { if (workspace.onDidCreateFiles) {// Theia doesn't support workspace.onDidCreateFiles yet context.subscriptions.push(workspace.onDidCreateFiles(handleNewJavaFiles)); } @@ -144,12 +145,14 @@ async function handleNewJavaFiles(e: FileCreateEvent) { } } let declaration: string; + const preferPackagePrivate = getJavaConfiguration().get("templates.preferPackagePrivateVisibility", false); + const visibilityPrefix = preferPackagePrivate ? "" : "public "; if (isModuleInfo) { declaration = `module \${1:name}`; } else if (!serverReady || await isVersionLessThan(emptyFiles[i].toString(), 14)) { - declaration = `public \${1|class,interface,enum,abstract class,@interface|} ${typeName}`; + declaration = `${visibilityPrefix}\${1|class,interface,enum,abstract class,@interface|} ${typeName}`; } else { - declaration = `public \${1|class ${typeName},interface ${typeName},enum ${typeName},record ${typeName}(),abstract class ${typeName},@interface ${typeName}|}`; + declaration = `${visibilityPrefix}\${1|class ${typeName},interface ${typeName},enum ${typeName},record ${typeName}(),abstract class ${typeName},@interface ${typeName}|}`; } let bracePosition = projectSetting[BRACE_POSITION_KEY]; if (bracePosition !== END_OF_LINE && bracePosition !== NEXT_LINE && bracePosition !== NEXT_LINE_SHIFTED) { @@ -188,7 +191,11 @@ async function handleNewJavaFiles(e: FileCreateEvent) { }, 100); } -function getWillRenameHandler(client: LanguageClient) { +function getLanguageClient(client: LanguageClientProvider): LanguageClient { + return typeof client === 'function' ? client() : client; +} + +function getWillRenameHandler(client: LanguageClientProvider) { return function handleWillRenameFiles(e: FileWillRenameEvent): void { if (!serverReady) { return; @@ -213,10 +220,11 @@ function getWillRenameHandler(client: LanguageClient) { return; } - const edit = await client.sendRequest(WillRenameFiles.type, { + const languageClient = getLanguageClient(client); + const edit = await languageClient.sendRequest(WillRenameFiles.type, { files: javaRenameEvents }); - resolve(await client.protocol2CodeConverter.asWorkspaceEdit(edit)); + resolve(await languageClient.protocol2CodeConverter.asWorkspaceEdit(edit)); } catch (ex) { reject(ex); } diff --git a/src/hoverAction.ts b/src/hoverAction.ts index f4e91f4d0..760013524 100644 --- a/src/hoverAction.ts +++ b/src/hoverAction.ts @@ -74,7 +74,7 @@ class JavaHoverProvider implements HoverProvider { } const contributed = new MarkdownString(contributedCommands.map((command) => this.convertCommandToMarkdown(command)).join(' | ')); - contributed.isTrusted = true; + contributed.isTrusted = { enabledCommands: contributedCommands.map((command) => command.command) }; let contents: MarkdownString[] = [ contributed ]; let range; if (serverHover && serverHover.contents) { diff --git a/src/javaServerStarter.ts b/src/javaServerStarter.ts index 5e5cbed6f..9b566f372 100644 --- a/src/javaServerStarter.ts +++ b/src/javaServerStarter.ts @@ -42,7 +42,7 @@ const SHARED_ARCHIVE_FILE_LOC= '-XX:SharedArchiveFile='; export function prepareExecutable(requirements: RequirementsData, workspacePath, context: ExtensionContext, isSyntaxServer: boolean): Executable { const executable: Executable = Object.create(null); const options: ExecutableOptions = Object.create(null); - options.env = Object.assign({ syntaxserver: isSyntaxServer }, process.env, getVSCodeVariablesMap()); + options.env = Object.assign({ syntaxserver: isSyntaxServer }, process.env, getVSCodeVariablesMap(), getUnicodeLocaleEnv()); if (os.platform() === 'win32') { const vmargs = getJavaConfiguration().get('jdt.ls.vmargs', ''); const watchParentProcess = '-DwatchParentProcess=false'; @@ -73,6 +73,61 @@ export function prepareExecutable(requirements: RequirementsData, workspacePath, logger.info(`Starting Java server with: ${executable.command} ${executable.args?.join(' ')}`); return executable; } + +/** + * Environment variables that select the JVM's file name charset on POSIX systems, in the precedence + * order POSIX defines for the `LC_CTYPE` category. The JVM reads them through `setlocale(LC_ALL, "")` + * followed by `ParseLocale(LC_CTYPE, ...)` in `unix/native/libjava/java_props_md.c`. + */ +export const LOCALE_ENV_VARS: string[] = ['LC_ALL', 'LC_CTYPE', 'LANG']; + +/** Locales under which the JVM falls back to ASCII and cannot represent non-ASCII file names. */ +const ASCII_LOCALES: string[] = ['C', 'POSIX', 'C.ASCII']; + +export const UTF8_LOCALE: string = 'C.UTF-8'; + +/** + * On POSIX systems the JVM decodes and encodes file names with `sun.jnu.encoding`, which it derives + * from the process locale at startup. `-Dsun.jnu.encoding=...` is silently ignored, so neither + * `java.jdt.ls.vmargs` nor `-Dfile.encoding` can influence it. + * + * Containers and services routinely start with an unset or `C`/`POSIX` locale, which makes the JVM + * fall back to ASCII. Every workspace file whose name contains non-ASCII characters is then decoded + * into U+FFFD by `JNU_NewStringPlatform` and can no longer be encoded back by `UnixPath.encode`, + * which throws `InvalidPathException: Malformed input or input contains unmappable characters` and + * aborts the whole workspace initialization. + * See https://github.com/microsoft/vscode-java-dependency/issues/1041 + * + * Only the unset/`C`/`POSIX` cases are overridden, so a deliberately configured non-UTF-8 locale + * (e.g. `zh_CN.GBK`, matching file names actually stored in that encoding) is left untouched. When + * the locale has to be corrected, only the `LC_CTYPE` category is set, so message/number/time + * formatting keeps following the environment. + */ +export function getUnicodeLocaleEnv(): { [key: string]: string } { + // Windows is unaffected and does not read these variables: the JVM derives sun.jnu.encoding from + // GetACP() there, and file names never go through a charset because WinNTFileSystem hands the + // UTF-16 WIN32_FIND_DATAW.cFileName straight to NewString and WindowsPath copies the Java String + // into the native buffer verbatim. Injecting POSIX locale variables would only leak into the + // child processes JDT LS spawns. + if (os.platform() === 'win32') { + return {}; + } + const locale = LOCALE_ENV_VARS.map(name => process.env[name]).find(value => !!value); + if (locale && !ASCII_LOCALES.includes(locale)) { + return {}; + } + logger.info(`Locale '${locale ?? ''}' cannot represent non-ASCII file names, starting JDT LS with ${UTF8_LOCALE}`); + const env: { [key: string]: string } = {}; + if (process.env.LC_ALL) { + // LC_ALL overrides every other category, so it has to be replaced when it is the one selecting ASCII. + env.LC_ALL = UTF8_LOCALE; + } else { + // LC_CTYPE is the only category that selects the charset, so leave the others alone. + env.LC_CTYPE = UTF8_LOCALE; + } + return env; +} + export function awaitServerConnection(port): Thenable { const addr = parseInt(port); return new Promise((res, rej) => { diff --git a/src/protocol.ts b/src/protocol.ts index c31b5a590..6e9f61b9d 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -350,9 +350,10 @@ export interface RenamePosition { } export interface RefactorWorkspaceEdit { - edit: WorkspaceEdit; + edit?: WorkspaceEdit; command?: Command; errorMessage?: string; + confirmationToken?: string; } export interface GetRefactorEditParams { @@ -411,6 +412,7 @@ export interface MoveParams { params: CodeActionParams; destination?: any; updateReferences?: boolean; + confirmationToken?: string; } export interface MoveDestinationsResponse { diff --git a/src/providerDispatcher.ts b/src/providerDispatcher.ts index 3d4e29414..abacbe141 100644 --- a/src/providerDispatcher.ts +++ b/src/providerDispatcher.ts @@ -211,7 +211,13 @@ export function fixJdtSchemeHoverLinks(hover: Hover): Hover { const newContents: (MarkedString | MarkdownString)[] = []; for (const content of hover.contents) { if (content instanceof MarkdownString) { - newContents.push(fixJdtLinksInDocumentation(content)); + // Skip our own trusted contributed commands (e.g. "Go to Super Implementation"); + // only sanitize untrusted server-provided Javadoc. + if (content.isTrusted) { + newContents.push(content); + } else { + newContents.push(fixJdtLinksInDocumentation(content)); + } } else { newContents.push(content); } diff --git a/src/refactorAction.ts b/src/refactorAction.ts index f8b37fb54..b675f6408 100644 --- a/src/refactorAction.ts +++ b/src/refactorAction.ts @@ -6,7 +6,7 @@ import { commands, ExtensionContext, Position, QuickPickItem, TextDocument, Uri, import { FormattingOptions, WorkspaceEdit, RenameFile, DeleteFile, TextDocumentEdit, CodeActionParams, SymbolInformation } from 'vscode-languageclient'; import { LanguageClient } from 'vscode-languageclient/node'; import { Commands as javaCommands } from './commands'; -import { GetRefactorEditRequest, MoveRequest, RefactorWorkspaceEdit, RenamePosition, GetMoveDestinationsRequest, SearchSymbols, SelectionInfo, InferSelectionRequest, GetChangeSignatureInfoRequest, ChangeSignatureInfo } from './protocol'; +import { GetRefactorEditRequest, MoveRequest, RefactorWorkspaceEdit, RenamePosition, GetMoveDestinationsRequest, SearchSymbols, SelectionInfo, InferSelectionRequest, GetChangeSignatureInfoRequest, ChangeSignatureInfo, MoveParams } from './protocol'; import { ChangeSignaturePanel } from './refactoring/changeSignaturePanel'; import { getExtractInterfaceArguments, revealExtractedInterface } from './refactoring/extractInterface'; @@ -252,6 +252,32 @@ async function applyRefactorEdit(languageClient: LanguageClient, refactorEdit: R } } +async function requestMoveWithConfirmation(languageClient: LanguageClient, moveParams: MoveParams): Promise { + let refactorEdit: RefactorWorkspaceEdit = await languageClient.sendRequest(MoveRequest.type, moveParams); + if (!refactorEdit?.confirmationToken) { + await applyRefactorEdit(languageClient, refactorEdit); + return refactorEdit; + } + + const continueAction = 'Continue'; + const detail = 'Review the details below before continuing:\n\n' + refactorEdit.errorMessage; + const selection = await window.showWarningMessage( + 'This refactoring may change program behavior. Continue anyway?', + { modal: true, detail }, + continueAction, + ); + if (selection !== continueAction) { + return undefined; + } + + refactorEdit = await languageClient.sendRequest(MoveRequest.type, { + ...moveParams, + confirmationToken: refactorEdit.confirmationToken, + }); + await applyRefactorEdit(languageClient, refactorEdit); + return refactorEdit; +} + async function moveFile(languageClient: LanguageClient, fileUris: Uri[]) { if (!hasCommonParent(fileUris)) { window.showErrorMessage("Moving files from different directories are not supported. Please make sure they are from the same directory."); @@ -417,13 +443,12 @@ async function moveInstanceMethod(languageClient: LanguageClient, params: CodeAc return; } - const refactorEdit: RefactorWorkspaceEdit = await languageClient.sendRequest(MoveRequest.type, { + await requestMoveWithConfirmation(languageClient, { moveKind: 'moveInstanceMethod', sourceUris: [ params.textDocument.uri ], params, destination: selected.destination, }); - await applyRefactorEdit(languageClient, refactorEdit); } async function moveStaticMember(languageClient: LanguageClient, params: CodeActionParams, commandInfo: any) { diff --git a/src/refactoring/changeSignaturePanel.ts b/src/refactoring/changeSignaturePanel.ts index 5935d9f72..f5f7728a0 100644 --- a/src/refactoring/changeSignaturePanel.ts +++ b/src/refactoring/changeSignaturePanel.ts @@ -116,8 +116,8 @@ export class ChangeSignaturePanel { - - + + Change Signature diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index 7a0aae0eb..8677708fc 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -4,7 +4,7 @@ import * as net from 'net'; import * as path from 'path'; import { CancellationToken, CodeActionKind, commands, ConfigurationTarget, DocumentSelector, EventEmitter, ExtensionContext, extensions, languages, Location, ProgressLocation, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceConfiguration } from "vscode"; import { ConfigurationParams, ConfigurationRequest, LanguageClientOptions, Location as LSLocation, MessageType, Position as LSPosition, TextDocumentPositionParams, WorkspaceEdit, StaticFeature, ClientCapabilities, FeatureState, TelemetryEventNotification } from "vscode-languageclient"; -import { LanguageClient, StreamInfo } from "vscode-languageclient/node"; +import { LanguageClient, ServerOptions, StreamInfo } from "vscode-languageclient/node"; import { apiManager } from "./apiManager"; import * as buildPath from './buildpath'; import { javaRefactorKinds, RefactorDocumentProvider } from "./codeActionProvider"; @@ -42,6 +42,7 @@ import { listJdks, sortJdksBySource, sortJdksByVersion } from './jdkUtils'; import { ClientCodeActionProvider } from './clientCodeActionProvider'; import { BuildFileSelector } from './buildFilesSelector'; import { extendedOutlineQuickPick } from "./outline/extendedOutlineQuickPick"; +import { startWithStdioFallback } from './standardLanguageClientStart'; const extensionName = 'Language Support for Java'; const GRADLE_CHECKSUM = "gradle/checksum/prompt"; @@ -50,6 +51,7 @@ const USE_JAVA = "Use Java "; const AS_GRADLE_JVM = " as Gradle JVM"; const UPGRADE_GRADLE = "Upgrade Gradle to "; const GRADLE_IMPORT_JVM = "java.import.gradle.java.home"; +const PIPE_START_TIMEOUT_MS = 30000; export const JAVA_SELECTOR: DocumentSelector = [ { scheme: "file", language: "java", pattern: "**/*.java" }, { scheme: "jdt", language: "java", pattern: "**/*.class" }, @@ -59,6 +61,8 @@ export const JAVA_SELECTOR: DocumentSelector = [ export class StandardLanguageClient { private languageClient: LanguageClient; + private serverOptions: ServerOptions; + private clientOptions: LanguageClientOptions; private status: ClientStatus = ClientStatus.uninitialized; public async initialize(context: ExtensionContext, requirements: RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, jdtEventEmitter: EventEmitter): Promise { @@ -85,7 +89,7 @@ export class StandardLanguageClient { } }); - let serverOptions; + let serverOptions: ServerOptions; const port = process.env['JDTLS_SERVER_PORT']; if (!port) { const lsPort = process.env['JDTLS_CLIENT_PORT']; @@ -105,22 +109,29 @@ export class StandardLanguageClient { // used during development serverOptions = awaitServerConnection.bind(null, port); } + this.serverOptions = serverOptions; + this.clientOptions = clientOptions; // Create the language client and start the client. - this.languageClient = new TracingLanguageClient('java', extensionName, serverOptions, clientOptions, DEBUG); - this.languageClient.registerFeature(new DisableWillRenameFeature()); + this.languageClient = this.createLanguageClient(serverOptions, clientOptions); this.registerCommandsForStandardServer(context, jdtEventEmitter); - fileEventHandler.registerFileEventHandlers(this.languageClient, context); + fileEventHandler.registerFileEventHandlers(() => this.languageClient, context); collectBuildFilePattern(extensions.all); this.status = ClientStatus.initialized; } + private createLanguageClient(serverOptions: ServerOptions, clientOptions: LanguageClientOptions): LanguageClient { + const languageClient = new TracingLanguageClient('java', extensionName, serverOptions, clientOptions, DEBUG); + languageClient.registerFeature(new DisableWillRenameFeature()); + return languageClient; + } + public registerLanguageClientActions(context: ExtensionContext, hasImported: boolean, jdtEventEmitter: EventEmitter) { activationProgressNotification.showProgress(); - this.languageClient.onNotification(StatusNotification.type, (report) => { + this.languageClient.onNotification(StatusNotification.type, async (report) => { // Resolve serverRunning on the first status notification from the server, // indicating the server process is alive and can accept requests. apiManager.resolveServerRunningPromise(); @@ -149,10 +160,17 @@ export class StandardLanguageClient { apiManager.getApiInstance().onDidClasspathUpdate((projectUri: Uri) => { checkLombokDependency(context, projectUri); }); + apiManager.getApiInstance().onDidProjectsImport(() => { + updateJavaProjectsContext(); + }); + apiManager.getApiInstance().onDidProjectsDelete(() => { + updateJavaProjectsContext(); + }); // Disable the client-side snippet provider since LS is ready. snippetCompletionProvider.dispose(); registerDocumentValidationListener(context, this.languageClient); commands.executeCommand('setContext', 'javaLSReady', true); + updateJavaProjectsContext(); break; case 'Started': this.status = ClientStatus.started; @@ -770,7 +788,16 @@ export class StandardLanguageClient { public start(): Promise { if (this.languageClient && this.status === ClientStatus.initialized) { this.status = ClientStatus.starting; - return this.languageClient.start(); + return startWithStdioFallback({ + languageClient: this.languageClient, + serverOptions: this.serverOptions, + createLanguageClient: (serverOptions) => this.createLanguageClient(serverOptions, this.clientOptions), + pipeStartTimeout: PIPE_START_TIMEOUT_MS, + onFallback: (error) => logger.warn(`Falling back to 'stdio' (from 'pipe') because starting the pipe transport failed: ${error}`), + }).then(result => { + this.languageClient = result.client; + this.serverOptions = result.serverOptions; + }); } } @@ -844,6 +871,15 @@ export class StandardLanguageClient { } } +function updateJavaProjectsContext(): void { + getAllJavaProjects().then((projectUris) => { + const projectPaths = projectUris.map((uriString) => Uri.parse(uriString).fsPath.replace(/[\\/]$/, '')); + commands.executeCommand('setContext', 'java.projects', projectPaths); + }).catch((error) => { + logger.error(error); + }); +} + async function showImportFinishNotification(context: ExtensionContext) { const neverShow: boolean | undefined = context.globalState.get("java.neverShowImportFinishNotification"); if (!neverShow) { diff --git a/src/standardLanguageClientStart.ts b/src/standardLanguageClientStart.ts new file mode 100644 index 000000000..5ba496859 --- /dev/null +++ b/src/standardLanguageClientStart.ts @@ -0,0 +1,66 @@ +import { Executable, ServerOptions, TransportKind } from "vscode-languageclient/node"; + +export interface StartableLanguageClient { + start(): Promise; +} + +export interface StartWithStdioFallbackOptions { + languageClient: T; + serverOptions: ServerOptions; + createLanguageClient(serverOptions: Executable): T; + pipeStartTimeout: number; + onFallback?(error: any): void; +} + +class PipeStartTimeoutError extends Error { +} + +export async function startWithStdioFallback(options: StartWithStdioFallbackOptions): Promise<{ client: T; serverOptions: ServerOptions }> { + if (!isPipeExecutable(options.serverOptions)) { + await options.languageClient.start(); + return { client: options.languageClient, serverOptions: options.serverOptions }; + } + + try { + await startWithTimeout(options.languageClient, options.pipeStartTimeout); + return { client: options.languageClient, serverOptions: options.serverOptions }; + } catch (error) { + if (!(error instanceof PipeStartTimeoutError)) { + throw error; + } + options.onFallback?.(error); + const stdioServerOptions = createStdioServerOptions(options.serverOptions); + const stdioClient = options.createLanguageClient(stdioServerOptions); + await stdioClient.start(); + return { client: stdioClient, serverOptions: stdioServerOptions }; + } +} + +async function startWithTimeout(client: StartableLanguageClient, timeout: number): Promise { + let timeoutHandle: NodeJS.Timeout | undefined; + try { + await Promise.race([ + client.start(), + new Promise((_resolve, reject) => { + timeoutHandle = setTimeout(() => reject(new PipeStartTimeoutError(`Starting pipe transport timed out after ${timeout}ms.`)), timeout); + }) + ]); + } finally { + if (timeoutHandle) { + clearTimeout(timeoutHandle); + } + } +} + +function isPipeExecutable(serverOptions: ServerOptions): serverOptions is Executable { + return !!serverOptions && typeof (serverOptions as Executable).command === 'string' && (serverOptions as Executable).transport === TransportKind.pipe; +} + +function createStdioServerOptions(serverOptions: Executable): Executable { + return { + ...serverOptions, + args: serverOptions.args?.slice(), + options: serverOptions.options ? { ...serverOptions.options } : undefined, + transport: TransportKind.stdio, + }; +} diff --git a/src/webview/changeSignature/App.css b/src/webview/changeSignature/App.css index 2feef25ea..102e8222f 100644 --- a/src/webview/changeSignature/App.css +++ b/src/webview/changeSignature/App.css @@ -4,6 +4,9 @@ main { max-width: 600px; margin-left: auto; margin-right: auto; + color: var(--vscode-foreground); + font-family: var(--vscode-font-family); + font-size: var(--vscode-font-size); } .section { @@ -13,18 +16,18 @@ main { .section-columns { display: flex; width: 100%; - padding-left: calc(var(--design-unit) * 1px); + padding-left: 4px; } .text-title { margin: 0; - height: calc(var(--input-height) * 0.8px); + height: 21px; } .text-title-content { - padding: 0 0 0 calc(var(--design-unit) * 1px); + padding: 0 0 0 4px; margin: 0.5rem 0 0 0; - height: calc(var(--input-height) * 0.8px); + height: 21px; } .header-left { @@ -51,6 +54,91 @@ main { box-sizing: border-box; } +/* Form controls -------------------------------------------------------- */ + +.vsc-textfield, +.vsc-dropdown { + box-sizing: border-box; + width: 100%; + height: 26px; + padding: 2px 6px; + color: var(--vscode-input-foreground); + background-color: var(--vscode-input-background); + border: 1px solid var(--vscode-dropdown-border, var(--vscode-input-border, transparent)); + border-radius: 2px; + font-family: inherit; + font-size: inherit; + outline: none; +} + +.vsc-textfield:focus, +.vsc-dropdown:focus { + border-color: var(--vscode-focusBorder); +} + +.vsc-dropdown { + cursor: pointer; +} + +/* Buttons -------------------------------------------------------------- */ + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + height: 26px; + padding: 0 11px; + border: 1px solid var(--vscode-button-border, transparent); + border-radius: 2px; + font-family: inherit; + font-size: inherit; + cursor: pointer; + outline: none; +} + +.btn:focus-visible { + outline: 1px solid var(--vscode-focusBorder); + outline-offset: 2px; +} + +.btn:disabled { + opacity: 0.4; + cursor: default; +} + +.btn-primary { + color: var(--vscode-button-foreground); + background-color: var(--vscode-button-background); +} + +.btn-primary:hover:not(:disabled) { + background-color: var(--vscode-button-hoverBackground); +} + +.btn-secondary { + color: var(--vscode-button-secondaryForeground); + background-color: var(--vscode-button-secondaryBackground); +} + +.btn-secondary:hover:not(:disabled) { + background-color: var(--vscode-button-secondaryHoverBackground); +} + +.btn-icon { + height: 22px; + width: 22px; + padding: 0; + color: var(--vscode-icon-foreground); + background-color: transparent; + border: none; + border-radius: 4px; +} + +.btn-icon:hover:not(:disabled) { + background-color: var(--vscode-toolbar-hoverBackground); +} + .vsc-button-left { float: left; margin: 0 0.5rem 0.5rem 0; @@ -66,80 +154,150 @@ main { } .bottom-buttons { - padding: 0 0 0 calc(var(--design-unit) * 1px); + padding: 0 0 0 4px; margin: 0.5rem 0 0 0; + overflow: hidden; } .preview { - padding: 0 0 0 calc(var(--design-unit) * 1px); + box-sizing: border-box; margin: 0 0 0.5rem 0; width: 99%; + color: var(--vscode-input-foreground); + background-color: var(--vscode-input-background); + border: 1px solid var(--vscode-input-border, transparent); + border-radius: 2px; + padding: 4px 6px; + font-family: var(--vscode-editor-font-family, monospace); + font-size: inherit; + resize: vertical; + outline: none; +} + +.preview:focus { + border-color: var(--vscode-focusBorder); } +/* Tabs ----------------------------------------------------------------- */ + .parameters-panel { margin: 0; width: calc(99% + 4px); } +.tabs { + display: flex; + border-bottom: 1px solid var(--vscode-panel-border, var(--vscode-editorGroup-border)); +} + +.tab { + padding: 6px 10px; + background-color: transparent; + border: none; + border-bottom: 1px solid transparent; + color: var(--vscode-panelTitle-inactiveForeground, var(--vscode-foreground)); + font-family: inherit; + font-size: inherit; + cursor: pointer; + outline: none; +} + +.tab:hover { + color: var(--vscode-panelTitle-activeForeground, var(--vscode-foreground)); +} + +.tab-active { + color: var(--vscode-panelTitle-activeForeground, var(--vscode-foreground)); + border-bottom-color: var(--vscode-panelTitle-activeBorder, var(--vscode-focusBorder)); +} + +.tab:focus-visible { + outline: 1px solid var(--vscode-focusBorder); + outline-offset: -1px; +} + .parameters-view { - padding: 0 0 0 calc(var(--design-unit) * 1px); + padding: 0 0 0 4px; + display: flex; flex-direction: column; } -.parameter-cell { - padding-left: 0; - pointer-events: none; +.parameters-view[hidden] { + display: none; } -.parameter-cell-title { - padding-left: 0; +/* Table ---------------------------------------------------------------- */ + +.parameter-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; } -.parameter-cell-title:focus { - border-color: var(--vscode-keybindingTable-headerBackground); - background-color: inherit; - color: inherit; +.parameter-table th, +.parameter-table td { + text-align: left; + vertical-align: middle; + padding: 2px 4px; + height: 26px; + box-sizing: border-box; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.parameter-cell-title { + padding-left: 4px; + font-weight: 600; } .parameter-cell-header { background-color: var(--vscode-keybindingTable-headerBackground); } +.parameter-cell { + padding-left: 4px; +} + .parameter-cell-edit { - padding-left: 0; + padding: 0 4px; background-color: var(--vscode-input-background); } -.parameter-cell-edit-button { +.parameter-input { + box-sizing: border-box; + width: 100%; + height: 100%; padding: 0; border: 0; - display: flex; - justify-content: right; - background-color: var(--vscode-input-background); + outline: none; + background-color: transparent; + color: var(--vscode-input-foreground); + font-family: inherit; + font-size: inherit; } +.parameter-cell-edit-button, .parameter-cell-button { padding: 0; border: 0; - display: flex; - justify-content: right; -} - -.parameter-cell-button:focus { - background-color: inherit; + text-align: right; + width: 1%; + white-space: nowrap; } -.parameter-cell-button:active { - background-color: inherit; +.parameter-cell-edit-button { + background-color: var(--vscode-input-background); } .table-buttons { display: inline-flex; + justify-content: flex-end; } .table-buttons-edit { display: inline-flex; - background-color: var(--vscode-editor-background); + justify-content: flex-end; } .table-buttons-edit-ok { @@ -151,7 +309,18 @@ main { margin: 0; } +/* Checkbox ------------------------------------------------------------- */ + .delegate { - padding: 0 0 0 calc(var(--design-unit) * 1px); + display: flex; + align-items: center; + gap: 6px; + padding: 0 0 0 4px; margin: 0.5rem 0 0.5rem 0; + cursor: pointer; +} + +.delegate input[type="checkbox"] { + accent-color: var(--vscode-checkbox-background); + cursor: pointer; } diff --git a/src/webview/changeSignature/App.tsx b/src/webview/changeSignature/App.tsx index 1531efeda..4e33a3e16 100644 --- a/src/webview/changeSignature/App.tsx +++ b/src/webview/changeSignature/App.tsx @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/prefer-for-of */ -import { VSCodeButton, VSCodeTextField, VSCodeDropdown, VSCodeOption, VSCodeCheckbox, VSCodePanels, VSCodePanelTab, VSCodePanelView, VSCodeDataGrid, VSCodeDataGridCell, VSCodeDataGridRow, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"; import "./App.css"; import React from "react"; import { vscode } from "../vscodeApiWrapper"; @@ -8,10 +7,13 @@ import cloneDeep from "lodash/cloneDeep"; type State = UIState & Metadata; +type ActiveTab = "parameters" | "exceptions"; + interface UIState { focusRow: number; editParameterRow: number; editExceptionRow: number; + activeTab: ActiveTab; } interface Metadata { @@ -50,6 +52,7 @@ export class App extends React.Component<{}, State> { focusRow: -1, editParameterRow: -1, editExceptionRow: -1, + activeTab: "parameters", methodIdentifier: undefined, isDelegate: false, methodName: undefined, @@ -91,6 +94,10 @@ export class App extends React.Component<{}, State> { this.setState({ methodName: event.target.value }); + } else if (id === "delegate") { + this.setState({ + isDelegate: event.target.checked + }); } return; }; @@ -121,7 +128,11 @@ export class App extends React.Component<{}, State> { if (!id) { return; } - if (id === "refactor") { + if (id === "tab-parameters") { + this.setState({ activeTab: "parameters", focusRow: -1 }); + } else if (id === "tab-exceptions") { + this.setState({ activeTab: "exceptions", focusRow: -1 }); + } else if (id === "refactor") { this.doRefactor(false); } else if (id === "preview") { this.doRefactor(true); @@ -175,11 +186,13 @@ export class App extends React.Component<{}, State> { editParameterRow: selectedRowNumber, editExceptionRow: -1, focusRow: -1, + }, () => { + const elementToSelect = document.getElementById(`parameterType-${selectedRowNumber}`) as HTMLInputElement | null; + if (elementToSelect) { + elementToSelect.focus(); + elementToSelect.select(); + } }); - const elementToSelect = document.getElementById(`parameterType-${selectedRowNumber}`); - if (elementToSelect) { - elementToSelect.focus(); - } } else if (id.startsWith("editException")) { const selectedRowNumber: number | undefined = this.getSelectedRowNumber(id); if (selectedRowNumber === undefined) { @@ -189,11 +202,13 @@ export class App extends React.Component<{}, State> { editParameterRow: -1, editExceptionRow: selectedRowNumber, focusRow: -1, + }, () => { + const elementToSelect = document.getElementById(`exceptionType-${selectedRowNumber}`) as HTMLInputElement | null; + if (elementToSelect) { + elementToSelect.focus(); + elementToSelect.select(); + } }); - const elementToSelect = document.getElementById(`exceptionType-${selectedRowNumber}`); - if (elementToSelect) { - elementToSelect.focus(); - } } else if (id.startsWith("upParameter")) { const selectedRowNumber: number | undefined = this.getSelectedRowNumber(id); if (selectedRowNumber === undefined) { @@ -244,29 +259,25 @@ export class App extends React.Component<{}, State> { return i !== selectedRowNumber; }) }); - } else if (id === "delegate") { - this.setState({ - isDelegate: event.target.checked - }); } else if (id.startsWith("confirmParameter")) { const selectedRowNumber: number | undefined = this.getSelectedRowNumber(id); if (selectedRowNumber === undefined) { return; } - const parameterType = document.getElementById(`parameterType-${selectedRowNumber}`); - const parameterName = document.getElementById(`parameterName-${selectedRowNumber}`); - const parameterDefault = this.isDefaultValueEditable(selectedRowNumber) ? document.getElementById(`parameterDefault-${selectedRowNumber}`) : undefined; + const parameterType = document.getElementById(`parameterType-${selectedRowNumber}`) as HTMLInputElement | null; + const parameterName = document.getElementById(`parameterName-${selectedRowNumber}`) as HTMLInputElement | null; + const parameterDefault = this.isDefaultValueEditable(selectedRowNumber) ? document.getElementById(`parameterDefault-${selectedRowNumber}`) as HTMLInputElement | null : undefined; this.setState({ parameters: this.state.parameters.map((e, i) => { if (i === selectedRowNumber) { - if (parameterType?.outerText) { - e.type = parameterType.outerText; + if (parameterType?.value) { + e.type = parameterType.value; } - if (parameterName?.outerText) { - e.name = parameterName.outerText; + if (parameterName?.value) { + e.name = parameterName.value; } - if (parameterDefault?.outerText) { - e.defaultValue = parameterDefault.outerText; + if (parameterDefault?.value) { + e.defaultValue = parameterDefault.value; } } return e; @@ -280,20 +291,6 @@ export class App extends React.Component<{}, State> { if (selectedRowNumber === undefined) { return; } - const parameterType = document.getElementById(`parameterType-${selectedRowNumber}`); - if (parameterType) { - parameterType.textContent = this.state.parameters[selectedRowNumber].type; - } - const parameterName = document.getElementById(`parameterName-${selectedRowNumber}`); - if (parameterName) { - parameterName.textContent = this.state.parameters[selectedRowNumber].name; - } - if (this.isDefaultValueEditable(selectedRowNumber)) { - const parameterDefault = document.getElementById(`parameterDefault-${selectedRowNumber}`); - if (parameterDefault) { - parameterDefault.textContent = this.state.parameters[selectedRowNumber].defaultValue; - } - } this.setState({ editParameterRow: -1, editExceptionRow: -1, @@ -304,12 +301,12 @@ export class App extends React.Component<{}, State> { if (selectedRowNumber === undefined) { return; } - const exceptionType = document.getElementById(`exceptionType-${selectedRowNumber}`); + const exceptionType = document.getElementById(`exceptionType-${selectedRowNumber}`) as HTMLInputElement | null; this.setState({ exceptions: this.state.exceptions.map((e, i) => { if (i === selectedRowNumber) { - if (exceptionType?.outerText) { - e.type = exceptionType.outerText; + if (exceptionType?.value) { + e.type = exceptionType.value; } } return e; @@ -323,10 +320,6 @@ export class App extends React.Component<{}, State> { if (selectedRowNumber === undefined) { return; } - const exceptionType = document.getElementById(`exceptionType-${selectedRowNumber}`); - if (exceptionType) { - exceptionType.textContent = this.state.exceptions[selectedRowNumber].type; - } this.setState({ editParameterRow: -1, editExceptionRow: -1, @@ -361,7 +354,9 @@ export class App extends React.Component<{}, State> { }; onMouseEnter = (event: any) => { - const id = event.target.id as string; + const currentTarget = event.currentTarget as HTMLElement | null; + const target = event.target as HTMLElement | null; + const id = currentTarget?.id || target?.id || currentTarget?.closest("tr")?.id || target?.closest("tr")?.id || ""; if (id.includes("Header")) { this.setState({ focusRow: -1 @@ -383,7 +378,6 @@ export class App extends React.Component<{}, State> { }; componentDidMount(): void { - this.setTextAreaCursorStyle(); window.addEventListener("message", this.handleMessage); vscode.postMessage({ command: "webviewReady" @@ -410,19 +404,6 @@ export class App extends React.Component<{}, State> { : o1 === o2; }; - /** - * Set the cursor style of the text area to text. Since the text area is - * inside a shadow DOM, we need to add a style element to the shadow DOM. - */ - setTextAreaCursorStyle(): void { - const host = document.getElementById("textArea"); - if (host?.shadowRoot) { - const style = document.createElement('style'); - style.innerHTML = '.control { cursor: text !important; }'; - host.shadowRoot.appendChild(style); - } - } - isDefaultValueEditable = (row: number) => { return this.state.parameters[row].originalIndex === -1; }; @@ -431,54 +412,69 @@ export class App extends React.Component<{}, State> { return this.isDefaultValueEditable(row) ? this.state.parameters[row].defaultValue : "-"; }; + /** + * Render a table cell whose value can be edited. When editing, a real + * control is rendered so that the typed text is visibly rendered + * and read back reliably via its value (see redhat-developer/vscode-java#4417). + */ + renderEditableCell = (id: string, value: string, editing: boolean, editable: boolean) => { + return + {editable + ? + : {value}} + ; + }; + generateParameterDataGridRow = (row: number) => { - return - {this.state.parameters[row].type} - {this.state.parameters[row].name} - {this.getDefaultValue(row)} - - {row === this.state.editParameterRow ? + const editing = row === this.state.editParameterRow; + return + {this.renderEditableCell(`parameterType-${row}`, this.state.parameters[row].type, editing, editing)} + {this.renderEditableCell(`parameterName-${row}`, this.state.parameters[row].name, editing, editing)} + {this.renderEditableCell(`parameterDefault-${row}`, this.getDefaultValue(row), editing, editing && this.isDefaultValueEditable(row))} + + {editing ?
- OK - Cancel + +
: row === this.state.focusRow ?
- {row === 0 ? <> : - - } - {row === this.state.parameters.length - 1 ? <> : - - } - - - - - - + {row === 0 ? <> : } + {row === this.state.parameters.length - 1 ? <> : } + +
:
} -
-
; + + ; }; generateExceptionDataGridRow = (row: number) => { - return - {this.state.exceptions[row].type} - - {row === this.state.editExceptionRow ? + const editing = row === this.state.editExceptionRow; + return + {this.renderEditableCell(`exceptionType-${row}`, this.state.exceptions[row].type, editing, editing)} + + {editing ?
- OK - Cancel + +
: row === this.state.focusRow ?
- - - - - - + +
:
} -
-
; + + ; }; render = () => { @@ -489,76 +485,89 @@ export class App extends React.Component<{}, State> {
Access modifier:
- - public - protected - package-private - private - +
Return type:
- +
Method name:
- +
- - Parameters - Exceptions - - - - Type - Name - Default value - - - { - (() => { - const options: JSX.Element[] = []; - for (let row = 0; row < this.state.parameters.length; row++) { - options.push(this.generateParameterDataGridRow(row)); - } - return options; - })() - } - +
+
+ + +
+ + +
Method signature:
- - Keep original method as delegate to changed method + +
- Refactor - Preview - Reset + + +
); diff --git a/test/lightweight-mode-suite/extension.test.ts b/test/lightweight-mode-suite/extension.test.ts index 1c3f8e08a..bb65dd02e 100644 --- a/test/lightweight-mode-suite/extension.test.ts +++ b/test/lightweight-mode-suite/extension.test.ts @@ -30,7 +30,8 @@ suite('Java Language Extension - LightWeight', () => { Commands.FILESEXPLORER_ONPASTE, Commands.CHANGE_JAVA_SEARCH_SCOPE, Commands.OPEN_JAVA_DASHBOARD, - Commands.ADD_JAVA_RUNTIME + Commands.ADD_JAVA_RUNTIME, + Commands.COPY_FULLY_QUALIFIED_NAME ].sort(); const foundJavaCommands = commands.filter((value) => { return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.'); diff --git a/test/standard-mode-suite/extension.test.ts b/test/standard-mode-suite/extension.test.ts index a1237467b..aee1a1d02 100644 --- a/test/standard-mode-suite/extension.test.ts +++ b/test/standard-mode-suite/extension.test.ts @@ -7,6 +7,7 @@ import { Commands } from '../../src/commands'; import * as java from '../../src/javaServerStarter'; import * as plugin from '../../src/plugin'; import * as requirements from '../../src/requirements'; +import { escapeSnippetLiterals } from '../../src/extension'; suite('Java Language Extension - Standard', () => { @@ -128,6 +129,9 @@ suite('Java Language Extension - Standard', () => { Commands.FILESEXPLORER_ONPASTE, Commands.RESOLVE_PASTED_TEXT, Commands.CHANGE_JAVA_SEARCH_SCOPE, + Commands.COPY_FULLY_QUALIFIED_NAME, + Commands.GET_FULLY_QUALIFIED_NAME, + Commands.GET_TROUBLESHOOTING_INFO, Commands.OPEN_JAVA_DASHBOARD, Commands.ADD_JAVA_RUNTIME ].sort(); @@ -230,4 +234,10 @@ suite('Java Language Extension - Standard', () => { assert(java.hasDebugFlag(['foo', '--debug=1234'])); assert(java.hasDebugFlag(['foo', '--debug-brk=1234'])); }); + + test('should preserve escaped commas in code action snippets', () => { + const snippet = '${1|HashMap,Map|} ${2:x} = new HashMap();'; + + assert.equal(escapeSnippetLiterals(snippet), snippet); + }); }); diff --git a/test/standard-mode-suite/hoverLinks.test.ts b/test/standard-mode-suite/hoverLinks.test.ts new file mode 100644 index 000000000..627dc8867 --- /dev/null +++ b/test/standard-mode-suite/hoverLinks.test.ts @@ -0,0 +1,37 @@ +'use strict'; + +import * as assert from 'assert'; +import { Hover, MarkdownString } from 'vscode'; +import { fixJdtSchemeHoverLinks } from '../../src/providerDispatcher'; + +suite('Hover Links Test', () => { + + test('trusted contributed command links are preserved (super implementation)', () => { + const contributed = new MarkdownString('[Go to Super Implementation](command:java.action.navigateToSuperImplementation?%5B%5D)'); + contributed.isTrusted = { enabledCommands: ['java.action.navigateToSuperImplementation'] }; + const hover = new Hover([contributed]); + + const fixed = fixJdtSchemeHoverLinks(hover); + const value = (fixed.contents[0] as MarkdownString).value; + assert.ok(value.includes('(command:java.action.navigateToSuperImplementation'), 'contributed command link should not be sanitized'); + }); + + test('untrusted server command links are sanitized', () => { + const javadoc = new MarkdownString('[click here](command:evil.command?param=true)'); + const hover = new Hover([javadoc]); + + const fixed = fixJdtSchemeHoverLinks(hover); + const value = (fixed.contents[0] as MarkdownString).value; + assert.strictEqual(value, 'click here', 'server command link should be stripped to its label'); + }); + + test('jdt:// links are converted to command links', () => { + const javadoc = new MarkdownString('[String](jdt://contents/Foo.class)'); + const hover = new Hover([javadoc]); + + const fixed = fixJdtSchemeHoverLinks(hover); + const value = (fixed.contents[0] as MarkdownString).value; + assert.ok(value.includes('(command:'), 'jdt link should be converted to a command link'); + assert.ok(!value.includes('jdt://'), 'jdt scheme should be replaced'); + }); +}); diff --git a/test/standard-mode-suite/javaServerStarter.test.ts b/test/standard-mode-suite/javaServerStarter.test.ts new file mode 100644 index 000000000..95e898d26 --- /dev/null +++ b/test/standard-mode-suite/javaServerStarter.test.ts @@ -0,0 +1,103 @@ +'use strict'; + +import * as assert from 'assert'; +import { platform } from 'os'; +import { getUnicodeLocaleEnv, LOCALE_ENV_VARS, UTF8_LOCALE } from '../../src/javaServerStarter'; + +function setLocale(...values: [string, string][]): void { + for (const name of LOCALE_ENV_VARS) { + delete process.env[name]; + } + for (const [name, value] of values) { + process.env[name] = value; + } +} + +function utf8Env(variable: string): { [key: string]: string } { + const env: { [key: string]: string } = {}; + env[variable] = UTF8_LOCALE; + return env; +} + +suite('Java Server Starter Test', () => { + + const saved: [string, string][] = []; + + suiteSetup(() => { + for (const name of LOCALE_ENV_VARS) { + if (process.env[name] !== undefined) { + saved.push([name, process.env[name]]); + } + } + }); + + suiteTeardown(() => { + setLocale(...saved); + }); + + test('getUnicodeLocaleEnv() - never overrides the locale on Windows', function () { + if (platform() !== 'win32') { + this.skip(); + } + setLocale(); + assert.deepStrictEqual(getUnicodeLocaleEnv(), {}); + }); + + test('getUnicodeLocaleEnv() - forces UTF-8 when the locale is unset', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(); + assert.deepStrictEqual(getUnicodeLocaleEnv(), utf8Env('LC_CTYPE')); + }); + + test('getUnicodeLocaleEnv() - forces UTF-8 for ASCII only locales', function () { + if (platform() === 'win32') { + this.skip(); + } + for (const locale of ['C', 'POSIX', 'C.ASCII']) { + setLocale(['LANG', locale]); + assert.deepStrictEqual(getUnicodeLocaleEnv(), utf8Env('LC_CTYPE'), `LANG=${locale}`); + } + }); + + test('getUnicodeLocaleEnv() - keeps an existing UTF-8 locale', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(['LANG', 'en_US.UTF-8']); + assert.deepStrictEqual(getUnicodeLocaleEnv(), {}); + }); + + test('getUnicodeLocaleEnv() - keeps a deliberately configured non-UTF-8 locale', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(['LANG', 'zh_CN.GBK']); + assert.deepStrictEqual(getUnicodeLocaleEnv(), {}); + }); + + test('getUnicodeLocaleEnv() - replaces LC_ALL because it overrides every other category', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(['LC_ALL', 'C'], ['LANG', 'en_US.UTF-8']); + assert.deepStrictEqual(getUnicodeLocaleEnv(), utf8Env('LC_ALL')); + }); + + test('getUnicodeLocaleEnv() - only corrects LC_CTYPE when LC_ALL is unset', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(['LC_CTYPE', 'C'], ['LANG', 'en_US.UTF-8']); + assert.deepStrictEqual(getUnicodeLocaleEnv(), utf8Env('LC_CTYPE')); + }); + + test('getUnicodeLocaleEnv() - LC_CTYPE takes precedence over LANG', function () { + if (platform() === 'win32') { + this.skip(); + } + setLocale(['LC_CTYPE', 'en_US.UTF-8'], ['LANG', 'C']); + assert.deepStrictEqual(getUnicodeLocaleEnv(), {}); + }); +}); diff --git a/test/standard-mode-suite/standardLanguageClient.test.ts b/test/standard-mode-suite/standardLanguageClient.test.ts new file mode 100644 index 000000000..f30564da3 --- /dev/null +++ b/test/standard-mode-suite/standardLanguageClient.test.ts @@ -0,0 +1,83 @@ +'use strict'; + +import * as assert from 'assert'; +import { Executable, TransportKind } from 'vscode-languageclient/node'; +import { startWithStdioFallback, StartableLanguageClient } from '../../src/standardLanguageClientStart'; + +class TestLanguageClient implements StartableLanguageClient { + public startCount = 0; + + constructor(private readonly startResult: Promise) { + } + + public start(): Promise { + this.startCount++; + return this.startResult; + } +} + +suite('Standard Language Client Test', () => { + + test('startWithStdioFallback() - does not fall back when pipe start rejects', async () => { + const pipeClient = new TestLanguageClient(Promise.reject(new Error('pipe failed'))); + const stdioClient = new TestLanguageClient(Promise.resolve()); + const pipeOptions = createServerOptions(TransportKind.pipe); + let fallbackOptions: Executable | undefined; + + await assert.rejects(startWithStdioFallback({ + languageClient: pipeClient, + serverOptions: pipeOptions, + createLanguageClient: serverOptions => { + fallbackOptions = serverOptions; + return stdioClient; + }, + pipeStartTimeout: 1000, + }), /pipe failed/); + + assert.equal(pipeClient.startCount, 1); + assert.equal(stdioClient.startCount, 0); + assert.equal(fallbackOptions, undefined); + }); + + test('startWithStdioFallback() - falls back when pipe start times out', async () => { + const pipeClient = new TestLanguageClient(new Promise(() => { /* never resolves */ })); + const stdioClient = new TestLanguageClient(Promise.resolve()); + let fallbackError: any; + + const result = await startWithStdioFallback({ + languageClient: pipeClient, + serverOptions: createServerOptions(TransportKind.pipe), + createLanguageClient: () => stdioClient, + pipeStartTimeout: 1, + onFallback: error => fallbackError = error, + }); + + assert.equal(pipeClient.startCount, 1); + assert.equal(stdioClient.startCount, 1); + assert.equal(result.client, stdioClient); + assert.equal((result.serverOptions as Executable).transport, TransportKind.stdio); + assert.ok(String(fallbackError).includes('timed out')); + }); + + test('startWithStdioFallback() - does not fall back for stdio start failures', async () => { + const stdioClient = new TestLanguageClient(Promise.reject(new Error('stdio failed'))); + + await assert.rejects(startWithStdioFallback({ + languageClient: stdioClient, + serverOptions: createServerOptions(TransportKind.stdio), + createLanguageClient: () => new TestLanguageClient(Promise.resolve()), + pipeStartTimeout: 1, + }), /stdio failed/); + + assert.equal(stdioClient.startCount, 1); + }); +}); + +function createServerOptions(transport: TransportKind): Executable { + return { + command: 'java', + args: ['-version'], + options: { env: { test: 'true' } }, + transport, + }; +}